2 * net/dccp/ccids/ccid3.c
4 * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
6 * An implementation of the DCCP protocol
8 * This code has been developed by the University of Waikato WAND
9 * research group. For further information please see http://www.wand.net.nz/
10 * or e-mail Ian McDonald - iam4@cs.waikato.ac.nz
12 * This code also uses code from Lulea University, rereleased as GPL by its
14 * Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon
16 * Changes to meet Linux coding standards, to make it meet latest ccid3 draft
17 * and to make it work as a loadable module in the DCCP stack written by
18 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>.
20 * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
22 * This program is free software; you can redistribute it and/or modify
23 * it under the terms of the GNU General Public License as published by
24 * the Free Software Foundation; either version 2 of the License, or
25 * (at your option) any later version.
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37 #include <linux/config.h>
40 #include "../packet_history.h"
44 extern int ccid3_debug;
46 #define ccid3_pr_debug(format, a...) \
47 do { if (ccid3_debug) \
48 printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \
51 #define ccid3_pr_debug(format, a...)
54 #define TFRC_MIN_PACKET_SIZE 16
55 #define TFRC_STD_PACKET_SIZE 256
56 #define TFRC_MAX_PACKET_SIZE 65535
58 #define TFRC_INITIAL_TIMEOUT (2 * USEC_PER_SEC)
59 /* two seconds as per CCID3 spec 11 */
61 #define TFRC_OPSYS_HALF_TIME_GRAN (USEC_PER_SEC / (2 * HZ))
62 /* above is in usecs - half the scheduling granularity as per RFC3448 4.6 */
64 #define TFRC_WIN_COUNT_PER_RTT 4
65 #define TFRC_WIN_COUNT_LIMIT 16
67 #define TFRC_MAX_BACK_OFF_TIME 64
68 /* above is in seconds */
70 #define TFRC_SMALLEST_P 40
72 #define TFRC_RECV_IVAL_F_LENGTH 8 /* length(w[]) */
74 /* Number of later packets received before one is considered lost */
75 #define TFRC_RECV_NUM_LATE_LOSS 3
78 TFRC_OPT_LOSS_EVENT_RATE = 192,
79 TFRC_OPT_LOSS_INTERVALS = 193,
80 TFRC_OPT_RECEIVE_RATE = 194,
83 static int ccid3_debug;
85 static struct dccp_tx_hist *ccid3_tx_hist;
86 static struct dccp_rx_hist *ccid3_rx_hist;
88 static kmem_cache_t *ccid3_loss_interval_hist_slab;
90 static inline struct ccid3_loss_interval_hist_entry *
91 ccid3_loss_interval_hist_entry_new(const unsigned int __nocast prio)
93 return kmem_cache_alloc(ccid3_loss_interval_hist_slab, prio);
96 static inline void ccid3_loss_interval_hist_entry_delete(struct ccid3_loss_interval_hist_entry *entry)
99 kmem_cache_free(ccid3_loss_interval_hist_slab, entry);
102 static void ccid3_loss_interval_history_delete(struct list_head *hist)
104 struct ccid3_loss_interval_hist_entry *entry, *next;
106 list_for_each_entry_safe(entry, next, hist, ccid3lih_node) {
107 list_del_init(&entry->ccid3lih_node);
108 kmem_cache_free(ccid3_loss_interval_hist_slab, entry);
112 static int ccid3_init(struct sock *sk)
114 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
118 static void ccid3_exit(struct sock *sk)
120 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
123 /* TFRC sender states */
124 enum ccid3_hc_tx_states {
125 TFRC_SSTATE_NO_SENT = 1,
126 TFRC_SSTATE_NO_FBACK,
132 static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state)
134 static char *ccid3_state_names[] = {
135 [TFRC_SSTATE_NO_SENT] = "NO_SENT",
136 [TFRC_SSTATE_NO_FBACK] = "NO_FBACK",
137 [TFRC_SSTATE_FBACK] = "FBACK",
138 [TFRC_SSTATE_TERM] = "TERM",
141 return ccid3_state_names[state];
145 static inline void ccid3_hc_tx_set_state(struct sock *sk, enum ccid3_hc_tx_states state)
147 struct dccp_sock *dp = dccp_sk(sk);
148 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
149 enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state;
151 ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
152 dccp_role(sk), sk, ccid3_tx_state_name(oldstate), ccid3_tx_state_name(state));
153 WARN_ON(state == oldstate);
154 hctx->ccid3hctx_state = state;
157 static void timeval_sub(struct timeval large, struct timeval small,
158 struct timeval *result)
160 result->tv_sec = large.tv_sec-small.tv_sec;
161 if (large.tv_usec < small.tv_usec) {
163 result->tv_usec = USEC_PER_SEC +
164 large.tv_usec - small.tv_usec;
166 result->tv_usec = large.tv_usec-small.tv_usec;
169 static inline void timeval_fix(struct timeval *tv)
171 if (tv->tv_usec >= USEC_PER_SEC) {
173 tv->tv_usec -= USEC_PER_SEC;
177 /* returns the difference in usecs between timeval passed in and current time */
178 static inline u32 now_delta(struct timeval tv) {
181 do_gettimeofday(&now);
182 return ((now.tv_sec-tv.tv_sec)*1000000+now.tv_usec-tv.tv_usec);
185 #define CALCX_ARRSIZE 500
187 #define CALCX_SPLIT 50000
188 /* equivalent to 0.05 */
190 static const u32 calcx_lookup[CALCX_ARRSIZE][2] = {
312 { 2976382 , 100134 },
313 { 3037850 , 100626 },
314 { 3100360 , 101117 },
315 { 3163924 , 101608 },
316 { 3228554 , 102097 },
317 { 3294263 , 102586 },
318 { 3361063 , 103073 },
319 { 3428966 , 103560 },
320 { 3497984 , 104045 },
321 { 3568131 , 104530 },
322 { 3639419 , 105014 },
323 { 3711860 , 105498 },
324 { 3785467 , 105980 },
325 { 3860253 , 106462 },
326 { 3936229 , 106942 },
327 { 4013410 , 107422 },
328 { 4091808 , 107902 },
329 { 4171435 , 108380 },
330 { 4252306 , 108858 },
331 { 4334431 , 109335 },
332 { 4417825 , 109811 },
333 { 4502501 , 110287 },
334 { 4588472 , 110762 },
335 { 4675750 , 111236 },
336 { 4764349 , 111709 },
337 { 4854283 , 112182 },
338 { 4945564 , 112654 },
339 { 5038206 , 113126 },
340 { 5132223 , 113597 },
341 { 5227627 , 114067 },
342 { 5324432 , 114537 },
343 { 5422652 , 115006 },
344 { 5522299 , 115474 },
345 { 5623389 , 115942 },
346 { 5725934 , 116409 },
347 { 5829948 , 116876 },
348 { 5935446 , 117342 },
349 { 6042439 , 117808 },
350 { 6150943 , 118273 },
351 { 6260972 , 118738 },
352 { 6372538 , 119202 },
353 { 6485657 , 119665 },
354 { 6600342 , 120128 },
355 { 6716607 , 120591 },
356 { 6834467 , 121053 },
357 { 6953935 , 121514 },
358 { 7075025 , 121976 },
359 { 7197752 , 122436 },
360 { 7322131 , 122896 },
361 { 7448175 , 123356 },
362 { 7575898 , 123815 },
363 { 7705316 , 124274 },
364 { 7836442 , 124733 },
365 { 7969291 , 125191 },
366 { 8103877 , 125648 },
367 { 8240216 , 126105 },
368 { 8378321 , 126562 },
369 { 8518208 , 127018 },
370 { 8659890 , 127474 },
371 { 8803384 , 127930 },
372 { 8948702 , 128385 },
373 { 9095861 , 128840 },
374 { 9244875 , 129294 },
375 { 9395760 , 129748 },
376 { 9548529 , 130202 },
377 { 9703198 , 130655 },
378 { 9859782 , 131108 },
379 { 10018296 , 131561 },
380 { 10178755 , 132014 },
381 { 10341174 , 132466 },
382 { 10505569 , 132917 },
383 { 10671954 , 133369 },
384 { 10840345 , 133820 },
385 { 11010757 , 134271 },
386 { 11183206 , 134721 },
387 { 11357706 , 135171 },
388 { 11534274 , 135621 },
389 { 11712924 , 136071 },
390 { 11893673 , 136520 },
391 { 12076536 , 136969 },
392 { 12261527 , 137418 },
393 { 12448664 , 137867 },
394 { 12637961 , 138315 },
395 { 12829435 , 138763 },
396 { 13023101 , 139211 },
397 { 13218974 , 139658 },
398 { 13417071 , 140106 },
399 { 13617407 , 140553 },
400 { 13819999 , 140999 },
401 { 14024862 , 141446 },
402 { 14232012 , 141892 },
403 { 14441465 , 142339 },
404 { 14653238 , 142785 },
405 { 14867346 , 143230 },
406 { 15083805 , 143676 },
407 { 15302632 , 144121 },
408 { 15523842 , 144566 },
409 { 15747453 , 145011 },
410 { 15973479 , 145456 },
411 { 16201939 , 145900 },
412 { 16432847 , 146345 },
413 { 16666221 , 146789 },
414 { 16902076 , 147233 },
415 { 17140429 , 147677 },
416 { 17381297 , 148121 },
417 { 17624696 , 148564 },
418 { 17870643 , 149007 },
419 { 18119154 , 149451 },
420 { 18370247 , 149894 },
421 { 18623936 , 150336 },
422 { 18880241 , 150779 },
423 { 19139176 , 151222 },
424 { 19400759 , 151664 },
425 { 19665007 , 152107 },
426 { 19931936 , 152549 },
427 { 20201564 , 152991 },
428 { 20473907 , 153433 },
429 { 20748982 , 153875 },
430 { 21026807 , 154316 },
431 { 21307399 , 154758 },
432 { 21590773 , 155199 },
433 { 21876949 , 155641 },
434 { 22165941 , 156082 },
435 { 22457769 , 156523 },
436 { 22752449 , 156964 },
437 { 23049999 , 157405 },
438 { 23350435 , 157846 },
439 { 23653774 , 158287 },
440 { 23960036 , 158727 },
441 { 24269236 , 159168 },
442 { 24581392 , 159608 },
443 { 24896521 , 160049 },
444 { 25214642 , 160489 },
445 { 25535772 , 160929 },
446 { 25859927 , 161370 },
447 { 26187127 , 161810 },
448 { 26517388 , 162250 },
449 { 26850728 , 162690 },
450 { 27187165 , 163130 },
451 { 27526716 , 163569 },
452 { 27869400 , 164009 },
453 { 28215234 , 164449 },
454 { 28564236 , 164889 },
455 { 28916423 , 165328 },
456 { 29271815 , 165768 },
457 { 29630428 , 166208 },
458 { 29992281 , 166647 },
459 { 30357392 , 167087 },
460 { 30725779 , 167526 },
461 { 31097459 , 167965 },
462 { 31472452 , 168405 },
463 { 31850774 , 168844 },
464 { 32232445 , 169283 },
465 { 32617482 , 169723 },
466 { 33005904 , 170162 },
467 { 33397730 , 170601 },
468 { 33792976 , 171041 },
469 { 34191663 , 171480 },
470 { 34593807 , 171919 },
471 { 34999428 , 172358 },
472 { 35408544 , 172797 },
473 { 35821174 , 173237 },
474 { 36237335 , 173676 },
475 { 36657047 , 174115 },
476 { 37080329 , 174554 },
477 { 37507197 , 174993 },
478 { 37937673 , 175433 },
479 { 38371773 , 175872 },
480 { 38809517 , 176311 },
481 { 39250924 , 176750 },
482 { 39696012 , 177190 },
483 { 40144800 , 177629 },
484 { 40597308 , 178068 },
485 { 41053553 , 178507 },
486 { 41513554 , 178947 },
487 { 41977332 , 179386 },
488 { 42444904 , 179825 },
489 { 42916290 , 180265 },
490 { 43391509 , 180704 },
491 { 43870579 , 181144 },
492 { 44353520 , 181583 },
493 { 44840352 , 182023 },
494 { 45331092 , 182462 },
495 { 45825761 , 182902 },
496 { 46324378 , 183342 },
497 { 46826961 , 183781 },
498 { 47333531 , 184221 },
499 { 47844106 , 184661 },
500 { 48358706 , 185101 },
501 { 48877350 , 185541 },
502 { 49400058 , 185981 },
503 { 49926849 , 186421 },
504 { 50457743 , 186861 },
505 { 50992759 , 187301 },
506 { 51531916 , 187741 },
507 { 52075235 , 188181 },
508 { 52622735 , 188622 },
509 { 53174435 , 189062 },
510 { 53730355 , 189502 },
511 { 54290515 , 189943 },
512 { 54854935 , 190383 },
513 { 55423634 , 190824 },
514 { 55996633 , 191265 },
515 { 56573950 , 191706 },
516 { 57155606 , 192146 },
517 { 57741621 , 192587 },
518 { 58332014 , 193028 },
519 { 58926806 , 193470 },
520 { 59526017 , 193911 },
521 { 60129666 , 194352 },
522 { 60737774 , 194793 },
523 { 61350361 , 195235 },
524 { 61967446 , 195677 },
525 { 62589050 , 196118 },
526 { 63215194 , 196560 },
527 { 63845897 , 197002 },
528 { 64481179 , 197444 },
529 { 65121061 , 197886 },
530 { 65765563 , 198328 },
531 { 66414705 , 198770 },
532 { 67068508 , 199213 },
533 { 67726992 , 199655 },
534 { 68390177 , 200098 },
535 { 69058085 , 200540 },
536 { 69730735 , 200983 },
537 { 70408147 , 201426 },
538 { 71090343 , 201869 },
539 { 71777343 , 202312 },
540 { 72469168 , 202755 },
541 { 73165837 , 203199 },
542 { 73867373 , 203642 },
543 { 74573795 , 204086 },
544 { 75285124 , 204529 },
545 { 76001380 , 204973 },
546 { 76722586 , 205417 },
547 { 77448761 , 205861 },
548 { 78179926 , 206306 },
549 { 78916102 , 206750 },
550 { 79657310 , 207194 },
551 { 80403571 , 207639 },
552 { 81154906 , 208084 },
553 { 81911335 , 208529 },
554 { 82672880 , 208974 },
555 { 83439562 , 209419 },
556 { 84211402 , 209864 },
557 { 84988421 , 210309 },
558 { 85770640 , 210755 },
559 { 86558080 , 211201 },
560 { 87350762 , 211647 },
561 { 88148708 , 212093 },
562 { 88951938 , 212539 },
563 { 89760475 , 212985 },
564 { 90574339 , 213432 },
565 { 91393551 , 213878 },
566 { 92218133 , 214325 },
567 { 93048107 , 214772 },
568 { 93883493 , 215219 },
569 { 94724314 , 215666 },
570 { 95570590 , 216114 },
571 { 96422343 , 216561 },
572 { 97279594 , 217009 },
573 { 98142366 , 217457 },
574 { 99010679 , 217905 },
575 { 99884556 , 218353 },
576 { 100764018 , 218801 },
577 { 101649086 , 219250 },
578 { 102539782 , 219698 },
579 { 103436128 , 220147 },
580 { 104338146 , 220596 },
581 { 105245857 , 221046 },
582 { 106159284 , 221495 },
583 { 107078448 , 221945 },
584 { 108003370 , 222394 },
585 { 108934074 , 222844 },
586 { 109870580 , 223294 },
587 { 110812910 , 223745 },
588 { 111761087 , 224195 },
589 { 112715133 , 224646 },
590 { 113675069 , 225097 },
591 { 114640918 , 225548 },
592 { 115612702 , 225999 },
593 { 116590442 , 226450 },
594 { 117574162 , 226902 },
595 { 118563882 , 227353 },
596 { 119559626 , 227805 },
597 { 120561415 , 228258 },
598 { 121569272 , 228710 },
599 { 122583219 , 229162 },
600 { 123603278 , 229615 },
601 { 124629471 , 230068 },
602 { 125661822 , 230521 },
603 { 126700352 , 230974 },
604 { 127745083 , 231428 },
605 { 128796039 , 231882 },
606 { 129853241 , 232336 },
607 { 130916713 , 232790 },
608 { 131986475 , 233244 },
609 { 133062553 , 233699 },
610 { 134144966 , 234153 },
611 { 135233739 , 234608 },
612 { 136328894 , 235064 },
613 { 137430453 , 235519 },
614 { 138538440 , 235975 },
615 { 139652876 , 236430 },
616 { 140773786 , 236886 },
617 { 141901190 , 237343 },
618 { 143035113 , 237799 },
619 { 144175576 , 238256 },
620 { 145322604 , 238713 },
621 { 146476218 , 239170 },
622 { 147636442 , 239627 },
623 { 148803298 , 240085 },
624 { 149976809 , 240542 },
625 { 151156999 , 241000 },
626 { 152343890 , 241459 },
627 { 153537506 , 241917 },
628 { 154737869 , 242376 },
629 { 155945002 , 242835 },
630 { 157158929 , 243294 },
631 { 158379673 , 243753 },
632 { 159607257 , 244213 },
633 { 160841704 , 244673 },
634 { 162083037 , 245133 },
635 { 163331279 , 245593 },
636 { 164586455 , 246054 },
637 { 165848586 , 246514 },
638 { 167117696 , 246975 },
639 { 168393810 , 247437 },
640 { 169676949 , 247898 },
641 { 170967138 , 248360 },
642 { 172264399 , 248822 },
643 { 173568757 , 249284 },
644 { 174880235 , 249747 },
645 { 176198856 , 250209 },
646 { 177524643 , 250672 },
647 { 178857621 , 251136 },
648 { 180197813 , 251599 },
649 { 181545242 , 252063 },
650 { 182899933 , 252527 },
651 { 184261908 , 252991 },
652 { 185631191 , 253456 },
653 { 187007807 , 253920 },
654 { 188391778 , 254385 },
655 { 189783129 , 254851 },
656 { 191181884 , 255316 },
657 { 192588065 , 255782 },
658 { 194001698 , 256248 },
659 { 195422805 , 256714 },
660 { 196851411 , 257181 },
661 { 198287540 , 257648 },
662 { 199731215 , 258115 },
663 { 201182461 , 258582 },
664 { 202641302 , 259050 },
665 { 204107760 , 259518 },
666 { 205581862 , 259986 },
667 { 207063630 , 260454 },
668 { 208553088 , 260923 },
669 { 210050262 , 261392 },
670 { 211555174 , 261861 },
671 { 213067849 , 262331 },
672 { 214588312 , 262800 },
673 { 216116586 , 263270 },
674 { 217652696 , 263741 },
675 { 219196666 , 264211 },
676 { 220748520 , 264682 },
677 { 222308282 , 265153 },
678 { 223875978 , 265625 },
679 { 225451630 , 266097 },
680 { 227035265 , 266569 },
681 { 228626905 , 267041 },
682 { 230226576 , 267514 },
683 { 231834302 , 267986 },
684 { 233450107 , 268460 },
685 { 235074016 , 268933 },
686 { 236706054 , 269407 },
687 { 238346244 , 269881 },
688 { 239994613 , 270355 },
689 { 241651183 , 270830 },
690 { 243315981 , 271305 }
693 /* Calculate the send rate as per section 3.1 of RFC3448
695 Returns send rate in bytes per second
697 Integer maths and lookups are used as not allowed floating point in kernel
699 The function for Xcalc as per section 3.1 of RFC3448 is:
702 -------------------------------------------------------------
703 R*sqrt(2*b*p/3) + (t_RTO * (3*sqrt(3*b*p/8) * p * (1+32*p^2)))
706 X is the trasmit rate in bytes/second
707 s is the packet size in bytes
708 R is the round trip time in seconds
709 p is the loss event rate, between 0 and 1.0, of the number of loss events
710 as a fraction of the number of packets transmitted
711 t_RTO is the TCP retransmission timeout value in seconds
712 b is the number of packets acknowledged by a single TCP acknowledgement
714 we can assume that b = 1 and t_RTO is 4 * R. With this the equation becomes:
717 -----------------------------------------------------------------------
718 R * sqrt(2 * p / 3) + (12 * R * (sqrt(3 * p / 8) * p * (1 + 32 * p^2)))
721 which we can break down into:
727 where f(p) = sqrt(2 * p / 3) + (12 * sqrt(3 * p / 8) * p * (1 + 32 * p * p))
732 p - loss rate (decimal fraction multiplied by 1,000,000)
734 Returns Xcalc in bytes per second
736 DON'T alter this code unless you run test cases against it as the code
737 has been manipulated to stop underflow/overlow.
740 static u32 ccid3_calc_x(u16 s, u32 R, u32 p)
747 index = (p / (CALCX_SPLIT / CALCX_ARRSIZE)) - 1;
749 index = (p / (1000000 / CALCX_ARRSIZE)) - 1;
752 /* p should be 0 unless there is a bug in my code */
756 R = 1; /* RTT can't be zero or else divide by zero */
758 BUG_ON(index >= CALCX_ARRSIZE);
760 if (p >= CALCX_SPLIT)
761 f = calcx_lookup[index][0];
763 f = calcx_lookup[index][1];
765 tmp1 = ((u64)s * 100000000);
766 tmp2 = ((u64)R * (u64)f);
769 /* don't alter above math unless you test due to overflow on 32 bit */
774 /* Calculate new t_ipi (inter packet interval) by t_ipi = s / X_inst */
775 static inline void ccid3_calc_new_t_ipi(struct ccid3_hc_tx_sock *hctx)
777 if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK)
779 /* if no feedback spec says t_ipi is 1 second (set elsewhere and then
780 * doubles after every no feedback timer (separate function) */
782 if (hctx->ccid3hctx_x < 10) {
783 ccid3_pr_debug("ccid3_calc_new_t_ipi - ccid3hctx_x < 10\n");
784 hctx->ccid3hctx_x = 10;
786 hctx->ccid3hctx_t_ipi = (hctx->ccid3hctx_s * 100000)
787 / (hctx->ccid3hctx_x / 10);
788 /* reason for above maths with 10 in there is to avoid 32 bit
789 * overflow for jumbo packets */
793 /* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */
794 static inline void ccid3_calc_new_delta(struct ccid3_hc_tx_sock *hctx)
796 hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2, TFRC_OPSYS_HALF_TIME_GRAN);
803 * x_calc = calcX(s, R, p);
804 * X = max(min(X_calc, 2 * X_recv), s / t_mbi);
806 * If (now - tld >= R)
807 * X = max(min(2 * X, 2 * X_recv), s / R);
810 static void ccid3_hc_tx_update_x(struct sock *sk)
812 struct dccp_sock *dp = dccp_sk(sk);
813 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
815 if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) { /* to avoid large error in calcX */
816 hctx->ccid3hctx_x_calc = ccid3_calc_x(hctx->ccid3hctx_s,
819 hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_calc, 2 * hctx->ccid3hctx_x_recv),
820 hctx->ccid3hctx_s / TFRC_MAX_BACK_OFF_TIME);
821 } else if (now_delta(hctx->ccid3hctx_t_ld) >= hctx->ccid3hctx_rtt) {
822 u32 rtt = hctx->ccid3hctx_rtt;
825 } /* avoid divide by zero below */
827 hctx->ccid3hctx_x = max_t(u32, min_t(u32, 2 * hctx->ccid3hctx_x_recv, 2 * hctx->ccid3hctx_x),
828 (hctx->ccid3hctx_s * 100000) / (rtt / 10));
829 /* Using 100000 and 10 to avoid 32 bit overflow for jumbo frames */
830 do_gettimeofday(&hctx->ccid3hctx_t_ld);
833 if (hctx->ccid3hctx_x == 0) {
834 ccid3_pr_debug("ccid3hctx_x = 0!\n");
835 hctx->ccid3hctx_x = 1;
839 static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
841 struct sock *sk = (struct sock *)data;
842 struct dccp_sock *dp = dccp_sk(sk);
843 unsigned long next_tmout = 0;
844 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
848 if (sock_owned_by_user(sk)) {
849 /* Try again later. */
850 /* XXX: set some sensible MIB */
851 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, jiffies + HZ / 5);
855 ccid3_pr_debug("%s, sk=%p, state=%s\n", dccp_role(sk), sk,
856 ccid3_tx_state_name(hctx->ccid3hctx_state));
858 if (hctx->ccid3hctx_x < 10) {
859 ccid3_pr_debug("TFRC_SSTATE_NO_FBACK ccid3hctx_x < 10\n");
860 hctx->ccid3hctx_x = 10;
863 switch (hctx->ccid3hctx_state) {
864 case TFRC_SSTATE_TERM:
866 case TFRC_SSTATE_NO_FBACK:
867 /* Halve send rate */
868 hctx->ccid3hctx_x /= 2;
869 if (hctx->ccid3hctx_x < (hctx->ccid3hctx_s / TFRC_MAX_BACK_OFF_TIME))
870 hctx->ccid3hctx_x = hctx->ccid3hctx_s / TFRC_MAX_BACK_OFF_TIME;
872 ccid3_pr_debug("%s, sk=%p, state=%s, updated tx rate to %d bytes/s\n",
873 dccp_role(sk), sk, ccid3_tx_state_name(hctx->ccid3hctx_state),
875 next_tmout = max_t(u32, 2 * (hctx->ccid3hctx_s * 100000)
876 / (hctx->ccid3hctx_x / 10), TFRC_INITIAL_TIMEOUT);
877 /* do above maths with 100000 and 10 to prevent overflow on 32 bit */
878 /* FIXME - not sure above calculation is correct. See section 5 of CCID3 11
879 * should adjust tx_t_ipi and double that to achieve it really */
881 case TFRC_SSTATE_FBACK:
882 /* Check if IDLE since last timeout and recv rate is less than 4 packets per RTT */
883 rtt = hctx->ccid3hctx_rtt;
886 /* stop divide by zero below */
887 if (!hctx->ccid3hctx_idle || (hctx->ccid3hctx_x_recv >=
888 4 * (hctx->ccid3hctx_s * 100000) / (rtt / 10))) {
889 ccid3_pr_debug("%s, sk=%p, state=%s, not idle\n", dccp_role(sk), sk,
890 ccid3_tx_state_name(hctx->ccid3hctx_state));
891 /* Halve sending rate */
893 /* If (X_calc > 2 * X_recv)
894 * X_recv = max(X_recv / 2, s / (2 * t_mbi));
896 * X_recv = X_calc / 4;
898 BUG_ON(hctx->ccid3hctx_p >= TFRC_SMALLEST_P && hctx->ccid3hctx_x_calc == 0);
900 /* check also if p is zero -> x_calc is infinity? */
901 if (hctx->ccid3hctx_p < TFRC_SMALLEST_P ||
902 hctx->ccid3hctx_x_calc > 2 * hctx->ccid3hctx_x_recv)
903 hctx->ccid3hctx_x_recv = max_t(u32, hctx->ccid3hctx_x_recv / 2,
904 hctx->ccid3hctx_s / (2 * TFRC_MAX_BACK_OFF_TIME));
906 hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc / 4;
908 /* Update sending rate */
909 ccid3_hc_tx_update_x(sk);
911 if (hctx->ccid3hctx_x == 0) {
912 ccid3_pr_debug("TFRC_SSTATE_FBACK ccid3hctx_x = 0!\n");
913 hctx->ccid3hctx_x = 10;
915 /* Schedule no feedback timer to expire in max(4 * R, 2 * s / X) */
916 next_tmout = max_t(u32, inet_csk(sk)->icsk_rto,
917 2 * (hctx->ccid3hctx_s * 100000) / (hctx->ccid3hctx_x / 10));
920 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
921 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
926 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
927 jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout)));
928 hctx->ccid3hctx_idle = 1;
934 static int ccid3_hc_tx_send_packet(struct sock *sk,
935 struct sk_buff *skb, int len)
937 struct dccp_sock *dp = dccp_sk(sk);
938 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
939 struct dccp_tx_hist_entry *new_packet;
944 // ccid3_pr_debug("%s, sk=%p, skb=%p, len=%d\n", dccp_role(sk), sk, skb, len);
946 * check if pure ACK or Terminating */
947 /* XXX: We only call this function for DATA and DATAACK, on, these packets can have
948 * zero length, but why the comment about "pure ACK"?
950 if (hctx == NULL || len == 0 || hctx->ccid3hctx_state == TFRC_SSTATE_TERM)
953 /* See if last packet allocated was not sent */
954 new_packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
955 if (new_packet == NULL || new_packet->dccphtx_sent) {
956 new_packet = dccp_tx_hist_entry_new(ccid3_tx_hist, SLAB_ATOMIC);
959 if (new_packet == NULL) {
960 ccid3_pr_debug("%s, sk=%p, not enough mem to add "
961 "to history, send refused\n", dccp_role(sk), sk);
965 dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet);
968 do_gettimeofday(&now);
970 switch (hctx->ccid3hctx_state) {
971 case TFRC_SSTATE_NO_SENT:
972 ccid3_pr_debug("%s, sk=%p, first packet(%llu)\n", dccp_role(sk), sk,
975 hctx->ccid3hctx_no_feedback_timer.function = ccid3_hc_tx_no_feedback_timer;
976 hctx->ccid3hctx_no_feedback_timer.data = (unsigned long)sk;
977 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, jiffies + usecs_to_jiffies(TFRC_INITIAL_TIMEOUT));
978 hctx->ccid3hctx_last_win_count = 0;
979 hctx->ccid3hctx_t_last_win_count = now;
980 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
981 hctx->ccid3hctx_t_ipi = TFRC_INITIAL_TIMEOUT;
983 /* Set nominal send time for initial packet */
984 hctx->ccid3hctx_t_nom = now;
985 (hctx->ccid3hctx_t_nom).tv_usec += hctx->ccid3hctx_t_ipi;
986 timeval_fix(&(hctx->ccid3hctx_t_nom));
987 ccid3_calc_new_delta(hctx);
990 case TFRC_SSTATE_NO_FBACK:
991 case TFRC_SSTATE_FBACK:
992 delay = (now_delta(hctx->ccid3hctx_t_nom) - hctx->ccid3hctx_delta);
993 ccid3_pr_debug("send_packet delay=%ld\n", delay);
995 /* divide by -1000 is to convert to ms and get sign right */
996 rc = delay > 0 ? -EAGAIN : 0;
999 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
1000 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
1006 /* Can we send? if so add options and add to packet history */
1008 new_packet->dccphtx_ccval =
1009 DCCP_SKB_CB(skb)->dccpd_ccval =
1010 hctx->ccid3hctx_last_win_count;
1015 static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
1017 struct dccp_sock *dp = dccp_sk(sk);
1018 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
1021 // ccid3_pr_debug("%s, sk=%p, more=%d, len=%d\n", dccp_role(sk), sk, more, len);
1022 BUG_ON(hctx == NULL);
1024 if (hctx->ccid3hctx_state == TFRC_SSTATE_TERM) {
1025 ccid3_pr_debug("%s, sk=%p, while state is TFRC_SSTATE_TERM!\n",
1030 do_gettimeofday(&now);
1032 /* check if we have sent a data packet */
1034 unsigned long quarter_rtt;
1035 struct dccp_tx_hist_entry *packet;
1037 packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
1038 if (packet == NULL) {
1039 printk(KERN_CRIT "%s: packet doesn't exists in history!\n", __FUNCTION__);
1042 if (packet->dccphtx_sent) {
1043 printk(KERN_CRIT "%s: no unsent packet in history!\n", __FUNCTION__);
1046 packet->dccphtx_tstamp = now;
1047 packet->dccphtx_seqno = dp->dccps_gss;
1049 ccid3_pr_debug("%s, sk=%p, seqno=%llu inserted!\n",
1050 dccp_role(sk), sk, packet->dccphtx_seqno);
1053 * Check if win_count have changed */
1055 * Algorithm in "8.1. Window Counter Valuer" in draft-ietf-dccp-ccid3-11.txt
1057 quarter_rtt = now_delta(hctx->ccid3hctx_t_last_win_count) / (hctx->ccid3hctx_rtt / 4);
1058 if (quarter_rtt > 0) {
1059 hctx->ccid3hctx_t_last_win_count = now;
1060 hctx->ccid3hctx_last_win_count = (hctx->ccid3hctx_last_win_count +
1061 min_t(unsigned long, quarter_rtt, 5)) % 16;
1062 ccid3_pr_debug("%s, sk=%p, window changed from %u to %u!\n",
1064 packet->dccphtx_ccval,
1065 hctx->ccid3hctx_last_win_count);
1067 /* COMPLIANCE_END */
1069 ccid3_pr_debug("%s, sk=%p, packet sent (%llu,%u)\n",
1071 packet->dccphtx_seqno,
1072 packet->dccphtx_ccval);
1074 hctx->ccid3hctx_idle = 0;
1075 packet->dccphtx_rtt = hctx->ccid3hctx_rtt;
1076 packet->dccphtx_sent = 1;
1078 ccid3_pr_debug("%s, sk=%p, seqno=%llu NOT inserted!\n",
1079 dccp_role(sk), sk, dp->dccps_gss);
1081 switch (hctx->ccid3hctx_state) {
1082 case TFRC_SSTATE_NO_SENT:
1083 /* if first wasn't pure ack */
1085 printk(KERN_CRIT "%s: %s, First packet sent is noted as a data packet\n",
1086 __FUNCTION__, dccp_role(sk));
1088 case TFRC_SSTATE_NO_FBACK:
1089 case TFRC_SSTATE_FBACK:
1091 hctx->ccid3hctx_t_nom = now;
1092 ccid3_calc_new_t_ipi(hctx);
1093 ccid3_calc_new_delta(hctx);
1094 (hctx->ccid3hctx_t_nom).tv_usec += hctx->ccid3hctx_t_ipi;
1095 timeval_fix(&(hctx->ccid3hctx_t_nom));
1099 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
1100 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
1106 static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
1108 struct dccp_sock *dp = dccp_sk(sk);
1109 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
1110 struct ccid3_options_received *opt_recv;
1111 struct dccp_tx_hist_entry *packet;
1112 unsigned long next_tmout;
1118 ccid3_pr_debug("%s, sk=%p(%s), skb=%p(%s)\n",
1119 dccp_role(sk), sk, dccp_state_name(sk->sk_state),
1120 skb, dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
1125 if (hctx->ccid3hctx_state == TFRC_SSTATE_TERM) {
1126 ccid3_pr_debug("%s, sk=%p, received a packet when terminating!\n", dccp_role(sk), sk);
1130 /* we are only interested in ACKs */
1131 if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK ||
1132 DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK))
1135 opt_recv = &hctx->ccid3hctx_options_received;
1137 t_elapsed = dp->dccps_options_received.dccpor_elapsed_time;
1138 x_recv = opt_recv->ccid3or_receive_rate;
1139 pinv = opt_recv->ccid3or_loss_event_rate;
1141 switch (hctx->ccid3hctx_state) {
1142 case TFRC_SSTATE_NO_SENT:
1143 /* FIXME: what to do here? */
1145 case TFRC_SSTATE_NO_FBACK:
1146 case TFRC_SSTATE_FBACK:
1147 /* Calculate new round trip sample by
1148 * R_sample = (now - t_recvdata) - t_delay */
1149 /* get t_recvdata from history */
1150 packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist,
1151 DCCP_SKB_CB(skb)->dccpd_ack_seq);
1152 if (packet == NULL) {
1153 ccid3_pr_debug("%s, sk=%p, seqno %llu(%s) does't exist in history!\n",
1154 dccp_role(sk), sk, DCCP_SKB_CB(skb)->dccpd_ack_seq,
1155 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
1160 r_sample = now_delta(packet->dccphtx_tstamp);
1162 // r_sample -= usecs_to_jiffies(t_elapsed * 10);
1164 /* Update RTT estimate by
1165 * If (No feedback recv)
1168 * R = q * R + (1 - q) * R_sample;
1170 * q is a constant, RFC 3448 recomments 0.9
1172 if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) {
1173 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
1174 hctx->ccid3hctx_rtt = r_sample;
1176 hctx->ccid3hctx_rtt = (hctx->ccid3hctx_rtt * 9) / 10 + r_sample / 10;
1179 * XXX: this is to avoid a division by zero in ccid3_hc_tx_packet_sent
1180 * implemention of the new window count.
1182 if (hctx->ccid3hctx_rtt < 4)
1183 hctx->ccid3hctx_rtt = 4;
1185 ccid3_pr_debug("%s, sk=%p, New RTT estimate=%uus, r_sample=%us\n",
1187 hctx->ccid3hctx_rtt,
1190 /* Update timeout interval */
1191 inet_csk(sk)->icsk_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
1194 /* Update receive rate */
1195 hctx->ccid3hctx_x_recv = x_recv; /* x_recv in bytes per second */
1197 /* Update loss event rate */
1198 if (pinv == ~0 || pinv == 0)
1199 hctx->ccid3hctx_p = 0;
1201 hctx->ccid3hctx_p = 1000000 / pinv;
1203 if (hctx->ccid3hctx_p < TFRC_SMALLEST_P) {
1204 hctx->ccid3hctx_p = TFRC_SMALLEST_P;
1205 ccid3_pr_debug("%s, sk=%p, Smallest p used!\n", dccp_role(sk), sk);
1209 /* unschedule no feedback timer */
1210 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
1212 /* Update sending rate */
1213 ccid3_hc_tx_update_x(sk);
1215 /* Update next send time */
1216 if (hctx->ccid3hctx_t_ipi > (hctx->ccid3hctx_t_nom).tv_usec) {
1217 hctx->ccid3hctx_t_nom.tv_usec += USEC_PER_SEC;
1218 (hctx->ccid3hctx_t_nom).tv_sec--;
1220 /* FIXME - if no feedback then t_ipi can go > 1 second */
1221 (hctx->ccid3hctx_t_nom).tv_usec -= hctx->ccid3hctx_t_ipi;
1222 ccid3_calc_new_t_ipi(hctx);
1223 (hctx->ccid3hctx_t_nom).tv_usec += hctx->ccid3hctx_t_ipi;
1224 timeval_fix(&(hctx->ccid3hctx_t_nom));
1225 ccid3_calc_new_delta(hctx);
1227 /* remove all packets older than the one acked from history */
1228 dccp_tx_hist_purge_older(ccid3_tx_hist,
1229 &hctx->ccid3hctx_hist, packet);
1231 if (hctx->ccid3hctx_x < 10) {
1232 ccid3_pr_debug("ccid3_hc_tx_packet_recv hctx->ccid3hctx_x < 10\n");
1233 hctx->ccid3hctx_x = 10;
1235 /* to prevent divide by zero below */
1237 /* Schedule no feedback timer to expire in max(4 * R, 2 * s / X) */
1238 next_tmout = max(inet_csk(sk)->icsk_rto,
1239 (2 * (hctx->ccid3hctx_s * 100000) /
1240 (hctx->ccid3hctx_x / 10)));
1241 /* maths with 100000 and 10 is to prevent overflow with 32 bit */
1243 ccid3_pr_debug("%s, sk=%p, Scheduled no feedback timer to expire in %lu jiffies (%luus)\n",
1244 dccp_role(sk), sk, usecs_to_jiffies(next_tmout), next_tmout);
1246 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
1247 jiffies + max_t(u32,1,usecs_to_jiffies(next_tmout)));
1250 hctx->ccid3hctx_idle = 1;
1253 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
1254 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
1260 static void ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb)
1262 const struct dccp_sock *dp = dccp_sk(sk);
1263 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
1265 if (hctx == NULL || !(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
1268 DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
1271 static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
1272 unsigned char len, u16 idx, unsigned char *value)
1275 struct dccp_sock *dp = dccp_sk(sk);
1276 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
1277 struct ccid3_options_received *opt_recv;
1282 opt_recv = &hctx->ccid3hctx_options_received;
1284 if (opt_recv->ccid3or_seqno != dp->dccps_gsr) {
1285 opt_recv->ccid3or_seqno = dp->dccps_gsr;
1286 opt_recv->ccid3or_loss_event_rate = ~0;
1287 opt_recv->ccid3or_loss_intervals_idx = 0;
1288 opt_recv->ccid3or_loss_intervals_len = 0;
1289 opt_recv->ccid3or_receive_rate = 0;
1293 case TFRC_OPT_LOSS_EVENT_RATE:
1295 ccid3_pr_debug("%s, sk=%p, invalid len for TFRC_OPT_LOSS_EVENT_RATE\n",
1299 opt_recv->ccid3or_loss_event_rate = ntohl(*(u32 *)value);
1300 ccid3_pr_debug("%s, sk=%p, LOSS_EVENT_RATE=%u\n",
1302 opt_recv->ccid3or_loss_event_rate);
1305 case TFRC_OPT_LOSS_INTERVALS:
1306 opt_recv->ccid3or_loss_intervals_idx = idx;
1307 opt_recv->ccid3or_loss_intervals_len = len;
1308 ccid3_pr_debug("%s, sk=%p, LOSS_INTERVALS=(%u, %u)\n",
1310 opt_recv->ccid3or_loss_intervals_idx,
1311 opt_recv->ccid3or_loss_intervals_len);
1313 case TFRC_OPT_RECEIVE_RATE:
1315 ccid3_pr_debug("%s, sk=%p, invalid len for TFRC_OPT_RECEIVE_RATE\n",
1319 opt_recv->ccid3or_receive_rate = ntohl(*(u32 *)value);
1320 ccid3_pr_debug("%s, sk=%p, RECEIVE_RATE=%u\n",
1322 opt_recv->ccid3or_receive_rate);
1330 static int ccid3_hc_tx_init(struct sock *sk)
1332 struct dccp_sock *dp = dccp_sk(sk);
1333 struct ccid3_hc_tx_sock *hctx;
1335 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
1337 hctx = dp->dccps_hc_tx_ccid_private = kmalloc(sizeof(*hctx), gfp_any());
1341 memset(hctx, 0, sizeof(*hctx));
1343 if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE &&
1344 dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE)
1345 hctx->ccid3hctx_s = (u16)dp->dccps_avg_packet_size;
1347 hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE;
1349 hctx->ccid3hctx_x = hctx->ccid3hctx_s; /* set transmission rate to 1 packet per second */
1350 hctx->ccid3hctx_rtt = 4; /* See ccid3_hc_tx_packet_sent win_count calculatation */
1351 inet_csk(sk)->icsk_rto = USEC_PER_SEC;
1352 hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
1353 INIT_LIST_HEAD(&hctx->ccid3hctx_hist);
1354 init_timer(&hctx->ccid3hctx_no_feedback_timer);
1359 static void ccid3_hc_tx_exit(struct sock *sk)
1361 struct dccp_sock *dp = dccp_sk(sk);
1362 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
1364 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
1365 BUG_ON(hctx == NULL);
1367 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM);
1368 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
1370 /* Empty packet history */
1371 dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist);
1373 kfree(dp->dccps_hc_tx_ccid_private);
1374 dp->dccps_hc_tx_ccid_private = NULL;
1378 * RX Half Connection methods
1381 /* TFRC receiver states */
1382 enum ccid3_hc_rx_states {
1383 TFRC_RSTATE_NO_DATA = 1,
1385 TFRC_RSTATE_TERM = 127,
1389 static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
1391 static char *ccid3_rx_state_names[] = {
1392 [TFRC_RSTATE_NO_DATA] = "NO_DATA",
1393 [TFRC_RSTATE_DATA] = "DATA",
1394 [TFRC_RSTATE_TERM] = "TERM",
1397 return ccid3_rx_state_names[state];
1401 static inline void ccid3_hc_rx_set_state(struct sock *sk, enum ccid3_hc_rx_states state)
1403 struct dccp_sock *dp = dccp_sk(sk);
1404 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1405 enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state;
1407 ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
1408 dccp_role(sk), sk, ccid3_rx_state_name(oldstate), ccid3_rx_state_name(state));
1409 WARN_ON(state == oldstate);
1410 hcrx->ccid3hcrx_state = state;
1413 static int ccid3_hc_rx_add_hist(struct sock *sk,
1414 struct dccp_rx_hist_entry *packet)
1416 struct dccp_sock *dp = dccp_sk(sk);
1417 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1418 struct dccp_rx_hist_entry *entry, *next, *iter;
1421 iter = dccp_rx_hist_head(&hcrx->ccid3hcrx_hist);
1423 dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist, packet);
1425 const u64 seqno = packet->dccphrx_seqno;
1427 if (after48(seqno, iter->dccphrx_seqno))
1428 dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist, packet);
1430 if (dccp_rx_hist_entry_data_packet(iter))
1433 list_for_each_entry_continue(iter,
1434 &hcrx->ccid3hcrx_hist,
1436 if (after48(seqno, iter->dccphrx_seqno)) {
1437 dccp_rx_hist_add_entry(&iter->dccphrx_node,
1442 if (dccp_rx_hist_entry_data_packet(iter))
1445 if (num_later == TFRC_RECV_NUM_LATE_LOSS) {
1446 dccp_rx_hist_entry_delete(ccid3_rx_hist, packet);
1447 ccid3_pr_debug("%s, sk=%p, packet(%llu) already lost!\n",
1448 dccp_role(sk), sk, seqno);
1453 if (num_later < TFRC_RECV_NUM_LATE_LOSS)
1454 dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist,
1456 /* FIXME: else what? should we destroy the packet like above? */
1461 /* Trim history (remove all packets after the NUM_LATE_LOSS + 1 data packets) */
1462 num_later = TFRC_RECV_NUM_LATE_LOSS + 1;
1464 if (!list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) {
1465 list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
1467 if (num_later == 0) {
1468 list_del_init(&entry->dccphrx_node);
1469 dccp_rx_hist_entry_delete(ccid3_rx_hist, entry);
1470 } else if (dccp_rx_hist_entry_data_packet(entry))
1475 u8 win_count = 0; /* Not needed, but lets shut up gcc */
1478 * We have no loss interval history so we need at least one
1479 * rtt:s of data packets to approximate rtt.
1481 list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
1483 if (num_later == 0) {
1487 /* OK, find next data packet */
1492 /* OK, find next data packet */
1494 win_count = entry->dccphrx_ccval;
1497 tmp = win_count - entry->dccphrx_ccval;
1499 tmp += TFRC_WIN_COUNT_LIMIT;
1500 if (tmp > TFRC_WIN_COUNT_PER_RTT + 1) {
1501 /* we have found a packet older than one rtt
1502 * remove the rest */
1504 } else /* OK, find next data packet */
1508 list_del_init(&entry->dccphrx_node);
1509 dccp_rx_hist_entry_delete(ccid3_rx_hist, entry);
1512 } else if (dccp_rx_hist_entry_data_packet(entry))
1520 static void ccid3_hc_rx_send_feedback(struct sock *sk)
1522 struct dccp_sock *dp = dccp_sk(sk);
1523 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1524 struct dccp_rx_hist_entry *packet;
1526 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
1528 switch (hcrx->ccid3hcrx_state) {
1529 case TFRC_RSTATE_NO_DATA:
1530 hcrx->ccid3hcrx_x_recv = 0;
1532 case TFRC_RSTATE_DATA: {
1533 u32 delta = now_delta(hcrx->ccid3hcrx_tstamp_last_feedback);
1536 delta = 1; /* to prevent divide by zero */
1537 hcrx->ccid3hcrx_x_recv = (hcrx->ccid3hcrx_bytes_recv *
1538 USEC_PER_SEC) / delta;
1542 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
1543 __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
1548 packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist);
1549 if (packet == NULL) {
1550 printk(KERN_CRIT "%s: %s, sk=%p, no data packet in history!\n",
1551 __FUNCTION__, dccp_role(sk), sk);
1556 do_gettimeofday(&(hcrx->ccid3hcrx_tstamp_last_feedback));
1557 hcrx->ccid3hcrx_last_counter = packet->dccphrx_ccval;
1558 hcrx->ccid3hcrx_seqno_last_counter = packet->dccphrx_seqno;
1559 hcrx->ccid3hcrx_bytes_recv = 0;
1561 /* Convert to multiples of 10us */
1562 hcrx->ccid3hcrx_elapsed_time = now_delta(packet->dccphrx_tstamp) / 10;
1563 if (hcrx->ccid3hcrx_p == 0)
1564 hcrx->ccid3hcrx_pinv = ~0;
1566 hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p;
1570 static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
1572 const struct dccp_sock *dp = dccp_sk(sk);
1573 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1575 if (hcrx == NULL || !(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
1578 if (hcrx->ccid3hcrx_elapsed_time != 0 && !dccp_packet_without_ack(skb))
1579 dccp_insert_option_elapsed_time(sk, skb, hcrx->ccid3hcrx_elapsed_time);
1581 if (DCCP_SKB_CB(skb)->dccpd_type != DCCP_PKT_DATA) {
1582 const u32 x_recv = htonl(hcrx->ccid3hcrx_x_recv);
1583 const u32 pinv = htonl(hcrx->ccid3hcrx_pinv);
1585 dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE, &pinv, sizeof(pinv));
1586 dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE, &x_recv, sizeof(x_recv));
1589 DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter;
1592 /* Weights used to calculate loss event rate */
1594 * These are integers as per section 8 of RFC3448. We can then divide by 4 *
1597 static const int ccid3_hc_rx_w[TFRC_RECV_IVAL_F_LENGTH] = {
1598 4, 4, 4, 4, 3, 2, 1, 1,
1602 * args: fvalue - function value to match
1603 * returns: p closest to that value
1605 * both fvalue and p are multiplied by 1,000,000 to use ints
1607 static u32 calcx_reverse_lookup(u32 fvalue) {
1611 if (fvalue < calcx_lookup[0][1])
1613 if (fvalue <= calcx_lookup[CALCX_ARRSIZE-1][1])
1615 else if (fvalue > calcx_lookup[CALCX_ARRSIZE-1][0])
1619 while (fvalue > calcx_lookup[ctr][small])
1622 return (CALCX_SPLIT * ctr / CALCX_ARRSIZE);
1624 return (1000000 * ctr / CALCX_ARRSIZE) ;
1627 /* calculate first loss interval
1629 * returns estimated loss interval in usecs */
1631 static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
1633 struct dccp_sock *dp = dccp_sk(sk);
1634 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1635 struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
1636 u32 rtt, delta, x_recv, fval, p, tmp2;
1637 struct timeval tstamp = { 0 }, tmp_tv;
1643 list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
1645 if (dccp_rx_hist_entry_data_packet(entry)) {
1650 tstamp = entry->dccphrx_tstamp;
1651 win_count = entry->dccphrx_ccval;
1655 interval = win_count - entry->dccphrx_ccval;
1657 interval += TFRC_WIN_COUNT_LIMIT;
1666 printk(KERN_CRIT "%s: %s, sk=%p, packet history contains no data packets!\n",
1667 __FUNCTION__, dccp_role(sk), sk);
1671 if (interval == 0) {
1672 ccid3_pr_debug("%s, sk=%p, Could not find a win_count interval > 0. Defaulting to 1\n",
1677 timeval_sub(tstamp,tail->dccphrx_tstamp,&tmp_tv);
1678 rtt = (tmp_tv.tv_sec * USEC_PER_SEC + tmp_tv.tv_usec) * 4 / interval;
1679 ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n",
1680 dccp_role(sk), sk, rtt);
1684 delta = now_delta(hcrx->ccid3hcrx_tstamp_last_feedback);
1688 x_recv = (hcrx->ccid3hcrx_bytes_recv * USEC_PER_SEC) / delta;
1690 tmp1 = (u64)x_recv * (u64)rtt;
1691 do_div(tmp1,10000000);
1693 fval = (hcrx->ccid3hcrx_s * 100000) / tmp2;
1694 /* do not alter order above or you will get overflow on 32 bit */
1695 p = calcx_reverse_lookup(fval);
1696 ccid3_pr_debug("%s, sk=%p, receive rate=%u bytes/s, implied loss rate=%u\n",\
1697 dccp_role(sk), sk, x_recv, p);
1705 static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
1707 struct dccp_sock *dp = dccp_sk(sk);
1708 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1709 struct ccid3_loss_interval_hist_entry *li_entry;
1711 if (seq_loss != DCCP_MAX_SEQNO + 1) {
1712 ccid3_pr_debug("%s, sk=%p, seq_loss=%llu, win_loss=%u, packet loss detected\n",
1713 dccp_role(sk), sk, seq_loss, win_loss);
1715 if (list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) {
1716 struct ccid3_loss_interval_hist_entry *li_tail = NULL;
1719 ccid3_pr_debug("%s, sk=%p, first loss event detected, creating history\n", dccp_role(sk), sk);
1720 for (i = 0; i <= TFRC_RECV_IVAL_F_LENGTH; ++i) {
1721 li_entry = ccid3_loss_interval_hist_entry_new(SLAB_ATOMIC);
1722 if (li_entry == NULL) {
1723 ccid3_loss_interval_history_delete(&hcrx->ccid3hcrx_loss_interval_hist);
1724 ccid3_pr_debug("%s, sk=%p, not enough mem for creating history\n",
1728 if (li_tail == NULL)
1730 list_add(&li_entry->ccid3lih_node, &hcrx->ccid3hcrx_loss_interval_hist);
1733 li_entry->ccid3lih_seqno = seq_loss;
1734 li_entry->ccid3lih_win_count = win_loss;
1736 li_tail->ccid3lih_interval = ccid3_hc_rx_calc_first_li(sk);
1739 /* FIXME: find end of interval */
1742 static void ccid3_hc_rx_detect_loss(struct sock *sk)
1744 struct dccp_sock *dp = dccp_sk(sk);
1745 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1746 struct dccp_rx_hist_entry *entry, *next, *packet;
1747 struct dccp_rx_hist_entry *a_loss = NULL;
1748 struct dccp_rx_hist_entry *b_loss = NULL;
1749 u64 seq_loss = DCCP_MAX_SEQNO + 1;
1751 u8 num_later = TFRC_RECV_NUM_LATE_LOSS;
1753 list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
1755 if (num_later == 0) {
1758 } else if (dccp_rx_hist_entry_data_packet(entry))
1767 list_for_each_entry_safe_continue(entry, next, &hcrx->ccid3hcrx_hist,
1769 if (num_later == 0) {
1772 } else if (dccp_rx_hist_entry_data_packet(entry))
1776 if (a_loss == NULL) {
1777 if (list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) {
1778 /* no loss event have occured yet */
1779 ccid3_pr_debug("%s, sk=%p, TODO: find a lost data "
1780 "packet by comparing to initial seqno\n",
1784 pr_info("%s: %s, sk=%p, ERROR! Less than 4 data packets in history",
1785 __FUNCTION__, dccp_role(sk), sk);
1790 /* Locate a lost data packet */
1791 entry = packet = b_loss;
1792 list_for_each_entry_safe_continue(entry, next, &hcrx->ccid3hcrx_hist,
1794 u64 delta = dccp_delta_seqno(entry->dccphrx_seqno,
1795 packet->dccphrx_seqno);
1798 if (dccp_rx_hist_entry_data_packet(packet))
1801 * FIXME: check this, probably this % usage is because
1802 * in earlier drafts the ndp count was just 8 bits
1803 * long, but now it cam be up to 24 bits long.
1806 if (delta % DCCP_NDP_LIMIT !=
1807 (packet->dccphrx_ndp -
1808 entry->dccphrx_ndp) % DCCP_NDP_LIMIT)
1811 packet->dccphrx_ndp - entry->dccphrx_ndp) {
1812 seq_loss = entry->dccphrx_seqno;
1813 dccp_inc_seqno(&seq_loss);
1817 if (packet == a_loss)
1821 if (seq_loss != DCCP_MAX_SEQNO + 1)
1822 win_loss = a_loss->dccphrx_ccval;
1825 ccid3_hc_rx_update_li(sk, seq_loss, win_loss);
1828 static u32 ccid3_hc_rx_calc_i_mean(struct sock *sk)
1830 struct dccp_sock *dp = dccp_sk(sk);
1831 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1832 struct ccid3_loss_interval_hist_entry *li_entry, *li_next;
1839 list_for_each_entry_safe(li_entry, li_next, &hcrx->ccid3hcrx_loss_interval_hist, ccid3lih_node) {
1840 if (i < TFRC_RECV_IVAL_F_LENGTH) {
1841 i_tot0 += li_entry->ccid3lih_interval * ccid3_hc_rx_w[i];
1842 w_tot += ccid3_hc_rx_w[i];
1846 i_tot1 += li_entry->ccid3lih_interval * ccid3_hc_rx_w[i - 1];
1848 if (++i > TFRC_RECV_IVAL_F_LENGTH)
1852 if (i != TFRC_RECV_IVAL_F_LENGTH) {
1853 pr_info("%s: %s, sk=%p, ERROR! Missing entry in interval history!\n",
1854 __FUNCTION__, dccp_role(sk), sk);
1858 i_tot = max(i_tot0, i_tot1);
1860 /* FIXME: Why do we do this? -Ian McDonald */
1861 if (i_tot * 4 < w_tot)
1864 return i_tot * 4 / w_tot;
1867 static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
1869 struct dccp_sock *dp = dccp_sk(sk);
1870 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1871 struct dccp_rx_hist_entry *packet;
1877 ccid3_pr_debug("%s, sk=%p(%s), skb=%p(%s)\n",
1878 dccp_role(sk), sk, dccp_state_name(sk->sk_state),
1879 skb, dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
1884 BUG_ON(!(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA ||
1885 hcrx->ccid3hcrx_state == TFRC_RSTATE_DATA));
1887 switch (DCCP_SKB_CB(skb)->dccpd_type) {
1889 if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
1891 case DCCP_PKT_DATAACK:
1892 if (dp->dccps_options_received.dccpor_timestamp_echo == 0)
1894 p_prev = hcrx->ccid3hcrx_rtt;
1895 do_gettimeofday(&now);
1896 /* hcrx->ccid3hcrx_rtt = now - dp->dccps_options_received.dccpor_timestamp_echo -
1897 usecs_to_jiffies(dp->dccps_options_received.dccpor_elapsed_time * 10);
1898 FIXME - I think above code is broken - have to look at options more, will also need
1899 to fix pr_debug below */
1900 if (p_prev != hcrx->ccid3hcrx_rtt)
1901 ccid3_pr_debug("%s, sk=%p, New RTT estimate=%lu jiffies, tstamp_echo=%u, elapsed time=%u\n",
1902 dccp_role(sk), sk, hcrx->ccid3hcrx_rtt,
1903 dp->dccps_options_received.dccpor_timestamp_echo,
1904 dp->dccps_options_received.dccpor_elapsed_time);
1909 ccid3_pr_debug("%s, sk=%p, not DATA/DATAACK/ACK packet(%s)\n",
1911 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
1915 packet = dccp_rx_hist_entry_new(ccid3_rx_hist,
1916 dp->dccps_options_received.dccpor_ndp,
1918 if (packet == NULL) {
1919 ccid3_pr_debug("%s, sk=%p, Not enough mem to add rx packet to history (consider it lost)!",
1924 win_count = packet->dccphrx_ccval;
1926 ins = ccid3_hc_rx_add_hist(sk, packet);
1928 if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK)
1931 switch (hcrx->ccid3hcrx_state) {
1932 case TFRC_RSTATE_NO_DATA:
1933 ccid3_pr_debug("%s, sk=%p(%s), skb=%p, sending initial feedback\n",
1934 dccp_role(sk), sk, dccp_state_name(sk->sk_state), skb);
1935 ccid3_hc_rx_send_feedback(sk);
1936 ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
1938 case TFRC_RSTATE_DATA:
1939 hcrx->ccid3hcrx_bytes_recv += skb->len - dccp_hdr(skb)->dccph_doff * 4;
1941 do_gettimeofday(&now);
1942 if ((now_delta(hcrx->ccid3hcrx_tstamp_last_ack)) >= hcrx->ccid3hcrx_rtt) {
1943 hcrx->ccid3hcrx_tstamp_last_ack = now;
1944 ccid3_hc_rx_send_feedback(sk);
1950 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
1951 __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
1956 /* Dealing with packet loss */
1957 ccid3_pr_debug("%s, sk=%p(%s), skb=%p, data loss! Reacting...\n",
1958 dccp_role(sk), sk, dccp_state_name(sk->sk_state), skb);
1960 ccid3_hc_rx_detect_loss(sk);
1961 p_prev = hcrx->ccid3hcrx_p;
1963 /* Calculate loss event rate */
1964 if (!list_empty(&hcrx->ccid3hcrx_loss_interval_hist))
1965 /* Scaling up by 1000000 as fixed decimal */
1966 hcrx->ccid3hcrx_p = 1000000 / ccid3_hc_rx_calc_i_mean(sk);
1968 if (hcrx->ccid3hcrx_p > p_prev) {
1969 ccid3_hc_rx_send_feedback(sk);
1974 static int ccid3_hc_rx_init(struct sock *sk)
1976 struct dccp_sock *dp = dccp_sk(sk);
1977 struct ccid3_hc_rx_sock *hcrx;
1979 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
1981 hcrx = dp->dccps_hc_rx_ccid_private = kmalloc(sizeof(*hcrx), gfp_any());
1985 memset(hcrx, 0, sizeof(*hcrx));
1987 if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE &&
1988 dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE)
1989 hcrx->ccid3hcrx_s = (u16)dp->dccps_avg_packet_size;
1991 hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE;
1993 hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA;
1994 INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist);
1995 INIT_LIST_HEAD(&hcrx->ccid3hcrx_loss_interval_hist);
2000 static void ccid3_hc_rx_exit(struct sock *sk)
2002 struct dccp_sock *dp = dccp_sk(sk);
2003 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
2005 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
2010 ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);
2012 /* Empty packet history */
2013 dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist);
2015 /* Empty loss interval history */
2016 ccid3_loss_interval_history_delete(&hcrx->ccid3hcrx_loss_interval_hist);
2018 kfree(dp->dccps_hc_rx_ccid_private);
2019 dp->dccps_hc_rx_ccid_private = NULL;
2022 static struct ccid ccid3 = {
2024 .ccid_name = "ccid3",
2025 .ccid_owner = THIS_MODULE,
2026 .ccid_init = ccid3_init,
2027 .ccid_exit = ccid3_exit,
2028 .ccid_hc_tx_init = ccid3_hc_tx_init,
2029 .ccid_hc_tx_exit = ccid3_hc_tx_exit,
2030 .ccid_hc_tx_send_packet = ccid3_hc_tx_send_packet,
2031 .ccid_hc_tx_packet_sent = ccid3_hc_tx_packet_sent,
2032 .ccid_hc_tx_packet_recv = ccid3_hc_tx_packet_recv,
2033 .ccid_hc_tx_insert_options = ccid3_hc_tx_insert_options,
2034 .ccid_hc_tx_parse_options = ccid3_hc_tx_parse_options,
2035 .ccid_hc_rx_init = ccid3_hc_rx_init,
2036 .ccid_hc_rx_exit = ccid3_hc_rx_exit,
2037 .ccid_hc_rx_insert_options = ccid3_hc_rx_insert_options,
2038 .ccid_hc_rx_packet_recv = ccid3_hc_rx_packet_recv,
2041 module_param(ccid3_debug, int, 0444);
2042 MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");
2044 static __init int ccid3_module_init(void)
2048 ccid3_rx_hist = dccp_rx_hist_new("ccid3");
2049 if (ccid3_rx_hist == NULL)
2052 ccid3_tx_hist = dccp_tx_hist_new("ccid3");
2053 if (ccid3_tx_hist == NULL)
2056 ccid3_loss_interval_hist_slab = kmem_cache_create("li_hist_ccid3",
2057 sizeof(struct ccid3_loss_interval_hist_entry),
2058 0, SLAB_HWCACHE_ALIGN,
2060 if (ccid3_loss_interval_hist_slab == NULL)
2063 rc = ccid_register(&ccid3);
2065 goto out_free_loss_interval_history;
2069 out_free_loss_interval_history:
2070 kmem_cache_destroy(ccid3_loss_interval_hist_slab);
2071 ccid3_loss_interval_hist_slab = NULL;
2073 dccp_tx_hist_delete(ccid3_tx_hist);
2074 ccid3_tx_hist = NULL;
2076 dccp_rx_hist_delete(ccid3_rx_hist);
2077 ccid3_rx_hist = NULL;
2080 module_init(ccid3_module_init);
2082 static __exit void ccid3_module_exit(void)
2084 #ifdef CONFIG_IP_DCCP_UNLOAD_HACK
2086 * Hack to use while developing, so that we get rid of the control
2087 * sock, that is what keeps a refcount on dccp.ko -acme
2089 extern void dccp_ctl_sock_exit(void);
2091 dccp_ctl_sock_exit();
2093 ccid_unregister(&ccid3);
2095 if (ccid3_tx_hist != NULL) {
2096 dccp_tx_hist_delete(ccid3_tx_hist);
2097 ccid3_tx_hist = NULL;
2099 if (ccid3_rx_hist != NULL) {
2100 dccp_rx_hist_delete(ccid3_rx_hist);
2101 ccid3_rx_hist = NULL;
2103 if (ccid3_loss_interval_hist_slab != NULL) {
2104 kmem_cache_destroy(ccid3_loss_interval_hist_slab);
2105 ccid3_loss_interval_hist_slab = NULL;
2108 module_exit(ccid3_module_exit);
2110 MODULE_AUTHOR("Ian McDonald <iam4@cs.waikato.ac.nz> & Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
2111 MODULE_DESCRIPTION("DCCP TFRC CCID3 CCID");
2112 MODULE_LICENSE("GPL");
2113 MODULE_ALIAS("net-dccp-ccid-3");