Hi, On Mon, 2020-11-23 at 12:57 +0100, Eric Dumazet wrote: > > diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c > > index 4ae2c4a30e44..748343f1a968 100644 > > --- a/net/mptcp/protocol.c > > +++ b/net/mptcp/protocol.c > > @@ -407,16 +407,42 @@ static void mptcp_set_timeout(const struct sock *sk, > > const struct sock *ssk) > > mptcp_sk(sk)->timer_ival = tout > 0 ? tout : TCP_RTO_MIN; > > } > > > > -static void mptcp_send_ack(struct mptcp_sock *msk) > > +static bool mptcp_subflow_active(struct mptcp_subflow_context *subflow) > > +{ > > + struct sock *ssk = mptcp_subflow_tcp_sock(subflow); > > + > > + /* can't send if JOIN hasn't completed yet (i.e. is usable for mptcp) */ > > + if (subflow->request_join && !subflow->fully_established) > > + return false; > > + > > + /* only send if our side has not closed yet */ > > + return ((1 << ssk->sk_state) & (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)); > > +} > > + > > +static void mptcp_send_ack(struct mptcp_sock *msk, bool force) > > { > > struct mptcp_subflow_context *subflow; > > + struct sock *pick = NULL; > > > > mptcp_for_each_subflow(msk, subflow) { > > struct sock *ssk = mptcp_subflow_tcp_sock(subflow); > > > > - lock_sock(ssk); > > - tcp_send_ack(ssk); > > - release_sock(ssk); > > + if (force) { > > + lock_sock(ssk); > > + tcp_send_ack(ssk); > > + release_sock(ssk); > > + continue; > > + } > > + > > + /* if the hintes ssk is still active, use it */ > > + pick = ssk; > > + if (ssk == msk->ack_hint) > > + break; > > + } > > + if (!force && pick) { > > + lock_sock(pick); > > + tcp_cleanup_rbuf(pick, 1); > > Calling tcp_cleanup_rbuf() on a socket that was never established is going to > fail > with a divide by 0 (mss being 0) > > AFAIK, mptcp_recvmsg() can be called right after a socket(AF_INET, > SOCK_STREAM, IPPROTO_MPTCP) > call. > > Probably, after a lock_sock(), you should double check socket state (same > above before calling tcp_send_ack())
Thank you for looking into this. Indeed you are right! I'll try to cook a fix. Cheers, Paolo