Blame view
net/dccp/input.c
21.6 KB
7c657876b [DCCP]: Initial i... |
1 2 |
/* * net/dccp/input.c |
8109b02b5 [DCCP]: Whitespac... |
3 |
* |
7c657876b [DCCP]: Initial i... |
4 5 6 7 8 9 10 11 |
* An implementation of the DCCP protocol * Arnaldo Carvalho de Melo <acme@conectiva.com.br> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ |
7c657876b [DCCP]: Initial i... |
12 13 |
#include <linux/dccp.h> #include <linux/skbuff.h> |
5a0e3ad6a include cleanup: ... |
14 |
#include <linux/slab.h> |
7c657876b [DCCP]: Initial i... |
15 16 |
#include <net/sock.h> |
ae31c3399 [DCCP]: Move the ... |
17 |
#include "ackvec.h" |
7c657876b [DCCP]: Initial i... |
18 19 |
#include "ccid.h" #include "dccp.h" |
bd5435e76 [DCCP]: fix link ... |
20 21 |
/* rate-limit for syncs in reply to sequence-invalid packets; RFC 4340, 7.5.4 */ int sysctl_dccp_sync_ratelimit __read_mostly = HZ / 8; |
69567d0b6 [DCCP]: Perform S... |
22 |
static void dccp_enqueue_skb(struct sock *sk, struct sk_buff *skb) |
7c657876b [DCCP]: Initial i... |
23 |
{ |
7c657876b [DCCP]: Initial i... |
24 25 26 27 28 |
__skb_pull(skb, dccp_hdr(skb)->dccph_doff * 4); __skb_queue_tail(&sk->sk_receive_queue, skb); skb_set_owner_r(skb, sk); sk->sk_data_ready(sk, 0); } |
69567d0b6 [DCCP]: Perform S... |
29 30 31 32 33 34 35 36 37 38 39 40 |
static void dccp_fin(struct sock *sk, struct sk_buff *skb) { /* * On receiving Close/CloseReq, both RD/WR shutdown are performed. * RFC 4340, 8.3 says that we MAY send further Data/DataAcks after * receiving the closing segment, but there is no guarantee that such * data will be processed at all. */ sk->sk_shutdown = SHUTDOWN_MASK; sock_set_flag(sk, SOCK_DONE); dccp_enqueue_skb(sk, skb); } |
0c8696207 [DCCP]: Integrate... |
41 |
static int dccp_rcv_close(struct sock *sk, struct sk_buff *skb) |
7c657876b [DCCP]: Initial i... |
42 |
{ |
0c8696207 [DCCP]: Integrate... |
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
int queued = 0; switch (sk->sk_state) { /* * We ignore Close when received in one of the following states: * - CLOSED (may be a late or duplicate packet) * - PASSIVE_CLOSEREQ (the peer has sent a CloseReq earlier) * - RESPOND (already handled by dccp_check_req) */ case DCCP_CLOSING: /* * Simultaneous-close: receiving a Close after sending one. This * can happen if both client and server perform active-close and * will result in an endless ping-pong of crossing and retrans- * mitted Close packets, which only terminates when one of the * nodes times out (min. 64 seconds). Quicker convergence can be * achieved when one of the nodes acts as tie-breaker. * This is ok as both ends are done with data transfer and each * end is just waiting for the other to acknowledge termination. */ if (dccp_sk(sk)->dccps_role != DCCP_ROLE_CLIENT) break; /* fall through */ case DCCP_REQUESTING: case DCCP_ACTIVE_CLOSEREQ: dccp_send_reset(sk, DCCP_RESET_CODE_CLOSED); dccp_done(sk); break; case DCCP_OPEN: case DCCP_PARTOPEN: /* Give waiting application a chance to read pending data */ queued = 1; dccp_fin(sk, skb); dccp_set_state(sk, DCCP_PASSIVE_CLOSE); /* fall through */ case DCCP_PASSIVE_CLOSE: /* * Retransmitted Close: we have already enqueued the first one. */ sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_HUP); } return queued; |
7c657876b [DCCP]: Initial i... |
85 |
} |
0c8696207 [DCCP]: Integrate... |
86 |
static int dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb) |
7c657876b [DCCP]: Initial i... |
87 |
{ |
0c8696207 [DCCP]: Integrate... |
88 |
int queued = 0; |
7c657876b [DCCP]: Initial i... |
89 90 91 92 93 94 95 |
/* * Step 7: Check for unexpected packet types * If (S.is_server and P.type == CloseReq) * Send Sync packet acknowledging P.seqno * Drop packet and return */ if (dccp_sk(sk)->dccps_role != DCCP_ROLE_CLIENT) { |
e92ae93a8 [DCCP]: Send SYNC... |
96 |
dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, DCCP_PKT_SYNC); |
0c8696207 [DCCP]: Integrate... |
97 |
return queued; |
7c657876b [DCCP]: Initial i... |
98 |
} |
0c8696207 [DCCP]: Integrate... |
99 100 101 102 |
/* Step 13: process relevant Client states < CLOSEREQ */ switch (sk->sk_state) { case DCCP_REQUESTING: dccp_send_close(sk, 0); |
811265b8e [DCCP]: Check if ... |
103 |
dccp_set_state(sk, DCCP_CLOSING); |
0c8696207 [DCCP]: Integrate... |
104 105 106 107 108 109 110 111 112 113 114 115 |
break; case DCCP_OPEN: case DCCP_PARTOPEN: /* Give waiting application a chance to read pending data */ queued = 1; dccp_fin(sk, skb); dccp_set_state(sk, DCCP_PASSIVE_CLOSEREQ); /* fall through */ case DCCP_PASSIVE_CLOSEREQ: sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_HUP); } return queued; |
7c657876b [DCCP]: Initial i... |
116 |
} |
d9b52dc6f net/dccp: expansi... |
117 |
static u16 dccp_reset_code_convert(const u8 code) |
d8ef2c29a [DCCP]: Convert R... |
118 |
{ |
d9b52dc6f net/dccp: expansi... |
119 |
const u16 error_code[] = { |
d8ef2c29a [DCCP]: Convert R... |
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
[DCCP_RESET_CODE_CLOSED] = 0, /* normal termination */ [DCCP_RESET_CODE_UNSPECIFIED] = 0, /* nothing known */ [DCCP_RESET_CODE_ABORTED] = ECONNRESET, [DCCP_RESET_CODE_NO_CONNECTION] = ECONNREFUSED, [DCCP_RESET_CODE_CONNECTION_REFUSED] = ECONNREFUSED, [DCCP_RESET_CODE_TOO_BUSY] = EUSERS, [DCCP_RESET_CODE_AGGRESSION_PENALTY] = EDQUOT, [DCCP_RESET_CODE_PACKET_ERROR] = ENOMSG, [DCCP_RESET_CODE_BAD_INIT_COOKIE] = EBADR, [DCCP_RESET_CODE_BAD_SERVICE_CODE] = EBADRQC, [DCCP_RESET_CODE_OPTION_ERROR] = EILSEQ, [DCCP_RESET_CODE_MANDATORY_ERROR] = EOPNOTSUPP, }; return code >= DCCP_MAX_RESET_CODES ? 0 : error_code[code]; } static void dccp_rcv_reset(struct sock *sk, struct sk_buff *skb) { |
d9b52dc6f net/dccp: expansi... |
141 |
u16 err = dccp_reset_code_convert(dccp_hdr_reset(skb)->dccph_reset_code); |
d8ef2c29a [DCCP]: Convert R... |
142 143 144 145 146 147 148 |
sk->sk_err = err; /* Queue the equivalent of TCP fin so that dccp_recvmsg exits the loop */ dccp_fin(sk, skb); if (err && !sock_flag(sk, SOCK_DEAD)) |
8d8ad9d7c [NET]: Name magic... |
149 |
sk_wake_async(sk, SOCK_WAKE_IO, POLL_ERR); |
d8ef2c29a [DCCP]: Convert R... |
150 151 |
dccp_time_wait(sk, DCCP_TIME_WAIT, 0); } |
18219463c dccp ccid-2: Cons... |
152 |
static void dccp_handle_ackvec_processing(struct sock *sk, struct sk_buff *skb) |
7c657876b [DCCP]: Initial i... |
153 |
{ |
18219463c dccp ccid-2: Cons... |
154 |
struct dccp_ackvec *av = dccp_sk(sk)->dccps_hc_rx_ackvec; |
7c657876b [DCCP]: Initial i... |
155 |
|
18219463c dccp ccid-2: Cons... |
156 157 158 159 160 |
if (av == NULL) return; if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) dccp_ackvec_clear_state(av, DCCP_SKB_CB(skb)->dccpd_ack_seq); dccp_ackvec_input(av, skb); |
7c657876b [DCCP]: Initial i... |
161 |
} |
8e8c71f1a [DCCP]: Honour an... |
162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
static void dccp_deliver_input_to_ccids(struct sock *sk, struct sk_buff *skb) { const struct dccp_sock *dp = dccp_sk(sk); /* Don't deliver to RX CCID when node has shut down read end. */ if (!(sk->sk_shutdown & RCV_SHUTDOWN)) ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); /* * Until the TX queue has been drained, we can not honour SHUT_WR, since * we need received feedback as input to adjust congestion control. */ if (sk->sk_write_queue.qlen > 0 || !(sk->sk_shutdown & SEND_SHUTDOWN)) ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb); } |
7c657876b [DCCP]: Initial i... |
176 177 178 179 |
static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb) { const struct dccp_hdr *dh = dccp_hdr(skb); struct dccp_sock *dp = dccp_sk(sk); |
cbe1f5f88 [DCCP]: Shorten v... |
180 181 |
u64 lswl, lawl, seqno = DCCP_SKB_CB(skb)->dccpd_seq, ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq; |
7c657876b [DCCP]: Initial i... |
182 183 184 185 186 187 188 189 190 191 192 193 194 |
/* * Step 5: Prepare sequence numbers for Sync * If P.type == Sync or P.type == SyncAck, * If S.AWL <= P.ackno <= S.AWH and P.seqno >= S.SWL, * / * P is valid, so update sequence number variables * accordingly. After this update, P will pass the tests * in Step 6. A SyncAck is generated if necessary in * Step 15 * / * Update S.GSR, S.SWL, S.SWH * Otherwise, * Drop packet and return */ |
8109b02b5 [DCCP]: Whitespac... |
195 |
if (dh->dccph_type == DCCP_PKT_SYNC || |
7c657876b [DCCP]: Initial i... |
196 |
dh->dccph_type == DCCP_PKT_SYNCACK) { |
cbe1f5f88 [DCCP]: Shorten v... |
197 198 199 |
if (between48(ackno, dp->dccps_awl, dp->dccps_awh) && dccp_delta_seqno(dp->dccps_swl, seqno) >= 0) dccp_update_gsr(sk, seqno); |
7c657876b [DCCP]: Initial i... |
200 201 |
else return -1; |
e92ae93a8 [DCCP]: Send SYNC... |
202 |
} |
c9eaf1734 [NET] DCCP: Fix w... |
203 |
|
7c657876b [DCCP]: Initial i... |
204 205 206 207 208 209 210 211 212 213 |
/* * Step 6: Check sequence numbers * Let LSWL = S.SWL and LAWL = S.AWL * If P.type == CloseReq or P.type == Close or P.type == Reset, * LSWL := S.GSR + 1, LAWL := S.GAR * If LSWL <= P.seqno <= S.SWH * and (P.ackno does not exist or LAWL <= P.ackno <= S.AWH), * Update S.GSR, S.SWL, S.SWH * If P.type != Sync, * Update S.GAR |
7c657876b [DCCP]: Initial i... |
214 |
*/ |
e92ae93a8 [DCCP]: Send SYNC... |
215 216 217 218 |
lswl = dp->dccps_swl; lawl = dp->dccps_awl; if (dh->dccph_type == DCCP_PKT_CLOSEREQ || |
c59eab463 [DCCP]: Use LIMIT... |
219 220 |
dh->dccph_type == DCCP_PKT_CLOSE || dh->dccph_type == DCCP_PKT_RESET) { |
cbe1f5f88 [DCCP]: Shorten v... |
221 |
lswl = ADD48(dp->dccps_gsr, 1); |
7c657876b [DCCP]: Initial i... |
222 223 |
lawl = dp->dccps_gar; } |
cbe1f5f88 [DCCP]: Shorten v... |
224 225 226 227 |
if (between48(seqno, lswl, dp->dccps_swh) && (ackno == DCCP_PKT_WITHOUT_ACK_SEQ || between48(ackno, lawl, dp->dccps_awh))) { dccp_update_gsr(sk, seqno); |
7c657876b [DCCP]: Initial i... |
228 229 |
if (dh->dccph_type != DCCP_PKT_SYNC && |
0ac788702 dccp: fix error i... |
230 231 |
ackno != DCCP_PKT_WITHOUT_ACK_SEQ && after48(ackno, dp->dccps_gar)) |
cbe1f5f88 [DCCP]: Shorten v... |
232 |
dp->dccps_gar = ackno; |
7c657876b [DCCP]: Initial i... |
233 |
} else { |
a94f0f970 [DCCP]: Rate-limi... |
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
unsigned long now = jiffies; /* * Step 6: Check sequence numbers * Otherwise, * If P.type == Reset, * Send Sync packet acknowledging S.GSR * Otherwise, * Send Sync packet acknowledging P.seqno * Drop packet and return * * These Syncs are rate-limited as per RFC 4340, 7.5.4: * at most 1 / (dccp_sync_rate_limit * HZ) Syncs per second. */ if (time_before(now, (dp->dccps_rate_last + sysctl_dccp_sync_ratelimit))) |
2cf5be93d dccp: fix return ... |
249 |
return -1; |
a94f0f970 [DCCP]: Rate-limi... |
250 |
|
2f34b3297 dccp: cosmetics -... |
251 |
DCCP_WARN("Step 6 failed for %s packet, " |
59348b19e [DCCP]: Simplifie... |
252 253 254 255 |
"(LSWL(%llu) <= P.seqno(%llu) <= S.SWH(%llu)) and " "(P.ackno %s or LAWL(%llu) <= P.ackno(%llu) <= S.AWH(%llu), " "sending SYNC... ", dccp_packet_name(dh->dccph_type), |
cbe1f5f88 [DCCP]: Shorten v... |
256 |
(unsigned long long) lswl, (unsigned long long) seqno, |
59348b19e [DCCP]: Simplifie... |
257 |
(unsigned long long) dp->dccps_swh, |
cbe1f5f88 [DCCP]: Shorten v... |
258 259 260 |
(ackno == DCCP_PKT_WITHOUT_ACK_SEQ) ? "doesn't exist" : "exists", (unsigned long long) lawl, (unsigned long long) ackno, |
59348b19e [DCCP]: Simplifie... |
261 |
(unsigned long long) dp->dccps_awh); |
a94f0f970 [DCCP]: Rate-limi... |
262 263 |
dp->dccps_rate_last = now; |
e155d7692 [DCCP]: Fix Reset... |
264 265 |
if (dh->dccph_type == DCCP_PKT_RESET) seqno = dp->dccps_gsr; |
cbe1f5f88 [DCCP]: Shorten v... |
266 |
dccp_send_sync(sk, seqno, DCCP_PKT_SYNC); |
7c657876b [DCCP]: Initial i... |
267 268 269 270 271 |
return -1; } return 0; } |
c25a18ba3 [DCCP]: Uninline ... |
272 273 |
static int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb, const struct dccp_hdr *dh, const unsigned len) |
7c657876b [DCCP]: Initial i... |
274 275 |
{ struct dccp_sock *dp = dccp_sk(sk); |
7c657876b [DCCP]: Initial i... |
276 277 278 279 |
switch (dccp_hdr(skb)->dccph_type) { case DCCP_PKT_DATAACK: case DCCP_PKT_DATA: /* |
8e8c71f1a [DCCP]: Honour an... |
280 281 282 |
* FIXME: schedule DATA_DROPPED (RFC 4340, 11.7.2) if and when * - sk_shutdown == RCV_SHUTDOWN, use Code 1, "Not Listening" * - sk_receive_queue is full, use Code 2, "Receive Buffer" |
7c657876b [DCCP]: Initial i... |
283 |
*/ |
69567d0b6 [DCCP]: Perform S... |
284 |
dccp_enqueue_skb(sk, skb); |
7c657876b [DCCP]: Initial i... |
285 286 287 288 289 290 291 292 293 294 295 |
return 0; case DCCP_PKT_ACK: goto discard; case DCCP_PKT_RESET: /* * Step 9: Process Reset * If P.type == Reset, * Tear down connection * S.state := TIMEWAIT * Set TIMEWAIT timer * Drop packet and return |
d8ef2c29a [DCCP]: Convert R... |
296 297 |
*/ dccp_rcv_reset(sk, skb); |
7c657876b [DCCP]: Initial i... |
298 299 |
return 0; case DCCP_PKT_CLOSEREQ: |
0c8696207 [DCCP]: Integrate... |
300 301 |
if (dccp_rcv_closereq(sk, skb)) return 0; |
7c657876b [DCCP]: Initial i... |
302 303 |
goto discard; case DCCP_PKT_CLOSE: |
0c8696207 [DCCP]: Integrate... |
304 305 306 |
if (dccp_rcv_close(sk, skb)) return 0; goto discard; |
7c657876b [DCCP]: Initial i... |
307 |
case DCCP_PKT_REQUEST: |
8109b02b5 [DCCP]: Whitespac... |
308 309 |
/* Step 7 * or (S.is_server and P.type == Response) |
7c657876b [DCCP]: Initial i... |
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
* or (S.is_client and P.type == Request) * or (S.state >= OPEN and P.type == Request * and P.seqno >= S.OSR) * or (S.state >= OPEN and P.type == Response * and P.seqno >= S.OSR) * or (S.state == RESPOND and P.type == Data), * Send Sync packet acknowledging P.seqno * Drop packet and return */ if (dp->dccps_role != DCCP_ROLE_LISTEN) goto send_sync; goto check_seq; case DCCP_PKT_RESPONSE: if (dp->dccps_role != DCCP_ROLE_CLIENT) goto send_sync; check_seq: |
8d13bf9a0 [DCCP]: Remove am... |
326 327 |
if (dccp_delta_seqno(dp->dccps_osr, DCCP_SKB_CB(skb)->dccpd_seq) >= 0) { |
7c657876b [DCCP]: Initial i... |
328 |
send_sync: |
e92ae93a8 [DCCP]: Send SYNC... |
329 330 |
dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, DCCP_PKT_SYNC); |
7c657876b [DCCP]: Initial i... |
331 332 |
} break; |
e92ae93a8 [DCCP]: Send SYNC... |
333 334 335 336 |
case DCCP_PKT_SYNC: dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, DCCP_PKT_SYNCACK); /* |
0e64e94e4 [DCCP]: Update do... |
337 |
* From RFC 4340, sec. 5.7 |
e92ae93a8 [DCCP]: Send SYNC... |
338 339 340 |
* * As with DCCP-Ack packets, DCCP-Sync and DCCP-SyncAck packets * MAY have non-zero-length application data areas, whose |
0e64e94e4 [DCCP]: Update do... |
341 |
* contents receivers MUST ignore. |
e92ae93a8 [DCCP]: Send SYNC... |
342 343 |
*/ goto discard; |
7c657876b [DCCP]: Initial i... |
344 345 346 347 348 349 350 |
} DCCP_INC_STATS_BH(DCCP_MIB_INERRS); discard: __kfree_skb(skb); return 0; } |
709dd3aaf [DCCP]: Do not pr... |
351 352 353 |
int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, const struct dccp_hdr *dh, const unsigned len) { |
709dd3aaf [DCCP]: Do not pr... |
354 355 |
if (dccp_check_seqno(sk, skb)) goto discard; |
8b8194124 [DCCP]: Allow to ... |
356 |
if (dccp_parse_options(sk, NULL, skb)) |
ba1a6c7bc dccp: Always gene... |
357 |
return 1; |
709dd3aaf [DCCP]: Do not pr... |
358 |
|
18219463c dccp ccid-2: Cons... |
359 |
dccp_handle_ackvec_processing(sk, skb); |
8e8c71f1a [DCCP]: Honour an... |
360 |
dccp_deliver_input_to_ccids(sk, skb); |
709dd3aaf [DCCP]: Do not pr... |
361 362 363 364 365 366 |
return __dccp_rcv_established(sk, skb, dh, len); discard: __kfree_skb(skb); return 0; } |
f21e68caa [DCCP]: Prepare t... |
367 |
EXPORT_SYMBOL_GPL(dccp_rcv_established); |
7c657876b [DCCP]: Initial i... |
368 369 370 371 372 |
static int dccp_rcv_request_sent_state_process(struct sock *sk, struct sk_buff *skb, const struct dccp_hdr *dh, const unsigned len) { |
8109b02b5 [DCCP]: Whitespac... |
373 |
/* |
7c657876b [DCCP]: Initial i... |
374 375 376 377 378 379 380 381 382 383 384 385 386 |
* Step 4: Prepare sequence numbers in REQUEST * If S.state == REQUEST, * If (P.type == Response or P.type == Reset) * and S.AWL <= P.ackno <= S.AWH, * / * Set sequence number variables corresponding to the * other endpoint, so P will pass the tests in Step 6 * / * Set S.GSR, S.ISR, S.SWL, S.SWH * / * Response processing continues in Step 10; Reset * processing continues in Step 9 * / */ if (dh->dccph_type == DCCP_PKT_RESPONSE) { const struct inet_connection_sock *icsk = inet_csk(sk); struct dccp_sock *dp = dccp_sk(sk); |
3393da824 [DCCP]: Simplify ... |
387 |
long tstamp = dccp_timestamp(); |
7c657876b [DCCP]: Initial i... |
388 |
|
7690af3ff [DCCP]: Just refl... |
389 390 391 |
if (!between48(DCCP_SKB_CB(skb)->dccpd_ack_seq, dp->dccps_awl, dp->dccps_awh)) { dccp_pr_debug("invalid ackno: S.AWL=%llu, " |
b13833805 net: remove trail... |
392 393 |
"P.ackno=%llu, S.AWH=%llu ", |
7690af3ff [DCCP]: Just refl... |
394 395 396 |
(unsigned long long)dp->dccps_awl, (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq, (unsigned long long)dp->dccps_awh); |
7c657876b [DCCP]: Initial i... |
397 398 |
goto out_invalid_packet; } |
9e377202d [DCCP]: Send an A... |
399 |
|
991d927c8 dccp: Integration... |
400 401 402 403 404 |
/* * If option processing (Step 8) failed, return 1 here so that * dccp_v4_do_rcv() sends a Reset. The Reset code depends on * the option type and is set in dccp_parse_options(). */ |
8b8194124 [DCCP]: Allow to ... |
405 |
if (dccp_parse_options(sk, NULL, skb)) |
991d927c8 dccp: Integration... |
406 |
return 1; |
afe00251d [DCCP]: Initial f... |
407 |
|
59b80802a dccp: make implem... |
408 |
/* Obtain usec RTT sample from SYN exchange (used by TFRC). */ |
3393da824 [DCCP]: Simplify ... |
409 410 411 |
if (likely(dp->dccps_options_received.dccpor_timestamp_echo)) dp->dccps_syn_rtt = dccp_sample_rtt(sk, 10 * (tstamp - dp->dccps_options_received.dccpor_timestamp_echo)); |
89560b53b [DCCP]: Sample RT... |
412 |
|
d28934ad8 dccp: Fix panic c... |
413 414 415 416 417 |
/* Stop the REQUEST timer */ inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS); WARN_ON(sk->sk_send_head == NULL); kfree_skb(sk->sk_send_head); sk->sk_send_head = NULL; |
03ace394a [DCCP]: Fix the A... |
418 |
/* |
0b53d4604 dccp: fix the adj... |
419 420 421 422 423 |
* Set ISR, GSR from packet. ISS was set in dccp_v{4,6}_connect * and GSS in dccp_transmit_skb(). Setting AWL/AWH and SWL/SWH * is done as part of activating the feature values below, since * these settings depend on the local/remote Sequence Window * features, which were undefined or not confirmed until now. |
03ace394a [DCCP]: Fix the A... |
424 |
*/ |
0b53d4604 dccp: fix the adj... |
425 |
dp->dccps_gsr = dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq; |
7c657876b [DCCP]: Initial i... |
426 |
|
d83d8461f [IP_SOCKGLUE]: Re... |
427 |
dccp_sync_mss(sk, icsk->icsk_pmtu_cookie); |
7c657876b [DCCP]: Initial i... |
428 429 430 431 |
/* * Step 10: Process REQUEST state (second part) * If S.state == REQUEST, |
7690af3ff [DCCP]: Just refl... |
432 433 434 435 436 437 |
* / * If we get here, P is a valid Response from the * server (see Step 4), and we should move to * PARTOPEN state. PARTOPEN means send an Ack, * don't send Data packets, retransmit Acks * periodically, and always include any Init Cookie * from the Response * / |
7c657876b [DCCP]: Initial i... |
438 439 |
* S.state := PARTOPEN * Set PARTOPEN timer |
8109b02b5 [DCCP]: Whitespac... |
440 |
* Continue with S.state == PARTOPEN |
7690af3ff [DCCP]: Just refl... |
441 442 |
* / * Step 12 will send the Ack completing the * three-way handshake * / |
7c657876b [DCCP]: Initial i... |
443 444 |
*/ dccp_set_state(sk, DCCP_PARTOPEN); |
991d927c8 dccp: Integration... |
445 446 447 448 449 450 451 452 |
/* * If feature negotiation was successful, activate features now; * an activation failure means that this host could not activate * one ore more features (e.g. insufficient memory), which would * leave at least one feature in an undefined state. */ if (dccp_feat_activate_values(sk, &dp->dccps_featneg)) goto unable_to_proceed; |
7c657876b [DCCP]: Initial i... |
453 |
/* Make sure socket is routed, for correct metrics. */ |
57cca05af [DCCP]: Introduce... |
454 |
icsk->icsk_af_ops->rebuild_header(sk); |
7c657876b [DCCP]: Initial i... |
455 456 457 |
if (!sock_flag(sk, SOCK_DEAD)) { sk->sk_state_change(sk); |
8d8ad9d7c [NET]: Name magic... |
458 |
sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT); |
7c657876b [DCCP]: Initial i... |
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 |
} if (sk->sk_write_pending || icsk->icsk_ack.pingpong || icsk->icsk_accept_queue.rskq_defer_accept) { /* Save one ACK. Data will be ready after * several ticks, if write_pending is set. * * It may be deleted, but with this feature tcpdumps * look so _wonderfully_ clever, that I was not able * to stand against the temptation 8) --ANK */ /* * OK, in DCCP we can as well do a similar trick, its * even in the draft, but there is no need for us to * schedule an ack here, as dccp_sendmsg does this for * us, also stated in the draft. -acme */ __kfree_skb(skb); return 0; |
8109b02b5 [DCCP]: Whitespac... |
478 |
} |
7c657876b [DCCP]: Initial i... |
479 480 481 482 483 |
dccp_send_ack(sk); return -1; } out_invalid_packet: |
0c10c5d96 [DCCP]: More prec... |
484 485 |
/* dccp_v4_do_rcv will send a reset */ DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; |
8109b02b5 [DCCP]: Whitespac... |
486 |
return 1; |
991d927c8 dccp: Integration... |
487 488 489 490 491 492 493 494 495 496 |
unable_to_proceed: DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_ABORTED; /* * We mark this socket as no longer usable, so that the loop in * dccp_sendmsg() terminates and the application gets notified. */ dccp_set_state(sk, DCCP_CLOSED); sk->sk_err = ECOMM; return 1; |
7c657876b [DCCP]: Initial i... |
497 498 499 500 501 502 503 |
} static int dccp_rcv_respond_partopen_state_process(struct sock *sk, struct sk_buff *skb, const struct dccp_hdr *dh, const unsigned len) { |
59b80802a dccp: make implem... |
504 505 |
struct dccp_sock *dp = dccp_sk(sk); u32 sample = dp->dccps_options_received.dccpor_timestamp_echo; |
7c657876b [DCCP]: Initial i... |
506 507 508 509 510 511 |
int queued = 0; switch (dh->dccph_type) { case DCCP_PKT_RESET: inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); break; |
2a9bc9bb4 [DCCP]: Transitio... |
512 513 514 |
case DCCP_PKT_DATA: if (sk->sk_state == DCCP_RESPOND) break; |
7c657876b [DCCP]: Initial i... |
515 516 517 |
case DCCP_PKT_DATAACK: case DCCP_PKT_ACK: /* |
7690af3ff [DCCP]: Just refl... |
518 519 520 521 522 523 |
* FIXME: we should be reseting the PARTOPEN (DELACK) timer * here but only if we haven't used the DELACK timer for * something else, like sending a delayed ack for a TIMESTAMP * echo, etc, for now were not clearing it, sending an extra * ACK when there is nothing else to do in DELACK is not a big * deal after all. |
7c657876b [DCCP]: Initial i... |
524 525 526 527 528 |
*/ /* Stop the PARTOPEN timer */ if (sk->sk_state == DCCP_PARTOPEN) inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); |
59b80802a dccp: make implem... |
529 530 531 532 533 534 535 536 |
/* Obtain usec RTT sample from SYN exchange (used by TFRC). */ if (likely(sample)) { long delta = dccp_timestamp() - sample; dp->dccps_syn_rtt = dccp_sample_rtt(sk, 10 * delta); } dp->dccps_osr = DCCP_SKB_CB(skb)->dccpd_seq; |
7c657876b [DCCP]: Initial i... |
537 |
dccp_set_state(sk, DCCP_OPEN); |
2a9bc9bb4 [DCCP]: Transitio... |
538 539 |
if (dh->dccph_type == DCCP_PKT_DATAACK || dh->dccph_type == DCCP_PKT_DATA) { |
709dd3aaf [DCCP]: Do not pr... |
540 |
__dccp_rcv_established(sk, skb, dh, len); |
7690af3ff [DCCP]: Just refl... |
541 |
queued = 1; /* packet was queued |
709dd3aaf [DCCP]: Do not pr... |
542 |
(by __dccp_rcv_established) */ |
7c657876b [DCCP]: Initial i... |
543 544 545 546 547 548 549 550 551 552 553 |
} break; } return queued; } int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, struct dccp_hdr *dh, unsigned len) { struct dccp_sock *dp = dccp_sk(sk); |
0c10c5d96 [DCCP]: More prec... |
554 |
struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); |
7c657876b [DCCP]: Initial i... |
555 556 |
const int old_state = sk->sk_state; int queued = 0; |
8649b0d41 [DCCP]: Fix RESET... |
557 558 |
/* * Step 3: Process LISTEN state |
8649b0d41 [DCCP]: Fix RESET... |
559 560 |
* * If S.state == LISTEN, |
d83ca5acc [DCCP]: Update co... |
561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 |
* If P.type == Request or P contains a valid Init Cookie option, * (* Must scan the packet's options to check for Init * Cookies. Only Init Cookies are processed here, * however; other options are processed in Step 8. This * scan need only be performed if the endpoint uses Init * Cookies *) * (* Generate a new socket and switch to that socket *) * Set S := new socket for this port pair * S.state = RESPOND * Choose S.ISS (initial seqno) or set from Init Cookies * Initialize S.GAR := S.ISS * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init * Cookies Continue with S.state == RESPOND * (* A Response packet will be generated in Step 11 *) * Otherwise, * Generate Reset(No Connection) unless P.type == Reset * Drop packet and return |
8649b0d41 [DCCP]: Fix RESET... |
578 579 580 |
*/ if (sk->sk_state == DCCP_LISTEN) { if (dh->dccph_type == DCCP_PKT_REQUEST) { |
57cca05af [DCCP]: Introduce... |
581 582 |
if (inet_csk(sk)->icsk_af_ops->conn_request(sk, skb) < 0) |
8649b0d41 [DCCP]: Fix RESET... |
583 |
return 1; |
8649b0d41 [DCCP]: Fix RESET... |
584 585 586 587 |
goto discard; } if (dh->dccph_type == DCCP_PKT_RESET) goto discard; |
0c10c5d96 [DCCP]: More prec... |
588 589 |
/* Caller (dccp_v4_do_rcv) will send Reset */ dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; |
8649b0d41 [DCCP]: Fix RESET... |
590 |
return 1; |
720dc34bb dccp: fix oops on... |
591 592 593 |
} else if (sk->sk_state == DCCP_CLOSED) { dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; return 1; |
8649b0d41 [DCCP]: Fix RESET... |
594 |
} |
c0c201505 dccp: Clean up sl... |
595 596 597 |
/* Step 6: Check sequence numbers (omitted in LISTEN/REQUEST state) */ if (sk->sk_state != DCCP_REQUESTING && dccp_check_seqno(sk, skb)) goto discard; |
7c657876b [DCCP]: Initial i... |
598 |
|
c0c201505 dccp: Clean up sl... |
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 |
/* * Step 7: Check for unexpected packet types * If (S.is_server and P.type == Response) * or (S.is_client and P.type == Request) * or (S.state == RESPOND and P.type == Data), * Send Sync packet acknowledging P.seqno * Drop packet and return */ if ((dp->dccps_role != DCCP_ROLE_CLIENT && dh->dccph_type == DCCP_PKT_RESPONSE) || (dp->dccps_role == DCCP_ROLE_CLIENT && dh->dccph_type == DCCP_PKT_REQUEST) || (sk->sk_state == DCCP_RESPOND && dh->dccph_type == DCCP_PKT_DATA)) { dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNC); goto discard; |
410e27a49 This reverts "Mer... |
614 |
} |
ddab05568 dccp: Clean up sl... |
615 |
|
c0c201505 dccp: Clean up sl... |
616 617 618 |
/* Step 8: Process options */ if (dccp_parse_options(sk, NULL, skb)) return 1; |
7c657876b [DCCP]: Initial i... |
619 620 621 622 623 624 625 |
/* * Step 9: Process Reset * If P.type == Reset, * Tear down connection * S.state := TIMEWAIT * Set TIMEWAIT timer * Drop packet and return |
c0c201505 dccp: Clean up sl... |
626 |
*/ |
7c657876b [DCCP]: Initial i... |
627 |
if (dh->dccph_type == DCCP_PKT_RESET) { |
d8ef2c29a [DCCP]: Convert R... |
628 |
dccp_rcv_reset(sk, skb); |
7c657876b [DCCP]: Initial i... |
629 |
return 0; |
c0c201505 dccp: Clean up sl... |
630 |
} else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) { /* Step 13 */ |
0c8696207 [DCCP]: Integrate... |
631 632 |
if (dccp_rcv_closereq(sk, skb)) return 0; |
7ad07e7cf [DCCP]: Implement... |
633 |
goto discard; |
c0c201505 dccp: Clean up sl... |
634 |
} else if (dh->dccph_type == DCCP_PKT_CLOSE) { /* Step 14 */ |
0c8696207 [DCCP]: Integrate... |
635 636 637 |
if (dccp_rcv_close(sk, skb)) return 0; goto discard; |
7c657876b [DCCP]: Initial i... |
638 639 640 |
} switch (sk->sk_state) { |
7c657876b [DCCP]: Initial i... |
641 |
case DCCP_REQUESTING: |
7c657876b [DCCP]: Initial i... |
642 643 644 645 646 647 |
queued = dccp_rcv_request_sent_state_process(sk, skb, dh, len); if (queued >= 0) return queued; __kfree_skb(skb); return 0; |
410e27a49 This reverts "Mer... |
648 |
case DCCP_PARTOPEN: |
c0c201505 dccp: Clean up sl... |
649 650 651 652 653 |
/* Step 8: if using Ack Vectors, mark packet acknowledgeable */ dccp_handle_ackvec_processing(sk, skb); dccp_deliver_input_to_ccids(sk, skb); /* fall through */ case DCCP_RESPOND: |
7690af3ff [DCCP]: Just refl... |
654 655 |
queued = dccp_rcv_respond_partopen_state_process(sk, skb, dh, len); |
7c657876b [DCCP]: Initial i... |
656 657 |
break; } |
7690af3ff [DCCP]: Just refl... |
658 659 |
if (dh->dccph_type == DCCP_PKT_ACK || dh->dccph_type == DCCP_PKT_DATAACK) { |
7c657876b [DCCP]: Initial i... |
660 661 662 |
switch (old_state) { case DCCP_PARTOPEN: sk->sk_state_change(sk); |
8d8ad9d7c [NET]: Name magic... |
663 |
sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT); |
7c657876b [DCCP]: Initial i... |
664 665 |
break; } |
08831700c [DCCP]: Send Rese... |
666 667 668 |
} else if (unlikely(dh->dccph_type == DCCP_PKT_SYNC)) { dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNCACK); goto discard; |
7c657876b [DCCP]: Initial i... |
669 |
} |
8109b02b5 [DCCP]: Whitespac... |
670 |
if (!queued) { |
7c657876b [DCCP]: Initial i... |
671 672 673 674 675 |
discard: __kfree_skb(skb); } return 0; } |
f21e68caa [DCCP]: Prepare t... |
676 677 |
EXPORT_SYMBOL_GPL(dccp_rcv_state_process); |
4712a792e [DCCP]: Provide f... |
678 679 |
/** |
3393da824 [DCCP]: Simplify ... |
680 681 682 683 |
* dccp_sample_rtt - Validate and finalise computation of RTT sample * @delta: number of microseconds between packet and acknowledgment * The routine is kept generic to work in different contexts. It should be * called immediately when the ACK used for the RTT sample arrives. |
4712a792e [DCCP]: Provide f... |
684 |
*/ |
3393da824 [DCCP]: Simplify ... |
685 |
u32 dccp_sample_rtt(struct sock *sk, long delta) |
4712a792e [DCCP]: Provide f... |
686 |
{ |
3393da824 [DCCP]: Simplify ... |
687 688 |
/* dccpor_elapsed_time is either zeroed out or set and > 0 */ delta -= dccp_sk(sk)->dccps_options_received.dccpor_elapsed_time * 10; |
4712a792e [DCCP]: Provide f... |
689 |
|
410e27a49 This reverts "Mer... |
690 691 692 693 694 695 696 697 698 699 700 701 |
if (unlikely(delta <= 0)) { DCCP_WARN("unusable RTT sample %ld, using min ", delta); return DCCP_SANE_RTT_MIN; } if (unlikely(delta > DCCP_SANE_RTT_MAX)) { DCCP_WARN("RTT sample %ld too large, using max ", delta); return DCCP_SANE_RTT_MAX; } return delta; |
4712a792e [DCCP]: Provide f... |
702 |
} |