2 * net/dccp/ccids/ccid2.c
4 * Copyright (c) 2005, 2006 Andrea Bittau <a.bittau@cs.ucl.ac.uk>
6 * Changes to meet Linux coding standards, and DCCP infrastructure fixes.
8 * Copyright (c) 2006 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
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.
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.
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.
26 * This implementation should follow RFC 4341
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)
38 static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx)
42 struct ccid2_seq *seqp = hctx->ccid2hctx_seqh;
44 /* there is data in the chain */
45 if (seqp != hctx->ccid2hctx_seqt) {
46 seqp = seqp->ccid2s_prev;
48 if (!seqp->ccid2s_acked)
51 while (seqp != hctx->ccid2hctx_seqt) {
52 struct ccid2_seq *prev = seqp->ccid2s_prev;
55 if (!prev->ccid2s_acked)
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,
68 BUG_ON(pipe != hctx->ccid2hctx_pipe);
69 ccid2_pr_debug("len of chain=%d\n", len);
72 seqp = seqp->ccid2s_prev;
74 } while (seqp != hctx->ccid2hctx_seqh);
76 ccid2_pr_debug("total len=%d\n", len);
77 BUG_ON(len != hctx->ccid2hctx_seqbufc * CCID2_SEQBUF_LEN);
80 #define ccid2_pr_debug(format, a...)
81 #define ccid2_hc_tx_check_sanity(hctx)
84 static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hctx)
86 struct ccid2_seq *seqp;
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*)))
94 /* allocate buffer and initialize linked list */
95 seqp = kmalloc(CCID2_SEQBUF_LEN * sizeof(struct ccid2_seq), gfp_any());
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];
103 seqp[CCID2_SEQBUF_LEN - 1].ccid2s_next = seqp;
104 seqp->ccid2s_prev = &seqp[CCID2_SEQBUF_LEN - 1];
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;
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;
114 hctx->ccid2hctx_seqt->ccid2s_prev = &seqp[CCID2_SEQBUF_LEN - 1];
115 seqp[CCID2_SEQBUF_LEN - 1].ccid2s_next = hctx->ccid2hctx_seqt;
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++;
125 static int ccid2_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
127 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
129 ccid2_pr_debug("pipe=%d cwnd=%d\n", hctx->ccid2hctx_pipe,
130 hctx->ccid2hctx_cwnd);
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;
140 return 1; /* XXX CCID should dequeue when ready instead of polling */
143 static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val)
145 struct dccp_sock *dp = dccp_sk(sk);
146 u32 max_ratio = DIV_ROUND_UP(ccid2_hc_tx_sk(sk)->ccid2hctx_cwnd, 2);
149 * Ensure that Ack Ratio does not exceed ceil(cwnd/2), which is (2) from
150 * RFC 4341, 6.1.2. We ignore the statement that Ack Ratio 2 is always
151 * acceptable since this causes starvation/deadlock whenever cwnd < 2.
152 * The same problem arises when Ack Ratio is 0 (ie. Ack Ratio disabled).
154 if (val == 0 || val > max_ratio) {
155 DCCP_WARN("Limiting Ack Ratio (%u) to %u\n", val, max_ratio);
158 if (val > 0xFFFF) /* RFC 4340, 11.3 */
161 if (val == dp->dccps_l_ack_ratio)
164 ccid2_pr_debug("changing local ack ratio to %u\n", val);
165 dp->dccps_l_ack_ratio = val;
168 static void ccid2_change_cwnd(struct ccid2_hc_tx_sock *hctx, u32 val)
170 hctx->ccid2hctx_cwnd = val? : 1;
171 ccid2_pr_debug("changed cwnd to %u\n", hctx->ccid2hctx_cwnd);
174 static void ccid2_change_srtt(struct ccid2_hc_tx_sock *hctx, long val)
176 ccid2_pr_debug("change SRTT to %ld\n", val);
177 hctx->ccid2hctx_srtt = val;
180 static void ccid2_change_pipe(struct ccid2_hc_tx_sock *hctx, long val)
182 hctx->ccid2hctx_pipe = val;
185 static void ccid2_start_rto_timer(struct sock *sk);
187 static void ccid2_hc_tx_rto_expire(unsigned long data)
189 struct sock *sk = (struct sock *)data;
190 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
194 if (sock_owned_by_user(sk)) {
195 sk_reset_timer(sk, &hctx->ccid2hctx_rtotimer,
200 ccid2_pr_debug("RTO_EXPIRE\n");
202 ccid2_hc_tx_check_sanity(hctx);
205 hctx->ccid2hctx_rto <<= 1;
207 s = hctx->ccid2hctx_rto / HZ;
209 hctx->ccid2hctx_rto = 60 * HZ;
211 ccid2_start_rto_timer(sk);
213 /* adjust pipe, cwnd etc */
214 ccid2_change_pipe(hctx, 0);
215 hctx->ccid2hctx_ssthresh = hctx->ccid2hctx_cwnd >> 1;
216 if (hctx->ccid2hctx_ssthresh < 2)
217 hctx->ccid2hctx_ssthresh = 2;
218 ccid2_change_cwnd(hctx, 1);
220 /* clear state about stuff we sent */
221 hctx->ccid2hctx_seqt = hctx->ccid2hctx_seqh;
222 hctx->ccid2hctx_ssacks = 0;
223 hctx->ccid2hctx_acks = 0;
224 hctx->ccid2hctx_sent = 0;
226 /* clear ack ratio state. */
227 hctx->ccid2hctx_arsent = 0;
228 hctx->ccid2hctx_ackloss = 0;
229 hctx->ccid2hctx_rpseq = 0;
230 hctx->ccid2hctx_rpdupack = -1;
231 ccid2_change_l_ack_ratio(sk, 1);
232 ccid2_hc_tx_check_sanity(hctx);
238 static void ccid2_start_rto_timer(struct sock *sk)
240 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
242 ccid2_pr_debug("setting RTO timeout=%ld\n", hctx->ccid2hctx_rto);
244 BUG_ON(timer_pending(&hctx->ccid2hctx_rtotimer));
245 sk_reset_timer(sk, &hctx->ccid2hctx_rtotimer,
246 jiffies + hctx->ccid2hctx_rto);
249 static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
251 struct dccp_sock *dp = dccp_sk(sk);
252 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
253 struct ccid2_seq *next;
256 ccid2_hc_tx_check_sanity(hctx);
258 BUG_ON(!hctx->ccid2hctx_sendwait);
259 hctx->ccid2hctx_sendwait = 0;
260 ccid2_change_pipe(hctx, hctx->ccid2hctx_pipe + 1);
261 BUG_ON(hctx->ccid2hctx_pipe < 0);
263 /* There is an issue. What if another packet is sent between
264 * packet_send() and packet_sent(). Then the sequence number would be
270 hctx->ccid2hctx_seqh->ccid2s_seq = seq;
271 hctx->ccid2hctx_seqh->ccid2s_acked = 0;
272 hctx->ccid2hctx_seqh->ccid2s_sent = jiffies;
274 next = hctx->ccid2hctx_seqh->ccid2s_next;
275 /* check if we need to alloc more space */
276 if (next == hctx->ccid2hctx_seqt) {
277 if (ccid2_hc_tx_alloc_seq(hctx)) {
278 DCCP_CRIT("packet history - out of memory!");
279 /* FIXME: find a more graceful way to bail out */
282 next = hctx->ccid2hctx_seqh->ccid2s_next;
283 BUG_ON(next == hctx->ccid2hctx_seqt);
285 hctx->ccid2hctx_seqh = next;
287 ccid2_pr_debug("cwnd=%d pipe=%d\n", hctx->ccid2hctx_cwnd,
288 hctx->ccid2hctx_pipe);
290 hctx->ccid2hctx_sent++;
292 /* Ack Ratio. Need to maintain a concept of how many windows we sent */
293 hctx->ccid2hctx_arsent++;
294 /* We had an ack loss in this window... */
295 if (hctx->ccid2hctx_ackloss) {
296 if (hctx->ccid2hctx_arsent >= hctx->ccid2hctx_cwnd) {
297 hctx->ccid2hctx_arsent = 0;
298 hctx->ccid2hctx_ackloss = 0;
301 /* No acks lost up to now... */
302 /* decrease ack ratio if enough packets were sent */
303 if (dp->dccps_l_ack_ratio > 1) {
304 /* XXX don't calculate denominator each time */
305 int denom = dp->dccps_l_ack_ratio * dp->dccps_l_ack_ratio -
306 dp->dccps_l_ack_ratio;
308 denom = hctx->ccid2hctx_cwnd * hctx->ccid2hctx_cwnd / denom;
310 if (hctx->ccid2hctx_arsent >= denom) {
311 ccid2_change_l_ack_ratio(sk, dp->dccps_l_ack_ratio - 1);
312 hctx->ccid2hctx_arsent = 0;
315 /* we can't increase ack ratio further [1] */
316 hctx->ccid2hctx_arsent = 0; /* or maybe set it to cwnd*/
320 /* setup RTO timer */
321 if (!timer_pending(&hctx->ccid2hctx_rtotimer))
322 ccid2_start_rto_timer(sk);
324 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG
325 ccid2_pr_debug("pipe=%d\n", hctx->ccid2hctx_pipe);
326 ccid2_pr_debug("Sent: seq=%llu\n", (unsigned long long)seq);
328 struct ccid2_seq *seqp = hctx->ccid2hctx_seqt;
330 while (seqp != hctx->ccid2hctx_seqh) {
331 ccid2_pr_debug("out seq=%llu acked=%d time=%lu\n",
332 (unsigned long long)seqp->ccid2s_seq,
333 seqp->ccid2s_acked, seqp->ccid2s_sent);
334 seqp = seqp->ccid2s_next;
337 ccid2_pr_debug("=========\n");
338 ccid2_hc_tx_check_sanity(hctx);
342 /* XXX Lame code duplication!
343 * returns -1 if none was found.
344 * else returns the next offset to use in the function call.
346 static int ccid2_ackvector(struct sock *sk, struct sk_buff *skb, int offset,
347 unsigned char **vec, unsigned char *veclen)
349 const struct dccp_hdr *dh = dccp_hdr(skb);
350 unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb);
351 unsigned char *opt_ptr;
352 const unsigned char *opt_end = (unsigned char *)dh +
353 (dh->dccph_doff * 4);
354 unsigned char opt, len;
355 unsigned char *value;
360 if (opt_ptr >= opt_end)
363 while (opt_ptr != opt_end) {
368 /* Check if this isn't a single byte option */
369 if (opt > DCCPO_MAX_RESERVED) {
370 if (opt_ptr == opt_end)
371 goto out_invalid_option;
375 goto out_invalid_option;
377 * Remove the type and len fields, leaving
378 * just the value size
384 if (opt_ptr > opt_end)
385 goto out_invalid_option;
389 case DCCPO_ACK_VECTOR_0:
390 case DCCPO_ACK_VECTOR_1:
393 return offset + (opt_ptr - options);
400 DCCP_BUG("Invalid option - this should not happen (previous parsing)!");
404 static void ccid2_hc_tx_kill_rto_timer(struct sock *sk)
406 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
408 sk_stop_timer(sk, &hctx->ccid2hctx_rtotimer);
409 ccid2_pr_debug("deleted RTO timer\n");
412 static inline void ccid2_new_ack(struct sock *sk,
413 struct ccid2_seq *seqp,
414 unsigned int *maxincr)
416 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
419 if (hctx->ccid2hctx_cwnd < hctx->ccid2hctx_ssthresh) {
420 hctx->ccid2hctx_acks = 0;
422 /* We can increase cwnd at most maxincr [ack_ratio/2] */
424 /* increase every 2 acks */
425 hctx->ccid2hctx_ssacks++;
426 if (hctx->ccid2hctx_ssacks == 2) {
427 ccid2_change_cwnd(hctx, hctx->ccid2hctx_cwnd+1);
428 hctx->ccid2hctx_ssacks = 0;
429 *maxincr = *maxincr - 1;
432 /* increased cwnd enough for this single ack */
433 hctx->ccid2hctx_ssacks = 0;
436 hctx->ccid2hctx_ssacks = 0;
437 hctx->ccid2hctx_acks++;
439 if (hctx->ccid2hctx_acks >= hctx->ccid2hctx_cwnd) {
440 ccid2_change_cwnd(hctx, hctx->ccid2hctx_cwnd + 1);
441 hctx->ccid2hctx_acks = 0;
446 if (hctx->ccid2hctx_srtt == -1 ||
447 time_after(jiffies, hctx->ccid2hctx_lastrtt + hctx->ccid2hctx_srtt)) {
448 unsigned long r = (long)jiffies - (long)seqp->ccid2s_sent;
451 /* first measurement */
452 if (hctx->ccid2hctx_srtt == -1) {
453 ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n",
455 (unsigned long long)seqp->ccid2s_seq);
456 ccid2_change_srtt(hctx, r);
457 hctx->ccid2hctx_rttvar = r >> 1;
460 long tmp = hctx->ccid2hctx_srtt - r;
467 hctx->ccid2hctx_rttvar *= 3;
468 hctx->ccid2hctx_rttvar >>= 2;
469 hctx->ccid2hctx_rttvar += tmp;
472 srtt = hctx->ccid2hctx_srtt;
477 ccid2_change_srtt(hctx, srtt);
479 s = hctx->ccid2hctx_rttvar << 2;
480 /* clock granularity is 1 when based on jiffies */
483 hctx->ccid2hctx_rto = hctx->ccid2hctx_srtt + s;
485 /* must be at least a second */
486 s = hctx->ccid2hctx_rto / HZ;
487 /* DCCP doesn't require this [but I like it cuz my code sux] */
490 hctx->ccid2hctx_rto = HZ;
494 hctx->ccid2hctx_rto = HZ * 60;
496 hctx->ccid2hctx_lastrtt = jiffies;
498 ccid2_pr_debug("srtt: %ld rttvar: %ld rto: %ld (HZ=%d) R=%lu\n",
499 hctx->ccid2hctx_srtt, hctx->ccid2hctx_rttvar,
500 hctx->ccid2hctx_rto, HZ, r);
501 hctx->ccid2hctx_sent = 0;
504 /* we got a new ack, so re-start RTO timer */
505 ccid2_hc_tx_kill_rto_timer(sk);
506 ccid2_start_rto_timer(sk);
509 static void ccid2_hc_tx_dec_pipe(struct sock *sk)
511 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
513 ccid2_change_pipe(hctx, hctx->ccid2hctx_pipe-1);
514 BUG_ON(hctx->ccid2hctx_pipe < 0);
516 if (hctx->ccid2hctx_pipe == 0)
517 ccid2_hc_tx_kill_rto_timer(sk);
520 static void ccid2_congestion_event(struct sock *sk, struct ccid2_seq *seqp)
522 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
524 if (time_before(seqp->ccid2s_sent, hctx->ccid2hctx_last_cong)) {
525 ccid2_pr_debug("Multiple losses in an RTT---treating as one\n");
529 hctx->ccid2hctx_last_cong = jiffies;
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;
536 /* Avoid spurious timeouts resulting from Ack Ratio > cwnd */
537 if (dccp_sk(sk)->dccps_l_ack_ratio > hctx->ccid2hctx_cwnd)
538 ccid2_change_l_ack_ratio(sk, hctx->ccid2hctx_cwnd);
541 static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
543 struct dccp_sock *dp = dccp_sk(sk);
544 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
546 struct ccid2_seq *seqp;
547 unsigned char *vector;
548 unsigned char veclen;
551 unsigned int maxincr = 0;
553 ccid2_hc_tx_check_sanity(hctx);
554 /* check reverse path congestion */
555 seqno = DCCP_SKB_CB(skb)->dccpd_seq;
557 /* XXX this whole "algorithm" is broken. Need to fix it to keep track
558 * of the seqnos of the dupacks so that rpseq and rpdupack are correct
561 /* need to bootstrap */
562 if (hctx->ccid2hctx_rpdupack == -1) {
563 hctx->ccid2hctx_rpdupack = 0;
564 hctx->ccid2hctx_rpseq = seqno;
566 /* check if packet is consecutive */
567 if (dccp_delta_seqno(hctx->ccid2hctx_rpseq, seqno) == 1)
568 hctx->ccid2hctx_rpseq = seqno;
569 /* it's a later packet */
570 else if (after48(seqno, hctx->ccid2hctx_rpseq)) {
571 hctx->ccid2hctx_rpdupack++;
573 /* check if we got enough dupacks */
574 if (hctx->ccid2hctx_rpdupack >=
575 hctx->ccid2hctx_numdupack) {
576 hctx->ccid2hctx_rpdupack = -1; /* XXX lame */
577 hctx->ccid2hctx_rpseq = 0;
579 ccid2_change_l_ack_ratio(sk, 2 * dp->dccps_l_ack_ratio);
584 /* check forward path congestion */
585 /* still didn't send out new data packets */
586 if (hctx->ccid2hctx_seqh == hctx->ccid2hctx_seqt)
589 switch (DCCP_SKB_CB(skb)->dccpd_type) {
591 case DCCP_PKT_DATAACK:
597 ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq;
598 if (after48(ackno, hctx->ccid2hctx_high_ack))
599 hctx->ccid2hctx_high_ack = ackno;
601 seqp = hctx->ccid2hctx_seqt;
602 while (before48(seqp->ccid2s_seq, ackno)) {
603 seqp = seqp->ccid2s_next;
604 if (seqp == hctx->ccid2hctx_seqh) {
605 seqp = hctx->ccid2hctx_seqh->ccid2s_prev;
610 /* If in slow-start, cwnd can increase at most Ack Ratio / 2 packets for
611 * this single ack. I round up.
614 maxincr = dp->dccps_l_ack_ratio >> 1;
617 /* go through all ack vectors */
618 while ((offset = ccid2_ackvector(sk, skb, offset,
619 &vector, &veclen)) != -1) {
620 /* go through this ack vector */
622 const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK;
623 u64 ackno_end_rl = SUB48(ackno, rl);
625 ccid2_pr_debug("ackvec start:%llu end:%llu\n",
626 (unsigned long long)ackno,
627 (unsigned long long)ackno_end_rl);
628 /* if the seqno we are analyzing is larger than the
629 * current ackno, then move towards the tail of our
632 while (after48(seqp->ccid2s_seq, ackno)) {
633 if (seqp == hctx->ccid2hctx_seqt) {
637 seqp = seqp->ccid2s_prev;
642 /* check all seqnos in the range of the vector
645 while (between48(seqp->ccid2s_seq,ackno_end_rl,ackno)) {
646 const u8 state = *vector &
647 DCCP_ACKVEC_STATE_MASK;
649 /* new packet received or marked */
650 if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED &&
651 !seqp->ccid2s_acked) {
653 DCCP_ACKVEC_STATE_ECN_MARKED) {
654 ccid2_congestion_event(sk,
657 ccid2_new_ack(sk, seqp,
660 seqp->ccid2s_acked = 1;
661 ccid2_pr_debug("Got ack for %llu\n",
662 (unsigned long long)seqp->ccid2s_seq);
663 ccid2_hc_tx_dec_pipe(sk);
665 if (seqp == hctx->ccid2hctx_seqt) {
669 seqp = seqp->ccid2s_prev;
674 ackno = SUB48(ackno_end_rl, 1);
681 /* The state about what is acked should be correct now
682 * Check for NUMDUPACK
684 seqp = hctx->ccid2hctx_seqt;
685 while (before48(seqp->ccid2s_seq, hctx->ccid2hctx_high_ack)) {
686 seqp = seqp->ccid2s_next;
687 if (seqp == hctx->ccid2hctx_seqh) {
688 seqp = hctx->ccid2hctx_seqh->ccid2s_prev;
694 if (seqp->ccid2s_acked) {
696 if (done == hctx->ccid2hctx_numdupack)
699 if (seqp == hctx->ccid2hctx_seqt)
701 seqp = seqp->ccid2s_prev;
704 /* If there are at least 3 acknowledgements, anything unacknowledged
705 * below the last sequence number is considered lost
707 if (done == hctx->ccid2hctx_numdupack) {
708 struct ccid2_seq *last_acked = seqp;
710 /* check for lost packets */
712 if (!seqp->ccid2s_acked) {
713 ccid2_pr_debug("Packet lost: %llu\n",
714 (unsigned long long)seqp->ccid2s_seq);
715 /* XXX need to traverse from tail -> head in
716 * order to detect multiple congestion events in
719 ccid2_congestion_event(sk, seqp);
720 ccid2_hc_tx_dec_pipe(sk);
722 if (seqp == hctx->ccid2hctx_seqt)
724 seqp = seqp->ccid2s_prev;
727 hctx->ccid2hctx_seqt = last_acked;
730 /* trim acked packets in tail */
731 while (hctx->ccid2hctx_seqt != hctx->ccid2hctx_seqh) {
732 if (!hctx->ccid2hctx_seqt->ccid2s_acked)
735 hctx->ccid2hctx_seqt = hctx->ccid2hctx_seqt->ccid2s_next;
738 ccid2_hc_tx_check_sanity(hctx);
741 static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
743 struct ccid2_hc_tx_sock *hctx = ccid_priv(ccid);
745 ccid2_change_cwnd(hctx, 1);
746 /* Initialize ssthresh to infinity. This means that we will exit the
747 * initial slow-start after the first packet loss. This is what we
750 hctx->ccid2hctx_ssthresh = ~0;
751 hctx->ccid2hctx_numdupack = 3;
753 /* XXX init ~ to window size... */
754 if (ccid2_hc_tx_alloc_seq(hctx))
757 hctx->ccid2hctx_rto = 3 * HZ;
758 ccid2_change_srtt(hctx, -1);
759 hctx->ccid2hctx_rttvar = -1;
760 hctx->ccid2hctx_rpdupack = -1;
761 hctx->ccid2hctx_last_cong = jiffies;
762 setup_timer(&hctx->ccid2hctx_rtotimer, ccid2_hc_tx_rto_expire,
765 ccid2_hc_tx_check_sanity(hctx);
769 static void ccid2_hc_tx_exit(struct sock *sk)
771 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
774 ccid2_hc_tx_kill_rto_timer(sk);
776 for (i = 0; i < hctx->ccid2hctx_seqbufc; i++)
777 kfree(hctx->ccid2hctx_seqbuf[i]);
778 hctx->ccid2hctx_seqbufc = 0;
781 static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
783 const struct dccp_sock *dp = dccp_sk(sk);
784 struct ccid2_hc_rx_sock *hcrx = ccid2_hc_rx_sk(sk);
786 switch (DCCP_SKB_CB(skb)->dccpd_type) {
788 case DCCP_PKT_DATAACK:
789 hcrx->ccid2hcrx_data++;
790 if (hcrx->ccid2hcrx_data >= dp->dccps_r_ack_ratio) {
792 hcrx->ccid2hcrx_data = 0;
798 static struct ccid_operations ccid2 = {
799 .ccid_id = DCCPC_CCID2,
800 .ccid_name = "ccid2",
801 .ccid_owner = THIS_MODULE,
802 .ccid_hc_tx_obj_size = sizeof(struct ccid2_hc_tx_sock),
803 .ccid_hc_tx_init = ccid2_hc_tx_init,
804 .ccid_hc_tx_exit = ccid2_hc_tx_exit,
805 .ccid_hc_tx_send_packet = ccid2_hc_tx_send_packet,
806 .ccid_hc_tx_packet_sent = ccid2_hc_tx_packet_sent,
807 .ccid_hc_tx_packet_recv = ccid2_hc_tx_packet_recv,
808 .ccid_hc_rx_obj_size = sizeof(struct ccid2_hc_rx_sock),
809 .ccid_hc_rx_packet_recv = ccid2_hc_rx_packet_recv,
812 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG
813 module_param(ccid2_debug, bool, 0444);
814 MODULE_PARM_DESC(ccid2_debug, "Enable debug messages");
817 static __init int ccid2_module_init(void)
819 return ccid_register(&ccid2);
821 module_init(ccid2_module_init);
823 static __exit void ccid2_module_exit(void)
825 ccid_unregister(&ccid2);
827 module_exit(ccid2_module_exit);
829 MODULE_AUTHOR("Andrea Bittau <a.bittau@cs.ucl.ac.uk>");
830 MODULE_DESCRIPTION("DCCP TCP-Like (CCID2) CCID");
831 MODULE_LICENSE("GPL");
832 MODULE_ALIAS("net-dccp-ccid-2");