summaryrefslogtreecommitdiff
path: root/net/mptcp
diff options
context:
space:
mode:
authorMat Martineau <mathew.j.martineau@linux.intel.com>2020-02-29 02:47:39 +0300
committerDavid S. Miller <davem@davemloft.net>2020-03-04 04:01:42 +0300
commit1954b86016cf8522970e1b7aba801233d777ec47 (patch)
treee4c88f18cf8e12994126df67a317d7ec6b5be575 /net/mptcp
parent0a303214f8cb8e2043a03f7b727dba620e07e68d (diff)
downloadlinux-1954b86016cf8522970e1b7aba801233d777ec47.tar.xz
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: Mat Martineau <mathew.j.martineau@linux.intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mptcp')
-rw-r--r--net/mptcp/protocol.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index a8445407d25a..07559b45eec5 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -419,6 +419,15 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
return -EOPNOTSUPP;
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);
if (unlikely(ssock)) {
fallback:
@@ -427,8 +436,6 @@ fallback:
return ret >= 0 ? ret + copied : (copied ? copied : ret);
}
- timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
-
ssk = mptcp_subflow_get(msk);
if (!ssk) {
release_sock(sk);
@@ -460,6 +467,7 @@ fallback:
ssk_check_wmem(msk, ssk);
release_sock(ssk);
+out:
release_sock(sk);
return ret;
}