aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/ccids/ccid2.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/ccids/ccid2.c')
-rw-r--r--net/dccp/ccids/ccid2.c207
1 files changed, 135 insertions, 72 deletions
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index d4f9e2d33453..2efb505aeb35 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -27,18 +27,15 @@
27 * 27 *
28 * BUGS: 28 * BUGS:
29 * - sequence number wrapping 29 * - sequence number wrapping
30 * - jiffies wrapping
31 */ 30 */
32 31
33#include <linux/config.h>
34#include "../ccid.h" 32#include "../ccid.h"
35#include "../dccp.h" 33#include "../dccp.h"
36#include "ccid2.h" 34#include "ccid2.h"
37 35
38static int ccid2_debug; 36static int ccid2_debug;
39 37
40#undef CCID2_DEBUG 38#ifdef CONFIG_IP_DCCP_CCID2_DEBUG
41#ifdef CCID2_DEBUG
42#define ccid2_pr_debug(format, a...) \ 39#define ccid2_pr_debug(format, a...) \
43 do { if (ccid2_debug) \ 40 do { if (ccid2_debug) \
44 printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \ 41 printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \
@@ -47,9 +44,7 @@ static int ccid2_debug;
47#define ccid2_pr_debug(format, a...) 44#define ccid2_pr_debug(format, a...)
48#endif 45#endif
49 46
50static const int ccid2_seq_len = 128; 47#ifdef CONFIG_IP_DCCP_CCID2_DEBUG
51
52#ifdef CCID2_DEBUG
53static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx) 48static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx)
54{ 49{
55 int len = 0; 50 int len = 0;
@@ -72,8 +67,8 @@ static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx)
72 67
73 /* packets are sent sequentially */ 68 /* packets are sent sequentially */
74 BUG_ON(seqp->ccid2s_seq <= prev->ccid2s_seq); 69 BUG_ON(seqp->ccid2s_seq <= prev->ccid2s_seq);
75 BUG_ON(seqp->ccid2s_sent < prev->ccid2s_sent); 70 BUG_ON(time_before(seqp->ccid2s_sent,
76 BUG_ON(len > ccid2_seq_len); 71 prev->ccid2s_sent));
77 72
78 seqp = prev; 73 seqp = prev;
79 } 74 }
@@ -85,16 +80,57 @@ static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx)
85 do { 80 do {
86 seqp = seqp->ccid2s_prev; 81 seqp = seqp->ccid2s_prev;
87 len++; 82 len++;
88 BUG_ON(len > ccid2_seq_len);
89 } while (seqp != hctx->ccid2hctx_seqh); 83 } while (seqp != hctx->ccid2hctx_seqh);
90 84
91 BUG_ON(len != ccid2_seq_len);
92 ccid2_pr_debug("total len=%d\n", len); 85 ccid2_pr_debug("total len=%d\n", len);
86 BUG_ON(len != hctx->ccid2hctx_seqbufc * CCID2_SEQBUF_LEN);
93} 87}
94#else 88#else
95#define ccid2_hc_tx_check_sanity(hctx) do {} while (0) 89#define ccid2_hc_tx_check_sanity(hctx) do {} while (0)
96#endif 90#endif
97 91
92static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hctx, int num,
93 gfp_t gfp)
94{
95 struct ccid2_seq *seqp;
96 int i;
97
98 /* check if we have space to preserve the pointer to the buffer */
99 if (hctx->ccid2hctx_seqbufc >= (sizeof(hctx->ccid2hctx_seqbuf) /
100 sizeof(struct ccid2_seq*)))
101 return -ENOMEM;
102
103 /* allocate buffer and initialize linked list */
104 seqp = kmalloc(sizeof(*seqp) * num, gfp);
105 if (seqp == NULL)
106 return -ENOMEM;
107
108 for (i = 0; i < (num - 1); i++) {
109 seqp[i].ccid2s_next = &seqp[i + 1];
110 seqp[i + 1].ccid2s_prev = &seqp[i];
111 }
112 seqp[num - 1].ccid2s_next = seqp;
113 seqp->ccid2s_prev = &seqp[num - 1];
114
115 /* This is the first allocation. Initiate the head and tail. */
116 if (hctx->ccid2hctx_seqbufc == 0)
117 hctx->ccid2hctx_seqh = hctx->ccid2hctx_seqt = seqp;
118 else {
119 /* link the existing list with the one we just created */
120 hctx->ccid2hctx_seqh->ccid2s_next = seqp;
121 seqp->ccid2s_prev = hctx->ccid2hctx_seqh;
122
123 hctx->ccid2hctx_seqt->ccid2s_prev = &seqp[num - 1];
124 seqp[num - 1].ccid2s_next = hctx->ccid2hctx_seqt;
125 }
126
127 /* store the original pointer to the buffer so we can free it */
128 hctx->ccid2hctx_seqbuf[hctx->ccid2hctx_seqbufc] = seqp;
129 hctx->ccid2hctx_seqbufc++;
130
131 return 0;
132}
133
98static int ccid2_hc_tx_send_packet(struct sock *sk, 134static int ccid2_hc_tx_send_packet(struct sock *sk,
99 struct sk_buff *skb, int len) 135 struct sk_buff *skb, int len)
100{ 136{
@@ -123,7 +159,7 @@ static int ccid2_hc_tx_send_packet(struct sock *sk,
123 } 159 }
124 } 160 }
125 161
126 return 100; /* XXX */ 162 return 1; /* XXX CCID should dequeue when ready instead of polling */
127} 163}
128 164
129static void ccid2_change_l_ack_ratio(struct sock *sk, int val) 165static void ccid2_change_l_ack_ratio(struct sock *sk, int val)
@@ -151,10 +187,8 @@ static void ccid2_change_l_ack_ratio(struct sock *sk, int val)
151 dp->dccps_l_ack_ratio = val; 187 dp->dccps_l_ack_ratio = val;
152} 188}
153 189
154static void ccid2_change_cwnd(struct sock *sk, int val) 190static void ccid2_change_cwnd(struct ccid2_hc_tx_sock *hctx, int val)
155{ 191{
156 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
157
158 if (val == 0) 192 if (val == 0)
159 val = 1; 193 val = 1;
160 194
@@ -165,6 +199,17 @@ static void ccid2_change_cwnd(struct sock *sk, int val)
165 hctx->ccid2hctx_cwnd = val; 199 hctx->ccid2hctx_cwnd = val;
166} 200}
167 201
202static void ccid2_change_srtt(struct ccid2_hc_tx_sock *hctx, long val)
203{
204 ccid2_pr_debug("change SRTT to %ld\n", val);
205 hctx->ccid2hctx_srtt = val;
206}
207
208static void ccid2_change_pipe(struct ccid2_hc_tx_sock *hctx, long val)
209{
210 hctx->ccid2hctx_pipe = val;
211}
212
168static void ccid2_start_rto_timer(struct sock *sk); 213static void ccid2_start_rto_timer(struct sock *sk);
169 214
170static void ccid2_hc_tx_rto_expire(unsigned long data) 215static void ccid2_hc_tx_rto_expire(unsigned long data)
@@ -194,11 +239,11 @@ static void ccid2_hc_tx_rto_expire(unsigned long data)
194 ccid2_start_rto_timer(sk); 239 ccid2_start_rto_timer(sk);
195 240
196 /* adjust pipe, cwnd etc */ 241 /* adjust pipe, cwnd etc */
197 hctx->ccid2hctx_pipe = 0; 242 ccid2_change_pipe(hctx, 0);
198 hctx->ccid2hctx_ssthresh = hctx->ccid2hctx_cwnd >> 1; 243 hctx->ccid2hctx_ssthresh = hctx->ccid2hctx_cwnd >> 1;
199 if (hctx->ccid2hctx_ssthresh < 2) 244 if (hctx->ccid2hctx_ssthresh < 2)
200 hctx->ccid2hctx_ssthresh = 2; 245 hctx->ccid2hctx_ssthresh = 2;
201 ccid2_change_cwnd(sk, 1); 246 ccid2_change_cwnd(hctx, 1);
202 247
203 /* clear state about stuff we sent */ 248 /* clear state about stuff we sent */
204 hctx->ccid2hctx_seqt = hctx->ccid2hctx_seqh; 249 hctx->ccid2hctx_seqt = hctx->ccid2hctx_seqh;
@@ -233,13 +278,14 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, int len)
233{ 278{
234 struct dccp_sock *dp = dccp_sk(sk); 279 struct dccp_sock *dp = dccp_sk(sk);
235 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk); 280 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
281 struct ccid2_seq *next;
236 u64 seq; 282 u64 seq;
237 283
238 ccid2_hc_tx_check_sanity(hctx); 284 ccid2_hc_tx_check_sanity(hctx);
239 285
240 BUG_ON(!hctx->ccid2hctx_sendwait); 286 BUG_ON(!hctx->ccid2hctx_sendwait);
241 hctx->ccid2hctx_sendwait = 0; 287 hctx->ccid2hctx_sendwait = 0;
242 hctx->ccid2hctx_pipe++; 288 ccid2_change_pipe(hctx, hctx->ccid2hctx_pipe + 1);
243 BUG_ON(hctx->ccid2hctx_pipe < 0); 289 BUG_ON(hctx->ccid2hctx_pipe < 0);
244 290
245 /* There is an issue. What if another packet is sent between 291 /* There is an issue. What if another packet is sent between
@@ -252,15 +298,23 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, int len)
252 hctx->ccid2hctx_seqh->ccid2s_seq = seq; 298 hctx->ccid2hctx_seqh->ccid2s_seq = seq;
253 hctx->ccid2hctx_seqh->ccid2s_acked = 0; 299 hctx->ccid2hctx_seqh->ccid2s_acked = 0;
254 hctx->ccid2hctx_seqh->ccid2s_sent = jiffies; 300 hctx->ccid2hctx_seqh->ccid2s_sent = jiffies;
255 hctx->ccid2hctx_seqh = hctx->ccid2hctx_seqh->ccid2s_next;
256 301
257 ccid2_pr_debug("cwnd=%d pipe=%d\n", hctx->ccid2hctx_cwnd, 302 next = hctx->ccid2hctx_seqh->ccid2s_next;
258 hctx->ccid2hctx_pipe); 303 /* check if we need to alloc more space */
304 if (next == hctx->ccid2hctx_seqt) {
305 int rc;
306
307 ccid2_pr_debug("allocating more space in history\n");
308 rc = ccid2_hc_tx_alloc_seq(hctx, CCID2_SEQBUF_LEN, GFP_KERNEL);
309 BUG_ON(rc); /* XXX what do we do? */
259 310
260 if (hctx->ccid2hctx_seqh == hctx->ccid2hctx_seqt) { 311 next = hctx->ccid2hctx_seqh->ccid2s_next;
261 /* XXX allocate more space */ 312 BUG_ON(next == hctx->ccid2hctx_seqt);
262 WARN_ON(1);
263 } 313 }
314 hctx->ccid2hctx_seqh = next;
315
316 ccid2_pr_debug("cwnd=%d pipe=%d\n", hctx->ccid2hctx_cwnd,
317 hctx->ccid2hctx_pipe);
264 318
265 hctx->ccid2hctx_sent++; 319 hctx->ccid2hctx_sent++;
266 320
@@ -296,7 +350,7 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, int len)
296 if (!timer_pending(&hctx->ccid2hctx_rtotimer)) 350 if (!timer_pending(&hctx->ccid2hctx_rtotimer))
297 ccid2_start_rto_timer(sk); 351 ccid2_start_rto_timer(sk);
298 352
299#ifdef CCID2_DEBUG 353#ifdef CONFIG_IP_DCCP_CCID2_DEBUG
300 ccid2_pr_debug("pipe=%d\n", hctx->ccid2hctx_pipe); 354 ccid2_pr_debug("pipe=%d\n", hctx->ccid2hctx_pipe);
301 ccid2_pr_debug("Sent: seq=%llu\n", seq); 355 ccid2_pr_debug("Sent: seq=%llu\n", seq);
302 do { 356 do {
@@ -399,7 +453,7 @@ static inline void ccid2_new_ack(struct sock *sk,
399 /* increase every 2 acks */ 453 /* increase every 2 acks */
400 hctx->ccid2hctx_ssacks++; 454 hctx->ccid2hctx_ssacks++;
401 if (hctx->ccid2hctx_ssacks == 2) { 455 if (hctx->ccid2hctx_ssacks == 2) {
402 ccid2_change_cwnd(sk, hctx->ccid2hctx_cwnd + 1); 456 ccid2_change_cwnd(hctx, hctx->ccid2hctx_cwnd+1);
403 hctx->ccid2hctx_ssacks = 0; 457 hctx->ccid2hctx_ssacks = 0;
404 *maxincr = *maxincr - 1; 458 *maxincr = *maxincr - 1;
405 } 459 }
@@ -412,26 +466,28 @@ static inline void ccid2_new_ack(struct sock *sk,
412 hctx->ccid2hctx_acks++; 466 hctx->ccid2hctx_acks++;
413 467
414 if (hctx->ccid2hctx_acks >= hctx->ccid2hctx_cwnd) { 468 if (hctx->ccid2hctx_acks >= hctx->ccid2hctx_cwnd) {
415 ccid2_change_cwnd(sk, hctx->ccid2hctx_cwnd + 1); 469 ccid2_change_cwnd(hctx, hctx->ccid2hctx_cwnd + 1);
416 hctx->ccid2hctx_acks = 0; 470 hctx->ccid2hctx_acks = 0;
417 } 471 }
418 } 472 }
419 473
420 /* update RTO */ 474 /* update RTO */
421 if (hctx->ccid2hctx_srtt == -1 || 475 if (hctx->ccid2hctx_srtt == -1 ||
422 (jiffies - hctx->ccid2hctx_lastrtt) >= hctx->ccid2hctx_srtt) { 476 time_after(jiffies, hctx->ccid2hctx_lastrtt + hctx->ccid2hctx_srtt)) {
423 unsigned long r = jiffies - seqp->ccid2s_sent; 477 unsigned long r = (long)jiffies - (long)seqp->ccid2s_sent;
424 int s; 478 int s;
425 479
426 /* first measurement */ 480 /* first measurement */
427 if (hctx->ccid2hctx_srtt == -1) { 481 if (hctx->ccid2hctx_srtt == -1) {
428 ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n", 482 ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n",
429 r, jiffies, seqp->ccid2s_seq); 483 r, jiffies, seqp->ccid2s_seq);
430 hctx->ccid2hctx_srtt = r; 484 ccid2_change_srtt(hctx, r);
431 hctx->ccid2hctx_rttvar = r >> 1; 485 hctx->ccid2hctx_rttvar = r >> 1;
432 } else { 486 } else {
433 /* RTTVAR */ 487 /* RTTVAR */
434 long tmp = hctx->ccid2hctx_srtt - r; 488 long tmp = hctx->ccid2hctx_srtt - r;
489 long srtt;
490
435 if (tmp < 0) 491 if (tmp < 0)
436 tmp *= -1; 492 tmp *= -1;
437 493
@@ -441,10 +497,12 @@ static inline void ccid2_new_ack(struct sock *sk,
441 hctx->ccid2hctx_rttvar += tmp; 497 hctx->ccid2hctx_rttvar += tmp;
442 498
443 /* SRTT */ 499 /* SRTT */
444 hctx->ccid2hctx_srtt *= 7; 500 srtt = hctx->ccid2hctx_srtt;
445 hctx->ccid2hctx_srtt >>= 3; 501 srtt *= 7;
502 srtt >>= 3;
446 tmp = r >> 3; 503 tmp = r >> 3;
447 hctx->ccid2hctx_srtt += tmp; 504 srtt += tmp;
505 ccid2_change_srtt(hctx, srtt);
448 } 506 }
449 s = hctx->ccid2hctx_rttvar << 2; 507 s = hctx->ccid2hctx_rttvar << 2;
450 /* clock granularity is 1 when based on jiffies */ 508 /* clock granularity is 1 when based on jiffies */
@@ -480,13 +538,29 @@ static void ccid2_hc_tx_dec_pipe(struct sock *sk)
480{ 538{
481 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk); 539 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
482 540
483 hctx->ccid2hctx_pipe--; 541 ccid2_change_pipe(hctx, hctx->ccid2hctx_pipe-1);
484 BUG_ON(hctx->ccid2hctx_pipe < 0); 542 BUG_ON(hctx->ccid2hctx_pipe < 0);
485 543
486 if (hctx->ccid2hctx_pipe == 0) 544 if (hctx->ccid2hctx_pipe == 0)
487 ccid2_hc_tx_kill_rto_timer(sk); 545 ccid2_hc_tx_kill_rto_timer(sk);
488} 546}
489 547
548static void ccid2_congestion_event(struct ccid2_hc_tx_sock *hctx,
549 struct ccid2_seq *seqp)
550{
551 if (time_before(seqp->ccid2s_sent, hctx->ccid2hctx_last_cong)) {
552 ccid2_pr_debug("Multiple losses in an RTT---treating as one\n");
553 return;
554 }
555
556 hctx->ccid2hctx_last_cong = jiffies;
557
558 ccid2_change_cwnd(hctx, hctx->ccid2hctx_cwnd >> 1);
559 hctx->ccid2hctx_ssthresh = hctx->ccid2hctx_cwnd;
560 if (hctx->ccid2hctx_ssthresh < 2)
561 hctx->ccid2hctx_ssthresh = 2;
562}
563
490static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) 564static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
491{ 565{
492 struct dccp_sock *dp = dccp_sk(sk); 566 struct dccp_sock *dp = dccp_sk(sk);
@@ -497,7 +571,6 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
497 unsigned char veclen; 571 unsigned char veclen;
498 int offset = 0; 572 int offset = 0;
499 int done = 0; 573 int done = 0;
500 int loss = 0;
501 unsigned int maxincr = 0; 574 unsigned int maxincr = 0;
502 575
503 ccid2_hc_tx_check_sanity(hctx); 576 ccid2_hc_tx_check_sanity(hctx);
@@ -583,15 +656,16 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
583 * run length 656 * run length
584 */ 657 */
585 while (between48(seqp->ccid2s_seq,ackno_end_rl,ackno)) { 658 while (between48(seqp->ccid2s_seq,ackno_end_rl,ackno)) {
586 const u8 state = (*vector & 659 const u8 state = *vector &
587 DCCP_ACKVEC_STATE_MASK) >> 6; 660 DCCP_ACKVEC_STATE_MASK;
588 661
589 /* new packet received or marked */ 662 /* new packet received or marked */
590 if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED && 663 if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED &&
591 !seqp->ccid2s_acked) { 664 !seqp->ccid2s_acked) {
592 if (state == 665 if (state ==
593 DCCP_ACKVEC_STATE_ECN_MARKED) { 666 DCCP_ACKVEC_STATE_ECN_MARKED) {
594 loss = 1; 667 ccid2_congestion_event(hctx,
668 seqp);
595 } else 669 } else
596 ccid2_new_ack(sk, seqp, 670 ccid2_new_ack(sk, seqp,
597 &maxincr); 671 &maxincr);
@@ -643,7 +717,13 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
643 /* check for lost packets */ 717 /* check for lost packets */
644 while (1) { 718 while (1) {
645 if (!seqp->ccid2s_acked) { 719 if (!seqp->ccid2s_acked) {
646 loss = 1; 720 ccid2_pr_debug("Packet lost: %llu\n",
721 seqp->ccid2s_seq);
722 /* XXX need to traverse from tail -> head in
723 * order to detect multiple congestion events in
724 * one ack vector.
725 */
726 ccid2_congestion_event(hctx, seqp);
647 ccid2_hc_tx_dec_pipe(sk); 727 ccid2_hc_tx_dec_pipe(sk);
648 } 728 }
649 if (seqp == hctx->ccid2hctx_seqt) 729 if (seqp == hctx->ccid2hctx_seqt)
@@ -662,53 +742,33 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
662 hctx->ccid2hctx_seqt = hctx->ccid2hctx_seqt->ccid2s_next; 742 hctx->ccid2hctx_seqt = hctx->ccid2hctx_seqt->ccid2s_next;
663 } 743 }
664 744
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); 745 ccid2_hc_tx_check_sanity(hctx);
674} 746}
675 747
676static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) 748static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
677{ 749{
678 struct ccid2_hc_tx_sock *hctx = ccid_priv(ccid); 750 struct ccid2_hc_tx_sock *hctx = ccid_priv(ccid);
679 int seqcount = ccid2_seq_len;
680 int i;
681 751
682 /* XXX init variables with proper values */ 752 ccid2_change_cwnd(hctx, 1);
683 hctx->ccid2hctx_cwnd = 1; 753 /* Initialize ssthresh to infinity. This means that we will exit the
684 hctx->ccid2hctx_ssthresh = 10; 754 * initial slow-start after the first packet loss. This is what we
755 * want.
756 */
757 hctx->ccid2hctx_ssthresh = ~0;
685 hctx->ccid2hctx_numdupack = 3; 758 hctx->ccid2hctx_numdupack = 3;
759 hctx->ccid2hctx_seqbufc = 0;
686 760
687 /* XXX init ~ to window size... */ 761 /* XXX init ~ to window size... */
688 hctx->ccid2hctx_seqbuf = kmalloc(sizeof(*hctx->ccid2hctx_seqbuf) * 762 if (ccid2_hc_tx_alloc_seq(hctx, CCID2_SEQBUF_LEN, GFP_ATOMIC) != 0)
689 seqcount, gfp_any());
690 if (hctx->ccid2hctx_seqbuf == NULL)
691 return -ENOMEM; 763 return -ENOMEM;
692 764
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; 765 hctx->ccid2hctx_sent = 0;
707 hctx->ccid2hctx_rto = 3 * HZ; 766 hctx->ccid2hctx_rto = 3 * HZ;
708 hctx->ccid2hctx_srtt = -1; 767 ccid2_change_srtt(hctx, -1);
709 hctx->ccid2hctx_rttvar = -1; 768 hctx->ccid2hctx_rttvar = -1;
710 hctx->ccid2hctx_lastrtt = 0; 769 hctx->ccid2hctx_lastrtt = 0;
711 hctx->ccid2hctx_rpdupack = -1; 770 hctx->ccid2hctx_rpdupack = -1;
771 hctx->ccid2hctx_last_cong = jiffies;
712 772
713 hctx->ccid2hctx_rtotimer.function = &ccid2_hc_tx_rto_expire; 773 hctx->ccid2hctx_rtotimer.function = &ccid2_hc_tx_rto_expire;
714 hctx->ccid2hctx_rtotimer.data = (unsigned long)sk; 774 hctx->ccid2hctx_rtotimer.data = (unsigned long)sk;
@@ -721,10 +781,13 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
721static void ccid2_hc_tx_exit(struct sock *sk) 781static void ccid2_hc_tx_exit(struct sock *sk)
722{ 782{
723 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk); 783 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
784 int i;
724 785
725 ccid2_hc_tx_kill_rto_timer(sk); 786 ccid2_hc_tx_kill_rto_timer(sk);
726 kfree(hctx->ccid2hctx_seqbuf); 787
727 hctx->ccid2hctx_seqbuf = NULL; 788 for (i = 0; i < hctx->ccid2hctx_seqbufc; i++)
789 kfree(hctx->ccid2hctx_seqbuf[i]);
790 hctx->ccid2hctx_seqbufc = 0;
728} 791}
729 792
730static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) 793static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
@@ -745,7 +808,7 @@ static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
745} 808}
746 809
747static struct ccid_operations ccid2 = { 810static struct ccid_operations ccid2 = {
748 .ccid_id = 2, 811 .ccid_id = DCCPC_CCID2,
749 .ccid_name = "ccid2", 812 .ccid_name = "ccid2",
750 .ccid_owner = THIS_MODULE, 813 .ccid_owner = THIS_MODULE,
751 .ccid_hc_tx_obj_size = sizeof(struct ccid2_hc_tx_sock), 814 .ccid_hc_tx_obj_size = sizeof(struct ccid2_hc_tx_sock),