Commit 786fc124 authored by Paolo Abeni's avatar Paolo Abeni Committed by Jakub Kicinski
Browse files

mptcp: fix connect timeout handling



Ondrej reported a functional issue WRT timeout handling on connect
with a nice reproducer.

The problem is that the current mptcp connect waits for both the
MPTCP socket level timeout, and the first subflow socket timeout.
The latter is not influenced/touched by the exposed setsockopt().

Overall the above makes the SO_SNDTIMEO a no-op on connect.

Since mptcp_connect is invoked via inet_stream_connect and the
latter properly handle the MPTCP level timeout, we can address the
issue making the nested subflow level connect always unblocking.

This also allow simplifying a bit the code, dropping an ugly hack
to handle the fastopen and custom proto_ops connect.

The issues predates the blamed commit below, but the current resolution
requires the infrastructure introduced there.

Fixes: 54f1944e ("mptcp: factor out mptcp_connect()")
Reported-by: default avatarOndrej Mosnacek <omosnace@redhat.com>
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/399


Cc: stable@vger.kernel.org
Reviewed-by: default avatarMat Martineau <martineau@kernel.org>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarMat Martineau <martineau@kernel.org>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 3021dbfe
Loading
Loading
Loading
Loading
+7 −22
Original line number Diff line number Diff line
@@ -1702,7 +1702,6 @@ static int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,

	lock_sock(ssk);
	msg->msg_flags |= MSG_DONTWAIT;
	msk->connect_flags = O_NONBLOCK;
	msk->fastopening = 1;
	ret = tcp_sendmsg_fastopen(ssk, msg, copied_syn, len, NULL);
	msk->fastopening = 0;
@@ -3617,9 +3616,9 @@ static int mptcp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
	 * acquired the subflow socket lock, too.
	 */
	if (msk->fastopening)
		err = __inet_stream_connect(ssock, uaddr, addr_len, msk->connect_flags, 1);
		err = __inet_stream_connect(ssock, uaddr, addr_len, O_NONBLOCK, 1);
	else
		err = inet_stream_connect(ssock, uaddr, addr_len, msk->connect_flags);
		err = inet_stream_connect(ssock, uaddr, addr_len, O_NONBLOCK);
	inet_sk(sk)->defer_connect = inet_sk(ssock->sk)->defer_connect;

	/* on successful connect, the msk state will be moved to established by
@@ -3632,12 +3631,10 @@ static int mptcp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)

	mptcp_copy_inaddrs(sk, ssock->sk);

	/* unblocking connect, mptcp-level inet_stream_connect will error out
	 * without changing the socket state, update it here.
	/* silence EINPROGRESS and let the caller inet_stream_connect
	 * handle the connection in progress
	 */
	if (err == -EINPROGRESS)
		sk->sk_socket->state = ssock->state;
	return err;
	return 0;
}

static struct proto mptcp_prot = {
@@ -3696,18 +3693,6 @@ static int mptcp_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
	return err;
}

static int mptcp_stream_connect(struct socket *sock, struct sockaddr *uaddr,
				int addr_len, int flags)
{
	int ret;

	lock_sock(sock->sk);
	mptcp_sk(sock->sk)->connect_flags = flags;
	ret = __inet_stream_connect(sock, uaddr, addr_len, flags, 0);
	release_sock(sock->sk);
	return ret;
}

static int mptcp_listen(struct socket *sock, int backlog)
{
	struct mptcp_sock *msk = mptcp_sk(sock->sk);
@@ -3859,7 +3844,7 @@ static const struct proto_ops mptcp_stream_ops = {
	.owner		   = THIS_MODULE,
	.release	   = inet_release,
	.bind		   = mptcp_bind,
	.connect	   = mptcp_stream_connect,
	.connect	   = inet_stream_connect,
	.socketpair	   = sock_no_socketpair,
	.accept		   = mptcp_stream_accept,
	.getname	   = inet_getname,
@@ -3954,7 +3939,7 @@ static const struct proto_ops mptcp_v6_stream_ops = {
	.owner		   = THIS_MODULE,
	.release	   = inet6_release,
	.bind		   = mptcp_bind,
	.connect	   = mptcp_stream_connect,
	.connect	   = inet_stream_connect,
	.socketpair	   = sock_no_socketpair,
	.accept		   = mptcp_stream_accept,
	.getname	   = inet6_getname,
+0 −1
Original line number Diff line number Diff line
@@ -297,7 +297,6 @@ struct mptcp_sock {
			nodelay:1,
			fastopening:1,
			in_accept_queue:1;
	int		connect_flags;
	struct work_struct work;
	struct sk_buff  *ooo_last_skb;
	struct rb_root  out_of_order_queue;