Skip to content
This repository has been archived by the owner on Apr 18, 2024. It is now read-only.

Commit

Permalink
mptcp: Don't update meta-RTO from subflows that are retransmitting
Browse files Browse the repository at this point in the history
Because, the RTO of these subflows is inflated. Thus, if you have one
bad subflow hanging around, the MPTCP RTO-timer can blow up to the order
of minutes. Better to ignore the RTO of these subflows.

The following packet-drill script illustrates the behavior:

--tolerance_usecs=100000
+0	`sysctl -w net.mptcp.mptcp_checksum=0`

+0	socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0	setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0	setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0
+0	fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
+0	bind(3, {sa_family = AF_INET, sin_port = htons(13000), sin_addr = inet_addr("192.168.0.1")}, ...) = 0
+0	listen(3, 1) = 0

+0	socket(..., SOCK_STREAM, IPPROTO_TCP) = 5
+0	setsockopt(5, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0	bind(5, {sa_family = AF_INET, sin_port = htons(13001), sin_addr = inet_addr("192.168.0.1")}, ...) = 0
+0	listen(5,1) = 0

+0	< S 0:0(0) win 32792 <mss 1460,sackOK,nop,nop,nop,wscale 7,mp_capable_no_cs key_a> sock(3)
+0	> S. 0:0(0) ack 1 win 28800 <mss 1460,nop,nop,sackOK,nop,wscale 7,mp_capable_no_cs key_b> sock(3)
+0	< . 1:1(0) ack 1 win 257 <mp_capable_no_cs key_a key_b> sock(3)
+0	accept(3, ..., ...) = 4
+0	fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0

+0	write(4, ..., 1000) = 1000
+0	> P. 1:1001(1000) ack 1 <dss dack4 dsn4 nocs, nop, nop> sock(4)
+0	< . 1:1(0) ack 1001 win 4242 <dss dack4=1001> sock(4)
+0	write(4, ..., 1000) = 1000
+0	> P. 1001:2001(1000) ack 1 <dss dack4 dsn4 nocs, nop, nop> sock(4)
+0	write(4, ..., 1000) = 1000
+0	> P. 2001:3001(1000) ack 1 <dss dack4 dsn4 nocs, nop, nop> sock(4)
+0	write(4, ..., 1000) = 1000
+0	> P. 3001:4001(1000) ack 1 <dss dack4 dsn4 nocs, nop, nop> sock(4)
+0	write(4, ..., 1000) = 1000
+0	> P. 4001:5001(1000) ack 1 <dss dack4 dsn4 nocs, nop, nop> sock(4)

+0	< . 1:1(0) ack 5001 win 4242 <dss dack4=1001> sock(4)

/* ACK, without advencing dack: Now, the only way to recover is through a meta-retransmission timer */

/* Meta-level rexmit should fire in 400ms */

+0	write(4, ..., 1000) = 1000
+0	> P. 5001:6001(1000) ack 1 <dss dack4 dsn4=5001 nocs, nop, nop> sock(4)

+0.2	> P. 5001:6001(1000) ack 1 <dss dack4 dsn4=5001 nocs, nop, nop> sock(4)

/* Pushing out the timer */
+0.1	< . 1:1(0) ack 5001 win 4242 <dss dack4=2001> sock(4)

+0.2	> P. 5001:6001(1000) ack 1 <dss dack4 dsn4=5001 nocs, nop, nop> sock(4)

/* This one reschedules the meta-timer */
+0.01	< . 1:1(0) ack 5001 win 4242 <dss dack4=3001> sock(4)

+0	< S 0:0(0) win 32792 <mss 1460,sackOK,nop,nop,nop,wscale 7,mp_join_syn backup=0 address_id=0 token=sha1_32(key_b)> sock(5)
+0	> S. 0:0(0) ack 1 win 28800 <mss 1460,nop,nop,sackOK,nop,wscale 7, mp_join_syn_ack backup=0 address_id=0 sender_hmac=trunc_l64_hmac(key_b key_a) > sock(5)
+0	< . 1:1(0) ack 1 win 32792 <mp_join_ack sender_hmac=full_160_hmac(key_a key_b)> sock(5)
+0	mp_join_accept(5) = 6

+0	> . 1:1(0) ack 1 <...> sock(6) // reliably mp_join_ack

/* This first one is a reinjection. */
+0	> P. 1:1001(1000) ack 1 <dss dack4 dsn4=5001 nocs, nop, nop> sock(6)
+0	< . 1:1(0) ack 1001 win 4242 <dss dack4=3001> sock(6)

+0.4	> P. 5001:6001(1000) ack 1 <dss dack4 dsn4=5001 nocs, nop, nop> sock(4)

/* Fire, in 400ms after the above-mentioned ACK as the only working subflow has na RTO of 200ms */
+0	> P. 1001:2001(1000) ack 1 <dss dack4 dsn4=3001 nocs, nop, nop> sock(6)

+0	`sysctl -w net.mptcp.mptcp_checksum=1`

Signed-off-by: Christoph Paasch <[email protected]>
Signed-off-by: Matthieu Baerts <[email protected]>
  • Loading branch information
cpaasch authored and matttbe committed Mar 13, 2019
1 parent 98b2293 commit fc29b3a
Showing 1 changed file with 1 addition and 0 deletions.
1 change: 1 addition & 0 deletions include/net/mptcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -1195,6 +1195,7 @@ static inline void mptcp_set_rto(struct sock *sk)
struct sock *sk_it = mptcp_to_sock(mptcp);

if ((mptcp_sk_can_send(sk_it) || sk_it->sk_state == TCP_SYN_RECV) &&
inet_csk(sk_it)->icsk_retransmits == 0 &&
inet_csk(sk_it)->icsk_rto > max_rto)
max_rto = inet_csk(sk_it)->icsk_rto;
}
Expand Down

0 comments on commit fc29b3a

Please sign in to comment.