Skip to content

Commit 27e5ccc

Browse files
Paolo Abenidavem330
authored andcommitted
mptcp: fix dangling connection hang-up
According to RFC 8684 section 3.3: A connection is not closed unless [...] or an implementation-specific connection-level send timeout. Currently the MPTCP protocol does not implement such timeout, and connection timing-out at the TCP-level never move to close state. Introduces a catch-up condition at subflow close time to move the MPTCP socket to close, too. That additionally allows removing similar existing inside the worker. Finally, allow some additional timeout for plain ESTABLISHED mptcp sockets, as the protocol allows creating new subflows even at that point and making the connection functional again. This issue is actually present since the beginning, but it is basically impossible to solve without a long chain of functional pre-requisites topped by commit bbd49d1 ("mptcp: consolidate transition to TCP_CLOSE in mptcp_do_fastclose()"). When backporting this current patch, please also backport this other commit as well. Closes: multipath-tcp/mptcp_net-next#430 Fixes: e16163b ("mptcp: refactor shutdown and close") Cc: [email protected] Signed-off-by: Paolo Abeni <[email protected]> Reviewed-by: Matthieu Baerts <[email protected]> Reviewed-by: Mat Martineau <[email protected]> Signed-off-by: Matthieu Baerts <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f6909dc commit 27e5ccc

File tree

3 files changed

+65
-44
lines changed

3 files changed

+65
-44
lines changed

net/mptcp/protocol.c

Lines changed: 42 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,7 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
892892
mptcp_subflow_ctx(ssk)->subflow_id = msk->subflow_id++;
893893
mptcp_sockopt_sync_locked(msk, ssk);
894894
mptcp_subflow_joined(msk, ssk);
895+
mptcp_stop_tout_timer(sk);
895896
return true;
896897
}
897898

@@ -2369,18 +2370,14 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
23692370
bool dispose_it, need_push = false;
23702371

23712372
/* If the first subflow moved to a close state before accept, e.g. due
2372-
* to an incoming reset, mptcp either:
2373-
* - if either the subflow or the msk are dead, destroy the context
2374-
* (the subflow socket is deleted by inet_child_forget) and the msk
2375-
* - otherwise do nothing at the moment and take action at accept and/or
2376-
* listener shutdown - user-space must be able to accept() the closed
2377-
* socket.
2373+
* to an incoming reset or listener shutdown, the subflow socket is
2374+
* already deleted by inet_child_forget() and the mptcp socket can't
2375+
* survive too.
23782376
*/
2379-
if (msk->in_accept_queue && msk->first == ssk) {
2380-
if (!sock_flag(sk, SOCK_DEAD) && !sock_flag(ssk, SOCK_DEAD))
2381-
return;
2382-
2377+
if (msk->in_accept_queue && msk->first == ssk &&
2378+
(sock_flag(sk, SOCK_DEAD) || sock_flag(ssk, SOCK_DEAD))) {
23832379
/* ensure later check in mptcp_worker() will dispose the msk */
2380+
mptcp_set_close_tout(sk, tcp_jiffies32 - (TCP_TIMEWAIT_LEN + 1));
23842381
sock_set_flag(sk, SOCK_DEAD);
23852382
lock_sock_nested(ssk, SINGLE_DEPTH_NESTING);
23862383
mptcp_subflow_drop_ctx(ssk);
@@ -2443,6 +2440,22 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
24432440
out:
24442441
if (need_push)
24452442
__mptcp_push_pending(sk, 0);
2443+
2444+
/* Catch every 'all subflows closed' scenario, including peers silently
2445+
* closing them, e.g. due to timeout.
2446+
* For established sockets, allow an additional timeout before closing,
2447+
* as the protocol can still create more subflows.
2448+
*/
2449+
if (list_is_singular(&msk->conn_list) && msk->first &&
2450+
inet_sk_state_load(msk->first) == TCP_CLOSE) {
2451+
if (sk->sk_state != TCP_ESTABLISHED ||
2452+
msk->in_accept_queue || sock_flag(sk, SOCK_DEAD)) {
2453+
inet_sk_state_store(sk, TCP_CLOSE);
2454+
mptcp_close_wake_up(sk);
2455+
} else {
2456+
mptcp_start_tout_timer(sk);
2457+
}
2458+
}
24462459
}
24472460

24482461
void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
@@ -2486,23 +2499,14 @@ static void __mptcp_close_subflow(struct sock *sk)
24862499

24872500
}
24882501

