From e1243fb2105611d5b77ab799060415b462d21a14 Mon Sep 17 00:00:00 2001 From: Christoph Paasch Date: Thu, 13 Jul 2017 09:56:33 -0700 Subject: [PATCH] mptcp + TFO: Only send ADD_ADDR after receiving the third ACK When TFO is being used, we create the full-fledged MPTCP-socket right at the reception of the SYN. At this point, we also call mptcp_update_metasocket(), which ends up calling the path-manager to check for addresses,... This also means that the server will send ADD_ADDR-options. These ADD_ADDR-options will actually be sent before the SYN/ACK, in full_mesh_new_session(). These ACKs with ADD_ADDR-option will actually be discarded by the client, because the client is still waiting for a SYN/ACK. This patch changes this so that ADD_ADDR will only be sent after the reception of the third ACK. Fixes: 8d663619fcc6 (mptcp: fastopen server support) Signed-off-by: Christoph Paasch Signed-off-by: Matthieu Baerts (cherry picked from commit c642642799ae912191d98654ca0485c24d3d62d2) Signed-off-by: Matthieu Baerts --- include/net/mptcp.h | 4 ++-- net/ipv4/tcp_input.c | 16 ++++++++++------ net/mptcp/mptcp_ctrl.c | 9 +++------ 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/include/net/mptcp.h b/include/net/mptcp.h index 7f9819eca03409..1147d1f57fed5a 100644 --- a/include/net/mptcp.h +++ b/include/net/mptcp.h @@ -781,7 +781,7 @@ void mptcp_cleanup_rbuf(struct sock *meta_sk, int copied); int mptcp_add_sock(struct sock *meta_sk, struct sock *sk, u8 loc_id, u8 rem_id, gfp_t flags); void mptcp_del_sock(struct sock *sk); -void mptcp_update_metasocket(struct sock *sock, const struct sock *meta_sk); +void mptcp_update_metasocket(const struct sock *meta_sk); void mptcp_reinject_data(struct sock *orig_sk, int clone_it); void mptcp_update_sndbuf(const struct tcp_sock *tp); void mptcp_send_fin(struct sock *meta_sk); @@ -1366,7 +1366,7 @@ static inline int is_master_tp(const struct tcp_sock *tp) } static inline void mptcp_purge_ofo_queue(struct tcp_sock *meta_tp) {} static inline void mptcp_del_sock(const struct sock *sk) {} -static inline void mptcp_update_metasocket(struct sock *sock, const struct sock *meta_sk) {} +static inline void mptcp_update_metasocket(const struct sock *meta_sk) {} static inline void mptcp_reinject_data(struct sock *orig_sk, int clone_it) {} static inline void mptcp_update_sndbuf(const struct tcp_sock *tp) {} static inline void mptcp_clean_rtx_infinite(const struct sk_buff *skb, diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 50dab8ae40d29d..b975f85c6c3697 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5954,7 +5954,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) * addresses, which can only be done after the third ack * of the 3-way handshake. */ - mptcp_update_metasocket(sk, tp->meta_sk); + mptcp_update_metasocket(tp->meta_sk); } if (queued >= 0) return queued; @@ -6050,12 +6050,16 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) tcp_initialize_rcv_mss(sk); tcp_fast_path_on(tp); - /* Send an ACK when establishing a new - * MPTCP subflow, i.e. using an MP_JOIN - * subtype. + + /* Send an ACK when establishing a new MPTCP subflow, i.e. + * using an MP_JOIN subtype. */ - if (mptcp(tp) && !is_master_tp(tp)) - tcp_send_ack(sk); + if (mptcp(tp)) { + if (is_master_tp(tp)) + mptcp_update_metasocket(mptcp_meta_sk(sk)); + else + tcp_send_ack(sk); + } break; case TCP_FIN_WAIT1: { diff --git a/net/mptcp/mptcp_ctrl.c b/net/mptcp/mptcp_ctrl.c index 5368a6e89f1904..a45bd3b527facc 100644 --- a/net/mptcp/mptcp_ctrl.c +++ b/net/mptcp/mptcp_ctrl.c @@ -1404,10 +1404,10 @@ void mptcp_del_sock(struct sock *sk) /* Updates the MPTCP-session based on path-manager information (e.g., addresses, * low-prio flows,...). */ -void mptcp_update_metasocket(struct sock *sk, const struct sock *meta_sk) +void mptcp_update_metasocket(const struct sock *meta_sk) { - if (tcp_sk(sk)->mpcb->pm_ops->new_session) - tcp_sk(sk)->mpcb->pm_ops->new_session(meta_sk); + if (tcp_sk(meta_sk)->mpcb->pm_ops->new_session) + tcp_sk(meta_sk)->mpcb->pm_ops->new_session(meta_sk); } /* Clean up the receive buffer for full frames taken by the user, @@ -1984,9 +1984,6 @@ static int __mptcp_check_req_master(struct sock *child, mpcb->dss_csum = mtreq->dss_csum; mpcb->server_side = 1; - /* Will be moved to ESTABLISHED by tcp_rcv_state_process() */ - mptcp_update_metasocket(child, meta_sk); - /* Needs to be done here additionally, because when accepting a * new connection we pass by __reqsk_free and not reqsk_free. */