Blame view
net/dccp/minisocks.c
7.27 KB
2874c5fd2 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
7c657876b [DCCP]: Initial i... |
2 3 4 5 6 |
/* * net/dccp/minisocks.c * * An implementation of the DCCP protocol * Arnaldo Carvalho de Melo <acme@conectiva.com.br> |
7c657876b [DCCP]: Initial i... |
7 |
*/ |
7c657876b [DCCP]: Initial i... |
8 |
#include <linux/dccp.h> |
5a0e3ad6a include cleanup: ... |
9 |
#include <linux/gfp.h> |
8a73cd09d [DCCP]: calling d... |
10 |
#include <linux/kernel.h> |
7c657876b [DCCP]: Initial i... |
11 12 13 14 15 16 |
#include <linux/skbuff.h> #include <linux/timer.h> #include <net/sock.h> #include <net/xfrm.h> #include <net/inet_timewait_sock.h> |
ae31c3399 [DCCP]: Move the ... |
17 |
#include "ackvec.h" |
7c657876b [DCCP]: Initial i... |
18 19 |
#include "ccid.h" #include "dccp.h" |
afe00251d [DCCP]: Initial f... |
20 |
#include "feat.h" |
7c657876b [DCCP]: Initial i... |
21 |
|
64cf1e5d8 [DCCP]: Finish th... |
22 23 |
struct inet_timewait_death_row dccp_death_row = { .sysctl_max_tw_buckets = NR_FILE * 2, |
64cf1e5d8 [DCCP]: Finish th... |
24 |
.hashinfo = &dccp_hashinfo, |
64cf1e5d8 [DCCP]: Finish th... |
25 |
}; |
f21e68caa [DCCP]: Prepare t... |
26 |
EXPORT_SYMBOL_GPL(dccp_death_row); |
7c657876b [DCCP]: Initial i... |
27 28 |
void dccp_time_wait(struct sock *sk, int state, int timeo) { |
789f558cf tcp/dccp: get rid... |
29 |
struct inet_timewait_sock *tw; |
7c657876b [DCCP]: Initial i... |
30 |
|
789f558cf tcp/dccp: get rid... |
31 |
tw = inet_twsk_alloc(sk, &dccp_death_row, state); |
64cf1e5d8 [DCCP]: Finish th... |
32 33 34 35 |
if (tw != NULL) { const struct inet_connection_sock *icsk = inet_csk(sk); const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1); |
dfd56b8b3 net: use IS_ENABL... |
36 |
#if IS_ENABLED(CONFIG_IPV6) |
3df80d932 [DCCP]: Introduce... |
37 |
if (tw->tw_family == PF_INET6) { |
efe4208f4 ipv6: make lookup... |
38 39 |
tw->tw_v6_daddr = sk->sk_v6_daddr; tw->tw_v6_rcv_saddr = sk->sk_v6_rcv_saddr; |
9fe516ba3 inet: move ipv6on... |
40 |
tw->tw_ipv6only = sk->sk_ipv6only; |
3df80d932 [DCCP]: Introduce... |
41 42 |
} #endif |
64cf1e5d8 [DCCP]: Finish th... |
43 44 45 46 |
/* Get the TIME_WAIT timeout firing. */ if (timeo < rto) timeo = rto; |
64cf1e5d8 [DCCP]: Finish th... |
47 48 |
if (state == DCCP_TIME_WAIT) timeo = DCCP_TIMEWAIT_LEN; |
cfac7f836 tcp/dccp: block b... |
49 50 51 52 53 |
/* tw_timer is pinned, so we need to make sure BH are disabled * in following section, otherwise timer handler could run before * we complete the initialization. */ local_bh_disable(); |
789f558cf tcp/dccp: get rid... |
54 |
inet_twsk_schedule(tw, timeo); |
ec94c2696 tcp/dccp: avoid o... |
55 56 57 58 |
/* Linkage updates. * Note that access to tw after this point is illegal. */ inet_twsk_hashdance(tw, sk, &dccp_hashinfo); |
cfac7f836 tcp/dccp: block b... |
59 |
local_bh_enable(); |
64cf1e5d8 [DCCP]: Finish th... |
60 61 62 63 64 |
} else { /* Sorry, if we're out of memory, just CLOSE this * socket up. We've got bigger problems than * non-graceful socket closings. */ |
59348b19e [DCCP]: Simplifie... |
65 66 |
DCCP_WARN("time wait bucket table overflow "); |
64cf1e5d8 [DCCP]: Finish th... |
67 68 69 |
} dccp_done(sk); |
7c657876b [DCCP]: Initial i... |
70 |
} |
54105f98f dccp: constify dc... |
71 |
struct sock *dccp_create_openreq_child(const struct sock *sk, |
7c657876b [DCCP]: Initial i... |
72 73 74 75 76 77 |
const struct request_sock *req, const struct sk_buff *skb) { /* * Step 3: Process LISTEN state * |
d83ca5acc [DCCP]: Update co... |
78 79 |
* (* Generate a new socket and switch to that socket *) * Set S := new socket for this port pair |
7c657876b [DCCP]: Initial i... |
80 |
*/ |
e56c57d0d net: rename sk_cl... |
81 |
struct sock *newsk = inet_csk_clone_lock(sk, req, GFP_ATOMIC); |
7c657876b [DCCP]: Initial i... |
82 83 |
if (newsk != NULL) { |
192b27ff3 dccp: Integration... |
84 |
struct dccp_request_sock *dreq = dccp_rsk(req); |
99c72ce09 [DCCP]: Set RTO f... |
85 |
struct inet_connection_sock *newicsk = inet_csk(newsk); |
7c657876b [DCCP]: Initial i... |
86 |
struct dccp_sock *newdp = dccp_sk(newsk); |
b4d4f7c70 [DCCP]: Handle ti... |
87 88 89 90 91 92 93 |
newdp->dccps_role = DCCP_ROLE_SERVER; newdp->dccps_hc_rx_ackvec = NULL; newdp->dccps_service_list = NULL; newdp->dccps_service = dreq->dreq_service; newdp->dccps_timestamp_echo = dreq->dreq_timestamp_echo; newdp->dccps_timestamp_time = dreq->dreq_timestamp_time; newicsk->icsk_rto = DCCP_TIMEOUT_INIT; |
7c657876b [DCCP]: Initial i... |
94 |
|
ac75773c2 dccp: Per-socket ... |
95 |
INIT_LIST_HEAD(&newdp->dccps_featneg); |
7c657876b [DCCP]: Initial i... |
96 97 98 |
/* * Step 3: Process LISTEN state * |
d83ca5acc [DCCP]: Update co... |
99 100 |
* Choose S.ISS (initial seqno) or set from Init Cookies * Initialize S.GAR := S.ISS |
0b53d4604 dccp: fix the adj... |
101 102 103 104 105 |
* Set S.ISR, S.GSR from packet (or Init Cookies) * * Setting AWL/AWH and SWL/SWH happens as part of the feature * activation below, as these windows all depend on the local * and remote Sequence Window feature values (7.5.2). |
03ace394a [DCCP]: Fix the A... |
106 |
*/ |
f541fb7e2 dccp: fix bug in ... |
107 108 |
newdp->dccps_iss = dreq->dreq_iss; newdp->dccps_gss = dreq->dreq_gss; |
0b53d4604 dccp: fix the adj... |
109 |
newdp->dccps_gar = newdp->dccps_iss; |
f541fb7e2 dccp: fix bug in ... |
110 111 |
newdp->dccps_isr = dreq->dreq_isr; newdp->dccps_gsr = dreq->dreq_gsr; |
03ace394a [DCCP]: Fix the A... |
112 |
|
192b27ff3 dccp: Integration... |
113 |
/* |
0b53d4604 dccp: fix the adj... |
114 |
* Activate features: initialise CCIDs, sequence windows etc. |
192b27ff3 dccp: Integration... |
115 116 |
*/ if (dccp_feat_activate_values(newsk, &dreq->dreq_featneg)) { |
94352d450 net: Introduce sk... |
117 |
sk_free_unlock_clone(newsk); |
192b27ff3 dccp: Integration... |
118 119 |
return NULL; } |
7c657876b [DCCP]: Initial i... |
120 |
dccp_init_xmit_timers(newsk); |
aa62d76b6 dccp: rename DCCP... |
121 |
__DCCP_INC_STATS(DCCP_MIB_PASSIVEOPENS); |
7c657876b [DCCP]: Initial i... |
122 123 124 |
} return newsk; } |
f21e68caa [DCCP]: Prepare t... |
125 |
EXPORT_SYMBOL_GPL(dccp_create_openreq_child); |
8109b02b5 [DCCP]: Whitespac... |
126 |
/* |
7c657876b [DCCP]: Initial i... |
127 128 129 130 |
* Process an incoming packet for RESPOND sockets represented * as an request_sock. */ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, |
52452c542 inet: drop prev p... |
131 |
struct request_sock *req) |
7c657876b [DCCP]: Initial i... |
132 133 |
{ struct sock *child = NULL; |
8109616e2 [DCCP]: Add (miss... |
134 |
struct dccp_request_sock *dreq = dccp_rsk(req); |
5e0724d02 tcp/dccp: fix has... |
135 |
bool own_req; |
7c657876b [DCCP]: Initial i... |
136 |
|
62f8f4d90 dccp: fix use-aft... |
137 138 139 140 141 142 |
/* TCP/DCCP listeners became lockless. * DCCP stores complex state in its request_sock, so we need * a protection for them, now this code runs without being protected * by the parent (listener) lock. */ spin_lock_bh(&dreq->dreq_lock); |
7c657876b [DCCP]: Initial i... |
143 144 |
/* Check for retransmitted REQUEST */ if (dccp_hdr(skb)->dccph_type == DCCP_PKT_REQUEST) { |
7c657876b [DCCP]: Initial i... |
145 |
|
f541fb7e2 dccp: fix bug in ... |
146 |
if (after48(DCCP_SKB_CB(skb)->dccpd_seq, dreq->dreq_gsr)) { |
7c657876b [DCCP]: Initial i... |
147 148 |
dccp_pr_debug("Retransmitted REQUEST "); |
f541fb7e2 dccp: fix bug in ... |
149 |
dreq->dreq_gsr = DCCP_SKB_CB(skb)->dccpd_seq; |
e11d9d308 [DCCP]: Increment... |
150 151 152 153 154 |
/* * Send another RESPONSE packet * To protect against Request floods, increment retrans * counter (backoff, monitored by dccp_response_timer). */ |
e6c022a4f tcp: better retra... |
155 |
inet_rtx_syn_ack(sk, req); |
7c657876b [DCCP]: Initial i... |
156 157 |
} /* Network Duplicate, discard packet */ |
62f8f4d90 dccp: fix use-aft... |
158 |
goto out; |
7c657876b [DCCP]: Initial i... |
159 160 161 162 163 164 165 166 167 |
} DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; if (dccp_hdr(skb)->dccph_type != DCCP_PKT_ACK && dccp_hdr(skb)->dccph_type != DCCP_PKT_DATAACK) goto drop; /* Invalid ACK */ |
f541fb7e2 dccp: fix bug in ... |
168 169 |
if (!between48(DCCP_SKB_CB(skb)->dccpd_ack_seq, dreq->dreq_iss, dreq->dreq_gss)) { |
7690af3ff [DCCP]: Just refl... |
170 |
dccp_pr_debug("Invalid ACK number: ack_seq=%llu, " |
f541fb7e2 dccp: fix bug in ... |
171 172 |
"dreq_iss=%llu, dreq_gss=%llu ", |
f6ccf5541 [DCCP]: Fix u64 p... |
173 174 |
(unsigned long long) DCCP_SKB_CB(skb)->dccpd_ack_seq, |
f541fb7e2 dccp: fix bug in ... |
175 176 |
(unsigned long long) dreq->dreq_iss, (unsigned long long) dreq->dreq_gss); |
7c657876b [DCCP]: Initial i... |
177 178 |
goto drop; } |
8109616e2 [DCCP]: Add (miss... |
179 180 |
if (dccp_parse_options(sk, dreq, skb)) goto drop; |
5e0724d02 tcp/dccp: fix has... |
181 182 |
child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL, req, &own_req); |
62f8f4d90 dccp: fix use-aft... |
183 184 185 186 |
if (child) { child = inet_csk_complete_hashdance(sk, child, req, own_req); goto out; } |
5e0724d02 tcp/dccp: fix has... |
187 |
|
7c657876b [DCCP]: Initial i... |
188 189 190 |
DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_TOO_BUSY; drop: if (dccp_hdr(skb)->dccph_type != DCCP_PKT_RESET) |
cfb6eeb4c [TCP]: MD5 Signat... |
191 |
req->rsk_ops->send_reset(sk, skb); |
7c657876b [DCCP]: Initial i... |
192 |
|
52452c542 inet: drop prev p... |
193 |
inet_csk_reqsk_queue_drop(sk, req); |
62f8f4d90 dccp: fix use-aft... |
194 195 196 |
out: spin_unlock_bh(&dreq->dreq_lock); return child; |
7c657876b [DCCP]: Initial i... |
197 |
} |
f21e68caa [DCCP]: Prepare t... |
198 |
EXPORT_SYMBOL_GPL(dccp_check_req); |
7c657876b [DCCP]: Initial i... |
199 200 201 202 203 204 205 |
/* * Queue segment on the new socket if the new socket is active, * otherwise we just shortcircuit this and continue with * the new socket. */ int dccp_child_process(struct sock *parent, struct sock *child, struct sk_buff *skb) |
3283ff2ea dccp: Add missing... |
206 |
__releases(child) |
7c657876b [DCCP]: Initial i... |
207 208 209 210 211 |
{ int ret = 0; const int state = child->sk_state; if (!sock_owned_by_user(child)) { |
7690af3ff [DCCP]: Just refl... |
212 213 |
ret = dccp_rcv_state_process(child, skb, dccp_hdr(skb), skb->len); |
7c657876b [DCCP]: Initial i... |
214 215 216 |
/* Wakeup parent, send SIGIO */ if (state == DCCP_RESPOND && child->sk_state != state) |
676d23690 net: Fix use afte... |
217 |
parent->sk_data_ready(parent); |
7c657876b [DCCP]: Initial i... |
218 219 220 221 222 |
} else { /* Alas, it is possible again, because we do lookup * in main socket hash table and lock on listening * socket does not protect us more. */ |
a3a858ff1 net: backlog func... |
223 |
__sk_add_backlog(child, skb); |
7c657876b [DCCP]: Initial i... |
224 225 226 227 228 229 |
} bh_unlock_sock(child); sock_put(child); return ret; } |
f21e68caa [DCCP]: Prepare t... |
230 231 |
EXPORT_SYMBOL_GPL(dccp_child_process); |
8a73cd09d [DCCP]: calling d... |
232 |
|
a00e74442 tcp/dccp: constif... |
233 |
void dccp_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, |
6edafaaf6 tcp: Fix kernel p... |
234 |
struct request_sock *rsk) |
8a73cd09d [DCCP]: calling d... |
235 |
{ |
59348b19e [DCCP]: Simplifie... |
236 |
DCCP_BUG("DCCP-ACK packets are never sent in LISTEN/RESPOND state"); |
8a73cd09d [DCCP]: calling d... |
237 238 239 |
} EXPORT_SYMBOL_GPL(dccp_reqsk_send_ack); |
cf557926f [DCCP]: tidy up d... |
240 |
|
ac75773c2 dccp: Per-socket ... |
241 242 |
int dccp_reqsk_init(struct request_sock *req, struct dccp_sock const *dp, struct sk_buff const *skb) |
cf557926f [DCCP]: tidy up d... |
243 |
{ |
b4d4f7c70 [DCCP]: Handle ti... |
244 |
struct dccp_request_sock *dreq = dccp_rsk(req); |
62f8f4d90 dccp: fix use-aft... |
245 |
spin_lock_init(&dreq->dreq_lock); |
b44084c2c inet: rename ir_l... |
246 247 248 249 |
inet_rsk(req)->ir_rmt_port = dccp_hdr(skb)->dccph_sport; inet_rsk(req)->ir_num = ntohs(dccp_hdr(skb)->dccph_dport); inet_rsk(req)->acked = 0; dreq->dreq_timestamp_echo = 0; |
ac75773c2 dccp: Per-socket ... |
250 251 252 |
/* inherit feature negotiation options from listening socket */ return dccp_feat_clone_list(&dp->dccps_featneg, &dreq->dreq_featneg); |
cf557926f [DCCP]: tidy up d... |
253 254 255 |
} EXPORT_SYMBOL_GPL(dccp_reqsk_init); |