diff options
Diffstat (limited to 'net/sctp/outqueue.c')
-rw-r--r-- | net/sctp/outqueue.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 1c88c8911dc5..a6d27bf563a5 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -754,6 +754,16 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
754 | */ | 754 | */ |
755 | 755 | ||
756 | list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) { | 756 | list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) { |
757 | /* RFC 5061, 5.3 | ||
758 | * F1) This means that until such time as the ASCONF | ||
759 | * containing the add is acknowledged, the sender MUST | ||
760 | * NOT use the new IP address as a source for ANY SCTP | ||
761 | * packet except on carrying an ASCONF Chunk. | ||
762 | */ | ||
763 | if (asoc->src_out_of_asoc_ok && | ||
764 | chunk->chunk_hdr->type != SCTP_CID_ASCONF) | ||
765 | continue; | ||
766 | |||
757 | list_del_init(&chunk->list); | 767 | list_del_init(&chunk->list); |
758 | 768 | ||
759 | /* Pick the right transport to use. */ | 769 | /* Pick the right transport to use. */ |
@@ -881,6 +891,9 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
881 | } | 891 | } |
882 | } | 892 | } |
883 | 893 | ||
894 | if (q->asoc->src_out_of_asoc_ok) | ||
895 | goto sctp_flush_out; | ||
896 | |||
884 | /* Is it OK to send data chunks? */ | 897 | /* Is it OK to send data chunks? */ |
885 | switch (asoc->state) { | 898 | switch (asoc->state) { |
886 | case SCTP_STATE_COOKIE_ECHOED: | 899 | case SCTP_STATE_COOKIE_ECHOED: |
@@ -1582,6 +1595,8 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
1582 | #endif /* SCTP_DEBUG */ | 1595 | #endif /* SCTP_DEBUG */ |
1583 | if (transport) { | 1596 | if (transport) { |
1584 | if (bytes_acked) { | 1597 | if (bytes_acked) { |
1598 | struct sctp_association *asoc = transport->asoc; | ||
1599 | |||
1585 | /* We may have counted DATA that was migrated | 1600 | /* We may have counted DATA that was migrated |
1586 | * to this transport due to DEL-IP operation. | 1601 | * to this transport due to DEL-IP operation. |
1587 | * Subtract those bytes, since the were never | 1602 | * Subtract those bytes, since the were never |
@@ -1600,6 +1615,17 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
1600 | transport->error_count = 0; | 1615 | transport->error_count = 0; |
1601 | transport->asoc->overall_error_count = 0; | 1616 | transport->asoc->overall_error_count = 0; |
1602 | 1617 | ||
1618 | /* | ||
1619 | * While in SHUTDOWN PENDING, we may have started | ||
1620 | * the T5 shutdown guard timer after reaching the | ||
1621 | * retransmission limit. Stop that timer as soon | ||
1622 | * as the receiver acknowledged any data. | ||
1623 | */ | ||
1624 | if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING && | ||
1625 | del_timer(&asoc->timers | ||
1626 | [SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD])) | ||
1627 | sctp_association_put(asoc); | ||
1628 | |||
1603 | /* Mark the destination transport address as | 1629 | /* Mark the destination transport address as |
1604 | * active if it is not so marked. | 1630 | * active if it is not so marked. |
1605 | */ | 1631 | */ |
@@ -1629,10 +1655,15 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
1629 | * A sender is doing zero window probing when the | 1655 | * A sender is doing zero window probing when the |
1630 | * receiver's advertised window is zero, and there is | 1656 | * receiver's advertised window is zero, and there is |
1631 | * only one data chunk in flight to the receiver. | 1657 | * only one data chunk in flight to the receiver. |
1658 | * | ||
1659 | * Allow the association to timeout while in SHUTDOWN | ||
1660 | * PENDING or SHUTDOWN RECEIVED in case the receiver | ||
1661 | * stays in zero window mode forever. | ||
1632 | */ | 1662 | */ |
1633 | if (!q->asoc->peer.rwnd && | 1663 | if (!q->asoc->peer.rwnd && |
1634 | !list_empty(&tlist) && | 1664 | !list_empty(&tlist) && |
1635 | (sack_ctsn+2 == q->asoc->next_tsn)) { | 1665 | (sack_ctsn+2 == q->asoc->next_tsn) && |
1666 | q->asoc->state < SCTP_STATE_SHUTDOWN_PENDING) { | ||
1636 | SCTP_DEBUG_PRINTK("%s: SACK received for zero " | 1667 | SCTP_DEBUG_PRINTK("%s: SACK received for zero " |
1637 | "window probe: %u\n", | 1668 | "window probe: %u\n", |
1638 | __func__, sack_ctsn); | 1669 | __func__, sack_ctsn); |