diff options
author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2007-10-24 15:59:16 -0400 |
---|---|---|
committer | Vlad Yasevich <vladislav.yasevich@hp.com> | 2007-11-07 11:39:27 -0500 |
commit | b6157d8e03e1e780660a328f7183bcbfa4a93a19 (patch) | |
tree | cff4da4725b1bb0c5b603dc07204697dd0623ad5 /net/sctp/transport.c | |
parent | f3830ccc2ea503ab37d605f6c313d61423ddd94e (diff) |
SCTP: Fix difference cases of retransmit.
Commit d0ce92910bc04e107b2f3f2048f07e94f570035d broke several retransmit
cases including fast retransmit. The reason is that we should
only delay by rto while doing retranmists as a result of a timeout.
Retransmit as a result of path mtu discover, fast retransmit, or
other evernts that should trigger immidiate retransmissions got broken.
Also, since rto is doubled prior to marking of packets elegable for
retransmission, we never marked correct chunks anyway.
The fix is provide a reason for a given retransmission so that we
can mark chunks appropriately and to save the old rto value to do
comparisons against.
All regressions tests passed with this code.
Spotted by Wei Yongjun <yjwei@cn.fujitsu.com>
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Diffstat (limited to 'net/sctp/transport.c')
-rw-r--r-- | net/sctp/transport.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 5f467c914f80..d55ce83a020b 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -74,8 +74,8 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, | |||
74 | * given destination transport address, set RTO to the protocol | 74 | * given destination transport address, set RTO to the protocol |
75 | * parameter 'RTO.Initial'. | 75 | * parameter 'RTO.Initial'. |
76 | */ | 76 | */ |
77 | peer->last_rto = peer->rto = msecs_to_jiffies(sctp_rto_initial); | ||
77 | peer->rtt = 0; | 78 | peer->rtt = 0; |
78 | peer->rto = msecs_to_jiffies(sctp_rto_initial); | ||
79 | peer->rttvar = 0; | 79 | peer->rttvar = 0; |
80 | peer->srtt = 0; | 80 | peer->srtt = 0; |
81 | peer->rto_pending = 0; | 81 | peer->rto_pending = 0; |
@@ -385,6 +385,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt) | |||
385 | tp->rto = tp->asoc->rto_max; | 385 | tp->rto = tp->asoc->rto_max; |
386 | 386 | ||
387 | tp->rtt = rtt; | 387 | tp->rtt = rtt; |
388 | tp->last_rto = tp->rto; | ||
388 | 389 | ||
389 | /* Reset rto_pending so that a new RTT measurement is started when a | 390 | /* Reset rto_pending so that a new RTT measurement is started when a |
390 | * new data chunk is sent. | 391 | * new data chunk is sent. |
@@ -578,7 +579,7 @@ void sctp_transport_reset(struct sctp_transport *t) | |||
578 | */ | 579 | */ |
579 | t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380)); | 580 | t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380)); |
580 | t->ssthresh = asoc->peer.i.a_rwnd; | 581 | t->ssthresh = asoc->peer.i.a_rwnd; |
581 | t->rto = asoc->rto_initial; | 582 | t->last_rto = t->rto = asoc->rto_initial; |
582 | t->rtt = 0; | 583 | t->rtt = 0; |
583 | t->srtt = 0; | 584 | t->srtt = 0; |
584 | t->rttvar = 0; | 585 | t->rttvar = 0; |