2489-
static bool mptcp_should_close(const struct sock *sk)
2502+
static bool mptcp_close_tout_expired(const struct sock *sk)
24902503
{
2491-
s32 delta = tcp_jiffies32 - inet_csk(sk)->icsk_mtup.probe_timestamp;
2492-
struct mptcp_subflow_context *subflow;
2493-
2494-
if (delta >= TCP_TIMEWAIT_LEN || mptcp_sk(sk)->in_accept_queue)
2495-
return true;
2504+
if (!inet_csk(sk)->icsk_mtup.probe_timestamp ||
2505+
sk->sk_state == TCP_CLOSE)
2506+
return false;
24962507

2497-
/* if all subflows are in closed status don't bother with additional
2498-
* timeout
2499-
*/
2500-
mptcp_for_each_subflow(mptcp_sk(sk), subflow) {
2501-
if (inet_sk_state_load(mptcp_subflow_tcp_sock(subflow)) !=
2502-
TCP_CLOSE)
2503-
return false;
2504-
}
2505-
return true;
2508+
return time_after32(tcp_jiffies32,
2509+
inet_csk(sk)->icsk_mtup.probe_timestamp + TCP_TIMEWAIT_LEN);
25062510
}
25072511

25082512
static void mptcp_check_fastclose(struct mptcp_sock *msk)
@@ -2641,15 +2645,16 @@ void mptcp_reset_tout_timer(struct mptcp_sock *msk, unsigned long fail_tout)
26412645
struct sock *sk = (struct sock *)msk;
26422646
unsigned long timeout, close_timeout;
26432647

2644-
if (!fail_tout && !sock_flag(sk, SOCK_DEAD))
2648+
if (!fail_tout && !inet_csk(sk)->icsk_mtup.probe_timestamp)
26452649
return;
26462650

2647-
close_timeout = inet_csk(sk)->icsk_mtup.probe_timestamp - tcp_jiffies32 + jiffies + TCP_TIMEWAIT_LEN;
2651+
close_timeout = inet_csk(sk)->icsk_mtup.probe_timestamp - tcp_jiffies32 + jiffies +
2652+
TCP_TIMEWAIT_LEN;
26482653

26492654
/* the close timeout takes precedence on the fail one, and here at least one of
26502655
* them is active
26512656
*/
2652-
timeout = sock_flag(sk, SOCK_DEAD) ? close_timeout : fail_tout;
2657+
timeout = inet_csk(sk)->icsk_mtup.probe_timestamp ? close_timeout : fail_tout;
26532658

26542659
sk_reset_timer(sk, &sk->sk_timer, timeout);
26552660
}
@@ -2668,8 +2673,6 @@ static void mptcp_mp_fail_no_response(struct mptcp_sock *msk)
26682673
mptcp_subflow_reset(ssk);
26692674
WRITE_ONCE(mptcp_subflow_ctx(ssk)->fail_tout, 0);
26702675
unlock_sock_fast(ssk, slow);
2671-
2672-
mptcp_reset_tout_timer(msk, 0);
26732676
}
26742677

26752678
static void mptcp_do_fastclose(struct sock *sk)
@@ -2706,18 +2709,14 @@ static void mptcp_worker(struct work_struct *work)
27062709
if (test_and_clear_bit(MPTCP_WORK_CLOSE_SUBFLOW, &msk->flags))
27072710
__mptcp_close_subflow(sk);
27082711

