]> Git Repo - linux.git/blob - net/mptcp/fastopen.c
vc_screen: move load of struct vc_data pointer in vcs_read() to avoid UAF
[linux.git] / net / mptcp / fastopen.c
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 void mptcp_fastopen_subflow_synack_set_params(struct mptcp_subflow_context *subflow,
10                                               struct request_sock *req)
11 {
12         struct sock *ssk = subflow->tcp_sock;
13         struct sock *sk = subflow->conn;
14         struct sk_buff *skb;
15         struct tcp_sock *tp;
16
17         tp = tcp_sk(ssk);
18
19         subflow->is_mptfo = 1;
20
21         skb = skb_peek(&ssk->sk_receive_queue);
22         if (WARN_ON_ONCE(!skb))
23                 return;
24
25         /* dequeue the skb from sk receive queue */
26         __skb_unlink(skb, &ssk->sk_receive_queue);
27         skb_ext_reset(skb);
28         skb_orphan(skb);
29
30         /* We copy the fastopen data, but that don't belong to the mptcp sequence
31          * space, need to offset it in the subflow sequence, see mptcp_subflow_get_map_offset()
32          */
33         tp->copied_seq += skb->len;
34         subflow->ssn_offset += skb->len;
35
36         /* initialize a dummy sequence number, we will update it at MPC
37          * completion, if needed
38          */
39         MPTCP_SKB_CB(skb)->map_seq = -skb->len;
40         MPTCP_SKB_CB(skb)->end_seq = 0;
41         MPTCP_SKB_CB(skb)->offset = 0;
42         MPTCP_SKB_CB(skb)->has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp;
43
44         mptcp_data_lock(sk);
45
46         mptcp_set_owner_r(skb, sk);
47         __skb_queue_tail(&sk->sk_receive_queue, skb);
48
49         sk->sk_data_ready(sk);
50
51         mptcp_data_unlock(sk);
52 }
53
54 void mptcp_fastopen_gen_msk_ackseq(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
55                                    const struct mptcp_options_received *mp_opt)
56 {
57         struct sock *sk = (struct sock *)msk;
58         struct sk_buff *skb;
59
60         mptcp_data_lock(sk);
61         skb = skb_peek_tail(&sk->sk_receive_queue);
62         if (skb) {
63                 WARN_ON_ONCE(MPTCP_SKB_CB(skb)->end_seq);
64                 pr_debug("msk %p moving seq %llx -> %llx end_seq %llx -> %llx", sk,
65                          MPTCP_SKB_CB(skb)->map_seq, MPTCP_SKB_CB(skb)->map_seq + msk->ack_seq,
66                          MPTCP_SKB_CB(skb)->end_seq, MPTCP_SKB_CB(skb)->end_seq + msk->ack_seq);
67                 MPTCP_SKB_CB(skb)->map_seq += msk->ack_seq;
68                 MPTCP_SKB_CB(skb)->end_seq += msk->ack_seq;
69         }
70
71         pr_debug("msk=%p ack_seq=%llx", msk, msk->ack_seq);
72         mptcp_data_unlock(sk);
73 }
This page took 0.035916 seconds and 4 git commands to generate.