diff options
Diffstat (limited to 'net/sctp/transport.c')
-rw-r--r-- | net/sctp/transport.c | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 37a1184d789f..b827d21dbe54 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -83,7 +83,6 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, | |||
83 | peer->fast_recovery = 0; | 83 | peer->fast_recovery = 0; |
84 | 84 | ||
85 | peer->last_time_heard = jiffies; | 85 | peer->last_time_heard = jiffies; |
86 | peer->last_time_used = jiffies; | ||
87 | peer->last_time_ecne_reduced = jiffies; | 86 | peer->last_time_ecne_reduced = jiffies; |
88 | 87 | ||
89 | peer->init_sent_count = 0; | 88 | peer->init_sent_count = 0; |
@@ -564,10 +563,8 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, | |||
564 | * to be done every RTO interval, we do it every hearbeat | 563 | * to be done every RTO interval, we do it every hearbeat |
565 | * interval. | 564 | * interval. |
566 | */ | 565 | */ |
567 | if (time_after(jiffies, transport->last_time_used + | 566 | transport->cwnd = max(transport->cwnd/2, |
568 | transport->rto)) | 567 | 4*transport->asoc->pathmtu); |
569 | transport->cwnd = max(transport->cwnd/2, | ||
570 | 4*transport->asoc->pathmtu); | ||
571 | break; | 568 | break; |
572 | } | 569 | } |
573 | 570 | ||
@@ -578,6 +575,43 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, | |||
578 | transport->cwnd, transport->ssthresh); | 575 | transport->cwnd, transport->ssthresh); |
579 | } | 576 | } |
580 | 577 | ||
578 | /* Apply Max.Burst limit to the congestion window: | ||
579 | * sctpimpguide-05 2.14.2 | ||
580 | * D) When the time comes for the sender to | ||
581 | * transmit new DATA chunks, the protocol parameter Max.Burst MUST | ||
582 | * first be applied to limit how many new DATA chunks may be sent. | ||
583 | * The limit is applied by adjusting cwnd as follows: | ||
584 | * if ((flightsize+ Max.Burst * MTU) < cwnd) | ||
585 | * cwnd = flightsize + Max.Burst * MTU | ||
586 | */ | ||
587 | |||
588 | void sctp_transport_burst_limited(struct sctp_transport *t) | ||
589 | { | ||
590 | struct sctp_association *asoc = t->asoc; | ||
591 | u32 old_cwnd = t->cwnd; | ||
592 | u32 max_burst_bytes; | ||
593 | |||
594 | if (t->burst_limited) | ||
595 | return; | ||
596 | |||
597 | max_burst_bytes = t->flight_size + (asoc->max_burst * asoc->pathmtu); | ||
598 | if (max_burst_bytes < old_cwnd) { | ||
599 | t->cwnd = max_burst_bytes; | ||
600 | t->burst_limited = old_cwnd; | ||
601 | } | ||
602 | } | ||
603 | |||
604 | /* Restore the old cwnd congestion window, after the burst had it's | ||
605 | * desired effect. | ||
606 | */ | ||
607 | void sctp_transport_burst_reset(struct sctp_transport *t) | ||
608 | { | ||
609 | if (t->burst_limited) { | ||
610 | t->cwnd = t->burst_limited; | ||
611 | t->burst_limited = 0; | ||
612 | } | ||
613 | } | ||
614 | |||
581 | /* What is the next timeout value for this transport? */ | 615 | /* What is the next timeout value for this transport? */ |
582 | unsigned long sctp_transport_timeout(struct sctp_transport *t) | 616 | unsigned long sctp_transport_timeout(struct sctp_transport *t) |
583 | { | 617 | { |
@@ -600,6 +634,7 @@ void sctp_transport_reset(struct sctp_transport *t) | |||
600 | * (see Section 6.2.1) | 634 | * (see Section 6.2.1) |
601 | */ | 635 | */ |
602 | t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380)); | 636 | t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380)); |
637 | t->burst_limited = 0; | ||
603 | t->ssthresh = asoc->peer.i.a_rwnd; | 638 | t->ssthresh = asoc->peer.i.a_rwnd; |
604 | t->rto = asoc->rto_initial; | 639 | t->rto = asoc->rto_initial; |
605 | t->rtt = 0; | 640 | t->rtt = 0; |