Skip to content

Commit 6477dd3

Browse files
mjmartineaudavem330
authored andcommitted
mptcp: Retransmit DATA_FIN
With this change, the MPTCP-level retransmission timer is used to resend DATA_FIN. The retranmit timer is not stopped while waiting for a MPTCP-level ACK of DATA_FIN, and retransmitted DATA_FINs are sent on all subflows. The retry interval starts at TCP_RTO_MIN and then doubles on each attempt, up to TCP_RTO_MAX. Closes: multipath-tcp/mptcp_net-next#146 Fixes: 43b54c6 ("mptcp: Use full MPTCP-level disconnect state machine") Acked-by: Paolo Abeni <[email protected]> Signed-off-by: Mat Martineau <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d13f048 commit 6477dd3

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

net/mptcp/protocol.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,14 @@ static bool mptcp_pending_data_fin(struct sock *sk, u64 *seq)
399399
return false;
400400
}
401401

402+
static void mptcp_set_datafin_timeout(const struct sock *sk)
403+
{
404+
struct inet_connection_sock *icsk = inet_csk(sk);
405+
406+
mptcp_sk(sk)->timer_ival = min(TCP_RTO_MAX,
407+
TCP_RTO_MIN << icsk->icsk_retransmits);
408+
}
409+
402410
static void mptcp_set_timeout(const struct sock *sk, const struct sock *ssk)
403411
{
404412
long tout = ssk && inet_csk(ssk)->icsk_pending ?
@@ -1052,7 +1060,7 @@ static void __mptcp_clean_una(struct sock *sk)
10521060
}
10531061

10541062
if (snd_una == READ_ONCE(msk->snd_nxt)) {
1055-
if (msk->timer_ival)
1063+
if (msk->timer_ival && !mptcp_data_fin_enabled(msk))
10561064
mptcp_stop_timer(sk);
10571065
} else {
10581066
mptcp_reset_timer(sk);
@@ -2276,8 +2284,19 @@ static void __mptcp_retrans(struct sock *sk)
22762284

22772285
__mptcp_clean_una_wakeup(sk);
22782286
dfrag = mptcp_rtx_head(sk);
2279-
if (!dfrag)
2287+
if (!dfrag) {
2288+
if (mptcp_data_fin_enabled(msk)) {
2289+
struct inet_connection_sock *icsk = inet_csk(sk);
2290+
2291+
icsk->icsk_retransmits++;
2292+
mptcp_set_datafin_timeout(sk);
2293+
mptcp_send_ack(msk);
2294+
2295+
goto reset_timer;
2296+
}
2297+
22802298
return;
2299+
}
22812300

22822301
ssk = mptcp_subflow_get_retrans(msk);
22832302
if (!ssk)
@@ -2460,6 +2479,8 @@ void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how)
24602479
pr_debug("Sending DATA_FIN on subflow %p", ssk);
24612480
mptcp_set_timeout(sk, ssk);
24622481
tcp_send_ack(ssk);
2482+
if (!mptcp_timer_pending(sk))
2483+
mptcp_reset_timer(sk);
24632484
}
24642485
break;
24652486
}

0 commit comments

Comments
 (0)