Skip to content

Commit

Permalink
mptcp: fix unblocking connect()
Browse files Browse the repository at this point in the history
[ Upstream commit 41be81a ]

Currently unblocking connect() on MPTCP sockets fails frequently.
If mptcp_stream_connect() is invoked to complete a previously
attempted unblocking connection, it will still try to create
the first subflow via __mptcp_socket_create(). If the 3whs is
completed and the 'can_ack' flag is already set, the latter
will fail with -EINVAL.

This change addresses the issue checking for pending connect and
delegating the completion to the first subflow. Additionally
do msk addresses and sk_state changes only when needed.

Fixes: 2303f99 ("mptcp: Associate MPTCP context with TCP socket")
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Paolo Abeni authored and gregkh committed Jun 10, 2020
1 parent 691f6c8 commit 63f44ab
Showing 1 changed file with 18 additions and 2 deletions.
20 changes: 18 additions & 2 deletions net/mptcp/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,14 @@ static int mptcp_stream_connect(struct socket *sock, struct sockaddr *uaddr,
int err;

lock_sock(sock->sk);
if (sock->state != SS_UNCONNECTED && msk->subflow) {
/* pending connection or invalid state, let existing subflow
* cope with that
*/
ssock = msk->subflow;
goto do_connect;
}

ssock = __mptcp_socket_create(msk, TCP_SYN_SENT);
if (IS_ERR(ssock)) {
err = PTR_ERR(ssock);
Expand All @@ -934,9 +942,17 @@ static int mptcp_stream_connect(struct socket *sock, struct sockaddr *uaddr,
mptcp_subflow_ctx(ssock->sk)->request_mptcp = 0;
#endif

do_connect:
err = ssock->ops->connect(ssock, uaddr, addr_len, flags);
inet_sk_state_store(sock->sk, inet_sk_state_load(ssock->sk));
mptcp_copy_inaddrs(sock->sk, ssock->sk);
sock->state = ssock->state;

/* on successful connect, the msk state will be moved to established by
* subflow_finish_connect()
*/
if (!err || err == EINPROGRESS)
mptcp_copy_inaddrs(sock->sk, ssock->sk);
else
inet_sk_state_store(sock->sk, inet_sk_state_load(ssock->sk));

unlock:
release_sock(sock->sk);
Expand Down

0 comments on commit 63f44ab

Please sign in to comment.