Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : /* MPTCP Fast Open Mechanism
3 : : *
4 : : * Copyright (c) 2021-2022, Dmytro SHYTYI
5 : : */
6 : :
7 : : #include "protocol.h"
8 : :
9 : 56 : void mptcp_fastopen_subflow_synack_set_params(struct mptcp_subflow_context *subflow,
10 : : struct request_sock *req)
11 : : {
12 : 56 : struct sock *sk, *ssk;
13 : 56 : struct sk_buff *skb;
14 : 56 : struct tcp_sock *tp;
15 : 56 : bool has_rxtstamp;
16 : :
17 : : /* on early fallback the subflow context is deleted by
18 : : * subflow_syn_recv_sock()
19 : : */
20 [ + - ]: 56 : if (!subflow)
21 : : return;
22 : :
23 : 56 : ssk = subflow->tcp_sock;
24 : 56 : sk = subflow->conn;
25 [ - + ]: 56 : tp = tcp_sk(ssk);
26 : :
27 : : /* A valid TFO cookie does not guarantee SYN data. */
28 [ + + ]: 56 : skb = skb_peek(&ssk->sk_receive_queue);
29 [ + - ]: 50 : if (!skb)
30 : : return;
31 : :
32 : 50 : subflow->is_mptfo = 1;
33 : :
34 : : /* dequeue the skb from sk receive queue */
35 : 50 : __skb_unlink(skb, &ssk->sk_receive_queue);
36 : 50 : skb_ext_reset(skb);
37 : :
38 : 50 : mptcp_subflow_lend_fwdmem(subflow, skb);
39 : :
40 : : /* We copy the fastopen data, but that don't belong to the mptcp sequence
41 : : * space, need to offset it in the subflow sequence, see mptcp_subflow_get_map_offset()
42 : : */
43 : 50 : tp->copied_seq += skb->len;
44 : 50 : subflow->ssn_offset += skb->len;
45 : 50 : has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp;
46 : :
47 : : /* Only the sequence delta is relevant */
48 : 50 : MPTCP_SKB_CB(skb)->map_seq = -skb->len;
49 : 50 : MPTCP_SKB_CB(skb)->end_seq = 0;
50 : 50 : MPTCP_SKB_CB(skb)->offset = 0;
51 : 50 : MPTCP_SKB_CB(skb)->has_rxtstamp = has_rxtstamp;
52 : 50 : MPTCP_SKB_CB(skb)->cant_coalesce = 1;
53 : :
54 : 50 : mptcp_data_lock(sk);
55 [ - + ]: 50 : DEBUG_NET_WARN_ON_ONCE(sock_owned_by_user_nocheck(sk));
56 : :
57 : 50 : mptcp_borrow_fwdmem(sk, skb);
58 : 50 : skb_set_owner_r(skb, sk);
59 [ - + ]: 50 : __skb_queue_tail(&sk->sk_receive_queue, skb);
60 [ - + ]: 50 : mptcp_sk(sk)->bytes_received += skb->len;
61 : :
62 : 50 : sk->sk_data_ready(sk);
63 : :
64 : 50 : mptcp_data_unlock(sk);
65 : : }
|