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