[PACKET_HISTORY]: Add dccphtx_rtt and rename the win_count fields
[deliverable/linux.git] / net / dccp / options.c
CommitLineData
7c657876
ACM
1/*
2 * net/dccp/options.c
3 *
4 * An implementation of the DCCP protocol
5 * Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
6 * Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13#include <linux/config.h>
14#include <linux/dccp.h>
15#include <linux/module.h>
16#include <linux/types.h>
17#include <linux/kernel.h>
18#include <linux/skbuff.h>
19
20#include "ccid.h"
21#include "dccp.h"
22
23static void dccp_ackpkts_check_rcv_ackvector(struct dccp_ackpkts *ap,
24 struct sock *sk,
25 const u64 ackno,
26 const unsigned char len,
27 const unsigned char *vector);
28
29/* stores the default values for new connection. may be changed with sysctl */
30static const struct dccp_options dccpo_default_values = {
31 .dccpo_sequence_window = DCCPF_INITIAL_SEQUENCE_WINDOW,
32 .dccpo_ccid = DCCPF_INITIAL_CCID,
33 .dccpo_send_ack_vector = DCCPF_INITIAL_SEND_ACK_VECTOR,
34 .dccpo_send_ndp_count = DCCPF_INITIAL_SEND_NDP_COUNT,
35};
36
37void dccp_options_init(struct dccp_options *dccpo)
38{
39 memcpy(dccpo, &dccpo_default_values, sizeof(*dccpo));
40}
41
42static u32 dccp_decode_value_var(const unsigned char *bf, const u8 len)
43{
44 u32 value = 0;
45
46 if (len > 3)
47 value += *bf++ << 24;
48 if (len > 2)
49 value += *bf++ << 16;
50 if (len > 1)
51 value += *bf++ << 8;
52 if (len > 0)
53 value += *bf;
54
55 return value;
56}
57
58int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
59{
60 struct dccp_sock *dp = dccp_sk(sk);
61#ifdef DCCP_DEBUG
62 const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? "CLIENT rx opt: " :
63 "server rx opt: ";
64#endif
65 const struct dccp_hdr *dh = dccp_hdr(skb);
66 const u8 pkt_type = DCCP_SKB_CB(skb)->dccpd_type;
67 unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb);
68 unsigned char *opt_ptr = options;
69 const unsigned char *opt_end = (unsigned char *)dh + (dh->dccph_doff * 4);
70 struct dccp_options_received *opt_recv = &dp->dccps_options_received;
71 unsigned char opt, len;
72 unsigned char *value;
73
74 memset(opt_recv, 0, sizeof(*opt_recv));
75
76 while (opt_ptr != opt_end) {
77 opt = *opt_ptr++;
78 len = 0;
79 value = NULL;
80
81 /* Check if this isn't a single byte option */
82 if (opt > DCCPO_MAX_RESERVED) {
83 if (opt_ptr == opt_end)
84 goto out_invalid_option;
85
86 len = *opt_ptr++;
87 if (len < 3)
88 goto out_invalid_option;
89 /*
90 * Remove the type and len fields, leaving
91 * just the value size
92 */
93 len -= 2;
94 value = opt_ptr;
95 opt_ptr += len;
96
97 if (opt_ptr > opt_end)
98 goto out_invalid_option;
99 }
100
101 switch (opt) {
102 case DCCPO_PADDING:
103 break;
104 case DCCPO_NDP_COUNT:
105 if (len > 3)
106 goto out_invalid_option;
107
108 opt_recv->dccpor_ndp = dccp_decode_value_var(value, len);
109 dccp_pr_debug("%sNDP count=%d\n", debug_prefix, opt_recv->dccpor_ndp);
110 break;
111 case DCCPO_ACK_VECTOR_0:
112 if (len > DCCP_MAX_ACK_VECTOR_LEN)
113 goto out_invalid_option;
114
115 if (pkt_type == DCCP_PKT_DATA)
116 continue;
117
118 opt_recv->dccpor_ack_vector_len = len;
119 opt_recv->dccpor_ack_vector_idx = value - options;
120
121 dccp_pr_debug("%sACK vector 0, len=%d, ack_ackno=%llu\n",
f6ccf554
DM
122 debug_prefix, len,
123 (unsigned long long)
124 DCCP_SKB_CB(skb)->dccpd_ack_seq);
7c657876
ACM
125 dccp_ackvector_print(DCCP_SKB_CB(skb)->dccpd_ack_seq,
126 value, len);
127 dccp_ackpkts_check_rcv_ackvector(dp->dccps_hc_rx_ackpkts, sk,
128 DCCP_SKB_CB(skb)->dccpd_ack_seq,
129 len, value);
130 break;
131 case DCCPO_TIMESTAMP:
132 if (len != 4)
133 goto out_invalid_option;
134
135 opt_recv->dccpor_timestamp = ntohl(*(u32 *)value);
136
137 dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp;
138 dp->dccps_timestamp_time = jiffies;
139
140 dccp_pr_debug("%sTIMESTAMP=%u, ackno=%llu\n",
141 debug_prefix, opt_recv->dccpor_timestamp,
f6ccf554 142 (unsigned long long)
7c657876
ACM
143 DCCP_SKB_CB(skb)->dccpd_ack_seq);
144 break;
145 case DCCPO_TIMESTAMP_ECHO:
146 if (len < 4 || len > 8)
147 goto out_invalid_option;
148
149 opt_recv->dccpor_timestamp_echo = ntohl(*(u32 *)value);
150
151 dccp_pr_debug("%sTIMESTAMP_ECHO=%u, len=%d, ackno=%llu, diff=%u\n",
152 debug_prefix, opt_recv->dccpor_timestamp_echo,
f6ccf554
DM
153 len + 2,
154 (unsigned long long)
155 DCCP_SKB_CB(skb)->dccpd_ack_seq,
7c657876
ACM
156 tcp_time_stamp - opt_recv->dccpor_timestamp_echo);
157
158 opt_recv->dccpor_elapsed_time = dccp_decode_value_var(value + 4, len - 4);
159 dccp_pr_debug("%sTIMESTAMP_ECHO ELAPSED_TIME=%d\n", debug_prefix,
160 opt_recv->dccpor_elapsed_time);
161 break;
162 case DCCPO_ELAPSED_TIME:
163 if (len > 4)
164 goto out_invalid_option;
165
166 if (pkt_type == DCCP_PKT_DATA)
167 continue;
168 opt_recv->dccpor_elapsed_time = dccp_decode_value_var(value, len);
169 dccp_pr_debug("%sELAPSED_TIME=%d\n", debug_prefix,
170 opt_recv->dccpor_elapsed_time);
171 break;
172 /*
173 * From draft-ietf-dccp-spec-11.txt:
174 *
175 * Option numbers 128 through 191 are for options sent from the HC-
176 * Sender to the HC-Receiver; option numbers 192 through 255 are for
177 * options sent from the HC-Receiver to the HC-Sender.
178 */
179 case 128 ... 191: {
180 const u16 idx = value - options;
181
182 if (ccid_hc_rx_parse_options(dp->dccps_hc_rx_ccid, sk, opt, len, idx, value) != 0)
183 goto out_invalid_option;
184 }
185 break;
186 case 192 ... 255: {
187 const u16 idx = value - options;
188
189 if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk, opt, len, idx, value) != 0)
190 goto out_invalid_option;
191 }
192 break;
193 default:
194 pr_info("DCCP(%p): option %d(len=%d) not implemented, ignoring\n",
195 sk, opt, len);
196 break;
197 }
198 }
199
200 return 0;
201
202out_invalid_option:
203 DCCP_INC_STATS_BH(DCCP_MIB_INVALIDOPT);
204 DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_OPTION_ERROR;
205 pr_info("DCCP(%p): invalid option %d, len=%d\n", sk, opt, len);
206 return -1;
207}
208
209static void dccp_encode_value_var(const u32 value, unsigned char *to,
210 const unsigned int len)
211{
212 if (len > 3)
213 *to++ = (value & 0xFF000000) >> 24;
214 if (len > 2)
215 *to++ = (value & 0xFF0000) >> 16;
216 if (len > 1)
217 *to++ = (value & 0xFF00) >> 8;
218 if (len > 0)
219 *to++ = (value & 0xFF);
220}
221
222static inline int dccp_ndp_len(const int ndp)
223{
224 return likely(ndp <= 0xFF) ? 1 : ndp <= 0xFFFF ? 2 : 3;
225}
226
227void dccp_insert_option(struct sock *sk, struct sk_buff *skb,
228 const unsigned char option,
229 const void *value, const unsigned char len)
230{
231 unsigned char *to;
232
233 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len + 2 > DCCP_MAX_OPT_LEN) {
64ce2073 234 LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert %d option!\n", option);
7c657876
ACM
235 return;
236 }
237
238 DCCP_SKB_CB(skb)->dccpd_opt_len += len + 2;
239
240 to = skb_push(skb, len + 2);
241 *to++ = option;
242 *to++ = len + 2;
243
244 memcpy(to, value, len);
245}
246
247EXPORT_SYMBOL_GPL(dccp_insert_option);
248
249static void dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb)
250{
251 struct dccp_sock *dp = dccp_sk(sk);
252 int ndp = dp->dccps_ndp_count;
253
254 if (dccp_non_data_packet(skb))
255 ++dp->dccps_ndp_count;
256 else
257 dp->dccps_ndp_count = 0;
258
259 if (ndp > 0) {
260 unsigned char *ptr;
261 const int ndp_len = dccp_ndp_len(ndp);
262 const int len = ndp_len + 2;
263
264 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
265 return;
266
267 DCCP_SKB_CB(skb)->dccpd_opt_len += len;
268
269 ptr = skb_push(skb, len);
270 *ptr++ = DCCPO_NDP_COUNT;
271 *ptr++ = len;
272 dccp_encode_value_var(ndp, ptr, ndp_len);
273 }
274}
275
276static inline int dccp_elapsed_time_len(const u32 elapsed_time)
277{
278 return elapsed_time == 0 ? 0 :
279 elapsed_time <= 0xFF ? 1 :
280 elapsed_time <= 0xFFFF ? 2 :
281 elapsed_time <= 0xFFFFFF ? 3 : 4;
282}
283
284void dccp_insert_option_elapsed_time(struct sock *sk,
285 struct sk_buff *skb,
286 u32 elapsed_time)
287{
288#ifdef DCCP_DEBUG
289 struct dccp_sock *dp = dccp_sk(sk);
290 const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? "CLIENT TX opt: " :
291 "server TX opt: ";
292#endif
293 const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
294 const int len = 2 + elapsed_time_len;
295 unsigned char *to;
296
297 /* If elapsed_time == 0... */
298 if (elapsed_time_len == 2)
299 return;
300
301 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) {
64ce2073 302 LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert elapsed time!\n");
7c657876
ACM
303 return;
304 }
305
306 DCCP_SKB_CB(skb)->dccpd_opt_len += len;
307
308 to = skb_push(skb, len);
309 *to++ = DCCPO_ELAPSED_TIME;
310 *to++ = len;
311
312 dccp_encode_value_var(elapsed_time, to, elapsed_time_len);
313
314 dccp_pr_debug("%sELAPSED_TIME=%u, len=%d, seqno=%llu\n",
315 debug_prefix, elapsed_time,
f6ccf554
DM
316 len,
317 (unsigned long long) DCCP_SKB_CB(skb)->dccpd_seq);
7c657876
ACM
318}
319
320EXPORT_SYMBOL(dccp_insert_option_elapsed_time);
321
322static void dccp_insert_option_ack_vector(struct sock *sk, struct sk_buff *skb)
323{
324 struct dccp_sock *dp = dccp_sk(sk);
325#ifdef DCCP_DEBUG
326 const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? "CLIENT TX opt: " :
327 "server TX opt: ";
328#endif
329 struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts;
330 int len = ap->dccpap_buf_vector_len + 2;
331 const u32 elapsed_time = jiffies_to_usecs(jiffies - ap->dccpap_time) / 10;
332 unsigned char *to, *from;
333
334 if (elapsed_time != 0)
335 dccp_insert_option_elapsed_time(sk, skb, elapsed_time);
336
337 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) {
64ce2073 338 LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert ACK Vector!\n");
7c657876
ACM
339 return;
340 }
341
342 /*
343 * XXX: now we have just one ack vector sent record, so
344 * we have to wait for it to be cleared.
345 *
346 * Of course this is not acceptable, but this is just for
347 * basic testing now.
348 */
349 if (ap->dccpap_ack_seqno != DCCP_MAX_SEQNO + 1)
350 return;
351
352 DCCP_SKB_CB(skb)->dccpd_opt_len += len;
353
354 to = skb_push(skb, len);
355 *to++ = DCCPO_ACK_VECTOR_0;
356 *to++ = len;
357
358 len = ap->dccpap_buf_vector_len;
359 from = ap->dccpap_buf + ap->dccpap_buf_head;
360
361 /* Check if buf_head wraps */
362 if (ap->dccpap_buf_head + len > ap->dccpap_buf_len) {
363 const unsigned int tailsize = ap->dccpap_buf_len - ap->dccpap_buf_head;
364
365 memcpy(to, from, tailsize);
366 to += tailsize;
367 len -= tailsize;
368 from = ap->dccpap_buf;
369 }
370
371 memcpy(to, from, len);
372 /*
373 * From draft-ietf-dccp-spec-11.txt:
374 *
375 * For each acknowledgement it sends, the HC-Receiver will add an
376 * acknowledgement record. ack_seqno will equal the HC-Receiver
377 * sequence number it used for the ack packet; ack_ptr will equal
378 * buf_head; ack_ackno will equal buf_ackno; and ack_nonce will equal
379 * buf_nonce.
380 *
381 * This implemention uses just one ack record for now.
382 */
383 ap->dccpap_ack_seqno = DCCP_SKB_CB(skb)->dccpd_seq;
384 ap->dccpap_ack_ptr = ap->dccpap_buf_head;
385 ap->dccpap_ack_ackno = ap->dccpap_buf_ackno;
386 ap->dccpap_ack_nonce = ap->dccpap_buf_nonce;
387 ap->dccpap_ack_vector_len = ap->dccpap_buf_vector_len;
388
389 dccp_pr_debug("%sACK Vector 0, len=%d, ack_seqno=%llu, ack_ackno=%llu\n",
390 debug_prefix, ap->dccpap_ack_vector_len,
f6ccf554
DM
391 (unsigned long long) ap->dccpap_ack_seqno,
392 (unsigned long long) ap->dccpap_ack_ackno);
7c657876
ACM
393}
394
395static inline void dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb)
396{
397 const u32 now = htonl(tcp_time_stamp);
398 dccp_insert_option(sk, skb, DCCPO_TIMESTAMP, &now, sizeof(now));
399}
400
401static void dccp_insert_option_timestamp_echo(struct sock *sk, struct sk_buff *skb)
402{
403 struct dccp_sock *dp = dccp_sk(sk);
404#ifdef DCCP_DEBUG
405 const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? "CLIENT TX opt: " :
406 "server TX opt: ";
407#endif
408 u32 tstamp_echo;
409 const u32 elapsed_time = jiffies_to_usecs(jiffies - dp->dccps_timestamp_time) / 10;
410 const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
411 const int len = 6 + elapsed_time_len;
412 unsigned char *to;
413
414 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) {
64ce2073 415 LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert timestamp echo!\n");
7c657876
ACM
416 return;
417 }
418
419 DCCP_SKB_CB(skb)->dccpd_opt_len += len;
420
421 to = skb_push(skb, len);
422 *to++ = DCCPO_TIMESTAMP_ECHO;
423 *to++ = len;
424
425 tstamp_echo = htonl(dp->dccps_timestamp_echo);
426 memcpy(to, &tstamp_echo, 4);
427 to += 4;
428 dccp_encode_value_var(elapsed_time, to, elapsed_time_len);
429
430 dccp_pr_debug("%sTIMESTAMP_ECHO=%u, len=%d, seqno=%llu\n",
431 debug_prefix, dp->dccps_timestamp_echo,
f6ccf554
DM
432 len,
433 (unsigned long long) DCCP_SKB_CB(skb)->dccpd_seq);
7c657876
ACM
434
435 dp->dccps_timestamp_echo = 0;
436 dp->dccps_timestamp_time = 0;
437}
438
439void dccp_insert_options(struct sock *sk, struct sk_buff *skb)
440{
441 struct dccp_sock *dp = dccp_sk(sk);
442
443 DCCP_SKB_CB(skb)->dccpd_opt_len = 0;
444
445 if (dp->dccps_options.dccpo_send_ndp_count)
446 dccp_insert_option_ndp(sk, skb);
447
448 if (!dccp_packet_without_ack(skb)) {
449 if (dp->dccps_options.dccpo_send_ack_vector &&
450 dp->dccps_hc_rx_ackpkts->dccpap_buf_ackno != DCCP_MAX_SEQNO + 1)
451 dccp_insert_option_ack_vector(sk, skb);
452
453 dccp_insert_option_timestamp(sk, skb);
454 if (dp->dccps_timestamp_echo != 0)
455 dccp_insert_option_timestamp_echo(sk, skb);
456 }
457
458 ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb);
459 ccid_hc_tx_insert_options(dp->dccps_hc_tx_ccid, sk, skb);
460
461 /* XXX: insert other options when appropriate */
462
463 if (DCCP_SKB_CB(skb)->dccpd_opt_len != 0) {
464 /* The length of all options has to be a multiple of 4 */
465 int padding = DCCP_SKB_CB(skb)->dccpd_opt_len % 4;
466
467 if (padding != 0) {
468 padding = 4 - padding;
469 memset(skb_push(skb, padding), 0, padding);
470 DCCP_SKB_CB(skb)->dccpd_opt_len += padding;
471 }
472 }
473}
474
475struct dccp_ackpkts *dccp_ackpkts_alloc(unsigned int len, int priority)
476{
477 struct dccp_ackpkts *ap = kmalloc(sizeof(*ap) + len, priority);
478
479 if (ap != NULL) {
480#ifdef DCCP_DEBUG
481 memset(ap->dccpap_buf, 0xFF, len);
482#endif
483 ap->dccpap_buf_len = len;
484 ap->dccpap_buf_head = ap->dccpap_buf_tail = ap->dccpap_buf_len - 1;
485 ap->dccpap_buf_ackno = ap->dccpap_ack_ackno = ap->dccpap_ack_seqno = DCCP_MAX_SEQNO + 1;
486 ap->dccpap_buf_nonce = ap->dccpap_buf_nonce = 0;
487 ap->dccpap_ack_ptr = 0;
488 ap->dccpap_time = 0;
489 ap->dccpap_buf_vector_len = ap->dccpap_ack_vector_len = 0;
490 }
491
492 return ap;
493}
494
495void dccp_ackpkts_free(struct dccp_ackpkts *ap)
496{
497 if (ap != NULL) {
498#ifdef DCCP_DEBUG
499 memset(ap, 0xFF, sizeof(*ap) + ap->dccpap_buf_len);
500#endif
501 kfree(ap);
502 }
503}
504
505static inline u8 dccp_ackpkts_state(const struct dccp_ackpkts *ap,
506 const unsigned int index)
507{
508 return ap->dccpap_buf[index] & DCCP_ACKPKTS_STATE_MASK;
509}
510
511static inline u8 dccp_ackpkts_len(const struct dccp_ackpkts *ap,
512 const unsigned int index)
513{
514 return ap->dccpap_buf[index] & DCCP_ACKPKTS_LEN_MASK;
515}
516
517/*
518 * If several packets are missing, the HC-Receiver may prefer to enter multiple
519 * bytes with run length 0, rather than a single byte with a larger run length;
520 * this simplifies table updates if one of the missing packets arrives.
521 */
522static inline int dccp_ackpkts_set_buf_head_state(struct dccp_ackpkts *ap,
523 const unsigned int packets,
524 const unsigned char state)
525{
526 unsigned int gap;
527 signed long new_head;
528
529 if (ap->dccpap_buf_vector_len + packets > ap->dccpap_buf_len)
530 return -ENOBUFS;
531
532 gap = packets - 1;
533 new_head = ap->dccpap_buf_head - packets;
534
535 if (new_head < 0) {
536 if (gap > 0) {
537 memset(ap->dccpap_buf, DCCP_ACKPKTS_STATE_NOT_RECEIVED,
538 gap + new_head + 1);
539 gap = -new_head;
540 }
541 new_head += ap->dccpap_buf_len;
542 }
543
544 ap->dccpap_buf_head = new_head;
545
546 if (gap > 0)
547 memset(ap->dccpap_buf + ap->dccpap_buf_head + 1,
548 DCCP_ACKPKTS_STATE_NOT_RECEIVED, gap);
549
550 ap->dccpap_buf[ap->dccpap_buf_head] = state;
551 ap->dccpap_buf_vector_len += packets;
552 return 0;
553}
554
555/*
556 * Implements the draft-ietf-dccp-spec-11.txt Appendix A
557 */
558int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state)
559{
560 /*
561 * Check at the right places if the buffer is full, if it is, tell the
562 * caller to start dropping packets till the HC-Sender acks our ACK
563 * vectors, when we will free up space in dccpap_buf.
564 *
565 * We may well decide to do buffer compression, etc, but for now lets
566 * just drop.
567 *
568 * From Appendix A:
569 *
570 * Of course, the circular buffer may overflow, either when the HC-
571 * Sender is sending data at a very high rate, when the HC-Receiver's
572 * acknowledgements are not reaching the HC-Sender, or when the HC-
573 * Sender is forgetting to acknowledge those acks (so the HC-Receiver
574 * is unable to clean up old state). In this case, the HC-Receiver
575 * should either compress the buffer (by increasing run lengths when
576 * possible), transfer its state to a larger buffer, or, as a last
577 * resort, drop all received packets, without processing them
578 * whatsoever, until its buffer shrinks again.
579 */
580
581 /* See if this is the first ackno being inserted */
582 if (ap->dccpap_buf_vector_len == 0) {
583 ap->dccpap_buf[ap->dccpap_buf_head] = state;
584 ap->dccpap_buf_vector_len = 1;
585 } else if (after48(ackno, ap->dccpap_buf_ackno)) {
586 const u64 delta = dccp_delta_seqno(ap->dccpap_buf_ackno, ackno);
587
588 /*
589 * Look if the state of this packet is the same as the previous ackno
590 * and if so if we can bump the head len.
591 */
592 if (delta == 1 &&
593 dccp_ackpkts_state(ap, ap->dccpap_buf_head) == state &&
594 dccp_ackpkts_len(ap, ap->dccpap_buf_head) < DCCP_ACKPKTS_LEN_MASK)
595 ap->dccpap_buf[ap->dccpap_buf_head]++;
596 else if (dccp_ackpkts_set_buf_head_state(ap, delta, state))
597 return -ENOBUFS;
598 } else {
599 /*
600 * A.1.2. Old Packets
601 *
602 * When a packet with Sequence Number S arrives, and S <= buf_ackno,
603 * the HC-Receiver will scan the table for the byte corresponding to S.
604 * (Indexing structures could reduce the complexity of this scan.)
605 */
606 u64 delta = dccp_delta_seqno(ackno, ap->dccpap_buf_ackno);
607 unsigned int index = ap->dccpap_buf_head;
608
609 while (1) {
610 const u8 len = dccp_ackpkts_len(ap, index);
611 const u8 state = dccp_ackpkts_state(ap, index);
612 /*
613 * valid packets not yet in dccpap_buf have a reserved entry, with
614 * a len equal to 0
615 */
616 if (state == DCCP_ACKPKTS_STATE_NOT_RECEIVED &&
617 len == 0 && delta == 0) { /* Found our reserved seat! */
f6ccf554
DM
618 dccp_pr_debug("Found %llu reserved seat!\n",
619 (unsigned long long) ackno);
7c657876
ACM
620 ap->dccpap_buf[index] = state;
621 goto out;
622 }
623 /* len == 0 means one packet */
624 if (delta < len + 1)
625 goto out_duplicate;
626
627 delta -= len + 1;
628 if (++index == ap->dccpap_buf_len)
629 index = 0;
630 }
631 }
632
633 ap->dccpap_buf_ackno = ackno;
634 ap->dccpap_time = jiffies;
635out:
636 dccp_pr_debug("");
637 dccp_ackpkts_print(ap);
638 return 0;
639
640out_duplicate:
641 /* Duplicate packet */
f6ccf554
DM
642 dccp_pr_debug("Received a dup or already considered lost packet: %llu\n",
643 (unsigned long long) ackno);
7c657876
ACM
644 return -EILSEQ;
645}
646
647#ifdef DCCP_DEBUG
648void dccp_ackvector_print(const u64 ackno, const unsigned char *vector, int len)
649{
650 if (!dccp_debug)
651 return;
652
f6ccf554
DM
653 printk("ACK vector len=%d, ackno=%llu |", len,
654 (unsigned long long) ackno);
7c657876
ACM
655
656 while (len--) {
657 const u8 state = (*vector & DCCP_ACKPKTS_STATE_MASK) >> 6;
658 const u8 rl = (*vector & DCCP_ACKPKTS_LEN_MASK);
659
660 printk("%d,%d|", state, rl);
661 ++vector;
662 }
663
664 printk("\n");
665}
666
667void dccp_ackpkts_print(const struct dccp_ackpkts *ap)
668{
669 dccp_ackvector_print(ap->dccpap_buf_ackno,
670 ap->dccpap_buf + ap->dccpap_buf_head,
671 ap->dccpap_buf_vector_len);
672}
673#endif
674
675static void dccp_ackpkts_trow_away_ack_record(struct dccp_ackpkts *ap)
676{
677 /*
678 * As we're keeping track of the ack vector size
679 * (dccpap_buf_vector_len) and the sent ack vector size
680 * (dccpap_ack_vector_len) we don't need dccpap_buf_tail at all, but
681 * keep this code here as in the future we'll implement a vector of ack
682 * records, as suggested in draft-ietf-dccp-spec-11.txt Appendix A. -acme
683 */
684#if 0
685 ap->dccpap_buf_tail = ap->dccpap_ack_ptr + 1;
686 if (ap->dccpap_buf_tail >= ap->dccpap_buf_len)
687 ap->dccpap_buf_tail -= ap->dccpap_buf_len;
688#endif
689 ap->dccpap_buf_vector_len -= ap->dccpap_ack_vector_len;
690}
691
692void dccp_ackpkts_check_rcv_ackno(struct dccp_ackpkts *ap, struct sock *sk,
693 u64 ackno)
694{
695 /* Check if we actually sent an ACK vector */
696 if (ap->dccpap_ack_seqno == DCCP_MAX_SEQNO + 1)
697 return;
698
699 if (ackno == ap->dccpap_ack_seqno) {
700#ifdef DCCP_DEBUG
701 struct dccp_sock *dp = dccp_sk(sk);
702 const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? "CLIENT rx ack: " :
703 "server rx ack: ";
704#endif
705 dccp_pr_debug("%sACK packet 0, len=%d, ack_seqno=%llu, ack_ackno=%llu, ACKED!\n",
706 debug_prefix, 1,
f6ccf554
DM
707 (unsigned long long) ap->dccpap_ack_seqno,
708 (unsigned long long) ap->dccpap_ack_ackno);
7c657876
ACM
709 dccp_ackpkts_trow_away_ack_record(ap);
710 ap->dccpap_ack_seqno = DCCP_MAX_SEQNO + 1;
711 }
712}
713
714static void dccp_ackpkts_check_rcv_ackvector(struct dccp_ackpkts *ap,
715 struct sock *sk, u64 ackno,
716 const unsigned char len,
717 const unsigned char *vector)
718{
719 unsigned char i;
720
721 /* Check if we actually sent an ACK vector */
722 if (ap->dccpap_ack_seqno == DCCP_MAX_SEQNO + 1)
723 return;
724 /*
725 * We're in the receiver half connection, so if the received an ACK vector
726 * ackno (e.g. 50) before dccpap_ack_seqno (e.g. 52), we're not interested.
727 *
728 * Extra explanation with example:
729 *
730 * if we received an ACK vector with ackno 50, it can only be acking
731 * 50, 49, 48, etc, not 52 (the seqno for the ACK vector we sent).
732 */
733 // dccp_pr_debug("is %llu < %llu? ", ackno, ap->dccpap_ack_seqno);
734 if (before48(ackno, ap->dccpap_ack_seqno)) {
735 // dccp_pr_debug_cat("yes\n");
736 return;
737 }
738 // dccp_pr_debug_cat("no\n");
739
740 i = len;
741 while (i--) {
742 const u8 rl = (*vector & DCCP_ACKPKTS_LEN_MASK);
743 u64 ackno_end_rl;
744
745 dccp_set_seqno(&ackno_end_rl, ackno - rl);
746
747 // dccp_pr_debug("is %llu <= %llu <= %llu? ", ackno_end_rl, ap->dccpap_ack_seqno, ackno);
748 if (between48(ap->dccpap_ack_seqno, ackno_end_rl, ackno)) {
749 const u8 state = (*vector & DCCP_ACKPKTS_STATE_MASK) >> 6;
750 // dccp_pr_debug_cat("yes\n");
751
752 if (state != DCCP_ACKPKTS_STATE_NOT_RECEIVED) {
753#ifdef DCCP_DEBUG
754 struct dccp_sock *dp = dccp_sk(sk);
755 const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? "CLIENT rx ack: " :
756 "server rx ack: ";
757#endif
758 dccp_pr_debug("%sACK vector 0, len=%d, ack_seqno=%llu, ack_ackno=%llu, ACKED!\n",
759 debug_prefix, len,
f6ccf554
DM
760 (unsigned long long)
761 ap->dccpap_ack_seqno,
762 (unsigned long long)
763 ap->dccpap_ack_ackno);
7c657876
ACM
764 dccp_ackpkts_trow_away_ack_record(ap);
765 }
766 /*
767 * If dccpap_ack_seqno was not received, no problem we'll
768 * send another ACK vector.
769 */
770 ap->dccpap_ack_seqno = DCCP_MAX_SEQNO + 1;
771 break;
772 }
773 // dccp_pr_debug_cat("no\n");
774
775 dccp_set_seqno(&ackno, ackno_end_rl - 1);
776 ++vector;
777 }
778}
This page took 0.052981 seconds and 5 git commands to generate.