]> err.no Git - linux-2.6/blob - net/dccp/ccids/ccid2.c
[CCID2]: Fix sequence number arithmetic/comparisons
[linux-2.6] / net / dccp / ccids / ccid2.c
1 /*
2  *  net/dccp/ccids/ccid2.c
3  *
4  *  Copyright (c) 2005, 2006 Andrea Bittau <a.bittau@cs.ucl.ac.uk>
5  *
6  *  Changes to meet Linux coding standards, and DCCP infrastructure fixes.
7  *
8  *  Copyright (c) 2006 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25 /*
26  * This implementation should follow RFC 4341
27  */
28
29 #include "../ccid.h"
30 #include "../dccp.h"
31 #include "ccid2.h"
32
33
34 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG
35 static int ccid2_debug;
36 #define ccid2_pr_debug(format, a...)    DCCP_PR_DEBUG(ccid2_debug, format, ##a)
37
38 static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx)
39 {
40         int len = 0;
41         int pipe = 0;
42         struct ccid2_seq *seqp = hctx->ccid2hctx_seqh;
43
44         /* there is data in the chain */
45         if (seqp != hctx->ccid2hctx_seqt) {
46                 seqp = seqp->ccid2s_prev;
47                 len++;
48                 if (!seqp->ccid2s_acked)
49                         pipe++;
50
51                 while (seqp != hctx->ccid2hctx_seqt) {
52                         struct ccid2_seq *prev = seqp->ccid2s_prev;
53
54                         len++;
55                         if (!prev->ccid2s_acked)
56                                 pipe++;
57
58                         /* packets are sent sequentially */
59                         BUG_ON(dccp_delta_seqno(seqp->ccid2s_seq,
60                                                 prev->ccid2s_seq ) >= 0);
61                         BUG_ON(time_before(seqp->ccid2s_sent,
62                                            prev->ccid2s_sent));
63
64                         seqp = prev;
65                 }
66         }
67
68         BUG_ON(pipe != hctx->ccid2hctx_pipe);
69         ccid2_pr_debug("len of chain=%d\n", len);
70
71         do {
72                 seqp = seqp->ccid2s_prev;
73                 len++;
74         } while (seqp != hctx->ccid2hctx_seqh);
75
76         ccid2_pr_debug("total len=%d\n", len);
77         BUG_ON(len != hctx->ccid2hctx_seqbufc * CCID2_SEQBUF_LEN);
78 }
79 #else
80 #define ccid2_pr_debug(format, a...)
81 #define ccid2_hc_tx_check_sanity(hctx)
82 #endif
83
84 static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hctx)
85 {
86         struct ccid2_seq *seqp;
87         int i;
88
89         /* check if we have space to preserve the pointer to the buffer */
90         if (hctx->ccid2hctx_seqbufc >= (sizeof(hctx->ccid2hctx_seqbuf) /
91                                         sizeof(struct ccid2_seq*)))
92                 return -ENOMEM;
93
94         /* allocate buffer and initialize linked list */
95         seqp = kmalloc(CCID2_SEQBUF_LEN * sizeof(struct ccid2_seq), gfp_any());
96         if (seqp == NULL)
97                 return -ENOMEM;
98
99         for (i = 0; i < (CCID2_SEQBUF_LEN - 1); i++) {
100                 seqp[i].ccid2s_next = &seqp[i + 1];
101                 seqp[i + 1].ccid2s_prev = &seqp[i];
102         }
103         seqp[CCID2_SEQBUF_LEN - 1].ccid2s_next = seqp;
104         seqp->ccid2s_prev = &seqp[CCID2_SEQBUF_LEN - 1];
105
106         /* This is the first allocation.  Initiate the head and tail.  */
107         if (hctx->ccid2hctx_seqbufc == 0)
108                 hctx->ccid2hctx_seqh = hctx->ccid2hctx_seqt = seqp;
109         else {
110                 /* link the existing list with the one we just created */
111                 hctx->ccid2hctx_seqh->ccid2s_next = seqp;
112                 seqp->ccid2s_prev = hctx->ccid2hctx_seqh;
113
114                 hctx->ccid2hctx_seqt->ccid2s_prev = &seqp[CCID2_SEQBUF_LEN - 1];
115                 seqp[CCID2_SEQBUF_LEN - 1].ccid2s_next = hctx->ccid2hctx_seqt;
116         }
117
118         /* store the original pointer to the buffer so we can free it */
119         hctx->ccid2hctx_seqbuf[hctx->ccid2hctx_seqbufc] = seqp;
120         hctx->ccid2hctx_seqbufc++;
121
122         return 0;
123 }
124
125 static int ccid2_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
126 {
127         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
128
129         ccid2_pr_debug("pipe=%d cwnd=%d\n", hctx->ccid2hctx_pipe,
130                        hctx->ccid2hctx_cwnd);
131
132         if (hctx->ccid2hctx_pipe < hctx->ccid2hctx_cwnd) {
133                 /* OK we can send... make sure previous packet was sent off */
134                 if (!hctx->ccid2hctx_sendwait) {
135                         hctx->ccid2hctx_sendwait = 1;
136                         return 0;
137                 }
138         }
139
140         return 1; /* XXX CCID should dequeue when ready instead of polling */
141 }
142
143 static void ccid2_change_l_ack_ratio(struct sock *sk, int val)
144 {
145         struct dccp_sock *dp = dccp_sk(sk);
146         /*
147          * XXX I don't really agree with val != 2.  If cwnd is 1, ack ratio
148          * should be 1... it shouldn't be allowed to become 2.
149          * -sorbo.
150          */
151         if (val != 2) {
152                 const struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
153                 int max = hctx->ccid2hctx_cwnd / 2;
154
155                 /* round up */
156                 if (hctx->ccid2hctx_cwnd & 1)
157                         max++;
158
159                 if (val > max)
160                         val = max;
161         }
162
163         ccid2_pr_debug("changing local ack ratio to %d\n", val);
164         WARN_ON(val <= 0);
165         dp->dccps_l_ack_ratio = val;
166 }
167
168 static void ccid2_change_cwnd(struct ccid2_hc_tx_sock *hctx, u32 val)
169 {
170         /* XXX do we need to change ack ratio? */
171         hctx->ccid2hctx_cwnd = val? : 1;
172         ccid2_pr_debug("changed cwnd to %u\n", hctx->ccid2hctx_cwnd);
173 }
174
175 static void ccid2_change_srtt(struct ccid2_hc_tx_sock *hctx, long val)
176 {
177         ccid2_pr_debug("change SRTT to %ld\n", val);
178         hctx->ccid2hctx_srtt = val;
179 }
180
181 static void ccid2_change_pipe(struct ccid2_hc_tx_sock *hctx, long val)
182 {
183         hctx->ccid2hctx_pipe = val;
184 }
185
186 static void ccid2_start_rto_timer(struct sock *sk);
187
188 static void ccid2_hc_tx_rto_expire(unsigned long data)
189 {
190         struct sock *sk = (struct sock *)data;
191         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
192         long s;
193
194         bh_lock_sock(sk);
195         if (sock_owned_by_user(sk)) {
196                 sk_reset_timer(sk, &hctx->ccid2hctx_rtotimer,
197                                jiffies + HZ / 5);
198                 goto out;
199         }
200
201         ccid2_pr_debug("RTO_EXPIRE\n");
202
203         ccid2_hc_tx_check_sanity(hctx);
204
205         /* back-off timer */
206         hctx->ccid2hctx_rto <<= 1;
207
208         s = hctx->ccid2hctx_rto / HZ;
209         if (s > 60)
210                 hctx->ccid2hctx_rto = 60 * HZ;
211
212         ccid2_start_rto_timer(sk);
213
214         /* adjust pipe, cwnd etc */
215         ccid2_change_pipe(hctx, 0);
216         hctx->ccid2hctx_ssthresh = hctx->ccid2hctx_cwnd >> 1;
217         if (hctx->ccid2hctx_ssthresh < 2)
218                 hctx->ccid2hctx_ssthresh = 2;
219         ccid2_change_cwnd(hctx, 1);
220
221         /* clear state about stuff we sent */
222         hctx->ccid2hctx_seqt    = hctx->ccid2hctx_seqh;
223         hctx->ccid2hctx_ssacks  = 0;
224         hctx->ccid2hctx_acks    = 0;
225         hctx->ccid2hctx_sent    = 0;
226
227         /* clear ack ratio state. */
228         hctx->ccid2hctx_arsent   = 0;
229         hctx->ccid2hctx_ackloss  = 0;
230         hctx->ccid2hctx_rpseq    = 0;
231         hctx->ccid2hctx_rpdupack = -1;
232         ccid2_change_l_ack_ratio(sk, 1);
233         ccid2_hc_tx_check_sanity(hctx);
234 out:
235         bh_unlock_sock(sk);
236         sock_put(sk);
237 }
238
239 static void ccid2_start_rto_timer(struct sock *sk)
240 {
241         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
242
243         ccid2_pr_debug("setting RTO timeout=%ld\n", hctx->ccid2hctx_rto);
244
245         BUG_ON(timer_pending(&hctx->ccid2hctx_rtotimer));
246         sk_reset_timer(sk, &hctx->ccid2hctx_rtotimer,
247                        jiffies + hctx->ccid2hctx_rto);
248 }
249
250 static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
251 {
252         struct dccp_sock *dp = dccp_sk(sk);
253         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
254         struct ccid2_seq *next;
255         u64 seq;
256
257         ccid2_hc_tx_check_sanity(hctx);
258
259         BUG_ON(!hctx->ccid2hctx_sendwait);
260         hctx->ccid2hctx_sendwait = 0;
261         ccid2_change_pipe(hctx, hctx->ccid2hctx_pipe + 1);
262         BUG_ON(hctx->ccid2hctx_pipe < 0);
263
264         /* There is an issue.  What if another packet is sent between
265          * packet_send() and packet_sent().  Then the sequence number would be
266          * wrong.
267          * -sorbo.
268          */
269         seq = dp->dccps_gss;
270
271         hctx->ccid2hctx_seqh->ccid2s_seq   = seq;
272         hctx->ccid2hctx_seqh->ccid2s_acked = 0;
273         hctx->ccid2hctx_seqh->ccid2s_sent  = jiffies;
274
275         next = hctx->ccid2hctx_seqh->ccid2s_next;
276         /* check if we need to alloc more space */
277         if (next == hctx->ccid2hctx_seqt) {
278                 if (ccid2_hc_tx_alloc_seq(hctx)) {
279                         DCCP_CRIT("packet history - out of memory!");
280                         /* FIXME: find a more graceful way to bail out */
281                         return;
282                 }
283                 next = hctx->ccid2hctx_seqh->ccid2s_next;
284                 BUG_ON(next == hctx->ccid2hctx_seqt);
285         }
286         hctx->ccid2hctx_seqh = next;
287
288         ccid2_pr_debug("cwnd=%d pipe=%d\n", hctx->ccid2hctx_cwnd,
289                        hctx->ccid2hctx_pipe);
290
291         hctx->ccid2hctx_sent++;
292
293         /* Ack Ratio.  Need to maintain a concept of how many windows we sent */
294         hctx->ccid2hctx_arsent++;
295         /* We had an ack loss in this window... */
296         if (hctx->ccid2hctx_ackloss) {
297                 if (hctx->ccid2hctx_arsent >= hctx->ccid2hctx_cwnd) {
298                         hctx->ccid2hctx_arsent  = 0;
299                         hctx->ccid2hctx_ackloss = 0;
300                 }
301         } else {
302                 /* No acks lost up to now... */
303                 /* decrease ack ratio if enough packets were sent */
304                 if (dp->dccps_l_ack_ratio > 1) {
305                         /* XXX don't calculate denominator each time */
306                         int denom = dp->dccps_l_ack_ratio * dp->dccps_l_ack_ratio -
307                                     dp->dccps_l_ack_ratio;
308
309                         denom = hctx->ccid2hctx_cwnd * hctx->ccid2hctx_cwnd / denom;
310
311                         if (hctx->ccid2hctx_arsent >= denom) {
312                                 ccid2_change_l_ack_ratio(sk, dp->dccps_l_ack_ratio - 1);
313                                 hctx->ccid2hctx_arsent = 0;
314                         }
315                 } else {
316                         /* we can't increase ack ratio further [1] */
317                         hctx->ccid2hctx_arsent = 0; /* or maybe set it to cwnd*/
318                 }
319         }
320
321         /* setup RTO timer */
322         if (!timer_pending(&hctx->ccid2hctx_rtotimer))
323                 ccid2_start_rto_timer(sk);
324
325 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG
326         ccid2_pr_debug("pipe=%d\n", hctx->ccid2hctx_pipe);
327         ccid2_pr_debug("Sent: seq=%llu\n", (unsigned long long)seq);
328         do {
329                 struct ccid2_seq *seqp = hctx->ccid2hctx_seqt;
330
331                 while (seqp != hctx->ccid2hctx_seqh) {
332                         ccid2_pr_debug("out seq=%llu acked=%d time=%lu\n",
333                                        (unsigned long long)seqp->ccid2s_seq,
334                                        seqp->ccid2s_acked, seqp->ccid2s_sent);
335                         seqp = seqp->ccid2s_next;
336                 }
337         } while (0);
338         ccid2_pr_debug("=========\n");
339         ccid2_hc_tx_check_sanity(hctx);
340 #endif
341 }
342
343 /* XXX Lame code duplication!
344  * returns -1 if none was found.
345  * else returns the next offset to use in the function call.
346  */
347 static int ccid2_ackvector(struct sock *sk, struct sk_buff *skb, int offset,
348                            unsigned char **vec, unsigned char *veclen)
349 {
350         const struct dccp_hdr *dh = dccp_hdr(skb);
351         unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb);
352         unsigned char *opt_ptr;
353         const unsigned char *opt_end = (unsigned char *)dh +
354                                         (dh->dccph_doff * 4);
355         unsigned char opt, len;
356         unsigned char *value;
357
358         BUG_ON(offset < 0);
359         options += offset;
360         opt_ptr = options;
361         if (opt_ptr >= opt_end)
362                 return -1;
363
364         while (opt_ptr != opt_end) {
365                 opt   = *opt_ptr++;
366                 len   = 0;
367                 value = NULL;
368
369                 /* Check if this isn't a single byte option */
370                 if (opt > DCCPO_MAX_RESERVED) {
371                         if (opt_ptr == opt_end)
372                                 goto out_invalid_option;
373
374                         len = *opt_ptr++;
375                         if (len < 3)
376                                 goto out_invalid_option;
377                         /*
378                          * Remove the type and len fields, leaving
379                          * just the value size
380                          */
381                         len     -= 2;
382                         value   = opt_ptr;
383                         opt_ptr += len;
384
385                         if (opt_ptr > opt_end)
386                                 goto out_invalid_option;
387                 }
388
389                 switch (opt) {
390                 case DCCPO_ACK_VECTOR_0:
391                 case DCCPO_ACK_VECTOR_1:
392                         *vec    = value;
393                         *veclen = len;
394                         return offset + (opt_ptr - options);
395                 }
396         }
397
398         return -1;
399
400 out_invalid_option:
401         DCCP_BUG("Invalid option - this should not happen (previous parsing)!");
402         return -1;
403 }
404
405 static void ccid2_hc_tx_kill_rto_timer(struct sock *sk)
406 {
407         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
408
409         sk_stop_timer(sk, &hctx->ccid2hctx_rtotimer);
410         ccid2_pr_debug("deleted RTO timer\n");
411 }
412
413 static inline void ccid2_new_ack(struct sock *sk,
414                                  struct ccid2_seq *seqp,
415                                  unsigned int *maxincr)
416 {
417         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
418
419         /* slow start */
420         if (hctx->ccid2hctx_cwnd < hctx->ccid2hctx_ssthresh) {
421                 hctx->ccid2hctx_acks = 0;
422
423                 /* We can increase cwnd at most maxincr [ack_ratio/2] */
424                 if (*maxincr) {
425                         /* increase every 2 acks */
426                         hctx->ccid2hctx_ssacks++;
427                         if (hctx->ccid2hctx_ssacks == 2) {
428                                 ccid2_change_cwnd(hctx, hctx->ccid2hctx_cwnd+1);
429                                 hctx->ccid2hctx_ssacks = 0;
430                                 *maxincr = *maxincr - 1;
431                         }
432                 } else {
433                         /* increased cwnd enough for this single ack */
434                         hctx->ccid2hctx_ssacks = 0;
435                 }
436         } else {
437                 hctx->ccid2hctx_ssacks = 0;
438                 hctx->ccid2hctx_acks++;
439
440                 if (hctx->ccid2hctx_acks >= hctx->ccid2hctx_cwnd) {
441                         ccid2_change_cwnd(hctx, hctx->ccid2hctx_cwnd + 1);
442                         hctx->ccid2hctx_acks = 0;
443                 }
444         }
445
446         /* update RTO */
447         if (hctx->ccid2hctx_srtt == -1 ||
448             time_after(jiffies, hctx->ccid2hctx_lastrtt + hctx->ccid2hctx_srtt)) {
449                 unsigned long r = (long)jiffies - (long)seqp->ccid2s_sent;
450                 int s;
451
452                 /* first measurement */
453                 if (hctx->ccid2hctx_srtt == -1) {
454                         ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n",
455                                        r, jiffies,
456                                        (unsigned long long)seqp->ccid2s_seq);
457                         ccid2_change_srtt(hctx, r);
458                         hctx->ccid2hctx_rttvar = r >> 1;
459                 } else {
460                         /* RTTVAR */
461                         long tmp = hctx->ccid2hctx_srtt - r;
462                         long srtt;
463
464                         if (tmp < 0)
465                                 tmp *= -1;
466
467                         tmp >>= 2;
468                         hctx->ccid2hctx_rttvar *= 3;
469                         hctx->ccid2hctx_rttvar >>= 2;
470                         hctx->ccid2hctx_rttvar += tmp;
471
472                         /* SRTT */
473                         srtt = hctx->ccid2hctx_srtt;
474                         srtt *= 7;
475                         srtt >>= 3;
476                         tmp = r >> 3;
477                         srtt += tmp;
478                         ccid2_change_srtt(hctx, srtt);
479                 }
480                 s = hctx->ccid2hctx_rttvar << 2;
481                 /* clock granularity is 1 when based on jiffies */
482                 if (!s)
483                         s = 1;
484                 hctx->ccid2hctx_rto = hctx->ccid2hctx_srtt + s;
485
486                 /* must be at least a second */
487                 s = hctx->ccid2hctx_rto / HZ;
488                 /* DCCP doesn't require this [but I like it cuz my code sux] */
489 #if 1
490                 if (s < 1)
491                         hctx->ccid2hctx_rto = HZ;
492 #endif
493                 /* max 60 seconds */
494                 if (s > 60)
495                         hctx->ccid2hctx_rto = HZ * 60;
496
497                 hctx->ccid2hctx_lastrtt = jiffies;
498
499                 ccid2_pr_debug("srtt: %ld rttvar: %ld rto: %ld (HZ=%d) R=%lu\n",
500                                hctx->ccid2hctx_srtt, hctx->ccid2hctx_rttvar,
501                                hctx->ccid2hctx_rto, HZ, r);
502                 hctx->ccid2hctx_sent = 0;
503         }
504
505         /* we got a new ack, so re-start RTO timer */
506         ccid2_hc_tx_kill_rto_timer(sk);
507         ccid2_start_rto_timer(sk);
508 }
509
510 static void ccid2_hc_tx_dec_pipe(struct sock *sk)
511 {
512         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
513
514         ccid2_change_pipe(hctx, hctx->ccid2hctx_pipe-1);
515         BUG_ON(hctx->ccid2hctx_pipe < 0);
516
517         if (hctx->ccid2hctx_pipe == 0)
518                 ccid2_hc_tx_kill_rto_timer(sk);
519 }
520
521 static void ccid2_congestion_event(struct ccid2_hc_tx_sock *hctx,
522                                    struct ccid2_seq *seqp)
523 {
524         if (time_before(seqp->ccid2s_sent, hctx->ccid2hctx_last_cong)) {
525                 ccid2_pr_debug("Multiple losses in an RTT---treating as one\n");
526                 return;
527         }
528
529         hctx->ccid2hctx_last_cong = jiffies;
530
531         ccid2_change_cwnd(hctx, hctx->ccid2hctx_cwnd >> 1);
532         hctx->ccid2hctx_ssthresh = hctx->ccid2hctx_cwnd;
533         if (hctx->ccid2hctx_ssthresh < 2)
534                 hctx->ccid2hctx_ssthresh = 2;
535 }
536
537 static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
538 {
539         struct dccp_sock *dp = dccp_sk(sk);
540         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
541         u64 ackno, seqno;
542         struct ccid2_seq *seqp;
543         unsigned char *vector;
544         unsigned char veclen;
545         int offset = 0;
546         int done = 0;
547         unsigned int maxincr = 0;
548
549         ccid2_hc_tx_check_sanity(hctx);
550         /* check reverse path congestion */
551         seqno = DCCP_SKB_CB(skb)->dccpd_seq;
552
553         /* XXX this whole "algorithm" is broken.  Need to fix it to keep track
554          * of the seqnos of the dupacks so that rpseq and rpdupack are correct
555          * -sorbo.
556          */
557         /* need to bootstrap */
558         if (hctx->ccid2hctx_rpdupack == -1) {
559                 hctx->ccid2hctx_rpdupack = 0;
560                 hctx->ccid2hctx_rpseq = seqno;
561         } else {
562                 /* check if packet is consecutive */
563                 if (dccp_delta_seqno(hctx->ccid2hctx_rpseq, seqno) == 1)
564                         hctx->ccid2hctx_rpseq = seqno;
565                 /* it's a later packet */
566                 else if (after48(seqno, hctx->ccid2hctx_rpseq)) {
567                         hctx->ccid2hctx_rpdupack++;
568
569                         /* check if we got enough dupacks */
570                         if (hctx->ccid2hctx_rpdupack >=
571                             hctx->ccid2hctx_numdupack) {
572                                 hctx->ccid2hctx_rpdupack = -1; /* XXX lame */
573                                 hctx->ccid2hctx_rpseq = 0;
574
575                                 ccid2_change_l_ack_ratio(sk, dp->dccps_l_ack_ratio << 1);
576                         }
577                 }
578         }
579
580         /* check forward path congestion */
581         /* still didn't send out new data packets */
582         if (hctx->ccid2hctx_seqh == hctx->ccid2hctx_seqt)
583                 return;
584
585         switch (DCCP_SKB_CB(skb)->dccpd_type) {
586         case DCCP_PKT_ACK:
587         case DCCP_PKT_DATAACK:
588                 break;
589         default:
590                 return;
591         }
592
593         ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq;
594         if (after48(ackno, hctx->ccid2hctx_high_ack))
595                 hctx->ccid2hctx_high_ack = ackno;
596
597         seqp = hctx->ccid2hctx_seqt;
598         while (before48(seqp->ccid2s_seq, ackno)) {
599                 seqp = seqp->ccid2s_next;
600                 if (seqp == hctx->ccid2hctx_seqh) {
601                         seqp = hctx->ccid2hctx_seqh->ccid2s_prev;
602                         break;
603                 }
604         }
605
606         /* If in slow-start, cwnd can increase at most Ack Ratio / 2 packets for
607          * this single ack.  I round up.
608          * -sorbo.
609          */
610         maxincr = dp->dccps_l_ack_ratio >> 1;
611         maxincr++;
612
613         /* go through all ack vectors */
614         while ((offset = ccid2_ackvector(sk, skb, offset,
615                                          &vector, &veclen)) != -1) {
616                 /* go through this ack vector */
617                 while (veclen--) {
618                         const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK;
619                         u64 ackno_end_rl = SUB48(ackno, rl);
620
621                         ccid2_pr_debug("ackvec start:%llu end:%llu\n",
622                                        (unsigned long long)ackno,
623                                        (unsigned long long)ackno_end_rl);
624                         /* if the seqno we are analyzing is larger than the
625                          * current ackno, then move towards the tail of our
626                          * seqnos.
627                          */
628                         while (after48(seqp->ccid2s_seq, ackno)) {
629                                 if (seqp == hctx->ccid2hctx_seqt) {
630                                         done = 1;
631                                         break;
632                                 }
633                                 seqp = seqp->ccid2s_prev;
634                         }
635                         if (done)
636                                 break;
637
638                         /* check all seqnos in the range of the vector
639                          * run length
640                          */
641                         while (between48(seqp->ccid2s_seq,ackno_end_rl,ackno)) {
642                                 const u8 state = *vector &
643                                                  DCCP_ACKVEC_STATE_MASK;
644
645                                 /* new packet received or marked */
646                                 if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED &&
647                                     !seqp->ccid2s_acked) {
648                                         if (state ==
649                                             DCCP_ACKVEC_STATE_ECN_MARKED) {
650                                                 ccid2_congestion_event(hctx,
651                                                                        seqp);
652                                         } else
653                                                 ccid2_new_ack(sk, seqp,
654                                                               &maxincr);
655
656                                         seqp->ccid2s_acked = 1;
657                                         ccid2_pr_debug("Got ack for %llu\n",
658                                                        (unsigned long long)seqp->ccid2s_seq);
659                                         ccid2_hc_tx_dec_pipe(sk);
660                                 }
661                                 if (seqp == hctx->ccid2hctx_seqt) {
662                                         done = 1;
663                                         break;
664                                 }
665                                 seqp = seqp->ccid2s_prev;
666                         }
667                         if (done)
668                                 break;
669
670                         ackno = SUB48(ackno_end_rl, 1);
671                         vector++;
672                 }
673                 if (done)
674                         break;
675         }
676
677         /* The state about what is acked should be correct now
678          * Check for NUMDUPACK
679          */
680         seqp = hctx->ccid2hctx_seqt;
681         while (before48(seqp->ccid2s_seq, hctx->ccid2hctx_high_ack)) {
682                 seqp = seqp->ccid2s_next;
683                 if (seqp == hctx->ccid2hctx_seqh) {
684                         seqp = hctx->ccid2hctx_seqh->ccid2s_prev;
685                         break;
686                 }
687         }
688         done = 0;
689         while (1) {
690                 if (seqp->ccid2s_acked) {
691                         done++;
692                         if (done == hctx->ccid2hctx_numdupack)
693                                 break;
694                 }
695                 if (seqp == hctx->ccid2hctx_seqt)
696                         break;
697                 seqp = seqp->ccid2s_prev;
698         }
699
700         /* If there are at least 3 acknowledgements, anything unacknowledged
701          * below the last sequence number is considered lost
702          */
703         if (done == hctx->ccid2hctx_numdupack) {
704                 struct ccid2_seq *last_acked = seqp;
705
706                 /* check for lost packets */
707                 while (1) {
708                         if (!seqp->ccid2s_acked) {
709                                 ccid2_pr_debug("Packet lost: %llu\n",
710                                                (unsigned long long)seqp->ccid2s_seq);
711                                 /* XXX need to traverse from tail -> head in
712                                  * order to detect multiple congestion events in
713                                  * one ack vector.
714                                  */
715                                 ccid2_congestion_event(hctx, seqp);
716                                 ccid2_hc_tx_dec_pipe(sk);
717                         }
718                         if (seqp == hctx->ccid2hctx_seqt)
719                                 break;
720                         seqp = seqp->ccid2s_prev;
721                 }
722
723                 hctx->ccid2hctx_seqt = last_acked;
724         }
725
726         /* trim acked packets in tail */
727         while (hctx->ccid2hctx_seqt != hctx->ccid2hctx_seqh) {
728                 if (!hctx->ccid2hctx_seqt->ccid2s_acked)
729                         break;
730
731                 hctx->ccid2hctx_seqt = hctx->ccid2hctx_seqt->ccid2s_next;
732         }
733
734         ccid2_hc_tx_check_sanity(hctx);
735 }
736
737 static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
738 {
739         struct ccid2_hc_tx_sock *hctx = ccid_priv(ccid);
740
741         ccid2_change_cwnd(hctx, 1);
742         /* Initialize ssthresh to infinity.  This means that we will exit the
743          * initial slow-start after the first packet loss.  This is what we
744          * want.
745          */
746         hctx->ccid2hctx_ssthresh  = ~0;
747         hctx->ccid2hctx_numdupack = 3;
748
749         /* XXX init ~ to window size... */
750         if (ccid2_hc_tx_alloc_seq(hctx))
751                 return -ENOMEM;
752
753         hctx->ccid2hctx_rto      = 3 * HZ;
754         ccid2_change_srtt(hctx, -1);
755         hctx->ccid2hctx_rttvar   = -1;
756         hctx->ccid2hctx_rpdupack = -1;
757         hctx->ccid2hctx_last_cong = jiffies;
758         setup_timer(&hctx->ccid2hctx_rtotimer, ccid2_hc_tx_rto_expire,
759                         (unsigned long)sk);
760
761         ccid2_hc_tx_check_sanity(hctx);
762         return 0;
763 }
764
765 static void ccid2_hc_tx_exit(struct sock *sk)
766 {
767         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
768         int i;
769
770         ccid2_hc_tx_kill_rto_timer(sk);
771
772         for (i = 0; i < hctx->ccid2hctx_seqbufc; i++)
773                 kfree(hctx->ccid2hctx_seqbuf[i]);
774         hctx->ccid2hctx_seqbufc = 0;
775 }
776
777 static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
778 {
779         const struct dccp_sock *dp = dccp_sk(sk);
780         struct ccid2_hc_rx_sock *hcrx = ccid2_hc_rx_sk(sk);
781
782         switch (DCCP_SKB_CB(skb)->dccpd_type) {
783         case DCCP_PKT_DATA:
784         case DCCP_PKT_DATAACK:
785                 hcrx->ccid2hcrx_data++;
786                 if (hcrx->ccid2hcrx_data >= dp->dccps_r_ack_ratio) {
787                         dccp_send_ack(sk);
788                         hcrx->ccid2hcrx_data = 0;
789                 }
790                 break;
791         }
792 }
793
794 static struct ccid_operations ccid2 = {
795         .ccid_id                = DCCPC_CCID2,
796         .ccid_name              = "ccid2",
797         .ccid_owner             = THIS_MODULE,
798         .ccid_hc_tx_obj_size    = sizeof(struct ccid2_hc_tx_sock),
799         .ccid_hc_tx_init        = ccid2_hc_tx_init,
800         .ccid_hc_tx_exit        = ccid2_hc_tx_exit,
801         .ccid_hc_tx_send_packet = ccid2_hc_tx_send_packet,
802         .ccid_hc_tx_packet_sent = ccid2_hc_tx_packet_sent,
803         .ccid_hc_tx_packet_recv = ccid2_hc_tx_packet_recv,
804         .ccid_hc_rx_obj_size    = sizeof(struct ccid2_hc_rx_sock),
805         .ccid_hc_rx_packet_recv = ccid2_hc_rx_packet_recv,
806 };
807
808 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG
809 module_param(ccid2_debug, bool, 0444);
810 MODULE_PARM_DESC(ccid2_debug, "Enable debug messages");
811 #endif
812
813 static __init int ccid2_module_init(void)
814 {
815         return ccid_register(&ccid2);
816 }
817 module_init(ccid2_module_init);
818
819 static __exit void ccid2_module_exit(void)
820 {
821         ccid_unregister(&ccid2);
822 }
823 module_exit(ccid2_module_exit);
824
825 MODULE_AUTHOR("Andrea Bittau <a.bittau@cs.ucl.ac.uk>");
826 MODULE_DESCRIPTION("DCCP TCP-Like (CCID2) CCID");
827 MODULE_LICENSE("GPL");
828 MODULE_ALIAS("net-dccp-ccid-2");