]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - net/dccp/ccids/ccid2.c
dccp ccid-2: Ack Vector interface clean-up
[linux-2.6-omap-h63xx.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 RFC 4341
27  */
28 #include "../feat.h"
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->seqh;
43
44         /* there is data in the chain */
45         if (seqp != hctx->seqt) {
46                 seqp = seqp->ccid2s_prev;
47                 len++;
48                 if (!seqp->ccid2s_acked)
49                         pipe++;
50
51                 while (seqp != hctx->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->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->seqh);
75
76         ccid2_pr_debug("total len=%d\n", len);
77         BUG_ON(len != hctx->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->seqbufc >= sizeof(hctx->seqbuf) / sizeof(struct ccid2_seq *))
91                 return -ENOMEM;
92
93         /* allocate buffer and initialize linked list */
94         seqp = kmalloc(CCID2_SEQBUF_LEN * sizeof(struct ccid2_seq), gfp_any());
95         if (seqp == NULL)
96                 return -ENOMEM;
97
98         for (i = 0; i < (CCID2_SEQBUF_LEN - 1); i++) {
99                 seqp[i].ccid2s_next = &seqp[i + 1];
100                 seqp[i + 1].ccid2s_prev = &seqp[i];
101         }
102         seqp[CCID2_SEQBUF_LEN - 1].ccid2s_next = seqp;
103         seqp->ccid2s_prev = &seqp[CCID2_SEQBUF_LEN - 1];
104
105         /* This is the first allocation.  Initiate the head and tail.  */
106         if (hctx->seqbufc == 0)
107                 hctx->seqh = hctx->seqt = seqp;
108         else {
109                 /* link the existing list with the one we just created */
110                 hctx->seqh->ccid2s_next = seqp;
111                 seqp->ccid2s_prev = hctx->seqh;
112
113                 hctx->seqt->ccid2s_prev = &seqp[CCID2_SEQBUF_LEN - 1];
114                 seqp[CCID2_SEQBUF_LEN - 1].ccid2s_next = hctx->seqt;
115         }
116
117         /* store the original pointer to the buffer so we can free it */
118         hctx->seqbuf[hctx->seqbufc] = seqp;
119         hctx->seqbufc++;
120
121         return 0;
122 }
123
124 static int ccid2_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
125 {
126         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
127
128         if (hctx->pipe < hctx->cwnd)
129                 return 0;
130
131         return 1; /* XXX CCID should dequeue when ready instead of polling */
132 }
133
134 static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val)
135 {
136         struct dccp_sock *dp = dccp_sk(sk);
137         u32 max_ratio = DIV_ROUND_UP(ccid2_hc_tx_sk(sk)->cwnd, 2);
138
139         /*
140          * Ensure that Ack Ratio does not exceed ceil(cwnd/2), which is (2) from
141          * RFC 4341, 6.1.2. We ignore the statement that Ack Ratio 2 is always
142          * acceptable since this causes starvation/deadlock whenever cwnd < 2.
143          * The same problem arises when Ack Ratio is 0 (ie. Ack Ratio disabled).
144          */
145         if (val == 0 || val > max_ratio) {
146                 DCCP_WARN("Limiting Ack Ratio (%u) to %u\n", val, max_ratio);
147                 val = max_ratio;
148         }
149         if (val > DCCPF_ACK_RATIO_MAX)
150                 val = DCCPF_ACK_RATIO_MAX;
151
152         if (val == dp->dccps_l_ack_ratio)
153                 return;
154
155         ccid2_pr_debug("changing local ack ratio to %u\n", val);
156         dp->dccps_l_ack_ratio = val;
157 }
158
159 static void ccid2_change_srtt(struct ccid2_hc_tx_sock *hctx, long val)
160 {
161         ccid2_pr_debug("change SRTT to %ld\n", val);
162         hctx->srtt = val;
163 }
164
165 static void ccid2_start_rto_timer(struct sock *sk);
166
167 static void ccid2_hc_tx_rto_expire(unsigned long data)
168 {
169         struct sock *sk = (struct sock *)data;
170         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
171         long s;
172
173         bh_lock_sock(sk);
174         if (sock_owned_by_user(sk)) {
175                 sk_reset_timer(sk, &hctx->rtotimer, jiffies + HZ / 5);
176                 goto out;
177         }
178
179         ccid2_pr_debug("RTO_EXPIRE\n");
180
181         ccid2_hc_tx_check_sanity(hctx);
182
183         /* back-off timer */
184         hctx->rto <<= 1;
185
186         s = hctx->rto / HZ;
187         if (s > 60)
188                 hctx->rto = 60 * HZ;
189
190         ccid2_start_rto_timer(sk);
191
192         /* adjust pipe, cwnd etc */
193         hctx->ssthresh = hctx->cwnd / 2;
194         if (hctx->ssthresh < 2)
195                 hctx->ssthresh = 2;
196         hctx->cwnd = 1;
197         hctx->pipe = 0;
198
199         /* clear state about stuff we sent */
200         hctx->seqt = hctx->seqh;
201         hctx->packets_acked = 0;
202
203         /* clear ack ratio state. */
204         hctx->rpseq    = 0;
205         hctx->rpdupack = -1;
206         ccid2_change_l_ack_ratio(sk, 1);
207         ccid2_hc_tx_check_sanity(hctx);
208 out:
209         bh_unlock_sock(sk);
210         sock_put(sk);
211 }
212
213 static void ccid2_start_rto_timer(struct sock *sk)
214 {
215         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
216
217         ccid2_pr_debug("setting RTO timeout=%ld\n", hctx->rto);
218
219         BUG_ON(timer_pending(&hctx->rtotimer));
220         sk_reset_timer(sk, &hctx->rtotimer,
221                        jiffies + hctx->rto);
222 }
223
224 static void ccid2_hc_tx_packet_sent(struct sock *sk, unsigned int len)
225 {
226         struct dccp_sock *dp = dccp_sk(sk);
227         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
228         struct ccid2_seq *next;
229
230         hctx->pipe++;
231
232         hctx->seqh->ccid2s_seq   = dp->dccps_gss;
233         hctx->seqh->ccid2s_acked = 0;
234         hctx->seqh->ccid2s_sent  = jiffies;
235
236         next = hctx->seqh->ccid2s_next;
237         /* check if we need to alloc more space */
238         if (next == hctx->seqt) {
239                 if (ccid2_hc_tx_alloc_seq(hctx)) {
240                         DCCP_CRIT("packet history - out of memory!");
241                         /* FIXME: find a more graceful way to bail out */
242                         return;
243                 }
244                 next = hctx->seqh->ccid2s_next;
245                 BUG_ON(next == hctx->seqt);
246         }
247         hctx->seqh = next;
248
249         ccid2_pr_debug("cwnd=%d pipe=%d\n", hctx->cwnd, hctx->pipe);
250
251         /*
252          * FIXME: The code below is broken and the variables have been removed
253          * from the socket struct. The `ackloss' variable was always set to 0,
254          * and with arsent there are several problems:
255          *  (i) it doesn't just count the number of Acks, but all sent packets;
256          *  (ii) it is expressed in # of packets, not # of windows, so the
257          *  comparison below uses the wrong formula: Appendix A of RFC 4341
258          *  comes up with the number K = cwnd / (R^2 - R) of consecutive windows
259          *  of data with no lost or marked Ack packets. If arsent were the # of
260          *  consecutive Acks received without loss, then Ack Ratio needs to be
261          *  decreased by 1 when
262          *            arsent >=  K * cwnd / R  =  cwnd^2 / (R^3 - R^2)
263          *  where cwnd / R is the number of Acks received per window of data
264          *  (cf. RFC 4341, App. A). The problems are that
265          *  - arsent counts other packets as well;
266          *  - the comparison uses a formula different from RFC 4341;
267          *  - computing a cubic/quadratic equation each time is too complicated.
268          *  Hence a different algorithm is needed.
269          */
270 #if 0
271         /* Ack Ratio.  Need to maintain a concept of how many windows we sent */
272         hctx->arsent++;
273         /* We had an ack loss in this window... */
274         if (hctx->ackloss) {
275                 if (hctx->arsent >= hctx->cwnd) {
276                         hctx->arsent  = 0;
277                         hctx->ackloss = 0;
278                 }
279         } else {
280                 /* No acks lost up to now... */
281                 /* decrease ack ratio if enough packets were sent */
282                 if (dp->dccps_l_ack_ratio > 1) {
283                         /* XXX don't calculate denominator each time */
284                         int denom = dp->dccps_l_ack_ratio * dp->dccps_l_ack_ratio -
285                                     dp->dccps_l_ack_ratio;
286
287                         denom = hctx->cwnd * hctx->cwnd / denom;
288
289                         if (hctx->arsent >= denom) {
290                                 ccid2_change_l_ack_ratio(sk, dp->dccps_l_ack_ratio - 1);
291                                 hctx->arsent = 0;
292                         }
293                 } else {
294                         /* we can't increase ack ratio further [1] */
295                         hctx->arsent = 0; /* or maybe set it to cwnd*/
296                 }
297         }
298 #endif
299
300         /* setup RTO timer */
301         if (!timer_pending(&hctx->rtotimer))
302                 ccid2_start_rto_timer(sk);
303
304 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG
305         do {
306                 struct ccid2_seq *seqp = hctx->seqt;
307
308                 while (seqp != hctx->seqh) {
309                         ccid2_pr_debug("out seq=%llu acked=%d time=%lu\n",
310                                        (unsigned long long)seqp->ccid2s_seq,
311                                        seqp->ccid2s_acked, seqp->ccid2s_sent);
312                         seqp = seqp->ccid2s_next;
313                 }
314         } while (0);
315         ccid2_pr_debug("=========\n");
316         ccid2_hc_tx_check_sanity(hctx);
317 #endif
318 }
319
320 /* XXX Lame code duplication!
321  * returns -1 if none was found.
322  * else returns the next offset to use in the function call.
323  */
324 static int ccid2_ackvector(struct sock *sk, struct sk_buff *skb, int offset,
325                            unsigned char **vec, unsigned char *veclen)
326 {
327         const struct dccp_hdr *dh = dccp_hdr(skb);
328         unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb);
329         unsigned char *opt_ptr;
330         const unsigned char *opt_end = (unsigned char *)dh +
331                                         (dh->dccph_doff * 4);
332         unsigned char opt, len;
333         unsigned char *value;
334
335         BUG_ON(offset < 0);
336         options += offset;
337         opt_ptr = options;
338         if (opt_ptr >= opt_end)
339                 return -1;
340
341         while (opt_ptr != opt_end) {
342                 opt   = *opt_ptr++;
343                 len   = 0;
344                 value = NULL;
345
346                 /* Check if this isn't a single byte option */
347                 if (opt > DCCPO_MAX_RESERVED) {
348                         if (opt_ptr == opt_end)
349                                 goto out_invalid_option;
350
351                         len = *opt_ptr++;
352                         if (len < 3)
353                                 goto out_invalid_option;
354                         /*
355                          * Remove the type and len fields, leaving
356                          * just the value size
357                          */
358                         len     -= 2;
359                         value   = opt_ptr;
360                         opt_ptr += len;
361
362                         if (opt_ptr > opt_end)
363                                 goto out_invalid_option;
364                 }
365
366                 switch (opt) {
367                 case DCCPO_ACK_VECTOR_0:
368                 case DCCPO_ACK_VECTOR_1:
369                         *vec    = value;
370                         *veclen = len;
371                         return offset + (opt_ptr - options);
372                 }
373         }
374
375         return -1;
376
377 out_invalid_option:
378         DCCP_BUG("Invalid option - this should not happen (previous parsing)!");
379         return -1;
380 }
381
382 static void ccid2_hc_tx_kill_rto_timer(struct sock *sk)
383 {
384         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
385
386         sk_stop_timer(sk, &hctx->rtotimer);
387         ccid2_pr_debug("deleted RTO timer\n");
388 }
389
390 static inline void ccid2_new_ack(struct sock *sk,
391                                  struct ccid2_seq *seqp,
392                                  unsigned int *maxincr)
393 {
394         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
395
396         if (hctx->cwnd < hctx->ssthresh) {
397                 if (*maxincr > 0 && ++hctx->packets_acked == 2) {
398                         hctx->cwnd += 1;
399                         *maxincr   -= 1;
400                         hctx->packets_acked = 0;
401                 }
402         } else if (++hctx->packets_acked >= hctx->cwnd) {
403                         hctx->cwnd += 1;
404                         hctx->packets_acked = 0;
405         }
406
407         /* update RTO */
408         if (hctx->srtt == -1 ||
409             time_after(jiffies, hctx->lastrtt + hctx->srtt)) {
410                 unsigned long r = (long)jiffies - (long)seqp->ccid2s_sent;
411                 int s;
412
413                 /* first measurement */
414                 if (hctx->srtt == -1) {
415                         ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n",
416                                        r, jiffies,
417                                        (unsigned long long)seqp->ccid2s_seq);
418                         ccid2_change_srtt(hctx, r);
419                         hctx->rttvar = r >> 1;
420                 } else {
421                         /* RTTVAR */
422                         long tmp = hctx->srtt - r;
423                         long srtt;
424
425                         if (tmp < 0)
426                                 tmp *= -1;
427
428                         tmp >>= 2;
429                         hctx->rttvar *= 3;
430                         hctx->rttvar >>= 2;
431                         hctx->rttvar += tmp;
432
433                         /* SRTT */
434                         srtt = hctx->srtt;
435                         srtt *= 7;
436                         srtt >>= 3;
437                         tmp = r >> 3;
438                         srtt += tmp;
439                         ccid2_change_srtt(hctx, srtt);
440                 }
441                 s = hctx->rttvar << 2;
442                 /* clock granularity is 1 when based on jiffies */
443                 if (!s)
444                         s = 1;
445                 hctx->rto = hctx->srtt + s;
446
447                 /* must be at least a second */
448                 s = hctx->rto / HZ;
449                 /* DCCP doesn't require this [but I like it cuz my code sux] */
450 #if 1
451                 if (s < 1)
452                         hctx->rto = HZ;
453 #endif
454                 /* max 60 seconds */
455                 if (s > 60)
456                         hctx->rto = HZ * 60;
457
458                 hctx->lastrtt = jiffies;
459
460                 ccid2_pr_debug("srtt: %ld rttvar: %ld rto: %ld (HZ=%d) R=%lu\n",
461                                hctx->srtt, hctx->rttvar,
462                                hctx->rto, HZ, r);
463         }
464
465         /* we got a new ack, so re-start RTO timer */
466         ccid2_hc_tx_kill_rto_timer(sk);
467         ccid2_start_rto_timer(sk);
468 }
469
470 static void ccid2_hc_tx_dec_pipe(struct sock *sk)
471 {
472         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
473
474         if (hctx->pipe == 0)
475                 DCCP_BUG("pipe == 0");
476         else
477                 hctx->pipe--;
478
479         if (hctx->pipe == 0)
480                 ccid2_hc_tx_kill_rto_timer(sk);
481 }
482
483 static void ccid2_congestion_event(struct sock *sk, struct ccid2_seq *seqp)
484 {
485         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
486
487         if (time_before(seqp->ccid2s_sent, hctx->last_cong)) {
488                 ccid2_pr_debug("Multiple losses in an RTT---treating as one\n");
489                 return;
490         }
491
492         hctx->last_cong = jiffies;
493
494         hctx->cwnd     = hctx->cwnd / 2 ? : 1U;
495         hctx->ssthresh = max(hctx->cwnd, 2U);
496
497         /* Avoid spurious timeouts resulting from Ack Ratio > cwnd */
498         if (dccp_sk(sk)->dccps_l_ack_ratio > hctx->cwnd)
499                 ccid2_change_l_ack_ratio(sk, hctx->cwnd);
500 }
501
502 static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
503 {
504         struct dccp_sock *dp = dccp_sk(sk);
505         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
506         u64 ackno, seqno;
507         struct ccid2_seq *seqp;
508         unsigned char *vector;
509         unsigned char veclen;
510         int offset = 0;
511         int done = 0;
512         unsigned int maxincr = 0;
513
514         ccid2_hc_tx_check_sanity(hctx);
515         /* check reverse path congestion */
516         seqno = DCCP_SKB_CB(skb)->dccpd_seq;
517
518         /* XXX this whole "algorithm" is broken.  Need to fix it to keep track
519          * of the seqnos of the dupacks so that rpseq and rpdupack are correct
520          * -sorbo.
521          */
522         /* need to bootstrap */
523         if (hctx->rpdupack == -1) {
524                 hctx->rpdupack = 0;
525                 hctx->rpseq = seqno;
526         } else {
527                 /* check if packet is consecutive */
528                 if (dccp_delta_seqno(hctx->rpseq, seqno) == 1)
529                         hctx->rpseq = seqno;
530                 /* it's a later packet */
531                 else if (after48(seqno, hctx->rpseq)) {
532                         hctx->rpdupack++;
533
534                         /* check if we got enough dupacks */
535                         if (hctx->rpdupack >= NUMDUPACK) {
536                                 hctx->rpdupack = -1; /* XXX lame */
537                                 hctx->rpseq = 0;
538
539                                 ccid2_change_l_ack_ratio(sk, 2 * dp->dccps_l_ack_ratio);
540                         }
541                 }
542         }
543
544         /* check forward path congestion */
545         /* still didn't send out new data packets */
546         if (hctx->seqh == hctx->seqt)
547                 return;
548
549         switch (DCCP_SKB_CB(skb)->dccpd_type) {
550         case DCCP_PKT_ACK:
551         case DCCP_PKT_DATAACK:
552                 break;
553         default:
554                 return;
555         }
556
557         ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq;
558         if (after48(ackno, hctx->high_ack))
559                 hctx->high_ack = ackno;
560
561         seqp = hctx->seqt;
562         while (before48(seqp->ccid2s_seq, ackno)) {
563                 seqp = seqp->ccid2s_next;
564                 if (seqp == hctx->seqh) {
565                         seqp = hctx->seqh->ccid2s_prev;
566                         break;
567                 }
568         }
569
570         /*
571          * In slow-start, cwnd can increase up to a maximum of Ack Ratio/2
572          * packets per acknowledgement. Rounding up avoids that cwnd is not
573          * advanced when Ack Ratio is 1 and gives a slight edge otherwise.
574          */
575         if (hctx->cwnd < hctx->ssthresh)
576                 maxincr = DIV_ROUND_UP(dp->dccps_l_ack_ratio, 2);
577
578         /* go through all ack vectors */
579         while ((offset = ccid2_ackvector(sk, skb, offset,
580                                          &vector, &veclen)) != -1) {
581                 /* go through this ack vector */
582                 while (veclen--) {
583                         u64 ackno_end_rl = SUB48(ackno, dccp_ackvec_runlen(vector));
584
585                         ccid2_pr_debug("ackvec start:%llu end:%llu\n",
586                                        (unsigned long long)ackno,
587                                        (unsigned long long)ackno_end_rl);
588                         /* if the seqno we are analyzing is larger than the
589                          * current ackno, then move towards the tail of our
590                          * seqnos.
591                          */
592                         while (after48(seqp->ccid2s_seq, ackno)) {
593                                 if (seqp == hctx->seqt) {
594                                         done = 1;
595                                         break;
596                                 }
597                                 seqp = seqp->ccid2s_prev;
598                         }
599                         if (done)
600                                 break;
601
602                         /* check all seqnos in the range of the vector
603                          * run length
604                          */
605                         while (between48(seqp->ccid2s_seq,ackno_end_rl,ackno)) {
606                                 const u8 state = dccp_ackvec_state(vector);
607
608                                 /* new packet received or marked */
609                                 if (state != DCCPAV_NOT_RECEIVED &&
610                                     !seqp->ccid2s_acked) {
611                                         if (state == DCCPAV_ECN_MARKED)
612                                                 ccid2_congestion_event(sk,
613                                                                        seqp);
614                                         else
615                                                 ccid2_new_ack(sk, seqp,
616                                                               &maxincr);
617
618                                         seqp->ccid2s_acked = 1;
619                                         ccid2_pr_debug("Got ack for %llu\n",
620                                                        (unsigned long long)seqp->ccid2s_seq);
621                                         ccid2_hc_tx_dec_pipe(sk);
622                                 }
623                                 if (seqp == hctx->seqt) {
624                                         done = 1;
625                                         break;
626                                 }
627                                 seqp = seqp->ccid2s_prev;
628                         }
629                         if (done)
630                                 break;
631
632                         ackno = SUB48(ackno_end_rl, 1);
633                         vector++;
634                 }
635                 if (done)
636                         break;
637         }
638
639         /* The state about what is acked should be correct now
640          * Check for NUMDUPACK
641          */
642         seqp = hctx->seqt;
643         while (before48(seqp->ccid2s_seq, hctx->high_ack)) {
644                 seqp = seqp->ccid2s_next;
645                 if (seqp == hctx->seqh) {
646                         seqp = hctx->seqh->ccid2s_prev;
647                         break;
648                 }
649         }
650         done = 0;
651         while (1) {
652                 if (seqp->ccid2s_acked) {
653                         done++;
654                         if (done == NUMDUPACK)
655                                 break;
656                 }
657                 if (seqp == hctx->seqt)
658                         break;
659                 seqp = seqp->ccid2s_prev;
660         }
661
662         /* If there are at least 3 acknowledgements, anything unacknowledged
663          * below the last sequence number is considered lost
664          */
665         if (done == NUMDUPACK) {
666                 struct ccid2_seq *last_acked = seqp;
667
668                 /* check for lost packets */
669                 while (1) {
670                         if (!seqp->ccid2s_acked) {
671                                 ccid2_pr_debug("Packet lost: %llu\n",
672                                                (unsigned long long)seqp->ccid2s_seq);
673                                 /* XXX need to traverse from tail -> head in
674                                  * order to detect multiple congestion events in
675                                  * one ack vector.
676                                  */
677                                 ccid2_congestion_event(sk, seqp);
678                                 ccid2_hc_tx_dec_pipe(sk);
679                         }
680                         if (seqp == hctx->seqt)
681                                 break;
682                         seqp = seqp->ccid2s_prev;
683                 }
684
685                 hctx->seqt = last_acked;
686         }
687
688         /* trim acked packets in tail */
689         while (hctx->seqt != hctx->seqh) {
690                 if (!hctx->seqt->ccid2s_acked)
691                         break;
692
693                 hctx->seqt = hctx->seqt->ccid2s_next;
694         }
695
696         ccid2_hc_tx_check_sanity(hctx);
697 }
698
699 static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
700 {
701         struct ccid2_hc_tx_sock *hctx = ccid_priv(ccid);
702         struct dccp_sock *dp = dccp_sk(sk);
703         u32 max_ratio;
704
705         /* RFC 4341, 5: initialise ssthresh to arbitrarily high (max) value */
706         hctx->ssthresh = ~0U;
707
708         /*
709          * RFC 4341, 5: "The cwnd parameter is initialized to at most four
710          * packets for new connections, following the rules from [RFC3390]".
711          * We need to convert the bytes of RFC3390 into the packets of RFC 4341.
712          */
713         hctx->cwnd = clamp(4380U / dp->dccps_mss_cache, 2U, 4U);
714
715         /* Make sure that Ack Ratio is enabled and within bounds. */
716         max_ratio = DIV_ROUND_UP(hctx->cwnd, 2);
717         if (dp->dccps_l_ack_ratio == 0 || dp->dccps_l_ack_ratio > max_ratio)
718                 dp->dccps_l_ack_ratio = max_ratio;
719
720         /* XXX init ~ to window size... */
721         if (ccid2_hc_tx_alloc_seq(hctx))
722                 return -ENOMEM;
723
724         hctx->rto        = 3 * HZ;
725         ccid2_change_srtt(hctx, -1);
726         hctx->rttvar    = -1;
727         hctx->rpdupack  = -1;
728         hctx->last_cong = jiffies;
729         setup_timer(&hctx->rtotimer, ccid2_hc_tx_rto_expire, (unsigned long)sk);
730
731         ccid2_hc_tx_check_sanity(hctx);
732         return 0;
733 }
734
735 static void ccid2_hc_tx_exit(struct sock *sk)
736 {
737         struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
738         int i;
739
740         ccid2_hc_tx_kill_rto_timer(sk);
741
742         for (i = 0; i < hctx->seqbufc; i++)
743                 kfree(hctx->seqbuf[i]);
744         hctx->seqbufc = 0;
745 }
746
747 static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
748 {
749         const struct dccp_sock *dp = dccp_sk(sk);
750         struct ccid2_hc_rx_sock *hcrx = ccid2_hc_rx_sk(sk);
751
752         switch (DCCP_SKB_CB(skb)->dccpd_type) {
753         case DCCP_PKT_DATA:
754         case DCCP_PKT_DATAACK:
755                 hcrx->data++;
756                 if (hcrx->data >= dp->dccps_r_ack_ratio) {
757                         dccp_send_ack(sk);
758                         hcrx->data = 0;
759                 }
760                 break;
761         }
762 }
763
764 static struct ccid_operations ccid2 = {
765         .ccid_id                = DCCPC_CCID2,
766         .ccid_name              = "TCP-like",
767         .ccid_owner             = THIS_MODULE,
768         .ccid_hc_tx_obj_size    = sizeof(struct ccid2_hc_tx_sock),
769         .ccid_hc_tx_init        = ccid2_hc_tx_init,
770         .ccid_hc_tx_exit        = ccid2_hc_tx_exit,
771         .ccid_hc_tx_send_packet = ccid2_hc_tx_send_packet,
772         .ccid_hc_tx_packet_sent = ccid2_hc_tx_packet_sent,
773         .ccid_hc_tx_packet_recv = ccid2_hc_tx_packet_recv,
774         .ccid_hc_rx_obj_size    = sizeof(struct ccid2_hc_rx_sock),
775         .ccid_hc_rx_packet_recv = ccid2_hc_rx_packet_recv,
776 };
777
778 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG
779 module_param(ccid2_debug, bool, 0644);
780 MODULE_PARM_DESC(ccid2_debug, "Enable debug messages");
781 #endif
782
783 static __init int ccid2_module_init(void)
784 {
785         return ccid_register(&ccid2);
786 }
787 module_init(ccid2_module_init);
788
789 static __exit void ccid2_module_exit(void)
790 {
791         ccid_unregister(&ccid2);
792 }
793 module_exit(ccid2_module_exit);
794
795 MODULE_AUTHOR("Andrea Bittau <a.bittau@cs.ucl.ac.uk>");
796 MODULE_DESCRIPTION("DCCP TCP-Like (CCID2) CCID");
797 MODULE_LICENSE("GPL");
798 MODULE_ALIAS("net-dccp-ccid-2");