ccid2.c revision ff49e27089ec363b7fc3849504e0435d447ab18a
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 35static int ccid2_debug; 36#define ccid2_pr_debug(format, a...) DCCP_PR_DEBUG(ccid2_debug, format, ##a) 37 38static 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 84static 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 124static 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 134static 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 159static 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 165static void ccid2_start_rto_timer(struct sock *sk); 166 167static 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); 208out: 209 bh_unlock_sock(sk); 210 sock_put(sk); 211} 212 213static 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 224static 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 */ 324static 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 377out_invalid_option: 378 DCCP_BUG("Invalid option - this should not happen (previous parsing)!"); 379 return -1; 380} 381 382static 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 390static 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 470static 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 483static 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 502static 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 699static 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 735static 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 747static 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 764static 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 779module_param(ccid2_debug, bool, 0644); 780MODULE_PARM_DESC(ccid2_debug, "Enable debug messages"); 781#endif 782 783static __init int ccid2_module_init(void) 784{ 785 return ccid_register(&ccid2); 786} 787module_init(ccid2_module_init); 788 789static __exit void ccid2_module_exit(void) 790{ 791 ccid_unregister(&ccid2); 792} 793module_exit(ccid2_module_exit); 794 795MODULE_AUTHOR("Andrea Bittau <a.bittau@cs.ucl.ac.uk>"); 796MODULE_DESCRIPTION("DCCP TCP-Like (CCID2) CCID"); 797MODULE_LICENSE("GPL"); 798MODULE_ALIAS("net-dccp-ccid-2"); 799