2709-
/* There is no point in keeping around an orphaned sk timedout or
2710-
* closed, but we need the msk around to reply to incoming DATA_FIN,
2711-
* even if it is orphaned and in FIN_WAIT2 state
2712-
*/
2713-
if (sock_flag(sk, SOCK_DEAD)) {
2714-
if (mptcp_should_close(sk))
2715-
mptcp_do_fastclose(sk);
2712+
if (mptcp_close_tout_expired(sk)) {
2713+
mptcp_do_fastclose(sk);
2714+
mptcp_close_wake_up(sk);
2715+
}
27162716

2717-
if (sk->sk_state == TCP_CLOSE) {
2718-
__mptcp_destroy_sock(sk);
2719-
goto unlock;
2720-
}
2717+
if (sock_flag(sk, SOCK_DEAD) && sk->sk_state == TCP_CLOSE) {
2718+
__mptcp_destroy_sock(sk);
2719+
goto unlock;
27212720
}
27222721

27232722
if (test_and_clear_bit(MPTCP_WORK_RTX, &msk->flags))
@@ -3016,7 +3015,6 @@ bool __mptcp_close(struct sock *sk, long timeout)
30163015

30173016
cleanup:
30183017
/* orphan all the subflows */
3019-
inet_csk(sk)->icsk_mtup.probe_timestamp = tcp_jiffies32;
30203018
mptcp_for_each_subflow(msk, subflow) {
30213019
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
30223020
bool slow = lock_sock_fast_nested(ssk);
@@ -3053,7 +3051,7 @@ bool __mptcp_close(struct sock *sk, long timeout)
30533051
__mptcp_destroy_sock(sk);
30543052
do_cancel_work = true;
30553053
} else {
3056-
mptcp_reset_tout_timer(msk, 0);
3054+
mptcp_start_tout_timer(sk);
30573055
}
30583056

30593057
return do_cancel_work;
@@ -3117,7 +3115,7 @@ static int mptcp_disconnect(struct sock *sk, int flags)
31173115
inet_sk_state_store(sk, TCP_CLOSE);
31183116

31193117
mptcp_stop_rtx_timer(sk);
3120-
sk_stop_timer(sk, &sk->sk_timer);
3118+
mptcp_stop_tout_timer(sk);
31213119

31223120
if (msk->token)
31233121
mptcp_event(MPTCP_EVENT_CLOSED, msk, NULL, GFP_KERNEL);

net/mptcp/protocol.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,28 @@ void mptcp_get_options(const struct sk_buff *skb,
719719
void mptcp_finish_connect(struct sock *sk);
720720
void __mptcp_set_connected(struct sock *sk);
721721
void mptcp_reset_tout_timer(struct mptcp_sock *msk, unsigned long fail_tout);
722+
723+
static inline void mptcp_stop_tout_timer(struct sock *sk)
724+
{
725+
if (!inet_csk(sk)->icsk_mtup.probe_timestamp)
726+
return;
727+
728+
sk_stop_timer(sk, &sk->sk_timer);
729+
inet_csk(sk)->icsk_mtup.probe_timestamp = 0;
730+
}
731+
732+
static inline void mptcp_set_close_tout(struct sock *sk, unsigned long tout)
733+
{
734+
/* avoid 0 timestamp, as that means no close timeout */
735+
inet_csk(sk)->icsk_mtup.probe_timestamp = tout ? : 1;
736+
}
737+
738+
static inline void mptcp_start_tout_timer(struct sock *sk)
739+
{
740+
mptcp_set_close_tout(sk, tcp_jiffies32);
741+
mptcp_reset_tout_timer(mptcp_sk(sk), 0);
742+
}
743+
722744
static inline bool mptcp_is_fully_established(struct sock *sk)
723745
{
724746
return inet_sk_state_load(sk) == TCP_ESTABLISHED &&

net/mptcp/subflow.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,6 +1552,7 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
15521552
mptcp_sock_graft(ssk, sk->sk_socket);
15531553
iput(SOCK_INODE(sf));
15541554
WRITE_ONCE(msk->allow_infinite_fallback, false);
1555+
mptcp_stop_tout_timer(sk);
15551556
return 0;
15561557

15571558
failed_unlink:

0 commit comments

Comments
 (0)