diff options
Diffstat (limited to 'net/sctp/outqueue.c')
-rw-r--r-- | net/sctp/outqueue.c | 120 |
1 files changed, 77 insertions, 43 deletions
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 59edfd25a19c..ace6770e9048 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -208,6 +208,7 @@ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) | |||
208 | INIT_LIST_HEAD(&q->sacked); | 208 | INIT_LIST_HEAD(&q->sacked); |
209 | INIT_LIST_HEAD(&q->abandoned); | 209 | INIT_LIST_HEAD(&q->abandoned); |
210 | 210 | ||
211 | q->fast_rtx = 0; | ||
211 | q->outstanding_bytes = 0; | 212 | q->outstanding_bytes = 0; |
212 | q->empty = 1; | 213 | q->empty = 1; |
213 | q->cork = 0; | 214 | q->cork = 0; |
@@ -500,6 +501,7 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport, | |||
500 | case SCTP_RTXR_FAST_RTX: | 501 | case SCTP_RTXR_FAST_RTX: |
501 | SCTP_INC_STATS(SCTP_MIB_FAST_RETRANSMITS); | 502 | SCTP_INC_STATS(SCTP_MIB_FAST_RETRANSMITS); |
502 | sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX); | 503 | sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX); |
504 | q->fast_rtx = 1; | ||
503 | break; | 505 | break; |
504 | case SCTP_RTXR_PMTUD: | 506 | case SCTP_RTXR_PMTUD: |
505 | SCTP_INC_STATS(SCTP_MIB_PMTUD_RETRANSMITS); | 507 | SCTP_INC_STATS(SCTP_MIB_PMTUD_RETRANSMITS); |
@@ -518,9 +520,15 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport, | |||
518 | * the sender SHOULD try to advance the "Advanced.Peer.Ack.Point" by | 520 | * the sender SHOULD try to advance the "Advanced.Peer.Ack.Point" by |
519 | * following the procedures outlined in C1 - C5. | 521 | * following the procedures outlined in C1 - C5. |
520 | */ | 522 | */ |
521 | sctp_generate_fwdtsn(q, q->asoc->ctsn_ack_point); | 523 | if (reason == SCTP_RTXR_T3_RTX) |
524 | sctp_generate_fwdtsn(q, q->asoc->ctsn_ack_point); | ||
522 | 525 | ||
523 | error = sctp_outq_flush(q, /* rtx_timeout */ 1); | 526 | /* Flush the queues only on timeout, since fast_rtx is only |
527 | * triggered during sack processing and the queue | ||
528 | * will be flushed at the end. | ||
529 | */ | ||
530 | if (reason != SCTP_RTXR_FAST_RTX) | ||
531 | error = sctp_outq_flush(q, /* rtx_timeout */ 1); | ||
524 | 532 | ||
525 | if (error) | 533 | if (error) |
526 | q->asoc->base.sk->sk_err = -error; | 534 | q->asoc->base.sk->sk_err = -error; |
@@ -538,17 +546,23 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, | |||
538 | int rtx_timeout, int *start_timer) | 546 | int rtx_timeout, int *start_timer) |
539 | { | 547 | { |
540 | struct list_head *lqueue; | 548 | struct list_head *lqueue; |
541 | struct list_head *lchunk; | ||
542 | struct sctp_transport *transport = pkt->transport; | 549 | struct sctp_transport *transport = pkt->transport; |
543 | sctp_xmit_t status; | 550 | sctp_xmit_t status; |
544 | struct sctp_chunk *chunk, *chunk1; | 551 | struct sctp_chunk *chunk, *chunk1; |
545 | struct sctp_association *asoc; | 552 | struct sctp_association *asoc; |
553 | int fast_rtx; | ||
546 | int error = 0; | 554 | int error = 0; |
555 | int timer = 0; | ||
556 | int done = 0; | ||
547 | 557 | ||
548 | asoc = q->asoc; | 558 | asoc = q->asoc; |
549 | lqueue = &q->retransmit; | 559 | lqueue = &q->retransmit; |
560 | fast_rtx = q->fast_rtx; | ||
550 | 561 | ||
551 | /* RFC 2960 6.3.3 Handle T3-rtx Expiration | 562 | /* This loop handles time-out retransmissions, fast retransmissions, |
563 | * and retransmissions due to opening of whindow. | ||
564 | * | ||
565 | * RFC 2960 6.3.3 Handle T3-rtx Expiration | ||
552 | * | 566 | * |
553 | * E3) Determine how many of the earliest (i.e., lowest TSN) | 567 | * E3) Determine how many of the earliest (i.e., lowest TSN) |
554 | * outstanding DATA chunks for the address for which the | 568 | * outstanding DATA chunks for the address for which the |
@@ -563,12 +577,12 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, | |||
563 | * [Just to be painfully clear, if we are retransmitting | 577 | * [Just to be painfully clear, if we are retransmitting |
564 | * because a timeout just happened, we should send only ONE | 578 | * because a timeout just happened, we should send only ONE |
565 | * packet of retransmitted data.] | 579 | * packet of retransmitted data.] |
580 | * | ||
581 | * For fast retransmissions we also send only ONE packet. However, | ||
582 | * if we are just flushing the queue due to open window, we'll | ||
583 | * try to send as much as possible. | ||
566 | */ | 584 | */ |
567 | lchunk = sctp_list_dequeue(lqueue); | 585 | list_for_each_entry_safe(chunk, chunk1, lqueue, transmitted_list) { |
568 | |||
569 | while (lchunk) { | ||
570 | chunk = list_entry(lchunk, struct sctp_chunk, | ||
571 | transmitted_list); | ||
572 | 586 | ||
573 | /* Make sure that Gap Acked TSNs are not retransmitted. A | 587 | /* Make sure that Gap Acked TSNs are not retransmitted. A |
574 | * simple approach is just to move such TSNs out of the | 588 | * simple approach is just to move such TSNs out of the |
@@ -576,58 +590,60 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, | |||
576 | * next chunk. | 590 | * next chunk. |
577 | */ | 591 | */ |
578 | if (chunk->tsn_gap_acked) { | 592 | if (chunk->tsn_gap_acked) { |
579 | list_add_tail(lchunk, &transport->transmitted); | 593 | list_del(&chunk->transmitted_list); |
580 | lchunk = sctp_list_dequeue(lqueue); | 594 | list_add_tail(&chunk->transmitted_list, |
595 | &transport->transmitted); | ||
581 | continue; | 596 | continue; |
582 | } | 597 | } |
583 | 598 | ||
599 | /* If we are doing fast retransmit, ignore non-fast_rtransmit | ||
600 | * chunks | ||
601 | */ | ||
602 | if (fast_rtx && !chunk->fast_retransmit) | ||
603 | continue; | ||
604 | |||
584 | /* Attempt to append this chunk to the packet. */ | 605 | /* Attempt to append this chunk to the packet. */ |
585 | status = sctp_packet_append_chunk(pkt, chunk); | 606 | status = sctp_packet_append_chunk(pkt, chunk); |
586 | 607 | ||
587 | switch (status) { | 608 | switch (status) { |
588 | case SCTP_XMIT_PMTU_FULL: | 609 | case SCTP_XMIT_PMTU_FULL: |
589 | /* Send this packet. */ | 610 | /* Send this packet. */ |
590 | if ((error = sctp_packet_transmit(pkt)) == 0) | 611 | error = sctp_packet_transmit(pkt); |
591 | *start_timer = 1; | ||
592 | 612 | ||
593 | /* If we are retransmitting, we should only | 613 | /* If we are retransmitting, we should only |
594 | * send a single packet. | 614 | * send a single packet. |
595 | */ | 615 | */ |
596 | if (rtx_timeout) { | 616 | if (rtx_timeout || fast_rtx) |
597 | list_add(lchunk, lqueue); | 617 | done = 1; |
598 | lchunk = NULL; | ||
599 | } | ||
600 | 618 | ||
601 | /* Bundle lchunk in the next round. */ | 619 | /* Bundle next chunk in the next round. */ |
602 | break; | 620 | break; |
603 | 621 | ||
604 | case SCTP_XMIT_RWND_FULL: | 622 | case SCTP_XMIT_RWND_FULL: |
605 | /* Send this packet. */ | 623 | /* Send this packet. */ |
606 | if ((error = sctp_packet_transmit(pkt)) == 0) | 624 | error = sctp_packet_transmit(pkt); |
607 | *start_timer = 1; | ||
608 | 625 | ||
609 | /* Stop sending DATA as there is no more room | 626 | /* Stop sending DATA as there is no more room |
610 | * at the receiver. | 627 | * at the receiver. |
611 | */ | 628 | */ |
612 | list_add(lchunk, lqueue); | 629 | done = 1; |
613 | lchunk = NULL; | ||
614 | break; | 630 | break; |
615 | 631 | ||
616 | case SCTP_XMIT_NAGLE_DELAY: | 632 | case SCTP_XMIT_NAGLE_DELAY: |
617 | /* Send this packet. */ | 633 | /* Send this packet. */ |
618 | if ((error = sctp_packet_transmit(pkt)) == 0) | 634 | error = sctp_packet_transmit(pkt); |
619 | *start_timer = 1; | ||
620 | 635 | ||
621 | /* Stop sending DATA because of nagle delay. */ | 636 | /* Stop sending DATA because of nagle delay. */ |
622 | list_add(lchunk, lqueue); | 637 | done = 1; |
623 | lchunk = NULL; | ||
624 | break; | 638 | break; |
625 | 639 | ||
626 | default: | 640 | default: |
627 | /* The append was successful, so add this chunk to | 641 | /* The append was successful, so add this chunk to |
628 | * the transmitted list. | 642 | * the transmitted list. |
629 | */ | 643 | */ |
630 | list_add_tail(lchunk, &transport->transmitted); | 644 | list_del(&chunk->transmitted_list); |
645 | list_add_tail(&chunk->transmitted_list, | ||
646 | &transport->transmitted); | ||
631 | 647 | ||
632 | /* Mark the chunk as ineligible for fast retransmit | 648 | /* Mark the chunk as ineligible for fast retransmit |
633 | * after it is retransmitted. | 649 | * after it is retransmitted. |
@@ -635,27 +651,44 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, | |||
635 | if (chunk->fast_retransmit > 0) | 651 | if (chunk->fast_retransmit > 0) |
636 | chunk->fast_retransmit = -1; | 652 | chunk->fast_retransmit = -1; |
637 | 653 | ||
638 | *start_timer = 1; | 654 | /* Force start T3-rtx timer when fast retransmitting |
639 | q->empty = 0; | 655 | * the earliest outstanding TSN |
656 | */ | ||
657 | if (!timer && fast_rtx && | ||
658 | ntohl(chunk->subh.data_hdr->tsn) == | ||
659 | asoc->ctsn_ack_point + 1) | ||
660 | timer = 2; | ||
640 | 661 | ||
641 | /* Retrieve a new chunk to bundle. */ | 662 | q->empty = 0; |
642 | lchunk = sctp_list_dequeue(lqueue); | ||
643 | break; | 663 | break; |
644 | } | 664 | } |
645 | 665 | ||
646 | /* If we are here due to a retransmit timeout or a fast | 666 | /* Set the timer if there were no errors */ |
647 | * retransmit and if there are any chunks left in the retransmit | 667 | if (!error && !timer) |
648 | * queue that could not fit in the PMTU sized packet, they need | 668 | timer = 1; |
649 | * to be marked as ineligible for a subsequent fast retransmit. | 669 | |
650 | */ | 670 | if (done) |
651 | if (rtx_timeout && !lchunk) { | 671 | break; |
652 | list_for_each_entry(chunk1, lqueue, transmitted_list) { | 672 | } |
653 | if (chunk1->fast_retransmit > 0) | 673 | |
654 | chunk1->fast_retransmit = -1; | 674 | /* If we are here due to a retransmit timeout or a fast |
655 | } | 675 | * retransmit and if there are any chunks left in the retransmit |
676 | * queue that could not fit in the PMTU sized packet, they need | ||
677 | * to be marked as ineligible for a subsequent fast retransmit. | ||
678 | */ | ||
679 | if (rtx_timeout || fast_rtx) { | ||
680 | list_for_each_entry(chunk1, lqueue, transmitted_list) { | ||
681 | if (chunk1->fast_retransmit > 0) | ||
682 | chunk1->fast_retransmit = -1; | ||
656 | } | 683 | } |
657 | } | 684 | } |
658 | 685 | ||
686 | *start_timer = timer; | ||
687 | |||
688 | /* Clear fast retransmit hint */ | ||
689 | if (fast_rtx) | ||
690 | q->fast_rtx = 0; | ||
691 | |||
659 | return error; | 692 | return error; |
660 | } | 693 | } |
661 | 694 | ||
@@ -862,7 +895,8 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
862 | rtx_timeout, &start_timer); | 895 | rtx_timeout, &start_timer); |
863 | 896 | ||
864 | if (start_timer) | 897 | if (start_timer) |
865 | sctp_transport_reset_timers(transport); | 898 | sctp_transport_reset_timers(transport, |
899 | start_timer-1); | ||
866 | 900 | ||
867 | /* This can happen on COOKIE-ECHO resend. Only | 901 | /* This can happen on COOKIE-ECHO resend. Only |
868 | * one chunk can get bundled with a COOKIE-ECHO. | 902 | * one chunk can get bundled with a COOKIE-ECHO. |
@@ -977,7 +1011,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
977 | list_add_tail(&chunk->transmitted_list, | 1011 | list_add_tail(&chunk->transmitted_list, |
978 | &transport->transmitted); | 1012 | &transport->transmitted); |
979 | 1013 | ||
980 | sctp_transport_reset_timers(transport); | 1014 | sctp_transport_reset_timers(transport, start_timer-1); |
981 | 1015 | ||
982 | q->empty = 0; | 1016 | q->empty = 0; |
983 | 1017 | ||