blob: df4adfeaafaca8d19752fe97aa59c07697718dd9 [file] [log] [blame]
Arnaldo Carvalho de Melo7c657872005-08-09 20:14:34 -07001/*
2 * net/dccp/ccids/ccid3.c
3 *
4 * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
5 *
6 * An implementation of the DCCP protocol
7 *
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
11 *
12 * This code also uses code from Lulea University, rereleased as GPL by its
13 * authors:
14 * Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon
15 *
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>.
19 *
20 * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
21 *
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.
26 *
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.
31 *
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.
35 */
36
37#include "../ccid.h"
38#include "../dccp.h"
39#include "ccid3.h"
40
41#ifdef CCID3_DEBUG
42extern int ccid3_debug;
43
44#define ccid3_pr_debug(format, a...) \
45 do { if (ccid3_debug) \
46 printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \
47 } while (0)
48#else
49#define ccid3_pr_debug(format, a...)
50#endif
51
52#define TFRC_MIN_PACKET_SIZE 16
53#define TFRC_STD_PACKET_SIZE 256
54#define TFRC_MAX_PACKET_SIZE 65535
55
56#define USEC_IN_SEC 1000000
57
58#define TFRC_INITIAL_TIMEOUT (2 * USEC_IN_SEC)
59/* two seconds as per CCID3 spec 11 */
60
61#define TFRC_OPSYS_HALF_TIME_GRAN (USEC_IN_SEC / (2 * HZ))
62/* above is in usecs - half the scheduling granularity as per RFC3448 4.6 */
63
64#define TFRC_WIN_COUNT_PER_RTT 4
65#define TFRC_WIN_COUNT_LIMIT 16
66
67#define TFRC_MAX_BACK_OFF_TIME 64
68/* above is in seconds */
69
70#define TFRC_SMALLEST_P 40
71
72#define TFRC_RECV_IVAL_F_LENGTH 8 /* length(w[]) */
73
74/* Number of later packets received before one is considered lost */
75#define TFRC_RECV_NUM_LATE_LOSS 3
76
77enum ccid3_options {
78 TFRC_OPT_LOSS_EVENT_RATE = 192,
79 TFRC_OPT_LOSS_INTERVALS = 193,
80 TFRC_OPT_RECEIVE_RATE = 194,
81};
82
83static int ccid3_debug;
84
85static kmem_cache_t *ccid3_tx_hist_slab;
86static kmem_cache_t *ccid3_rx_hist_slab;
87static kmem_cache_t *ccid3_loss_interval_hist_slab;
88
89static inline struct ccid3_tx_hist_entry *ccid3_tx_hist_entry_new(int prio)
90{
91 struct ccid3_tx_hist_entry *entry = kmem_cache_alloc(ccid3_tx_hist_slab, prio);
92
93 if (entry != NULL)
94 entry->ccid3htx_sent = 0;
95
96 return entry;
97}
98
99static inline void ccid3_tx_hist_entry_delete(struct ccid3_tx_hist_entry *entry)
100{
101 if (entry != NULL)
102 kmem_cache_free(ccid3_tx_hist_slab, entry);
103}
104
105static inline struct ccid3_rx_hist_entry *ccid3_rx_hist_entry_new(struct sock *sk,
106 struct sk_buff *skb,
107 int prio)
108{
109 struct ccid3_rx_hist_entry *entry = kmem_cache_alloc(ccid3_rx_hist_slab, prio);
110
111 if (entry != NULL) {
112 const struct dccp_hdr *dh = dccp_hdr(skb);
113
114 entry->ccid3hrx_seqno = DCCP_SKB_CB(skb)->dccpd_seq;
115 entry->ccid3hrx_win_count = dh->dccph_ccval;
116 entry->ccid3hrx_type = dh->dccph_type;
117 entry->ccid3hrx_ndp = dccp_sk(sk)->dccps_options_received.dccpor_ndp;
118 do_gettimeofday(&(entry->ccid3hrx_tstamp));
119 }
120
121 return entry;
122}
123
124static inline void ccid3_rx_hist_entry_delete(struct ccid3_rx_hist_entry *entry)
125{
126 if (entry != NULL)
127 kmem_cache_free(ccid3_rx_hist_slab, entry);
128}
129
130static void ccid3_rx_history_delete(struct list_head *hist)
131{
132 struct ccid3_rx_hist_entry *entry, *next;
133
134 list_for_each_entry_safe(entry, next, hist, ccid3hrx_node) {
135 list_del_init(&entry->ccid3hrx_node);
136 kmem_cache_free(ccid3_rx_hist_slab, entry);
137 }
138}
139
140static inline struct ccid3_loss_interval_hist_entry *ccid3_loss_interval_hist_entry_new(int prio)
141{
142 return kmem_cache_alloc(ccid3_loss_interval_hist_slab, prio);
143}
144
145static inline void ccid3_loss_interval_hist_entry_delete(struct ccid3_loss_interval_hist_entry *entry)
146{
147 if (entry != NULL)
148 kmem_cache_free(ccid3_loss_interval_hist_slab, entry);
149}
150
151static void ccid3_loss_interval_history_delete(struct list_head *hist)
152{
153 struct ccid3_loss_interval_hist_entry *entry, *next;
154
155 list_for_each_entry_safe(entry, next, hist, ccid3lih_node) {
156 list_del_init(&entry->ccid3lih_node);
157 kmem_cache_free(ccid3_loss_interval_hist_slab, entry);
158 }
159}
160
161static int ccid3_init(struct sock *sk)
162{
163 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
164 return 0;
165}
166
167static void ccid3_exit(struct sock *sk)
168{
169 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
170}
171
172/* TFRC sender states */
173enum ccid3_hc_tx_states {
174 TFRC_SSTATE_NO_SENT = 1,
175 TFRC_SSTATE_NO_FBACK,
176 TFRC_SSTATE_FBACK,
177 TFRC_SSTATE_TERM,
178};
179
180#ifdef CCID3_DEBUG
181static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state)
182{
183 static char *ccid3_state_names[] = {
184 [TFRC_SSTATE_NO_SENT] = "NO_SENT",
185 [TFRC_SSTATE_NO_FBACK] = "NO_FBACK",
186 [TFRC_SSTATE_FBACK] = "FBACK",
187 [TFRC_SSTATE_TERM] = "TERM",
188 };
189
190 return ccid3_state_names[state];
191}
192#endif
193
194static inline void ccid3_hc_tx_set_state(struct sock *sk, enum ccid3_hc_tx_states state)
195{
196 struct dccp_sock *dp = dccp_sk(sk);
197 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
198 enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state;
199
200 ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
201 dccp_role(sk), sk, ccid3_tx_state_name(oldstate), ccid3_tx_state_name(state));
202 WARN_ON(state == oldstate);
203 hctx->ccid3hctx_state = state;
204}
205
206static void timeval_sub(struct timeval large, struct timeval small, struct timeval *result) {
207
208 result->tv_sec = large.tv_sec-small.tv_sec;
209 if (large.tv_usec < small.tv_usec) {
210 (result->tv_sec)--;
211 result->tv_usec = USEC_IN_SEC+large.tv_usec-small.tv_usec;
212 } else
213 result->tv_usec = large.tv_usec-small.tv_usec;
214}
215
216static inline void timeval_fix(struct timeval *tv) {
217 if (tv->tv_usec >= USEC_IN_SEC) {
218 tv->tv_sec++;
219 tv->tv_usec -= USEC_IN_SEC;
220 }
221}
222
223/* returns the difference in usecs between timeval passed in and current time */
224static inline u32 now_delta(struct timeval tv) {
225 struct timeval now;
226
227 do_gettimeofday(&now);
228 return ((now.tv_sec-tv.tv_sec)*1000000+now.tv_usec-tv.tv_usec);
229}
230
231#define CALCX_ARRSIZE 500
232
233#define CALCX_SPLIT 50000
234/* equivalent to 0.05 */
235
236static const u32 calcx_lookup[CALCX_ARRSIZE][2] = {
237 { 37172 , 8172 },
238 { 53499 , 11567 },
239 { 66664 , 14180 },
240 { 78298 , 16388 },
241 { 89021 , 18339 },
242 { 99147 , 20108 },
243 { 108858 , 21738 },
244 { 118273 , 23260 },
245 { 127474 , 24693 },
246 { 136520 , 26052 },
247 { 145456 , 27348 },
248 { 154316 , 28589 },
249 { 163130 , 29783 },
250 { 171919 , 30935 },
251 { 180704 , 32049 },
252 { 189502 , 33130 },
253 { 198328 , 34180 },
254 { 207194 , 35202 },
255 { 216114 , 36198 },
256 { 225097 , 37172 },
257 { 234153 , 38123 },
258 { 243294 , 39055 },
259 { 252527 , 39968 },
260 { 261861 , 40864 },
261 { 271305 , 41743 },
262 { 280866 , 42607 },
263 { 290553 , 43457 },
264 { 300372 , 44293 },
265 { 310333 , 45117 },
266 { 320441 , 45929 },
267 { 330705 , 46729 },
268 { 341131 , 47518 },
269 { 351728 , 48297 },
270 { 362501 , 49066 },
271 { 373460 , 49826 },
272 { 384609 , 50577 },
273 { 395958 , 51320 },
274 { 407513 , 52054 },
275 { 419281 , 52780 },
276 { 431270 , 53499 },
277 { 443487 , 54211 },
278 { 455940 , 54916 },
279 { 468635 , 55614 },
280 { 481581 , 56306 },
281 { 494785 , 56991 },
282 { 508254 , 57671 },
283 { 521996 , 58345 },
284 { 536019 , 59014 },
285 { 550331 , 59677 },
286 { 564939 , 60335 },
287 { 579851 , 60988 },
288 { 595075 , 61636 },
289 { 610619 , 62279 },
290 { 626491 , 62918 },
291 { 642700 , 63553 },
292 { 659253 , 64183 },
293 { 676158 , 64809 },
294 { 693424 , 65431 },
295 { 711060 , 66050 },
296 { 729073 , 66664 },
297 { 747472 , 67275 },
298 { 766266 , 67882 },
299 { 785464 , 68486 },
300 { 805073 , 69087 },
301 { 825103 , 69684 },
302 { 845562 , 70278 },
303 { 866460 , 70868 },
304 { 887805 , 71456 },
305 { 909606 , 72041 },
306 { 931873 , 72623 },
307 { 954614 , 73202 },
308 { 977839 , 73778 },
309 { 1001557 , 74352 },
310 { 1025777 , 74923 },
311 { 1050508 , 75492 },
312 { 1075761 , 76058 },
313 { 1101544 , 76621 },
314 { 1127867 , 77183 },
315 { 1154739 , 77741 },
316 { 1182172 , 78298 },
317 { 1210173 , 78852 },
318 { 1238753 , 79405 },
319 { 1267922 , 79955 },
320 { 1297689 , 80503 },
321 { 1328066 , 81049 },
322 { 1359060 , 81593 },
323 { 1390684 , 82135 },
324 { 1422947 , 82675 },
325 { 1455859 , 83213 },
326 { 1489430 , 83750 },
327 { 1523671 , 84284 },
328 { 1558593 , 84817 },
329 { 1594205 , 85348 },
330 { 1630518 , 85878 },
331 { 1667543 , 86406 },
332 { 1705290 , 86932 },
333 { 1743770 , 87457 },
334 { 1782994 , 87980 },
335 { 1822973 , 88501 },
336 { 1863717 , 89021 },
337 { 1905237 , 89540 },
338 { 1947545 , 90057 },
339 { 1990650 , 90573 },
340 { 2034566 , 91087 },
341 { 2079301 , 91600 },
342 { 2124869 , 92111 },
343 { 2171279 , 92622 },
344 { 2218543 , 93131 },
345 { 2266673 , 93639 },
346 { 2315680 , 94145 },
347 { 2365575 , 94650 },
348 { 2416371 , 95154 },
349 { 2468077 , 95657 },
350 { 2520707 , 96159 },
351 { 2574271 , 96660 },
352 { 2628782 , 97159 },
353 { 2684250 , 97658 },
354 { 2740689 , 98155 },
355 { 2798110 , 98651 },
356 { 2856524 , 99147 },
357 { 2915944 , 99641 },
358 { 2976382 , 100134 },
359 { 3037850 , 100626 },
360 { 3100360 , 101117 },
361 { 3163924 , 101608 },
362 { 3228554 , 102097 },
363 { 3294263 , 102586 },
364 { 3361063 , 103073 },
365 { 3428966 , 103560 },
366 { 3497984 , 104045 },
367 { 3568131 , 104530 },
368 { 3639419 , 105014 },
369 { 3711860 , 105498 },
370 { 3785467 , 105980 },
371 { 3860253 , 106462 },
372 { 3936229 , 106942 },
373 { 4013410 , 107422 },
374 { 4091808 , 107902 },
375 { 4171435 , 108380 },
376 { 4252306 , 108858 },
377 { 4334431 , 109335 },
378 { 4417825 , 109811 },
379 { 4502501 , 110287 },
380 { 4588472 , 110762 },
381 { 4675750 , 111236 },
382 { 4764349 , 111709 },
383 { 4854283 , 112182 },
384 { 4945564 , 112654 },
385 { 5038206 , 113126 },
386 { 5132223 , 113597 },
387 { 5227627 , 114067 },
388 { 5324432 , 114537 },
389 { 5422652 , 115006 },
390 { 5522299 , 115474 },
391 { 5623389 , 115942 },
392 { 5725934 , 116409 },
393 { 5829948 , 116876 },
394 { 5935446 , 117342 },
395 { 6042439 , 117808 },
396 { 6150943 , 118273 },
397 { 6260972 , 118738 },
398 { 6372538 , 119202 },
399 { 6485657 , 119665 },
400 { 6600342 , 120128 },
401 { 6716607 , 120591 },
402 { 6834467 , 121053 },
403 { 6953935 , 121514 },
404 { 7075025 , 121976 },
405 { 7197752 , 122436 },
406 { 7322131 , 122896 },
407 { 7448175 , 123356 },
408 { 7575898 , 123815 },
409 { 7705316 , 124274 },
410 { 7836442 , 124733 },
411 { 7969291 , 125191 },
412 { 8103877 , 125648 },
413 { 8240216 , 126105 },
414 { 8378321 , 126562 },
415 { 8518208 , 127018 },
416 { 8659890 , 127474 },
417 { 8803384 , 127930 },
418 { 8948702 , 128385 },
419 { 9095861 , 128840 },
420 { 9244875 , 129294 },
421 { 9395760 , 129748 },
422 { 9548529 , 130202 },
423 { 9703198 , 130655 },
424 { 9859782 , 131108 },
425 { 10018296 , 131561 },
426 { 10178755 , 132014 },
427 { 10341174 , 132466 },
428 { 10505569 , 132917 },
429 { 10671954 , 133369 },
430 { 10840345 , 133820 },
431 { 11010757 , 134271 },
432 { 11183206 , 134721 },
433 { 11357706 , 135171 },
434 { 11534274 , 135621 },
435 { 11712924 , 136071 },
436 { 11893673 , 136520 },
437 { 12076536 , 136969 },
438 { 12261527 , 137418 },
439 { 12448664 , 137867 },
440 { 12637961 , 138315 },
441 { 12829435 , 138763 },
442 { 13023101 , 139211 },
443 { 13218974 , 139658 },
444 { 13417071 , 140106 },
445 { 13617407 , 140553 },
446 { 13819999 , 140999 },
447 { 14024862 , 141446 },
448 { 14232012 , 141892 },
449 { 14441465 , 142339 },
450 { 14653238 , 142785 },
451 { 14867346 , 143230 },
452 { 15083805 , 143676 },
453 { 15302632 , 144121 },
454 { 15523842 , 144566 },
455 { 15747453 , 145011 },
456 { 15973479 , 145456 },
457 { 16201939 , 145900 },
458 { 16432847 , 146345 },
459 { 16666221 , 146789 },
460 { 16902076 , 147233 },
461 { 17140429 , 147677 },
462 { 17381297 , 148121 },
463 { 17624696 , 148564 },
464 { 17870643 , 149007 },
465 { 18119154 , 149451 },
466 { 18370247 , 149894 },
467 { 18623936 , 150336 },
468 { 18880241 , 150779 },
469 { 19139176 , 151222 },
470 { 19400759 , 151664 },
471 { 19665007 , 152107 },
472 { 19931936 , 152549 },
473 { 20201564 , 152991 },
474 { 20473907 , 153433 },
475 { 20748982 , 153875 },
476 { 21026807 , 154316 },
477 { 21307399 , 154758 },
478 { 21590773 , 155199 },
479 { 21876949 , 155641 },
480 { 22165941 , 156082 },
481 { 22457769 , 156523 },
482 { 22752449 , 156964 },
483 { 23049999 , 157405 },
484 { 23350435 , 157846 },
485 { 23653774 , 158287 },
486 { 23960036 , 158727 },
487 { 24269236 , 159168 },
488 { 24581392 , 159608 },
489 { 24896521 , 160049 },
490 { 25214642 , 160489 },
491 { 25535772 , 160929 },
492 { 25859927 , 161370 },
493 { 26187127 , 161810 },
494 { 26517388 , 162250 },
495 { 26850728 , 162690 },
496 { 27187165 , 163130 },
497 { 27526716 , 163569 },
498 { 27869400 , 164009 },
499 { 28215234 , 164449 },
500 { 28564236 , 164889 },
501 { 28916423 , 165328 },
502 { 29271815 , 165768 },
503 { 29630428 , 166208 },
504 { 29992281 , 166647 },
505 { 30357392 , 167087 },
506 { 30725779 , 167526 },
507 { 31097459 , 167965 },
508 { 31472452 , 168405 },
509 { 31850774 , 168844 },
510 { 32232445 , 169283 },
511 { 32617482 , 169723 },
512 { 33005904 , 170162 },
513 { 33397730 , 170601 },
514 { 33792976 , 171041 },
515 { 34191663 , 171480 },
516 { 34593807 , 171919 },
517 { 34999428 , 172358 },
518 { 35408544 , 172797 },
519 { 35821174 , 173237 },
520 { 36237335 , 173676 },
521 { 36657047 , 174115 },
522 { 37080329 , 174554 },
523 { 37507197 , 174993 },
524 { 37937673 , 175433 },
525 { 38371773 , 175872 },
526 { 38809517 , 176311 },
527 { 39250924 , 176750 },
528 { 39696012 , 177190 },
529 { 40144800 , 177629 },
530 { 40597308 , 178068 },
531 { 41053553 , 178507 },
532 { 41513554 , 178947 },
533 { 41977332 , 179386 },
534 { 42444904 , 179825 },
535 { 42916290 , 180265 },
536 { 43391509 , 180704 },
537 { 43870579 , 181144 },
538 { 44353520 , 181583 },
539 { 44840352 , 182023 },
540 { 45331092 , 182462 },
541 { 45825761 , 182902 },
542 { 46324378 , 183342 },
543 { 46826961 , 183781 },
544 { 47333531 , 184221 },
545 { 47844106 , 184661 },
546 { 48358706 , 185101 },
547 { 48877350 , 185541 },
548 { 49400058 , 185981 },
549 { 49926849 , 186421 },
550 { 50457743 , 186861 },
551 { 50992759 , 187301 },
552 { 51531916 , 187741 },
553 { 52075235 , 188181 },
554 { 52622735 , 188622 },
555 { 53174435 , 189062 },
556 { 53730355 , 189502 },
557 { 54290515 , 189943 },
558 { 54854935 , 190383 },
559 { 55423634 , 190824 },
560 { 55996633 , 191265 },
561 { 56573950 , 191706 },
562 { 57155606 , 192146 },
563 { 57741621 , 192587 },
564 { 58332014 , 193028 },
565 { 58926806 , 193470 },
566 { 59526017 , 193911 },
567 { 60129666 , 194352 },
568 { 60737774 , 194793 },
569 { 61350361 , 195235 },
570 { 61967446 , 195677 },
571 { 62589050 , 196118 },
572 { 63215194 , 196560 },
573 { 63845897 , 197002 },
574 { 64481179 , 197444 },
575 { 65121061 , 197886 },
576 { 65765563 , 198328 },
577 { 66414705 , 198770 },
578 { 67068508 , 199213 },
579 { 67726992 , 199655 },
580 { 68390177 , 200098 },
581 { 69058085 , 200540 },
582 { 69730735 , 200983 },
583 { 70408147 , 201426 },
584 { 71090343 , 201869 },
585 { 71777343 , 202312 },
586 { 72469168 , 202755 },
587 { 73165837 , 203199 },
588 { 73867373 , 203642 },
589 { 74573795 , 204086 },
590 { 75285124 , 204529 },
591 { 76001380 , 204973 },
592 { 76722586 , 205417 },
593 { 77448761 , 205861 },
594 { 78179926 , 206306 },
595 { 78916102 , 206750 },
596 { 79657310 , 207194 },
597 { 80403571 , 207639 },
598 { 81154906 , 208084 },
599 { 81911335 , 208529 },
600 { 82672880 , 208974 },
601 { 83439562 , 209419 },
602 { 84211402 , 209864 },
603 { 84988421 , 210309 },
604 { 85770640 , 210755 },
605 { 86558080 , 211201 },
606 { 87350762 , 211647 },
607 { 88148708 , 212093 },
608 { 88951938 , 212539 },
609 { 89760475 , 212985 },
610 { 90574339 , 213432 },
611 { 91393551 , 213878 },
612 { 92218133 , 214325 },
613 { 93048107 , 214772 },
614 { 93883493 , 215219 },
615 { 94724314 , 215666 },
616 { 95570590 , 216114 },
617 { 96422343 , 216561 },
618 { 97279594 , 217009 },
619 { 98142366 , 217457 },
620 { 99010679 , 217905 },
621 { 99884556 , 218353 },
622 { 100764018 , 218801 },
623 { 101649086 , 219250 },
624 { 102539782 , 219698 },
625 { 103436128 , 220147 },
626 { 104338146 , 220596 },
627 { 105245857 , 221046 },
628 { 106159284 , 221495 },
629 { 107078448 , 221945 },
630 { 108003370 , 222394 },
631 { 108934074 , 222844 },
632 { 109870580 , 223294 },
633 { 110812910 , 223745 },
634 { 111761087 , 224195 },
635 { 112715133 , 224646 },
636 { 113675069 , 225097 },
637 { 114640918 , 225548 },
638 { 115612702 , 225999 },
639 { 116590442 , 226450 },
640 { 117574162 , 226902 },
641 { 118563882 , 227353 },
642 { 119559626 , 227805 },
643 { 120561415 , 228258 },
644 { 121569272 , 228710 },
645 { 122583219 , 229162 },
646 { 123603278 , 229615 },
647 { 124629471 , 230068 },
648 { 125661822 , 230521 },
649 { 126700352 , 230974 },
650 { 127745083 , 231428 },
651 { 128796039 , 231882 },
652 { 129853241 , 232336 },
653 { 130916713 , 232790 },
654 { 131986475 , 233244 },
655 { 133062553 , 233699 },
656 { 134144966 , 234153 },
657 { 135233739 , 234608 },
658 { 136328894 , 235064 },
659 { 137430453 , 235519 },
660 { 138538440 , 235975 },
661 { 139652876 , 236430 },
662 { 140773786 , 236886 },
663 { 141901190 , 237343 },
664 { 143035113 , 237799 },
665 { 144175576 , 238256 },
666 { 145322604 , 238713 },
667 { 146476218 , 239170 },
668 { 147636442 , 239627 },
669 { 148803298 , 240085 },
670 { 149976809 , 240542 },
671 { 151156999 , 241000 },
672 { 152343890 , 241459 },
673 { 153537506 , 241917 },
674 { 154737869 , 242376 },
675 { 155945002 , 242835 },
676 { 157158929 , 243294 },
677 { 158379673 , 243753 },
678 { 159607257 , 244213 },
679 { 160841704 , 244673 },
680 { 162083037 , 245133 },
681 { 163331279 , 245593 },
682 { 164586455 , 246054 },
683 { 165848586 , 246514 },
684 { 167117696 , 246975 },
685 { 168393810 , 247437 },
686 { 169676949 , 247898 },
687 { 170967138 , 248360 },
688 { 172264399 , 248822 },
689 { 173568757 , 249284 },
690 { 174880235 , 249747 },
691 { 176198856 , 250209 },
692 { 177524643 , 250672 },
693 { 178857621 , 251136 },
694 { 180197813 , 251599 },
695 { 181545242 , 252063 },
696 { 182899933 , 252527 },
697 { 184261908 , 252991 },
698 { 185631191 , 253456 },
699 { 187007807 , 253920 },
700 { 188391778 , 254385 },
701 { 189783129 , 254851 },
702 { 191181884 , 255316 },
703 { 192588065 , 255782 },
704 { 194001698 , 256248 },
705 { 195422805 , 256714 },
706 { 196851411 , 257181 },
707 { 198287540 , 257648 },
708 { 199731215 , 258115 },
709 { 201182461 , 258582 },
710 { 202641302 , 259050 },
711 { 204107760 , 259518 },
712 { 205581862 , 259986 },
713 { 207063630 , 260454 },
714 { 208553088 , 260923 },
715 { 210050262 , 261392 },
716 { 211555174 , 261861 },
717 { 213067849 , 262331 },
718 { 214588312 , 262800 },
719 { 216116586 , 263270 },
720 { 217652696 , 263741 },
721 { 219196666 , 264211 },
722 { 220748520 , 264682 },
723 { 222308282 , 265153 },
724 { 223875978 , 265625 },
725 { 225451630 , 266097 },
726 { 227035265 , 266569 },
727 { 228626905 , 267041 },
728 { 230226576 , 267514 },
729 { 231834302 , 267986 },
730 { 233450107 , 268460 },
731 { 235074016 , 268933 },
732 { 236706054 , 269407 },
733 { 238346244 , 269881 },
734 { 239994613 , 270355 },
735 { 241651183 , 270830 },
736 { 243315981 , 271305 }
737};
738
739/* Calculate the send rate as per section 3.1 of RFC3448
740
741Returns send rate in bytes per second
742
743Integer maths and lookups are used as not allowed floating point in kernel
744
745The function for Xcalc as per section 3.1 of RFC3448 is:
746
747X = s
748 -------------------------------------------------------------
749 R*sqrt(2*b*p/3) + (t_RTO * (3*sqrt(3*b*p/8) * p * (1+32*p^2)))
750
751where
752X is the trasmit rate in bytes/second
753s is the packet size in bytes
754R is the round trip time in seconds
755p is the loss event rate, between 0 and 1.0, of the number of loss events
756 as a fraction of the number of packets transmitted
757t_RTO is the TCP retransmission timeout value in seconds
758b is the number of packets acknowledged by a single TCP acknowledgement
759
760we can assume that b = 1 and t_RTO is 4 * R. With this the equation becomes:
761
762X = s
763 -----------------------------------------------------------------------
764 R * sqrt(2 * p / 3) + (12 * R * (sqrt(3 * p / 8) * p * (1 + 32 * p^2)))
765
766
767which we can break down into:
768
769X = s
770 --------
771 R * f(p)
772
773where f(p) = sqrt(2 * p / 3) + (12 * sqrt(3 * p / 8) * p * (1 + 32 * p * p))
774
775Function parameters:
776s - bytes
777R - RTT in usecs
778p - loss rate (decimal fraction multiplied by 1,000,000)
779
780Returns Xcalc in bytes per second
781
782DON'T alter this code unless you run test cases against it as the code
783has been manipulated to stop underflow/overlow.
784
785*/
786static u32 ccid3_calc_x(u16 s, u32 R, u32 p)
787{
788 int index;
789 u32 f;
790 u64 tmp1, tmp2;
791
792 if (p < CALCX_SPLIT)
793 index = (p / (CALCX_SPLIT / CALCX_ARRSIZE)) - 1;
794 else
795 index = (p / (1000000 / CALCX_ARRSIZE)) - 1;
796
797 if (index < 0)
798 /* p should be 0 unless there is a bug in my code */
799 index = 0;
800
801 if (R == 0)
802 R = 1; /* RTT can't be zero or else divide by zero */
803
804 BUG_ON(index >= CALCX_ARRSIZE);
805
806 if (p >= CALCX_SPLIT)
807 f = calcx_lookup[index][0];
808 else
809 f = calcx_lookup[index][1];
810
811 tmp1 = ((u64)s * 100000000);
812 tmp2 = ((u64)R * (u64)f);
813 do_div(tmp2,10000);
814 do_div(tmp1,tmp2);
815 /* don't alter above math unless you test due to overflow on 32 bit */
816
817 return (u32)tmp1;
818}
819
820/* Calculate new t_ipi (inter packet interval) by t_ipi = s / X_inst */
821static inline void ccid3_calc_new_t_ipi(struct ccid3_hc_tx_sock *hctx)
822{
823 if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK)
824 return;
825 /* if no feedback spec says t_ipi is 1 second (set elsewhere and then
826 * doubles after every no feedback timer (separate function) */
827
828 if (hctx->ccid3hctx_x < 10) {
829 ccid3_pr_debug("ccid3_calc_new_t_ipi - ccid3hctx_x < 10\n");
830 hctx->ccid3hctx_x = 10;
831 }
832 hctx->ccid3hctx_t_ipi = (hctx->ccid3hctx_s * 100000)
833 / (hctx->ccid3hctx_x / 10);
834 /* reason for above maths with 10 in there is to avoid 32 bit
835 * overflow for jumbo packets */
836
837}
838
839/* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */
840static inline void ccid3_calc_new_delta(struct ccid3_hc_tx_sock *hctx)
841{
842 hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2, TFRC_OPSYS_HALF_TIME_GRAN);
843
844}
845
846/*
847 * Update X by
848 * If (p > 0)
849 * x_calc = calcX(s, R, p);
850 * X = max(min(X_calc, 2 * X_recv), s / t_mbi);
851 * Else
852 * If (now - tld >= R)
853 * X = max(min(2 * X, 2 * X_recv), s / R);
854 * tld = now;
855 */
856static void ccid3_hc_tx_update_x(struct sock *sk)
857{
858 struct dccp_sock *dp = dccp_sk(sk);
859 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
860
861 if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) { /* to avoid large error in calcX */
862 hctx->ccid3hctx_x_calc = ccid3_calc_x(hctx->ccid3hctx_s,
863 hctx->ccid3hctx_rtt,
864 hctx->ccid3hctx_p);
865 hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_calc, 2 * hctx->ccid3hctx_x_recv),
866 hctx->ccid3hctx_s / TFRC_MAX_BACK_OFF_TIME);
867 } else if (now_delta(hctx->ccid3hctx_t_ld) >= hctx->ccid3hctx_rtt) {
868 u32 rtt = hctx->ccid3hctx_rtt;
869 if (rtt < 10) {
870 rtt = 10;
871 } /* avoid divide by zero below */
872
873 hctx->ccid3hctx_x = max_t(u32, min_t(u32, 2 * hctx->ccid3hctx_x_recv, 2 * hctx->ccid3hctx_x),
874 (hctx->ccid3hctx_s * 100000) / (rtt / 10));
875 /* Using 100000 and 10 to avoid 32 bit overflow for jumbo frames */
876 do_gettimeofday(&hctx->ccid3hctx_t_ld);
877 }
878
879 if (hctx->ccid3hctx_x == 0) {
880 ccid3_pr_debug("ccid3hctx_x = 0!\n");
881 hctx->ccid3hctx_x = 1;
882 }
883}
884
885static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
886{
887 struct sock *sk = (struct sock *)data;
888 struct dccp_sock *dp = dccp_sk(sk);
889 unsigned long next_tmout = 0;
890 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
891 u32 rtt;
892
893 bh_lock_sock(sk);
894 if (sock_owned_by_user(sk)) {
895 /* Try again later. */
896 /* XXX: set some sensible MIB */
897 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, jiffies + HZ / 5);
898 goto out;
899 }
900
901 ccid3_pr_debug("%s, sk=%p, state=%s\n", dccp_role(sk), sk,
902 ccid3_tx_state_name(hctx->ccid3hctx_state));
903
904 if (hctx->ccid3hctx_x < 10) {
905 ccid3_pr_debug("TFRC_SSTATE_NO_FBACK ccid3hctx_x < 10\n");
906 hctx->ccid3hctx_x = 10;
907 }
908
909 switch (hctx->ccid3hctx_state) {
910 case TFRC_SSTATE_TERM:
911 goto out;
912 case TFRC_SSTATE_NO_FBACK:
913 /* Halve send rate */
914 hctx->ccid3hctx_x /= 2;
915 if (hctx->ccid3hctx_x < (hctx->ccid3hctx_s / TFRC_MAX_BACK_OFF_TIME))
916 hctx->ccid3hctx_x = hctx->ccid3hctx_s / TFRC_MAX_BACK_OFF_TIME;
917
918 ccid3_pr_debug("%s, sk=%p, state=%s, updated tx rate to %d bytes/s\n",
919 dccp_role(sk), sk, ccid3_tx_state_name(hctx->ccid3hctx_state),
920 hctx->ccid3hctx_x);
921 next_tmout = max_t(u32, 2 * (hctx->ccid3hctx_s * 100000)
922 / (hctx->ccid3hctx_x / 10), TFRC_INITIAL_TIMEOUT);
923 /* do above maths with 100000 and 10 to prevent overflow on 32 bit */
924 /* FIXME - not sure above calculation is correct. See section 5 of CCID3 11
925 * should adjust tx_t_ipi and double that to achieve it really */
926 break;
927 case TFRC_SSTATE_FBACK:
928 /* Check if IDLE since last timeout and recv rate is less than 4 packets per RTT */
929 rtt = hctx->ccid3hctx_rtt;
930 if (rtt < 10)
931 rtt = 10;
932 /* stop divide by zero below */
933 if (!hctx->ccid3hctx_idle || (hctx->ccid3hctx_x_recv >=
934 4 * (hctx->ccid3hctx_s * 100000) / (rtt / 10))) {
935 ccid3_pr_debug("%s, sk=%p, state=%s, not idle\n", dccp_role(sk), sk,
936 ccid3_tx_state_name(hctx->ccid3hctx_state));
937 /* Halve sending rate */
938
939 /* If (X_calc > 2 * X_recv)
940 * X_recv = max(X_recv / 2, s / (2 * t_mbi));
941 * Else
942 * X_recv = X_calc / 4;
943 */
944 BUG_ON(hctx->ccid3hctx_p >= TFRC_SMALLEST_P && hctx->ccid3hctx_x_calc == 0);
945
946 /* check also if p is zero -> x_calc is infinity? */
947 if (hctx->ccid3hctx_p < TFRC_SMALLEST_P ||
948 hctx->ccid3hctx_x_calc > 2 * hctx->ccid3hctx_x_recv)
949 hctx->ccid3hctx_x_recv = max_t(u32, hctx->ccid3hctx_x_recv / 2,
950 hctx->ccid3hctx_s / (2 * TFRC_MAX_BACK_OFF_TIME));
951 else
952 hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc / 4;
953
954 /* Update sending rate */
955 ccid3_hc_tx_update_x(sk);
956 }
957 if (hctx->ccid3hctx_x == 0) {
958 ccid3_pr_debug("TFRC_SSTATE_FBACK ccid3hctx_x = 0!\n");
959 hctx->ccid3hctx_x = 10;
960 }
961 /* Schedule no feedback timer to expire in max(4 * R, 2 * s / X) */
962 next_tmout = max_t(u32, inet_csk(sk)->icsk_rto,
963 2 * (hctx->ccid3hctx_s * 100000) / (hctx->ccid3hctx_x / 10));
964 break;
965 default:
966 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
967 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
968 dump_stack();
969 goto out;
970 }
971
972 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
973 jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout)));
974 hctx->ccid3hctx_idle = 1;
975out:
976 bh_unlock_sock(sk);
977 sock_put(sk);
978}
979
Arnaldo Carvalho de Melo27258ee2005-08-09 20:30:56 -0700980static int ccid3_hc_tx_send_packet(struct sock *sk,
981 struct sk_buff *skb, int len)
Arnaldo Carvalho de Melo7c657872005-08-09 20:14:34 -0700982{
983 struct dccp_sock *dp = dccp_sk(sk);
984 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
985 struct ccid3_tx_hist_entry *new_packet = NULL;
986 struct timeval now;
Arnaldo Carvalho de Melo27258ee2005-08-09 20:30:56 -0700987 long delay;
Arnaldo Carvalho de Melo7c657872005-08-09 20:14:34 -0700988 int rc = -ENOTCONN;
989
990// ccid3_pr_debug("%s, sk=%p, skb=%p, len=%d\n", dccp_role(sk), sk, skb, len);
991 /*
992 * check if pure ACK or Terminating */
993 /* XXX: We only call this function for DATA and DATAACK, on, these packets can have
994 * zero length, but why the comment about "pure ACK"?
995 */
996 if (hctx == NULL || len == 0 || hctx->ccid3hctx_state == TFRC_SSTATE_TERM)
997 goto out;
998
999 /* See if last packet allocated was not sent */
1000 if (!list_empty(&hctx->ccid3hctx_hist))
1001 new_packet = list_entry(hctx->ccid3hctx_hist.next,
1002 struct ccid3_tx_hist_entry, ccid3htx_node);
1003
1004 if (new_packet == NULL || new_packet->ccid3htx_sent) {
1005 new_packet = ccid3_tx_hist_entry_new(SLAB_ATOMIC);
1006
1007 rc = -ENOBUFS;
1008 if (new_packet == NULL) {
1009 ccid3_pr_debug("%s, sk=%p, not enough mem to add "
1010 "to history, send refused\n", dccp_role(sk), sk);
1011 goto out;
1012 }
1013
1014 list_add(&new_packet->ccid3htx_node, &hctx->ccid3hctx_hist);
1015 }
1016
1017 do_gettimeofday(&now);
1018
1019 switch (hctx->ccid3hctx_state) {
1020 case TFRC_SSTATE_NO_SENT:
1021 ccid3_pr_debug("%s, sk=%p, first packet(%llu)\n", dccp_role(sk), sk,
1022 dp->dccps_gss);
1023
1024 hctx->ccid3hctx_no_feedback_timer.function = ccid3_hc_tx_no_feedback_timer;
1025 hctx->ccid3hctx_no_feedback_timer.data = (unsigned long)sk;
1026 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, jiffies + usecs_to_jiffies(TFRC_INITIAL_TIMEOUT));
1027 hctx->ccid3hctx_last_win_count = 0;
1028 hctx->ccid3hctx_t_last_win_count = now;
1029 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
1030 hctx->ccid3hctx_t_ipi = TFRC_INITIAL_TIMEOUT;
1031
1032 /* Set nominal send time for initial packet */
1033 hctx->ccid3hctx_t_nom = now;
1034 (hctx->ccid3hctx_t_nom).tv_usec += hctx->ccid3hctx_t_ipi;
1035 timeval_fix(&(hctx->ccid3hctx_t_nom));
1036 ccid3_calc_new_delta(hctx);
1037 rc = 0;
1038 break;
1039 case TFRC_SSTATE_NO_FBACK:
1040 case TFRC_SSTATE_FBACK:
Arnaldo Carvalho de Melo27258ee2005-08-09 20:30:56 -07001041 delay = (now_delta(hctx->ccid3hctx_t_nom) - hctx->ccid3hctx_delta);
1042 ccid3_pr_debug("send_packet delay=%ld\n", delay);
1043 delay /= -1000;
Arnaldo Carvalho de Melo7c657872005-08-09 20:14:34 -07001044 /* divide by -1000 is to convert to ms and get sign right */
Arnaldo Carvalho de Melo27258ee2005-08-09 20:30:56 -07001045 rc = delay > 0 ? -EAGAIN : 0;
Arnaldo Carvalho de Melo7c657872005-08-09 20:14:34 -07001046 break;
1047 default:
1048 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
1049 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
1050 dump_stack();
1051 rc = -EINVAL;
1052 break;
1053 }
1054
1055 /* Can we send? if so add options and add to packet history */
1056 if (rc == 0)
1057 new_packet->ccid3htx_win_count = DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
1058out:
1059 return rc;
1060}
1061
1062static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
1063{
1064 struct dccp_sock *dp = dccp_sk(sk);
1065 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
1066 struct ccid3_tx_hist_entry *packet = NULL;
1067 struct timeval now;
1068
1069// ccid3_pr_debug("%s, sk=%p, more=%d, len=%d\n", dccp_role(sk), sk, more, len);
1070 BUG_ON(hctx == NULL);
1071
1072 if (hctx->ccid3hctx_state == TFRC_SSTATE_TERM) {
1073 ccid3_pr_debug("%s, sk=%p, while state is TFRC_SSTATE_TERM!\n",
1074 dccp_role(sk), sk);
1075 return;
1076 }
1077
1078 do_gettimeofday(&now);
1079
1080 /* check if we have sent a data packet */
1081 if (len > 0) {
1082 unsigned long quarter_rtt;
1083
1084 if (list_empty(&hctx->ccid3hctx_hist)) {
1085 printk(KERN_CRIT "%s: packet doesn't exists in history!\n", __FUNCTION__);
1086 return;
1087 }
1088 packet = list_entry(hctx->ccid3hctx_hist.next, struct ccid3_tx_hist_entry, ccid3htx_node);
1089 if (packet->ccid3htx_sent) {
1090 printk(KERN_CRIT "%s: no unsent packet in history!\n", __FUNCTION__);
1091 return;
1092 }
1093 packet->ccid3htx_tstamp = now;
1094 packet->ccid3htx_seqno = dp->dccps_gss;
1095 // ccid3_pr_debug("%s, sk=%p, seqno=%llu inserted!\n", dccp_role(sk), sk, packet->ccid3htx_seqno);
1096
1097 /*
1098 * Check if win_count have changed */
1099 /* COMPLIANCE_BEGIN
1100 * Algorithm in "8.1. Window Counter Valuer" in draft-ietf-dccp-ccid3-11.txt
1101 */
1102 quarter_rtt = now_delta(hctx->ccid3hctx_t_last_win_count) / (hctx->ccid3hctx_rtt / 4);
1103 if (quarter_rtt > 0) {
1104 hctx->ccid3hctx_t_last_win_count = now;
1105 hctx->ccid3hctx_last_win_count = (hctx->ccid3hctx_last_win_count +
1106 min_t(unsigned long, quarter_rtt, 5)) % 16;
1107 ccid3_pr_debug("%s, sk=%p, window changed from %u to %u!\n",
1108 dccp_role(sk), sk,
1109 packet->ccid3htx_win_count,
1110 hctx->ccid3hctx_last_win_count);
1111 }
1112 /* COMPLIANCE_END */
1113#if 0
1114 ccid3_pr_debug("%s, sk=%p, packet sent (%llu,%u)\n",
1115 dccp_role(sk), sk,
1116 packet->ccid3htx_seqno,
1117 packet->ccid3htx_win_count);
1118#endif
1119 hctx->ccid3hctx_idle = 0;
1120 packet->ccid3htx_sent = 1;
1121 } else
1122 ccid3_pr_debug("%s, sk=%p, seqno=%llu NOT inserted!\n",
1123 dccp_role(sk), sk, dp->dccps_gss);
1124
1125 switch (hctx->ccid3hctx_state) {
1126 case TFRC_SSTATE_NO_SENT:
1127 /* if first wasn't pure ack */
1128 if (len != 0)
1129 printk(KERN_CRIT "%s: %s, First packet sent is noted as a data packet\n",
1130 __FUNCTION__, dccp_role(sk));
1131 return;
1132 case TFRC_SSTATE_NO_FBACK:
1133 case TFRC_SSTATE_FBACK:
1134 if (len > 0) {
1135 hctx->ccid3hctx_t_nom = now;
1136 ccid3_calc_new_t_ipi(hctx);
1137 ccid3_calc_new_delta(hctx);
1138 (hctx->ccid3hctx_t_nom).tv_usec += hctx->ccid3hctx_t_ipi;
1139 timeval_fix(&(hctx->ccid3hctx_t_nom));
1140 }
1141 break;
1142 default:
1143 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
1144 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
1145 dump_stack();
1146 break;
1147 }
1148}
1149
1150static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
1151{
1152 struct dccp_sock *dp = dccp_sk(sk);
1153 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
1154 struct ccid3_options_received *opt_recv;
1155 struct ccid3_tx_hist_entry *entry, *next, *packet;
1156 unsigned long next_tmout;
1157 u16 t_elapsed;
1158 u32 pinv;
1159 u32 x_recv;
1160 u32 r_sample;
1161#if 0
1162 ccid3_pr_debug("%s, sk=%p(%s), skb=%p(%s)\n",
1163 dccp_role(sk), sk, dccp_state_name(sk->sk_state),
1164 skb, dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
1165#endif
1166 if (hctx == NULL)
1167 return;
1168
1169 if (hctx->ccid3hctx_state == TFRC_SSTATE_TERM) {
1170 ccid3_pr_debug("%s, sk=%p, received a packet when terminating!\n", dccp_role(sk), sk);
1171 return;
1172 }
1173
1174 /* we are only interested in ACKs */
1175 if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK ||
1176 DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK))
1177 return;
1178
1179 opt_recv = &hctx->ccid3hctx_options_received;
1180
1181 t_elapsed = dp->dccps_options_received.dccpor_elapsed_time;
1182 x_recv = opt_recv->ccid3or_receive_rate;
1183 pinv = opt_recv->ccid3or_loss_event_rate;
1184
1185 switch (hctx->ccid3hctx_state) {
1186 case TFRC_SSTATE_NO_SENT:
1187 /* FIXME: what to do here? */
1188 return;
1189 case TFRC_SSTATE_NO_FBACK:
1190 case TFRC_SSTATE_FBACK:
1191 /* Calculate new round trip sample by
1192 * R_sample = (now - t_recvdata) - t_delay */
1193 /* get t_recvdata from history */
1194 packet = NULL;
1195 list_for_each_entry_safe(entry, next, &hctx->ccid3hctx_hist, ccid3htx_node)
1196 if (entry->ccid3htx_seqno == DCCP_SKB_CB(skb)->dccpd_ack_seq) {
1197 packet = entry;
1198 break;
1199 }
1200
1201 if (packet == NULL) {
1202 ccid3_pr_debug("%s, sk=%p, seqno %llu(%s) does't exist in history!\n",
1203 dccp_role(sk), sk, DCCP_SKB_CB(skb)->dccpd_ack_seq,
1204 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
1205 return;
1206 }
1207
1208 /* Update RTT */
1209 r_sample = now_delta(packet->ccid3htx_tstamp);
1210 /* FIXME: */
1211 // r_sample -= usecs_to_jiffies(t_elapsed * 10);
1212
1213 /* Update RTT estimate by
1214 * If (No feedback recv)
1215 * R = R_sample;
1216 * Else
1217 * R = q * R + (1 - q) * R_sample;
1218 *
1219 * q is a constant, RFC 3448 recomments 0.9
1220 */
1221 if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) {
1222 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
1223 hctx->ccid3hctx_rtt = r_sample;
1224 } else
1225 hctx->ccid3hctx_rtt = (hctx->ccid3hctx_rtt * 9) / 10 + r_sample / 10;
1226
1227 /*
1228 * XXX: this is to avoid a division by zero in ccid3_hc_tx_packet_sent
1229 * implemention of the new window count.
1230 */
1231 if (hctx->ccid3hctx_rtt < 4)
1232 hctx->ccid3hctx_rtt = 4;
1233
1234 ccid3_pr_debug("%s, sk=%p, New RTT estimate=%uus, r_sample=%us\n",
1235 dccp_role(sk), sk,
1236 hctx->ccid3hctx_rtt,
1237 r_sample);
1238
1239 /* Update timeout interval */
1240 inet_csk(sk)->icsk_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt, USEC_IN_SEC);
1241
1242 /* Update receive rate */
1243 hctx->ccid3hctx_x_recv = x_recv; /* x_recv in bytes per second */
1244
1245 /* Update loss event rate */
1246 if (pinv == ~0 || pinv == 0)
1247 hctx->ccid3hctx_p = 0;
1248 else {
1249 hctx->ccid3hctx_p = 1000000 / pinv;
1250
1251 if (hctx->ccid3hctx_p < TFRC_SMALLEST_P) {
1252 hctx->ccid3hctx_p = TFRC_SMALLEST_P;
1253 ccid3_pr_debug("%s, sk=%p, Smallest p used!\n", dccp_role(sk), sk);
1254 }
1255 }
1256
1257 /* unschedule no feedback timer */
1258 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
1259
1260 /* Update sending rate */
1261 ccid3_hc_tx_update_x(sk);
1262
1263 /* Update next send time */
1264 if (hctx->ccid3hctx_t_ipi > (hctx->ccid3hctx_t_nom).tv_usec) {
1265 (hctx->ccid3hctx_t_nom).tv_usec += USEC_IN_SEC;
1266 (hctx->ccid3hctx_t_nom).tv_sec--;
1267 }
1268 /* FIXME - if no feedback then t_ipi can go > 1 second */
1269 (hctx->ccid3hctx_t_nom).tv_usec -= hctx->ccid3hctx_t_ipi;
1270 ccid3_calc_new_t_ipi(hctx);
1271 (hctx->ccid3hctx_t_nom).tv_usec += hctx->ccid3hctx_t_ipi;
1272 timeval_fix(&(hctx->ccid3hctx_t_nom));
1273 ccid3_calc_new_delta(hctx);
1274
1275 /* remove all packets older than the one acked from history */
Arnaldo Carvalho de Melo7c657872005-08-09 20:14:34 -07001276 list_for_each_entry_safe_continue(entry, next, &hctx->ccid3hctx_hist, ccid3htx_node) {
1277 list_del_init(&entry->ccid3htx_node);
1278 ccid3_tx_hist_entry_delete(entry);
1279 }
Arnaldo Carvalho de Melo7c657872005-08-09 20:14:34 -07001280 if (hctx->ccid3hctx_x < 10) {
1281 ccid3_pr_debug("ccid3_hc_tx_packet_recv hctx->ccid3hctx_x < 10\n");
1282 hctx->ccid3hctx_x = 10;
1283 }
1284 /* to prevent divide by zero below */
1285
1286 /* Schedule no feedback timer to expire in max(4 * R, 2 * s / X) */
1287 next_tmout = max(inet_csk(sk)->icsk_rto,
1288 2 * (hctx->ccid3hctx_s * 100000) / (hctx->ccid3hctx_x/10));
1289 /* maths with 100000 and 10 is to prevent overflow with 32 bit */
1290
1291 ccid3_pr_debug("%s, sk=%p, Scheduled no feedback timer to expire in %lu jiffies (%luus)\n",
1292 dccp_role(sk), sk, usecs_to_jiffies(next_tmout), next_tmout);
1293
1294 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
1295 jiffies + max_t(u32,1,usecs_to_jiffies(next_tmout)));
1296
1297 /* set idle flag */
1298 hctx->ccid3hctx_idle = 1;
1299 break;
1300 default:
1301 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
1302 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
1303 dump_stack();
1304 break;
1305 }
1306}
1307
1308static void ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb)
1309{
1310 const struct dccp_sock *dp = dccp_sk(sk);
1311 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
1312
1313 if (hctx == NULL || !(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
1314 return;
1315
1316 DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
1317}
1318
1319static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
1320 unsigned char len, u16 idx, unsigned char *value)
1321{
1322 int rc = 0;
1323 struct dccp_sock *dp = dccp_sk(sk);
1324 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
1325 struct ccid3_options_received *opt_recv;
1326
1327 if (hctx == NULL)
1328 return 0;
1329
1330 opt_recv = &hctx->ccid3hctx_options_received;
1331
1332 if (opt_recv->ccid3or_seqno != dp->dccps_gsr) {
1333 opt_recv->ccid3or_seqno = dp->dccps_gsr;
1334 opt_recv->ccid3or_loss_event_rate = ~0;
1335 opt_recv->ccid3or_loss_intervals_idx = 0;
1336 opt_recv->ccid3or_loss_intervals_len = 0;
1337 opt_recv->ccid3or_receive_rate = 0;
1338 }
1339
1340 switch (option) {
1341 case TFRC_OPT_LOSS_EVENT_RATE:
1342 if (len != 4) {
1343 ccid3_pr_debug("%s, sk=%p, invalid len for TFRC_OPT_LOSS_EVENT_RATE\n",
1344 dccp_role(sk), sk);
1345 rc = -EINVAL;
1346 } else {
1347 opt_recv->ccid3or_loss_event_rate = ntohl(*(u32 *)value);
1348 ccid3_pr_debug("%s, sk=%p, LOSS_EVENT_RATE=%u\n",
1349 dccp_role(sk), sk,
1350 opt_recv->ccid3or_loss_event_rate);
1351 }
1352 break;
1353 case TFRC_OPT_LOSS_INTERVALS:
1354 opt_recv->ccid3or_loss_intervals_idx = idx;
1355 opt_recv->ccid3or_loss_intervals_len = len;
1356 ccid3_pr_debug("%s, sk=%p, LOSS_INTERVALS=(%u, %u)\n",
1357 dccp_role(sk), sk,
1358 opt_recv->ccid3or_loss_intervals_idx,
1359 opt_recv->ccid3or_loss_intervals_len);
1360 break;
1361 case TFRC_OPT_RECEIVE_RATE:
1362 if (len != 4) {
1363 ccid3_pr_debug("%s, sk=%p, invalid len for TFRC_OPT_RECEIVE_RATE\n",
1364 dccp_role(sk), sk);
1365 rc = -EINVAL;
1366 } else {
1367 opt_recv->ccid3or_receive_rate = ntohl(*(u32 *)value);
1368 ccid3_pr_debug("%s, sk=%p, RECEIVE_RATE=%u\n",
1369 dccp_role(sk), sk,
1370 opt_recv->ccid3or_receive_rate);
1371 }
1372 break;
1373 }
1374
1375 return rc;
1376}
1377
1378static int ccid3_hc_tx_init(struct sock *sk)
1379{
1380 struct dccp_sock *dp = dccp_sk(sk);
1381 struct ccid3_hc_tx_sock *hctx;
1382
1383 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
1384
1385 hctx = dp->dccps_hc_tx_ccid_private = kmalloc(sizeof(*hctx), gfp_any());
1386 if (hctx == NULL)
1387 return -ENOMEM;
1388
1389 memset(hctx, 0, sizeof(*hctx));
1390
1391 if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE &&
1392 dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE)
1393 hctx->ccid3hctx_s = (u16)dp->dccps_avg_packet_size;
1394 else
1395 hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE;
1396
1397 hctx->ccid3hctx_x = hctx->ccid3hctx_s; /* set transmission rate to 1 packet per second */
1398 hctx->ccid3hctx_rtt = 4; /* See ccid3_hc_tx_packet_sent win_count calculatation */
1399 inet_csk(sk)->icsk_rto = USEC_IN_SEC;
1400 hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
1401 INIT_LIST_HEAD(&hctx->ccid3hctx_hist);
1402 init_timer(&hctx->ccid3hctx_no_feedback_timer);
1403
1404 return 0;
1405}
1406
1407static void ccid3_hc_tx_exit(struct sock *sk)
1408{
1409 struct dccp_sock *dp = dccp_sk(sk);
1410 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
1411 struct ccid3_tx_hist_entry *entry, *next;
1412
1413 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
1414 BUG_ON(hctx == NULL);
1415
1416 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM);
1417 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
1418
1419 /* Empty packet history */
1420 list_for_each_entry_safe(entry, next, &hctx->ccid3hctx_hist, ccid3htx_node) {
1421 list_del_init(&entry->ccid3htx_node);
1422 ccid3_tx_hist_entry_delete(entry);
1423 }
1424
1425 kfree(dp->dccps_hc_tx_ccid_private);
1426 dp->dccps_hc_tx_ccid_private = NULL;
1427}
1428
1429/*
1430 * RX Half Connection methods
1431 */
1432
1433/* TFRC receiver states */
1434enum ccid3_hc_rx_states {
1435 TFRC_RSTATE_NO_DATA = 1,
1436 TFRC_RSTATE_DATA,
1437 TFRC_RSTATE_TERM = 127,
1438};
1439
1440#ifdef CCID3_DEBUG
1441static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
1442{
1443 static char *ccid3_rx_state_names[] = {
1444 [TFRC_RSTATE_NO_DATA] = "NO_DATA",
1445 [TFRC_RSTATE_DATA] = "DATA",
1446 [TFRC_RSTATE_TERM] = "TERM",
1447 };
1448
1449 return ccid3_rx_state_names[state];
1450}
1451#endif
1452
1453static inline void ccid3_hc_rx_set_state(struct sock *sk, enum ccid3_hc_rx_states state)
1454{
1455 struct dccp_sock *dp = dccp_sk(sk);
1456 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1457 enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state;
1458
1459 ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
1460 dccp_role(sk), sk, ccid3_rx_state_name(oldstate), ccid3_rx_state_name(state));
1461 WARN_ON(state == oldstate);
1462 hcrx->ccid3hcrx_state = state;
1463}
1464
1465static int ccid3_hc_rx_add_hist(struct sock *sk, struct ccid3_rx_hist_entry *packet)
1466{
1467 struct dccp_sock *dp = dccp_sk(sk);
1468 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1469 struct ccid3_rx_hist_entry *entry, *next;
1470 u8 num_later = 0;
1471
1472 if (list_empty(&hcrx->ccid3hcrx_hist))
1473 list_add(&packet->ccid3hrx_node, &hcrx->ccid3hcrx_hist);
1474 else {
1475 u64 seqno = packet->ccid3hrx_seqno;
1476 struct ccid3_rx_hist_entry *iter = list_entry(hcrx->ccid3hcrx_hist.next,
1477 struct ccid3_rx_hist_entry,
1478 ccid3hrx_node);
1479 if (after48(seqno, iter->ccid3hrx_seqno))
1480 list_add(&packet->ccid3hrx_node, &hcrx->ccid3hcrx_hist);
1481 else {
1482 if (iter->ccid3hrx_type == DCCP_PKT_DATA ||
1483 iter->ccid3hrx_type == DCCP_PKT_DATAACK)
1484 num_later = 1;
1485
1486 list_for_each_entry_continue(iter, &hcrx->ccid3hcrx_hist, ccid3hrx_node) {
1487 if (after48(seqno, iter->ccid3hrx_seqno)) {
1488 list_add(&packet->ccid3hrx_node, &iter->ccid3hrx_node);
1489 goto trim_history;
1490 }
1491
1492 if (iter->ccid3hrx_type == DCCP_PKT_DATA ||
1493 iter->ccid3hrx_type == DCCP_PKT_DATAACK)
1494 num_later++;
1495
1496 if (num_later == TFRC_RECV_NUM_LATE_LOSS) {
1497 ccid3_rx_hist_entry_delete(packet);
1498 ccid3_pr_debug("%s, sk=%p, packet(%llu) already lost!\n",
1499 dccp_role(sk), sk, seqno);
1500 return 1;
1501 }
1502 }
1503
1504 if (num_later < TFRC_RECV_NUM_LATE_LOSS)
1505 list_add_tail(&packet->ccid3hrx_node, &hcrx->ccid3hcrx_hist);
1506 /* FIXME: else what? should we destroy the packet like above? */
1507 }
1508 }
1509
1510trim_history:
1511 /* Trim history (remove all packets after the NUM_LATE_LOSS + 1 data packets) */
1512 num_later = TFRC_RECV_NUM_LATE_LOSS + 1;
1513
1514 if (!list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) {
1515 list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist, ccid3hrx_node) {
1516 if (num_later == 0) {
1517 list_del_init(&entry->ccid3hrx_node);
1518 ccid3_rx_hist_entry_delete(entry);
1519 } else if (entry->ccid3hrx_type == DCCP_PKT_DATA ||
1520 entry->ccid3hrx_type == DCCP_PKT_DATAACK)
1521 --num_later;
1522 }
1523 } else {
1524 int step = 0;
1525 u8 win_count = 0; /* Not needed, but lets shut up gcc */
1526 int tmp;
1527 /*
1528 * We have no loss interval history so we need at least one
1529 * rtt:s of data packets to approximate rtt.
1530 */
1531 list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist, ccid3hrx_node) {
1532 if (num_later == 0) {
1533 switch (step) {
1534 case 0:
1535 step = 1;
1536 /* OK, find next data packet */
1537 num_later = 1;
1538 break;
1539 case 1:
1540 step = 2;
1541 /* OK, find next data packet */
1542 num_later = 1;
1543 win_count = entry->ccid3hrx_win_count;
1544 break;
1545 case 2:
1546 tmp = win_count - entry->ccid3hrx_win_count;
1547 if (tmp < 0)
1548 tmp += TFRC_WIN_COUNT_LIMIT;
1549 if (tmp > TFRC_WIN_COUNT_PER_RTT + 1) {
1550 /* we have found a packet older than one rtt
1551 * remove the rest */
1552 step = 3;
1553 } else /* OK, find next data packet */
1554 num_later = 1;
1555 break;
1556 case 3:
1557 list_del_init(&entry->ccid3hrx_node);
1558 ccid3_rx_hist_entry_delete(entry);
1559 break;
1560 }
1561 } else if (entry->ccid3hrx_type == DCCP_PKT_DATA ||
1562 entry->ccid3hrx_type == DCCP_PKT_DATAACK)
1563 --num_later;
1564 }
1565 }
1566
1567 return 0;
1568}
1569
1570static void ccid3_hc_rx_send_feedback(struct sock *sk)
1571{
1572 struct dccp_sock *dp = dccp_sk(sk);
1573 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1574 struct ccid3_rx_hist_entry *entry, *packet;
1575
1576 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
1577
1578 switch (hcrx->ccid3hcrx_state) {
1579 case TFRC_RSTATE_NO_DATA:
1580 hcrx->ccid3hcrx_x_recv = 0;
1581 break;
1582 case TFRC_RSTATE_DATA: {
1583 u32 delta = now_delta(hcrx->ccid3hcrx_tstamp_last_feedback);
1584
1585 if (delta == 0)
1586 delta = 1; /* to prevent divide by zero */
1587 hcrx->ccid3hcrx_x_recv = (hcrx->ccid3hcrx_bytes_recv * USEC_IN_SEC) / delta;
1588 }
1589 break;
1590 default:
1591 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
1592 __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
1593 dump_stack();
1594 return;
1595 }
1596
1597 packet = NULL;
1598 list_for_each_entry(entry, &hcrx->ccid3hcrx_hist, ccid3hrx_node)
1599 if (entry->ccid3hrx_type == DCCP_PKT_DATA ||
1600 entry->ccid3hrx_type == DCCP_PKT_DATAACK) {
1601 packet = entry;
1602 break;
1603 }
1604
1605 if (packet == NULL) {
1606 printk(KERN_CRIT "%s: %s, sk=%p, no data packet in history!\n",
1607 __FUNCTION__, dccp_role(sk), sk);
1608 dump_stack();
1609 return;
1610 }
1611
1612 do_gettimeofday(&(hcrx->ccid3hcrx_tstamp_last_feedback));
1613 hcrx->ccid3hcrx_last_counter = packet->ccid3hrx_win_count;
1614 hcrx->ccid3hcrx_seqno_last_counter = packet->ccid3hrx_seqno;
1615 hcrx->ccid3hcrx_bytes_recv = 0;
1616
1617 /* Convert to multiples of 10us */
1618 hcrx->ccid3hcrx_elapsed_time = now_delta(packet->ccid3hrx_tstamp) / 10;
1619 if (hcrx->ccid3hcrx_p == 0)
1620 hcrx->ccid3hcrx_pinv = ~0;
1621 else
1622 hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p;
1623 dccp_send_ack(sk);
1624}
1625
1626static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
1627{
1628 const struct dccp_sock *dp = dccp_sk(sk);
1629 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1630
1631 if (hcrx == NULL || !(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
1632 return;
1633
1634 if (hcrx->ccid3hcrx_elapsed_time != 0 && !dccp_packet_without_ack(skb))
1635 dccp_insert_option_elapsed_time(sk, skb, hcrx->ccid3hcrx_elapsed_time);
1636
1637 if (DCCP_SKB_CB(skb)->dccpd_type != DCCP_PKT_DATA) {
1638 const u32 x_recv = htonl(hcrx->ccid3hcrx_x_recv);
1639 const u32 pinv = htonl(hcrx->ccid3hcrx_pinv);
1640
1641 dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE, &pinv, sizeof(pinv));
1642 dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE, &x_recv, sizeof(x_recv));
1643 }
1644
1645 DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter;
1646}
1647
1648/* Weights used to calculate loss event rate */
1649/*
1650 * These are integers as per section 8 of RFC3448. We can then divide by 4 *
1651 * when we use it.
1652 */
1653const int ccid3_hc_rx_w[TFRC_RECV_IVAL_F_LENGTH] = { 4, 4, 4, 4, 3, 2, 1, 1, };
1654
1655/*
1656 * args: fvalue - function value to match
1657 * returns: p closest to that value
1658 *
1659 * both fvalue and p are multiplied by 1,000,000 to use ints
1660 */
1661u32 calcx_reverse_lookup(u32 fvalue) {
1662 int ctr = 0;
1663 int small;
1664
1665 if (fvalue < calcx_lookup[0][1])
1666 return 0;
1667 if (fvalue <= calcx_lookup[CALCX_ARRSIZE-1][1])
1668 small = 1;
1669 else if (fvalue > calcx_lookup[CALCX_ARRSIZE-1][0])
1670 return 1000000;
1671 else
1672 small = 0;
1673 while (fvalue > calcx_lookup[ctr][small])
1674 ctr++;
1675 if (small)
1676 return (CALCX_SPLIT * ctr / CALCX_ARRSIZE);
1677 else
1678 return (1000000 * ctr / CALCX_ARRSIZE) ;
1679}
1680
1681/* calculate first loss interval
1682 *
1683 * returns estimated loss interval in usecs */
1684
1685static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
1686{
1687 struct dccp_sock *dp = dccp_sk(sk);
1688 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1689 struct ccid3_rx_hist_entry *entry, *next, *tail = NULL;
1690 u32 rtt, delta, x_recv, fval, p, tmp2;
1691 struct timeval tstamp, tmp_tv;
1692 int interval = 0;
1693 int win_count = 0;
1694 int step = 0;
1695 u64 tmp1;
1696
1697 list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist, ccid3hrx_node) {
1698 if (entry->ccid3hrx_type == DCCP_PKT_DATA ||
1699 entry->ccid3hrx_type == DCCP_PKT_DATAACK) {
1700 tail = entry;
1701
1702 switch (step) {
1703 case 0:
1704 tstamp = entry->ccid3hrx_tstamp;
1705 win_count = entry->ccid3hrx_win_count;
1706 step = 1;
1707 break;
1708 case 1:
1709 interval = win_count - entry->ccid3hrx_win_count;
1710 if (interval < 0)
1711 interval += TFRC_WIN_COUNT_LIMIT;
1712 if (interval > 4)
1713 goto found;
1714 break;
1715 }
1716 }
1717 }
1718
1719 if (step == 0) {
1720 printk(KERN_CRIT "%s: %s, sk=%p, packet history contains no data packets!\n",
1721 __FUNCTION__, dccp_role(sk), sk);
1722 return ~0;
1723 }
1724
1725 if (interval == 0) {
1726 ccid3_pr_debug("%s, sk=%p, Could not find a win_count interval > 0. Defaulting to 1\n",
1727 dccp_role(sk), sk);
1728 interval = 1;
1729 }
1730found:
1731 timeval_sub(tstamp,tail->ccid3hrx_tstamp,&tmp_tv);
1732 rtt = (tmp_tv.tv_sec * USEC_IN_SEC + tmp_tv.tv_usec) * 4 / interval;
1733 ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n",
1734 dccp_role(sk), sk, rtt);
1735 if (rtt == 0)
1736 rtt = 1;
1737
1738 delta = now_delta(hcrx->ccid3hcrx_tstamp_last_feedback);
1739 if (delta == 0)
1740 delta = 1;
1741
1742 x_recv = (hcrx->ccid3hcrx_bytes_recv * USEC_IN_SEC) / delta;
1743
1744 tmp1 = (u64)x_recv * (u64)rtt;
1745 do_div(tmp1,10000000);
1746 tmp2 = (u32)tmp1;
1747 fval = (hcrx->ccid3hcrx_s * 100000) / tmp2;
1748 /* do not alter order above or you will get overflow on 32 bit */
1749 p = calcx_reverse_lookup(fval);
1750 ccid3_pr_debug("%s, sk=%p, receive rate=%u bytes/s, implied loss rate=%u\n",\
1751 dccp_role(sk), sk, x_recv, p);
1752
1753 if (p == 0)
1754 return ~0;
1755 else
1756 return 1000000 / p;
1757}
1758
1759static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
1760{
1761 struct dccp_sock *dp = dccp_sk(sk);
1762 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1763 struct ccid3_loss_interval_hist_entry *li_entry;
1764
1765 if (seq_loss != DCCP_MAX_SEQNO + 1) {
1766 ccid3_pr_debug("%s, sk=%p, seq_loss=%llu, win_loss=%u, packet loss detected\n",
1767 dccp_role(sk), sk, seq_loss, win_loss);
1768
1769 if (list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) {
1770 struct ccid3_loss_interval_hist_entry *li_tail = NULL;
1771 int i;
1772
1773 ccid3_pr_debug("%s, sk=%p, first loss event detected, creating history\n", dccp_role(sk), sk);
1774 for (i = 0; i <= TFRC_RECV_IVAL_F_LENGTH; ++i) {
1775 li_entry = ccid3_loss_interval_hist_entry_new(SLAB_ATOMIC);
1776 if (li_entry == NULL) {
1777 ccid3_loss_interval_history_delete(&hcrx->ccid3hcrx_loss_interval_hist);
1778 ccid3_pr_debug("%s, sk=%p, not enough mem for creating history\n",
1779 dccp_role(sk), sk);
1780 return;
1781 }
1782 if (li_tail == NULL)
1783 li_tail = li_entry;
1784 list_add(&li_entry->ccid3lih_node, &hcrx->ccid3hcrx_loss_interval_hist);
1785 }
1786
1787 li_entry->ccid3lih_seqno = seq_loss;
1788 li_entry->ccid3lih_win_count = win_loss;
1789
1790 li_tail->ccid3lih_interval = ccid3_hc_rx_calc_first_li(sk);
1791 }
1792 }
1793 /* FIXME: find end of interval */
1794}
1795
1796static void ccid3_hc_rx_detect_loss(struct sock *sk)
1797{
1798 struct dccp_sock *dp = dccp_sk(sk);
1799 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1800 struct ccid3_rx_hist_entry *entry, *a_next, *b_next, *packet;
1801 struct ccid3_rx_hist_entry *a_loss = NULL;
1802 struct ccid3_rx_hist_entry *b_loss = NULL;
1803 u64 seq_loss = DCCP_MAX_SEQNO + 1;
1804 u8 win_loss = 0;
1805 u8 num_later = TFRC_RECV_NUM_LATE_LOSS;
1806
1807 list_for_each_entry_safe(entry, b_next, &hcrx->ccid3hcrx_hist, ccid3hrx_node) {
1808 if (num_later == 0) {
1809 b_loss = entry;
1810 break;
1811 } else if (entry->ccid3hrx_type == DCCP_PKT_DATA ||
1812 entry->ccid3hrx_type == DCCP_PKT_DATAACK)
1813 --num_later;
1814 }
1815
1816 if (b_loss == NULL)
1817 goto out_update_li;
1818
1819 a_next = b_next;
1820 num_later = 1;
Arnaldo Carvalho de Melo757f6122005-08-09 20:16:04 -07001821
Arnaldo Carvalho de Melo7c657872005-08-09 20:14:34 -07001822 list_for_each_entry_safe_continue(entry, a_next, &hcrx->ccid3hcrx_hist, ccid3hrx_node) {
1823 if (num_later == 0) {
1824 a_loss = entry;
1825 break;
1826 } else if (entry->ccid3hrx_type == DCCP_PKT_DATA ||
1827 entry->ccid3hrx_type == DCCP_PKT_DATAACK)
1828 --num_later;
1829 }
Arnaldo Carvalho de Melo7c657872005-08-09 20:14:34 -07001830
1831 if (a_loss == NULL) {
1832 if (list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) {
1833 /* no loss event have occured yet */
1834 ccid3_pr_debug("%s, sk=%p, TODO: find a lost data "
1835 "packet by comparing to initial seqno\n",
1836 dccp_role(sk), sk);
1837 goto out_update_li;
1838 } else {
1839 pr_info("%s: %s, sk=%p, ERROR! Less than 4 data packets in history",
1840 __FUNCTION__, dccp_role(sk), sk);
1841 return;
1842 }
1843 }
1844
1845 /* Locate a lost data packet */
1846 entry = packet = b_loss;
Arnaldo Carvalho de Melo7c657872005-08-09 20:14:34 -07001847 list_for_each_entry_safe_continue(entry, b_next, &hcrx->ccid3hcrx_hist, ccid3hrx_node) {
1848 u64 delta = dccp_delta_seqno(entry->ccid3hrx_seqno, packet->ccid3hrx_seqno);
1849
1850 if (delta != 0) {
1851 if (packet->ccid3hrx_type == DCCP_PKT_DATA ||
1852 packet->ccid3hrx_type == DCCP_PKT_DATAACK)
1853 --delta;
1854 /*
1855 * FIXME: check this, probably this % usage is because
1856 * in earlier drafts the ndp count was just 8 bits
1857 * long, but now it cam be up to 24 bits long.
1858 */
1859#if 0
1860 if (delta % DCCP_NDP_LIMIT !=
1861 (packet->ccid3hrx_ndp - entry->ccid3hrx_ndp) % DCCP_NDP_LIMIT)
1862#endif
1863 if (delta != packet->ccid3hrx_ndp - entry->ccid3hrx_ndp) {
1864 seq_loss = entry->ccid3hrx_seqno;
1865 dccp_inc_seqno(&seq_loss);
1866 }
1867 }
1868 packet = entry;
1869 if (packet == a_loss)
1870 break;
1871 }
Arnaldo Carvalho de Melo7c657872005-08-09 20:14:34 -07001872
1873 if (seq_loss != DCCP_MAX_SEQNO + 1)
1874 win_loss = a_loss->ccid3hrx_win_count;
1875
1876out_update_li:
1877 ccid3_hc_rx_update_li(sk, seq_loss, win_loss);
1878}
1879
1880static u32 ccid3_hc_rx_calc_i_mean(struct sock *sk)
1881{
1882 struct dccp_sock *dp = dccp_sk(sk);
1883 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1884 struct ccid3_loss_interval_hist_entry *li_entry, *li_next;
1885 int i = 0;
1886 u32 i_tot;
1887 u32 i_tot0 = 0;
1888 u32 i_tot1 = 0;
1889 u32 w_tot = 0;
1890
1891 list_for_each_entry_safe(li_entry, li_next, &hcrx->ccid3hcrx_loss_interval_hist, ccid3lih_node) {
1892 if (i < TFRC_RECV_IVAL_F_LENGTH) {
1893 i_tot0 += li_entry->ccid3lih_interval * ccid3_hc_rx_w[i];
1894 w_tot += ccid3_hc_rx_w[i];
1895 }
1896
1897 if (i != 0)
1898 i_tot1 += li_entry->ccid3lih_interval * ccid3_hc_rx_w[i - 1];
1899
1900 if (++i > TFRC_RECV_IVAL_F_LENGTH)
1901 break;
1902 }
1903
1904 if (i != TFRC_RECV_IVAL_F_LENGTH) {
1905 pr_info("%s: %s, sk=%p, ERROR! Missing entry in interval history!\n",
1906 __FUNCTION__, dccp_role(sk), sk);
1907 return 0;
1908 }
1909
1910 i_tot = max(i_tot0, i_tot1);
1911
1912 /* FIXME: Why do we do this? -Ian McDonald */
1913 if (i_tot * 4 < w_tot)
1914 i_tot = w_tot * 4;
1915
1916 return i_tot * 4 / w_tot;
1917}
1918
1919static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
1920{
1921 struct dccp_sock *dp = dccp_sk(sk);
1922 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1923 struct ccid3_rx_hist_entry *packet;
1924 struct timeval now;
1925 u8 win_count;
1926 u32 p_prev;
1927 int ins;
1928#if 0
1929 ccid3_pr_debug("%s, sk=%p(%s), skb=%p(%s)\n",
1930 dccp_role(sk), sk, dccp_state_name(sk->sk_state),
1931 skb, dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
1932#endif
1933 if (hcrx == NULL)
1934 return;
1935
1936 BUG_ON(!(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA ||
1937 hcrx->ccid3hcrx_state == TFRC_RSTATE_DATA));
1938
1939 switch (DCCP_SKB_CB(skb)->dccpd_type) {
1940 case DCCP_PKT_ACK:
1941 if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
1942 return;
1943 case DCCP_PKT_DATAACK:
1944 if (dp->dccps_options_received.dccpor_timestamp_echo == 0)
1945 break;
1946 p_prev = hcrx->ccid3hcrx_rtt;
1947 do_gettimeofday(&now);
1948 /* hcrx->ccid3hcrx_rtt = now - dp->dccps_options_received.dccpor_timestamp_echo -
1949 usecs_to_jiffies(dp->dccps_options_received.dccpor_elapsed_time * 10);
1950 FIXME - I think above code is broken - have to look at options more, will also need
1951 to fix pr_debug below */
1952 if (p_prev != hcrx->ccid3hcrx_rtt)
1953 ccid3_pr_debug("%s, sk=%p, New RTT estimate=%lu jiffies, tstamp_echo=%u, elapsed time=%u\n",
1954 dccp_role(sk), sk, hcrx->ccid3hcrx_rtt,
1955 dp->dccps_options_received.dccpor_timestamp_echo,
1956 dp->dccps_options_received.dccpor_elapsed_time);
1957 break;
1958 case DCCP_PKT_DATA:
1959 break;
1960 default:
1961 ccid3_pr_debug("%s, sk=%p, not DATA/DATAACK/ACK packet(%s)\n",
1962 dccp_role(sk), sk,
1963 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
1964 return;
1965 }
1966
1967 packet = ccid3_rx_hist_entry_new(sk, skb, SLAB_ATOMIC);
1968 if (packet == NULL) {
1969 ccid3_pr_debug("%s, sk=%p, Not enough mem to add rx packet to history (consider it lost)!",
1970 dccp_role(sk), sk);
1971 return;
1972 }
1973
1974 win_count = packet->ccid3hrx_win_count;
1975
1976 ins = ccid3_hc_rx_add_hist(sk, packet);
1977
1978 if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK)
1979 return;
1980
1981 switch (hcrx->ccid3hcrx_state) {
1982 case TFRC_RSTATE_NO_DATA:
1983 ccid3_pr_debug("%s, sk=%p(%s), skb=%p, sending initial feedback\n",
1984 dccp_role(sk), sk, dccp_state_name(sk->sk_state), skb);
1985 ccid3_hc_rx_send_feedback(sk);
1986 ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
1987 return;
1988 case TFRC_RSTATE_DATA:
1989 hcrx->ccid3hcrx_bytes_recv += skb->len - dccp_hdr(skb)->dccph_doff * 4;
1990 if (ins == 0) {
1991 do_gettimeofday(&now);
1992 if ((now_delta(hcrx->ccid3hcrx_tstamp_last_ack)) >= hcrx->ccid3hcrx_rtt) {
1993 hcrx->ccid3hcrx_tstamp_last_ack = now;
1994 ccid3_hc_rx_send_feedback(sk);
1995 }
1996 return;
1997 }
1998 break;
1999 default:
2000 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
2001 __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
2002 dump_stack();
2003 return;
2004 }
2005
2006 /* Dealing with packet loss */
2007 ccid3_pr_debug("%s, sk=%p(%s), skb=%p, data loss! Reacting...\n",
2008 dccp_role(sk), sk, dccp_state_name(sk->sk_state), skb);
2009
2010 ccid3_hc_rx_detect_loss(sk);
2011 p_prev = hcrx->ccid3hcrx_p;
2012
2013 /* Calculate loss event rate */
2014 if (!list_empty(&hcrx->ccid3hcrx_loss_interval_hist))
2015 /* Scaling up by 1000000 as fixed decimal */
2016 hcrx->ccid3hcrx_p = 1000000 / ccid3_hc_rx_calc_i_mean(sk);
2017
2018 if (hcrx->ccid3hcrx_p > p_prev) {
2019 ccid3_hc_rx_send_feedback(sk);
2020 return;
2021 }
2022}
2023
2024static int ccid3_hc_rx_init(struct sock *sk)
2025{
2026 struct dccp_sock *dp = dccp_sk(sk);
2027 struct ccid3_hc_rx_sock *hcrx;
2028
2029 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
2030
2031 hcrx = dp->dccps_hc_rx_ccid_private = kmalloc(sizeof(*hcrx), gfp_any());
2032 if (hcrx == NULL)
2033 return -ENOMEM;
2034
2035 memset(hcrx, 0, sizeof(*hcrx));
2036
2037 if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE &&
2038 dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE)
2039 hcrx->ccid3hcrx_s = (u16)dp->dccps_avg_packet_size;
2040 else
2041 hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE;
2042
2043 hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA;
2044 INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist);
2045 INIT_LIST_HEAD(&hcrx->ccid3hcrx_loss_interval_hist);
2046
2047 return 0;
2048}
2049
2050static void ccid3_hc_rx_exit(struct sock *sk)
2051{
2052 struct dccp_sock *dp = dccp_sk(sk);
2053 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
2054
2055 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
2056
2057 if (hcrx == NULL)
2058 return;
2059
2060 ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);
2061
2062 /* Empty packet history */
2063 ccid3_rx_history_delete(&hcrx->ccid3hcrx_hist);
2064
2065 /* Empty loss interval history */
2066 ccid3_loss_interval_history_delete(&hcrx->ccid3hcrx_loss_interval_hist);
2067
2068 kfree(dp->dccps_hc_rx_ccid_private);
2069 dp->dccps_hc_rx_ccid_private = NULL;
2070}
2071
2072static struct ccid ccid3 = {
2073 .ccid_id = 3,
2074 .ccid_name = "ccid3",
2075 .ccid_owner = THIS_MODULE,
2076 .ccid_init = ccid3_init,
2077 .ccid_exit = ccid3_exit,
2078 .ccid_hc_tx_init = ccid3_hc_tx_init,
2079 .ccid_hc_tx_exit = ccid3_hc_tx_exit,
2080 .ccid_hc_tx_send_packet = ccid3_hc_tx_send_packet,
2081 .ccid_hc_tx_packet_sent = ccid3_hc_tx_packet_sent,
2082 .ccid_hc_tx_packet_recv = ccid3_hc_tx_packet_recv,
2083 .ccid_hc_tx_insert_options = ccid3_hc_tx_insert_options,
2084 .ccid_hc_tx_parse_options = ccid3_hc_tx_parse_options,
2085 .ccid_hc_rx_init = ccid3_hc_rx_init,
2086 .ccid_hc_rx_exit = ccid3_hc_rx_exit,
2087 .ccid_hc_rx_insert_options = ccid3_hc_rx_insert_options,
2088 .ccid_hc_rx_packet_recv = ccid3_hc_rx_packet_recv,
2089};
2090
2091module_param(ccid3_debug, int, 0444);
2092MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");
2093
2094static __init int ccid3_module_init(void)
2095{
2096 int rc = -ENOMEM;
2097
2098 ccid3_tx_hist_slab = kmem_cache_create("dccp_ccid3_tx_history",
2099 sizeof(struct ccid3_tx_hist_entry), 0,
2100 SLAB_HWCACHE_ALIGN, NULL, NULL);
2101 if (ccid3_tx_hist_slab == NULL)
2102 goto out;
2103
2104 ccid3_rx_hist_slab = kmem_cache_create("dccp_ccid3_rx_history",
2105 sizeof(struct ccid3_rx_hist_entry), 0,
2106 SLAB_HWCACHE_ALIGN, NULL, NULL);
2107 if (ccid3_rx_hist_slab == NULL)
2108 goto out_free_tx_history;
2109
2110 ccid3_loss_interval_hist_slab = kmem_cache_create("dccp_ccid3_loss_interval_history",
2111 sizeof(struct ccid3_loss_interval_hist_entry), 0,
2112 SLAB_HWCACHE_ALIGN, NULL, NULL);
2113 if (ccid3_loss_interval_hist_slab == NULL)
2114 goto out_free_rx_history;
2115
2116 rc = ccid_register(&ccid3);
2117 if (rc != 0)
2118 goto out_free_loss_interval_history;
2119
2120out:
2121 return rc;
2122out_free_loss_interval_history:
2123 kmem_cache_destroy(ccid3_loss_interval_hist_slab);
2124 ccid3_loss_interval_hist_slab = NULL;
2125out_free_rx_history:
2126 kmem_cache_destroy(ccid3_rx_hist_slab);
2127 ccid3_rx_hist_slab = NULL;
2128out_free_tx_history:
2129 kmem_cache_destroy(ccid3_tx_hist_slab);
2130 ccid3_tx_hist_slab = NULL;
2131 goto out;
2132}
2133module_init(ccid3_module_init);
2134
2135static __exit void ccid3_module_exit(void)
2136{
2137 ccid_unregister(&ccid3);
2138
2139 if (ccid3_tx_hist_slab != NULL) {
2140 kmem_cache_destroy(ccid3_tx_hist_slab);
2141 ccid3_tx_hist_slab = NULL;
2142 }
2143 if (ccid3_rx_hist_slab != NULL) {
2144 kmem_cache_destroy(ccid3_rx_hist_slab);
2145 ccid3_rx_hist_slab = NULL;
2146 }
2147 if (ccid3_loss_interval_hist_slab != NULL) {
2148 kmem_cache_destroy(ccid3_loss_interval_hist_slab);
2149 ccid3_loss_interval_hist_slab = NULL;
2150 }
2151}
2152module_exit(ccid3_module_exit);
2153
2154MODULE_AUTHOR("Ian McDonald <iam4@cs.waikato.ac.nz> & Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
2155MODULE_DESCRIPTION("DCCP TFRC CCID3 CCID");
2156MODULE_LICENSE("GPL");
2157MODULE_ALIAS("net-dccp-ccid-3");