Commit 1954b860 authored by Mat Martineau's avatar Mat Martineau Committed by David S. Miller

mptcp: Check connection state before attempting send

MPTCP should wait for an active connection or skip sending depending on
the connection state, as TCP does. This happens before the possible
passthrough to a regular TCP sendmsg because the subflow's socket type
(MPTCP or TCP fallback) is not known until the connection is
complete. This is also relevent at disconnect time, where data should
not be sent in certain MPTCP-level connection states.
Signed-off-by: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0a303214
...@@ -419,6 +419,15 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -419,6 +419,15 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
return -EOPNOTSUPP; return -EOPNOTSUPP;
lock_sock(sk); lock_sock(sk);
timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
if ((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) {
ret = sk_stream_wait_connect(sk, &timeo);
if (ret)
goto out;
}
ssock = __mptcp_tcp_fallback(msk); ssock = __mptcp_tcp_fallback(msk);
if (unlikely(ssock)) { if (unlikely(ssock)) {
fallback: fallback:
...@@ -427,8 +436,6 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -427,8 +436,6 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
return ret >= 0 ? ret + copied : (copied ? copied : ret); return ret >= 0 ? ret + copied : (copied ? copied : ret);
} }
timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
ssk = mptcp_subflow_get(msk); ssk = mptcp_subflow_get(msk);
if (!ssk) { if (!ssk) {
release_sock(sk); release_sock(sk);
...@@ -460,6 +467,7 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -460,6 +467,7 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
ssk_check_wmem(msk, ssk); ssk_check_wmem(msk, ssk);
release_sock(ssk); release_sock(ssk);
out:
release_sock(sk); release_sock(sk);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment