summaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_sideeffect.c
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2007-10-24 21:59:16 +0200
committerVlad Yasevich <vladislav.yasevich@hp.com>2007-11-07 17:39:27 +0100
commitb6157d8e03e1e780660a328f7183bcbfa4a93a19 (patch)
treecff4da4725b1bb0c5b603dc07204697dd0623ad5 /net/sctp/sm_sideeffect.c
parentSCTP : Fix to process bundled ASCONF chunk correctly (diff)
downloadlinux-b6157d8e03e1e780660a328f7183bcbfa4a93a19.tar.xz
linux-b6157d8e03e1e780660a328f7183bcbfa4a93a19.zip
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/sm_sideeffect.c')
-rw-r--r--net/sctp/sm_sideeffect.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index bbdc938da86f..78d1a8a49bd0 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -453,6 +453,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
* maximum value discussed in rule C7 above (RTO.max) may be
* used to provide an upper bound to this doubling operation.
*/
+ transport->last_rto = transport->rto;
transport->rto = min((transport->rto * 2), transport->asoc->rto_max);
}
@@ -1267,6 +1268,12 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
sctp_ootb_pkt_free(packet);
break;
+ case SCTP_CMD_T1_RETRAN:
+ /* Mark a transport for retransmission. */
+ sctp_retransmit(&asoc->outqueue, cmd->obj.transport,
+ SCTP_RTXR_T1_RTX);
+ break;
+
case SCTP_CMD_RETRAN:
/* Mark a transport for retransmission. */
sctp_retransmit(&asoc->outqueue, cmd->obj.transport,
@@ -1393,7 +1400,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
list_for_each(pos, &asoc->peer.transport_addr_list) {
t = list_entry(pos, struct sctp_transport,
transports);
- sctp_retransmit_mark(&asoc->outqueue, t, 0);
+ sctp_retransmit_mark(&asoc->outqueue, t,
+ SCTP_RTXR_T1_RTX);
}
sctp_add_cmd_sf(commands,