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