1 /* 2 * net/dccp/ccids/ccid3.c 3 * 4 * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. 5 * Copyright (c) 2005-6 Ian McDonald <ian.mcdonald@jandi.co.nz> 6 * 7 * An implementation of the DCCP protocol 8 * 9 * This code has been developed by the University of Waikato WAND 10 * research group. For further information please see http://www.wand.net.nz/ 11 * 12 * This code also uses code from Lulea University, rereleased as GPL by its 13 * authors: 14 * Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon 15 * 16 * Changes to meet Linux coding standards, to make it meet latest ccid3 draft 17 * and to make it work as a loadable module in the DCCP stack written by 18 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>. 19 * 20 * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br> 21 * 22 * This program is free software; you can redistribute it and/or modify 23 * it under the terms of the GNU General Public License as published by 24 * the Free Software Foundation; either version 2 of the License, or 25 * (at your option) any later version. 26 * 27 * This program is distributed in the hope that it will be useful, 28 * but WITHOUT ANY WARRANTY; without even the implied warranty of 29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 30 * GNU General Public License for more details. 31 * 32 * You should have received a copy of the GNU General Public License 33 * along with this program; if not, write to the Free Software 34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 35 */ 36 37 #include "../ccid.h" 38 #include "../dccp.h" 39 #include "lib/packet_history.h" 40 #include "lib/loss_interval.h" 41 #include "lib/tfrc.h" 42 #include "ccid3.h" 43 44 /* 45 * Reason for maths here is to avoid 32 bit overflow when a is big. 46 * With this we get close to the limit. 47 */ 48 static u32 usecs_div(const u32 a, const u32 b) 49 { 50 const u32 div = a < (UINT_MAX / (USEC_PER_SEC / 10)) ? 10 : 51 a < (UINT_MAX / (USEC_PER_SEC / 50)) ? 50 : 52 a < (UINT_MAX / (USEC_PER_SEC / 100)) ? 100 : 53 a < (UINT_MAX / (USEC_PER_SEC / 500)) ? 500 : 54 a < (UINT_MAX / (USEC_PER_SEC / 1000)) ? 1000 : 55 a < (UINT_MAX / (USEC_PER_SEC / 5000)) ? 5000 : 56 a < (UINT_MAX / (USEC_PER_SEC / 10000)) ? 10000 : 57 a < (UINT_MAX / (USEC_PER_SEC / 50000)) ? 50000 : 58 100000; 59 const u32 tmp = a * (USEC_PER_SEC / div); 60 return (b >= 2 * div) ? tmp / (b / div) : tmp; 61 } 62 63 static int ccid3_debug; 64 65 #ifdef CCID3_DEBUG 66 #define ccid3_pr_debug(format, a...) \ 67 do { if (ccid3_debug) \ 68 printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \ 69 } while (0) 70 #else 71 #define ccid3_pr_debug(format, a...) 72 #endif 73 74 static struct dccp_tx_hist *ccid3_tx_hist; 75 static struct dccp_rx_hist *ccid3_rx_hist; 76 static struct dccp_li_hist *ccid3_li_hist; 77 78 /* TFRC sender states */ 79 enum ccid3_hc_tx_states { 80 TFRC_SSTATE_NO_SENT = 1, 81 TFRC_SSTATE_NO_FBACK, 82 TFRC_SSTATE_FBACK, 83 TFRC_SSTATE_TERM, 84 }; 85 86 #ifdef CCID3_DEBUG 87 static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state) 88 { 89 static char *ccid3_state_names[] = { 90 [TFRC_SSTATE_NO_SENT] = "NO_SENT", 91 [TFRC_SSTATE_NO_FBACK] = "NO_FBACK", 92 [TFRC_SSTATE_FBACK] = "FBACK", 93 [TFRC_SSTATE_TERM] = "TERM", 94 }; 95 96 return ccid3_state_names[state]; 97 } 98 #endif 99 100 static void ccid3_hc_tx_set_state(struct sock *sk, 101 enum ccid3_hc_tx_states state) 102 { 103 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 104 enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state; 105 106 ccid3_pr_debug("%s(%p) %-8.8s -> %s\n", 107 dccp_role(sk), sk, ccid3_tx_state_name(oldstate), 108 ccid3_tx_state_name(state)); 109 WARN_ON(state == oldstate); 110 hctx->ccid3hctx_state = state; 111 } 112 113 /* Calculate new t_ipi (inter packet interval) by t_ipi = s / X_inst */ 114 static inline void ccid3_calc_new_t_ipi(struct ccid3_hc_tx_sock *hctx) 115 { 116 /* 117 * If no feedback spec says t_ipi is 1 second (set elsewhere and then 118 * doubles after every no feedback timer (separate function) 119 */ 120 if (hctx->ccid3hctx_state != TFRC_SSTATE_NO_FBACK) 121 hctx->ccid3hctx_t_ipi = usecs_div(hctx->ccid3hctx_s, 122 hctx->ccid3hctx_x); 123 } 124 125 /* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */ 126 static inline void ccid3_calc_new_delta(struct ccid3_hc_tx_sock *hctx) 127 { 128 hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2, 129 TFRC_OPSYS_HALF_TIME_GRAN); 130 } 131 132 /* 133 * Update X by 134 * If (p > 0) 135 * x_calc = calcX(s, R, p); 136 * X = max(min(X_calc, 2 * X_recv), s / t_mbi); 137 * Else 138 * If (now - tld >= R) 139 * X = max(min(2 * X, 2 * X_recv), s / R); 140 * tld = now; 141 */ 142 static void ccid3_hc_tx_update_x(struct sock *sk) 143 { 144 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 145 146 /* To avoid large error in calcX */ 147 if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) { 148 hctx->ccid3hctx_x_calc = tfrc_calc_x(hctx->ccid3hctx_s, 149 hctx->ccid3hctx_rtt, 150 hctx->ccid3hctx_p); 151 hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_calc, 152 2 * hctx->ccid3hctx_x_recv), 153 (hctx->ccid3hctx_s / 154 TFRC_MAX_BACK_OFF_TIME)); 155 } else { 156 struct timeval now; 157 158 dccp_timestamp(sk, &now); 159 if (timeval_delta(&now, &hctx->ccid3hctx_t_ld) >= 160 hctx->ccid3hctx_rtt) { 161 hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_recv, 162 hctx->ccid3hctx_x) * 2, 163 usecs_div(hctx->ccid3hctx_s, 164 hctx->ccid3hctx_rtt)); 165 hctx->ccid3hctx_t_ld = now; 166 } 167 } 168 } 169 170 static void ccid3_hc_tx_no_feedback_timer(unsigned long data) 171 { 172 struct sock *sk = (struct sock *)data; 173 unsigned long next_tmout = 0; 174 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 175 176 bh_lock_sock(sk); 177 if (sock_owned_by_user(sk)) { 178 /* Try again later. */ 179 /* XXX: set some sensible MIB */ 180 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 181 jiffies + HZ / 5); 182 goto out; 183 } 184 185 ccid3_pr_debug("%s, sk=%p, state=%s\n", dccp_role(sk), sk, 186 ccid3_tx_state_name(hctx->ccid3hctx_state)); 187 188 switch (hctx->ccid3hctx_state) { 189 case TFRC_SSTATE_TERM: 190 goto out; 191 case TFRC_SSTATE_NO_FBACK: 192 /* Halve send rate */ 193 hctx->ccid3hctx_x /= 2; 194 if (hctx->ccid3hctx_x < (hctx->ccid3hctx_s / 195 TFRC_MAX_BACK_OFF_TIME)) 196 hctx->ccid3hctx_x = (hctx->ccid3hctx_s / 197 TFRC_MAX_BACK_OFF_TIME); 198 199 ccid3_pr_debug("%s, sk=%p, state=%s, updated tx rate to %d " 200 "bytes/s\n", 201 dccp_role(sk), sk, 202 ccid3_tx_state_name(hctx->ccid3hctx_state), 203 hctx->ccid3hctx_x); 204 next_tmout = max_t(u32, 2 * usecs_div(hctx->ccid3hctx_s, 205 hctx->ccid3hctx_x), 206 TFRC_INITIAL_TIMEOUT); 207 /* 208 * FIXME - not sure above calculation is correct. See section 209 * 5 of CCID3 11 should adjust tx_t_ipi and double that to 210 * achieve it really 211 */ 212 break; 213 case TFRC_SSTATE_FBACK: 214 /* 215 * Check if IDLE since last timeout and recv rate is less than 216 * 4 packets per RTT 217 */ 218 if (!hctx->ccid3hctx_idle || 219 (hctx->ccid3hctx_x_recv >= 220 4 * usecs_div(hctx->ccid3hctx_s, hctx->ccid3hctx_rtt))) { 221 ccid3_pr_debug("%s, sk=%p, state=%s, not idle\n", 222 dccp_role(sk), sk, 223 ccid3_tx_state_name(hctx->ccid3hctx_state)); 224 /* Halve sending rate */ 225 226 /* If (X_calc > 2 * X_recv) 227 * X_recv = max(X_recv / 2, s / (2 * t_mbi)); 228 * Else 229 * X_recv = X_calc / 4; 230 */ 231 BUG_ON(hctx->ccid3hctx_p >= TFRC_SMALLEST_P && 232 hctx->ccid3hctx_x_calc == 0); 233 234 /* check also if p is zero -> x_calc is infinity? */ 235 if (hctx->ccid3hctx_p < TFRC_SMALLEST_P || 236 hctx->ccid3hctx_x_calc > 2 * hctx->ccid3hctx_x_recv) 237 hctx->ccid3hctx_x_recv = max_t(u32, hctx->ccid3hctx_x_recv / 2, 238 hctx->ccid3hctx_s / (2 * TFRC_MAX_BACK_OFF_TIME)); 239 else 240 hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc / 4; 241 242 /* Update sending rate */ 243 ccid3_hc_tx_update_x(sk); 244 } 245 /* 246 * Schedule no feedback timer to expire in 247 * max(4 * R, 2 * s / X) 248 */ 249 next_tmout = max_t(u32, hctx->ccid3hctx_t_rto, 250 2 * usecs_div(hctx->ccid3hctx_s, 251 hctx->ccid3hctx_x)); 252 break; 253 default: 254 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 255 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state); 256 dump_stack(); 257 goto out; 258 } 259 260 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 261 jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout))); 262 hctx->ccid3hctx_idle = 1; 263 out: 264 bh_unlock_sock(sk); 265 sock_put(sk); 266 } 267 268 static int ccid3_hc_tx_send_packet(struct sock *sk, 269 struct sk_buff *skb, int len) 270 { 271 struct dccp_sock *dp = dccp_sk(sk); 272 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 273 struct dccp_tx_hist_entry *new_packet; 274 struct timeval now; 275 long delay; 276 int rc = -ENOTCONN; 277 278 BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM); 279 280 /* Check if pure ACK or Terminating*/ 281 /* 282 * XXX: We only call this function for DATA and DATAACK, on, these 283 * packets can have zero length, but why the comment about "pure ACK"? 284 */ 285 if (unlikely(len == 0)) 286 goto out; 287 288 /* See if last packet allocated was not sent */ 289 new_packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist); 290 if (new_packet == NULL || new_packet->dccphtx_sent) { 291 new_packet = dccp_tx_hist_entry_new(ccid3_tx_hist, 292 SLAB_ATOMIC); 293 294 rc = -ENOBUFS; 295 if (unlikely(new_packet == NULL)) { 296 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, not enough " 297 "mem to add to history, send refused\n", 298 __FUNCTION__, dccp_role(sk), sk); 299 goto out; 300 } 301 302 dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet); 303 } 304 305 dccp_timestamp(sk, &now); 306 307 switch (hctx->ccid3hctx_state) { 308 case TFRC_SSTATE_NO_SENT: 309 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 310 jiffies + usecs_to_jiffies(TFRC_INITIAL_TIMEOUT)); 311 hctx->ccid3hctx_last_win_count = 0; 312 hctx->ccid3hctx_t_last_win_count = now; 313 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK); 314 hctx->ccid3hctx_t_ipi = TFRC_INITIAL_IPI; 315 316 /* Set nominal send time for initial packet */ 317 hctx->ccid3hctx_t_nom = now; 318 timeval_add_usecs(&hctx->ccid3hctx_t_nom, 319 hctx->ccid3hctx_t_ipi); 320 ccid3_calc_new_delta(hctx); 321 rc = 0; 322 break; 323 case TFRC_SSTATE_NO_FBACK: 324 case TFRC_SSTATE_FBACK: 325 delay = (timeval_delta(&now, &hctx->ccid3hctx_t_nom) - 326 hctx->ccid3hctx_delta); 327 delay /= -1000; 328 /* divide by -1000 is to convert to ms and get sign right */ 329 rc = delay > 0 ? delay : 0; 330 break; 331 default: 332 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 333 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state); 334 dump_stack(); 335 rc = -EINVAL; 336 break; 337 } 338 339 /* Can we send? if so add options and add to packet history */ 340 if (rc == 0) { 341 dp->dccps_hc_tx_insert_options = 1; 342 new_packet->dccphtx_ccval = 343 DCCP_SKB_CB(skb)->dccpd_ccval = 344 hctx->ccid3hctx_last_win_count; 345 timeval_add_usecs(&hctx->ccid3hctx_t_nom, 346 hctx->ccid3hctx_t_ipi); 347 } 348 out: 349 return rc; 350 } 351 352 static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len) 353 { 354 const struct dccp_sock *dp = dccp_sk(sk); 355 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 356 struct timeval now; 357 358 BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM); 359 360 dccp_timestamp(sk, &now); 361 362 /* check if we have sent a data packet */ 363 if (len > 0) { 364 unsigned long quarter_rtt; 365 struct dccp_tx_hist_entry *packet; 366 367 packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist); 368 if (unlikely(packet == NULL)) { 369 LIMIT_NETDEBUG(KERN_WARNING "%s: packet doesn't " 370 "exists in history!\n", __FUNCTION__); 371 return; 372 } 373 if (unlikely(packet->dccphtx_sent)) { 374 LIMIT_NETDEBUG(KERN_WARNING "%s: no unsent packet in " 375 "history!\n", __FUNCTION__); 376 return; 377 } 378 packet->dccphtx_tstamp = now; 379 packet->dccphtx_seqno = dp->dccps_gss; 380 /* 381 * Check if win_count have changed 382 * Algorithm in "8.1. Window Counter Valuer" in 383 * draft-ietf-dccp-ccid3-11.txt 384 */ 385 quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count); 386 if (likely(hctx->ccid3hctx_rtt > 8)) 387 quarter_rtt /= hctx->ccid3hctx_rtt / 4; 388 389 if (quarter_rtt > 0) { 390 hctx->ccid3hctx_t_last_win_count = now; 391 hctx->ccid3hctx_last_win_count = (hctx->ccid3hctx_last_win_count + 392 min_t(unsigned long, quarter_rtt, 5)) % 16; 393 ccid3_pr_debug("%s, sk=%p, window changed from " 394 "%u to %u!\n", 395 dccp_role(sk), sk, 396 packet->dccphtx_ccval, 397 hctx->ccid3hctx_last_win_count); 398 } 399 400 hctx->ccid3hctx_idle = 0; 401 packet->dccphtx_rtt = hctx->ccid3hctx_rtt; 402 packet->dccphtx_sent = 1; 403 } else 404 ccid3_pr_debug("%s, sk=%p, seqno=%llu NOT inserted!\n", 405 dccp_role(sk), sk, dp->dccps_gss); 406 407 switch (hctx->ccid3hctx_state) { 408 case TFRC_SSTATE_NO_SENT: 409 /* if first wasn't pure ack */ 410 if (len != 0) 411 printk(KERN_CRIT "%s: %s, First packet sent is noted " 412 "as a data packet\n", 413 __FUNCTION__, dccp_role(sk)); 414 return; 415 case TFRC_SSTATE_NO_FBACK: 416 case TFRC_SSTATE_FBACK: 417 if (len > 0) { 418 timeval_sub_usecs(&hctx->ccid3hctx_t_nom, 419 hctx->ccid3hctx_t_ipi); 420 ccid3_calc_new_t_ipi(hctx); 421 ccid3_calc_new_delta(hctx); 422 timeval_add_usecs(&hctx->ccid3hctx_t_nom, 423 hctx->ccid3hctx_t_ipi); 424 } 425 break; 426 default: 427 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 428 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state); 429 dump_stack(); 430 break; 431 } 432 } 433 434 static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) 435 { 436 const struct dccp_sock *dp = dccp_sk(sk); 437 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 438 struct ccid3_options_received *opt_recv; 439 struct dccp_tx_hist_entry *packet; 440 struct timeval now; 441 unsigned long next_tmout; 442 u32 t_elapsed; 443 u32 pinv; 444 u32 x_recv; 445 u32 r_sample; 446 447 BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM); 448 449 /* we are only interested in ACKs */ 450 if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK || 451 DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK)) 452 return; 453 454 opt_recv = &hctx->ccid3hctx_options_received; 455 456 t_elapsed = dp->dccps_options_received.dccpor_elapsed_time * 10; 457 x_recv = opt_recv->ccid3or_receive_rate; 458 pinv = opt_recv->ccid3or_loss_event_rate; 459 460 switch (hctx->ccid3hctx_state) { 461 case TFRC_SSTATE_NO_SENT: 462 /* FIXME: what to do here? */ 463 return; 464 case TFRC_SSTATE_NO_FBACK: 465 case TFRC_SSTATE_FBACK: 466 /* Calculate new round trip sample by 467 * R_sample = (now - t_recvdata) - t_delay */ 468 /* get t_recvdata from history */ 469 packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist, 470 DCCP_SKB_CB(skb)->dccpd_ack_seq); 471 if (unlikely(packet == NULL)) { 472 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, seqno " 473 "%llu(%s) does't exist in history!\n", 474 __FUNCTION__, dccp_role(sk), sk, 475 (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq, 476 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type)); 477 return; 478 } 479 480 /* Update RTT */ 481 dccp_timestamp(sk, &now); 482 r_sample = timeval_delta(&now, &packet->dccphtx_tstamp); 483 if (unlikely(r_sample <= t_elapsed)) 484 LIMIT_NETDEBUG(KERN_WARNING "%s: r_sample=%uus, " 485 "t_elapsed=%uus\n", 486 __FUNCTION__, r_sample, t_elapsed); 487 else 488 r_sample -= t_elapsed; 489 490 /* Update RTT estimate by 491 * If (No feedback recv) 492 * R = R_sample; 493 * Else 494 * R = q * R + (1 - q) * R_sample; 495 * 496 * q is a constant, RFC 3448 recomments 0.9 497 */ 498 if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) { 499 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK); 500 hctx->ccid3hctx_rtt = r_sample; 501 } else 502 hctx->ccid3hctx_rtt = (hctx->ccid3hctx_rtt * 9) / 10 + 503 r_sample / 10; 504 505 ccid3_pr_debug("%s, sk=%p, New RTT estimate=%uus, " 506 "r_sample=%us\n", dccp_role(sk), sk, 507 hctx->ccid3hctx_rtt, r_sample); 508 509 /* Update timeout interval */ 510 hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt, 511 USEC_PER_SEC); 512 513 /* Update receive rate */ 514 hctx->ccid3hctx_x_recv = x_recv;/* X_recv in bytes per sec */ 515 516 /* Update loss event rate */ 517 if (pinv == ~0 || pinv == 0) 518 hctx->ccid3hctx_p = 0; 519 else { 520 hctx->ccid3hctx_p = 1000000 / pinv; 521 522 if (hctx->ccid3hctx_p < TFRC_SMALLEST_P) { 523 hctx->ccid3hctx_p = TFRC_SMALLEST_P; 524 ccid3_pr_debug("%s, sk=%p, Smallest p used!\n", 525 dccp_role(sk), sk); 526 } 527 } 528 529 /* unschedule no feedback timer */ 530 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer); 531 532 /* Update sending rate */ 533 ccid3_hc_tx_update_x(sk); 534 535 /* Update next send time */ 536 timeval_sub_usecs(&hctx->ccid3hctx_t_nom, 537 hctx->ccid3hctx_t_ipi); 538 ccid3_calc_new_t_ipi(hctx); 539 timeval_add_usecs(&hctx->ccid3hctx_t_nom, 540 hctx->ccid3hctx_t_ipi); 541 ccid3_calc_new_delta(hctx); 542 543 /* remove all packets older than the one acked from history */ 544 dccp_tx_hist_purge_older(ccid3_tx_hist, 545 &hctx->ccid3hctx_hist, packet); 546 /* 547 * As we have calculated new ipi, delta, t_nom it is possible that 548 * we now can send a packet, so wake up dccp_wait_for_ccids. 549 */ 550 sk->sk_write_space(sk); 551 552 /* 553 * Schedule no feedback timer to expire in 554 * max(4 * R, 2 * s / X) 555 */ 556 next_tmout = max(hctx->ccid3hctx_t_rto, 557 2 * usecs_div(hctx->ccid3hctx_s, 558 hctx->ccid3hctx_x)); 559 560 ccid3_pr_debug("%s, sk=%p, Scheduled no feedback timer to " 561 "expire in %lu jiffies (%luus)\n", 562 dccp_role(sk), sk, 563 usecs_to_jiffies(next_tmout), next_tmout); 564 565 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 566 jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout))); 567 568 /* set idle flag */ 569 hctx->ccid3hctx_idle = 1; 570 break; 571 default: 572 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 573 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state); 574 dump_stack(); 575 break; 576 } 577 } 578 579 static int ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb) 580 { 581 const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 582 583 BUG_ON(hctx == NULL); 584 585 if (sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN) 586 DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count; 587 return 0; 588 } 589 590 static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, 591 unsigned char len, u16 idx, 592 unsigned char *value) 593 { 594 int rc = 0; 595 const struct dccp_sock *dp = dccp_sk(sk); 596 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 597 struct ccid3_options_received *opt_recv; 598 599 BUG_ON(hctx == NULL); 600 601 opt_recv = &hctx->ccid3hctx_options_received; 602 603 if (opt_recv->ccid3or_seqno != dp->dccps_gsr) { 604 opt_recv->ccid3or_seqno = dp->dccps_gsr; 605 opt_recv->ccid3or_loss_event_rate = ~0; 606 opt_recv->ccid3or_loss_intervals_idx = 0; 607 opt_recv->ccid3or_loss_intervals_len = 0; 608 opt_recv->ccid3or_receive_rate = 0; 609 } 610 611 switch (option) { 612 case TFRC_OPT_LOSS_EVENT_RATE: 613 if (unlikely(len != 4)) { 614 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, invalid " 615 "len for TFRC_OPT_LOSS_EVENT_RATE\n", 616 __FUNCTION__, dccp_role(sk), sk); 617 rc = -EINVAL; 618 } else { 619 opt_recv->ccid3or_loss_event_rate = ntohl(*(__be32 *)value); 620 ccid3_pr_debug("%s, sk=%p, LOSS_EVENT_RATE=%u\n", 621 dccp_role(sk), sk, 622 opt_recv->ccid3or_loss_event_rate); 623 } 624 break; 625 case TFRC_OPT_LOSS_INTERVALS: 626 opt_recv->ccid3or_loss_intervals_idx = idx; 627 opt_recv->ccid3or_loss_intervals_len = len; 628 ccid3_pr_debug("%s, sk=%p, LOSS_INTERVALS=(%u, %u)\n", 629 dccp_role(sk), sk, 630 opt_recv->ccid3or_loss_intervals_idx, 631 opt_recv->ccid3or_loss_intervals_len); 632 break; 633 case TFRC_OPT_RECEIVE_RATE: 634 if (unlikely(len != 4)) { 635 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, invalid " 636 "len for TFRC_OPT_RECEIVE_RATE\n", 637 __FUNCTION__, dccp_role(sk), sk); 638 rc = -EINVAL; 639 } else { 640 opt_recv->ccid3or_receive_rate = ntohl(*(__be32 *)value); 641 ccid3_pr_debug("%s, sk=%p, RECEIVE_RATE=%u\n", 642 dccp_role(sk), sk, 643 opt_recv->ccid3or_receive_rate); 644 } 645 break; 646 } 647 648 return rc; 649 } 650 651 static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk) 652 { 653 struct dccp_sock *dp = dccp_sk(sk); 654 struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid); 655 656 if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && 657 dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE) 658 hctx->ccid3hctx_s = dp->dccps_packet_size; 659 else 660 hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE; 661 662 /* Set transmission rate to 1 packet per second */ 663 hctx->ccid3hctx_x = hctx->ccid3hctx_s; 664 hctx->ccid3hctx_t_rto = USEC_PER_SEC; 665 hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT; 666 INIT_LIST_HEAD(&hctx->ccid3hctx_hist); 667 668 hctx->ccid3hctx_no_feedback_timer.function = ccid3_hc_tx_no_feedback_timer; 669 hctx->ccid3hctx_no_feedback_timer.data = (unsigned long)sk; 670 init_timer(&hctx->ccid3hctx_no_feedback_timer); 671 672 return 0; 673 } 674 675 static void ccid3_hc_tx_exit(struct sock *sk) 676 { 677 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 678 679 BUG_ON(hctx == NULL); 680 681 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM); 682 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer); 683 684 /* Empty packet history */ 685 dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist); 686 } 687 688 /* 689 * RX Half Connection methods 690 */ 691 692 /* TFRC receiver states */ 693 enum ccid3_hc_rx_states { 694 TFRC_RSTATE_NO_DATA = 1, 695 TFRC_RSTATE_DATA, 696 TFRC_RSTATE_TERM = 127, 697 }; 698 699 #ifdef CCID3_DEBUG 700 static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state) 701 { 702 static char *ccid3_rx_state_names[] = { 703 [TFRC_RSTATE_NO_DATA] = "NO_DATA", 704 [TFRC_RSTATE_DATA] = "DATA", 705 [TFRC_RSTATE_TERM] = "TERM", 706 }; 707 708 return ccid3_rx_state_names[state]; 709 } 710 #endif 711 712 static void ccid3_hc_rx_set_state(struct sock *sk, 713 enum ccid3_hc_rx_states state) 714 { 715 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 716 enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state; 717 718 ccid3_pr_debug("%s(%p) %-8.8s -> %s\n", 719 dccp_role(sk), sk, ccid3_rx_state_name(oldstate), 720 ccid3_rx_state_name(state)); 721 WARN_ON(state == oldstate); 722 hcrx->ccid3hcrx_state = state; 723 } 724 725 static void ccid3_hc_rx_send_feedback(struct sock *sk) 726 { 727 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 728 struct dccp_sock *dp = dccp_sk(sk); 729 struct dccp_rx_hist_entry *packet; 730 struct timeval now; 731 732 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 733 734 dccp_timestamp(sk, &now); 735 736 switch (hcrx->ccid3hcrx_state) { 737 case TFRC_RSTATE_NO_DATA: 738 hcrx->ccid3hcrx_x_recv = 0; 739 break; 740 case TFRC_RSTATE_DATA: { 741 const u32 delta = timeval_delta(&now, 742 &hcrx->ccid3hcrx_tstamp_last_feedback); 743 hcrx->ccid3hcrx_x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv, 744 delta); 745 } 746 break; 747 default: 748 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 749 __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state); 750 dump_stack(); 751 return; 752 } 753 754 packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist); 755 if (unlikely(packet == NULL)) { 756 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, no data packet " 757 "in history!\n", 758 __FUNCTION__, dccp_role(sk), sk); 759 return; 760 } 761 762 hcrx->ccid3hcrx_tstamp_last_feedback = now; 763 hcrx->ccid3hcrx_ccval_last_counter = packet->dccphrx_ccval; 764 hcrx->ccid3hcrx_bytes_recv = 0; 765 766 /* Convert to multiples of 10us */ 767 hcrx->ccid3hcrx_elapsed_time = 768 timeval_delta(&now, &packet->dccphrx_tstamp) / 10; 769 if (hcrx->ccid3hcrx_p == 0) 770 hcrx->ccid3hcrx_pinv = ~0; 771 else 772 hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p; 773 dp->dccps_hc_rx_insert_options = 1; 774 dccp_send_ack(sk); 775 } 776 777 static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb) 778 { 779 const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 780 __be32 x_recv, pinv; 781 782 BUG_ON(hcrx == NULL); 783 784 if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)) 785 return 0; 786 787 DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_ccval_last_counter; 788 789 if (dccp_packet_without_ack(skb)) 790 return 0; 791 792 x_recv = htonl(hcrx->ccid3hcrx_x_recv); 793 pinv = htonl(hcrx->ccid3hcrx_pinv); 794 795 if ((hcrx->ccid3hcrx_elapsed_time != 0 && 796 dccp_insert_option_elapsed_time(sk, skb, 797 hcrx->ccid3hcrx_elapsed_time)) || 798 dccp_insert_option_timestamp(sk, skb) || 799 dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE, 800 &pinv, sizeof(pinv)) || 801 dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE, 802 &x_recv, sizeof(x_recv))) 803 return -1; 804 805 return 0; 806 } 807 808 /* calculate first loss interval 809 * 810 * returns estimated loss interval in usecs */ 811 812 static u32 ccid3_hc_rx_calc_first_li(struct sock *sk) 813 { 814 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 815 struct dccp_rx_hist_entry *entry, *next, *tail = NULL; 816 u32 rtt, delta, x_recv, fval, p, tmp2; 817 struct timeval tstamp = { 0, }; 818 int interval = 0; 819 int win_count = 0; 820 int step = 0; 821 u64 tmp1; 822 823 list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist, 824 dccphrx_node) { 825 if (dccp_rx_hist_entry_data_packet(entry)) { 826 tail = entry; 827 828 switch (step) { 829 case 0: 830 tstamp = entry->dccphrx_tstamp; 831 win_count = entry->dccphrx_ccval; 832 step = 1; 833 break; 834 case 1: 835 interval = win_count - entry->dccphrx_ccval; 836 if (interval < 0) 837 interval += TFRC_WIN_COUNT_LIMIT; 838 if (interval > 4) 839 goto found; 840 break; 841 } 842 } 843 } 844 845 if (unlikely(step == 0)) { 846 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, packet history " 847 "contains no data packets!\n", 848 __FUNCTION__, dccp_role(sk), sk); 849 return ~0; 850 } 851 852 if (unlikely(interval == 0)) { 853 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, Could not find a " 854 "win_count interval > 0. Defaulting to 1\n", 855 __FUNCTION__, dccp_role(sk), sk); 856 interval = 1; 857 } 858 found: 859 if (!tail) { 860 LIMIT_NETDEBUG(KERN_WARNING "%s: tail is null\n", 861 __FUNCTION__); 862 return ~0; 863 } 864 rtt = timeval_delta(&tstamp, &tail->dccphrx_tstamp) * 4 / interval; 865 ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n", 866 dccp_role(sk), sk, rtt); 867 if (rtt == 0) 868 rtt = 1; 869 870 dccp_timestamp(sk, &tstamp); 871 delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback); 872 x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv, delta); 873 874 if (x_recv == 0) 875 x_recv = hcrx->ccid3hcrx_x_recv; 876 877 tmp1 = (u64)x_recv * (u64)rtt; 878 do_div(tmp1,10000000); 879 tmp2 = (u32)tmp1; 880 881 if (!tmp2) { 882 LIMIT_NETDEBUG(KERN_WARNING "tmp2 = 0 " 883 "%s: x_recv = %u, rtt =%u\n", 884 __FUNCTION__, x_recv, rtt); 885 return ~0; 886 } 887 888 fval = (hcrx->ccid3hcrx_s * 100000) / tmp2; 889 /* do not alter order above or you will get overflow on 32 bit */ 890 p = tfrc_calc_x_reverse_lookup(fval); 891 ccid3_pr_debug("%s, sk=%p, receive rate=%u bytes/s, implied " 892 "loss rate=%u\n", dccp_role(sk), sk, x_recv, p); 893 894 if (p == 0) 895 return ~0; 896 else 897 return 1000000 / p; 898 } 899 900 static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss) 901 { 902 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 903 struct dccp_li_hist_entry *next, *head; 904 u64 seq_temp; 905 906 if (list_empty(&hcrx->ccid3hcrx_li_hist)) { 907 if (!dccp_li_hist_interval_new(ccid3_li_hist, 908 &hcrx->ccid3hcrx_li_hist, seq_loss, win_loss)) 909 return; 910 911 next = (struct dccp_li_hist_entry *) 912 hcrx->ccid3hcrx_li_hist.next; 913 next->dccplih_interval = ccid3_hc_rx_calc_first_li(sk); 914 } else { 915 struct dccp_li_hist_entry *entry; 916 struct list_head *tail; 917 918 head = (struct dccp_li_hist_entry *) 919 hcrx->ccid3hcrx_li_hist.next; 920 /* FIXME win count check removed as was wrong */ 921 /* should make this check with receive history */ 922 /* and compare there as per section 10.2 of RFC4342 */ 923 924 /* new loss event detected */ 925 /* calculate last interval length */ 926 seq_temp = dccp_delta_seqno(head->dccplih_seqno, seq_loss); 927 entry = dccp_li_hist_entry_new(ccid3_li_hist, SLAB_ATOMIC); 928 929 if (entry == NULL) { 930 printk(KERN_CRIT "%s: out of memory\n",__FUNCTION__); 931 dump_stack(); 932 return; 933 } 934 935 list_add(&entry->dccplih_node, &hcrx->ccid3hcrx_li_hist); 936 937 tail = hcrx->ccid3hcrx_li_hist.prev; 938 list_del(tail); 939 kmem_cache_free(ccid3_li_hist->dccplih_slab, tail); 940 941 /* Create the newest interval */ 942 entry->dccplih_seqno = seq_loss; 943 entry->dccplih_interval = seq_temp; 944 entry->dccplih_win_count = win_loss; 945 } 946 } 947 948 static int ccid3_hc_rx_detect_loss(struct sock *sk, 949 struct dccp_rx_hist_entry *packet) 950 { 951 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 952 struct dccp_rx_hist_entry *rx_hist = dccp_rx_hist_head(&hcrx->ccid3hcrx_hist); 953 u64 seqno = packet->dccphrx_seqno; 954 u64 tmp_seqno; 955 int loss = 0; 956 u8 ccval; 957 958 959 tmp_seqno = hcrx->ccid3hcrx_seqno_nonloss; 960 961 if (!rx_hist || 962 follows48(packet->dccphrx_seqno, hcrx->ccid3hcrx_seqno_nonloss)) { 963 hcrx->ccid3hcrx_seqno_nonloss = seqno; 964 hcrx->ccid3hcrx_ccval_nonloss = packet->dccphrx_ccval; 965 goto detect_out; 966 } 967 968 969 while (dccp_delta_seqno(hcrx->ccid3hcrx_seqno_nonloss, seqno) 970 > TFRC_RECV_NUM_LATE_LOSS) { 971 loss = 1; 972 ccid3_hc_rx_update_li(sk, hcrx->ccid3hcrx_seqno_nonloss, 973 hcrx->ccid3hcrx_ccval_nonloss); 974 tmp_seqno = hcrx->ccid3hcrx_seqno_nonloss; 975 dccp_inc_seqno(&tmp_seqno); 976 hcrx->ccid3hcrx_seqno_nonloss = tmp_seqno; 977 dccp_inc_seqno(&tmp_seqno); 978 while (dccp_rx_hist_find_entry(&hcrx->ccid3hcrx_hist, 979 tmp_seqno, &ccval)) { 980 hcrx->ccid3hcrx_seqno_nonloss = tmp_seqno; 981 hcrx->ccid3hcrx_ccval_nonloss = ccval; 982 dccp_inc_seqno(&tmp_seqno); 983 } 984 } 985 986 /* FIXME - this code could be simplified with above while */ 987 /* but works at moment */ 988 if (follows48(packet->dccphrx_seqno, hcrx->ccid3hcrx_seqno_nonloss)) { 989 hcrx->ccid3hcrx_seqno_nonloss = seqno; 990 hcrx->ccid3hcrx_ccval_nonloss = packet->dccphrx_ccval; 991 } 992 993 detect_out: 994 dccp_rx_hist_add_packet(ccid3_rx_hist, &hcrx->ccid3hcrx_hist, 995 &hcrx->ccid3hcrx_li_hist, packet, 996 hcrx->ccid3hcrx_seqno_nonloss); 997 return loss; 998 } 999 1000 static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) 1001 { 1002 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 1003 const struct dccp_options_received *opt_recv; 1004 struct dccp_rx_hist_entry *packet; 1005 struct timeval now; 1006 u8 win_count; 1007 u32 p_prev, rtt_prev, r_sample, t_elapsed; 1008 int loss; 1009 1010 BUG_ON(hcrx == NULL || 1011 !(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA || 1012 hcrx->ccid3hcrx_state == TFRC_RSTATE_DATA)); 1013 1014 opt_recv = &dccp_sk(sk)->dccps_options_received; 1015 1016 switch (DCCP_SKB_CB(skb)->dccpd_type) { 1017 case DCCP_PKT_ACK: 1018 if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA) 1019 return; 1020 case DCCP_PKT_DATAACK: 1021 if (opt_recv->dccpor_timestamp_echo == 0) 1022 break; 1023 rtt_prev = hcrx->ccid3hcrx_rtt; 1024 dccp_timestamp(sk, &now); 1025 timeval_sub_usecs(&now, opt_recv->dccpor_timestamp_echo * 10); 1026 r_sample = timeval_usecs(&now); 1027 t_elapsed = opt_recv->dccpor_elapsed_time * 10; 1028 1029 if (unlikely(r_sample <= t_elapsed)) 1030 LIMIT_NETDEBUG(KERN_WARNING "%s: r_sample=%uus, " 1031 "t_elapsed=%uus\n", 1032 __FUNCTION__, r_sample, t_elapsed); 1033 else 1034 r_sample -= t_elapsed; 1035 1036 if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA) 1037 hcrx->ccid3hcrx_rtt = r_sample; 1038 else 1039 hcrx->ccid3hcrx_rtt = (hcrx->ccid3hcrx_rtt * 9) / 10 + 1040 r_sample / 10; 1041 1042 if (rtt_prev != hcrx->ccid3hcrx_rtt) 1043 ccid3_pr_debug("%s, New RTT=%uus, elapsed time=%u\n", 1044 dccp_role(sk), hcrx->ccid3hcrx_rtt, 1045 opt_recv->dccpor_elapsed_time); 1046 break; 1047 case DCCP_PKT_DATA: 1048 break; 1049 default: /* We're not interested in other packet types, move along */ 1050 return; 1051 } 1052 1053 packet = dccp_rx_hist_entry_new(ccid3_rx_hist, sk, opt_recv->dccpor_ndp, 1054 skb, SLAB_ATOMIC); 1055 if (unlikely(packet == NULL)) { 1056 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, Not enough mem to " 1057 "add rx packet to history, consider it lost!\n", 1058 __FUNCTION__, dccp_role(sk), sk); 1059 return; 1060 } 1061 1062 win_count = packet->dccphrx_ccval; 1063 1064 loss = ccid3_hc_rx_detect_loss(sk, packet); 1065 1066 if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK) 1067 return; 1068 1069 switch (hcrx->ccid3hcrx_state) { 1070 case TFRC_RSTATE_NO_DATA: 1071 ccid3_pr_debug("%s, sk=%p(%s), skb=%p, sending initial " 1072 "feedback\n", 1073 dccp_role(sk), sk, 1074 dccp_state_name(sk->sk_state), skb); 1075 ccid3_hc_rx_send_feedback(sk); 1076 ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA); 1077 return; 1078 case TFRC_RSTATE_DATA: 1079 hcrx->ccid3hcrx_bytes_recv += skb->len - 1080 dccp_hdr(skb)->dccph_doff * 4; 1081 if (loss) 1082 break; 1083 1084 dccp_timestamp(sk, &now); 1085 if (timeval_delta(&now, &hcrx->ccid3hcrx_tstamp_last_ack) >= 1086 hcrx->ccid3hcrx_rtt) { 1087 hcrx->ccid3hcrx_tstamp_last_ack = now; 1088 ccid3_hc_rx_send_feedback(sk); 1089 } 1090 return; 1091 default: 1092 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 1093 __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state); 1094 dump_stack(); 1095 return; 1096 } 1097 1098 /* Dealing with packet loss */ 1099 ccid3_pr_debug("%s, sk=%p(%s), data loss! Reacting...\n", 1100 dccp_role(sk), sk, dccp_state_name(sk->sk_state)); 1101 1102 p_prev = hcrx->ccid3hcrx_p; 1103 1104 /* Calculate loss event rate */ 1105 if (!list_empty(&hcrx->ccid3hcrx_li_hist)) { 1106 u32 i_mean = dccp_li_hist_calc_i_mean(&hcrx->ccid3hcrx_li_hist); 1107 1108 /* Scaling up by 1000000 as fixed decimal */ 1109 if (i_mean != 0) 1110 hcrx->ccid3hcrx_p = 1000000 / i_mean; 1111 } else { 1112 printk(KERN_CRIT "%s: empty loss hist\n",__FUNCTION__); 1113 dump_stack(); 1114 } 1115 1116 if (hcrx->ccid3hcrx_p > p_prev) { 1117 ccid3_hc_rx_send_feedback(sk); 1118 return; 1119 } 1120 } 1121 1122 static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk) 1123 { 1124 struct dccp_sock *dp = dccp_sk(sk); 1125 struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid); 1126 1127 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 1128 1129 if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && 1130 dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE) 1131 hcrx->ccid3hcrx_s = dp->dccps_packet_size; 1132 else 1133 hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE; 1134 1135 hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA; 1136 INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist); 1137 INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist); 1138 dccp_timestamp(sk, &hcrx->ccid3hcrx_tstamp_last_ack); 1139 hcrx->ccid3hcrx_tstamp_last_feedback = hcrx->ccid3hcrx_tstamp_last_ack; 1140 hcrx->ccid3hcrx_rtt = 5000; /* XXX 5ms for now... */ 1141 return 0; 1142 } 1143 1144 static void ccid3_hc_rx_exit(struct sock *sk) 1145 { 1146 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 1147 1148 BUG_ON(hcrx == NULL); 1149 1150 ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM); 1151 1152 /* Empty packet history */ 1153 dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist); 1154 1155 /* Empty loss interval history */ 1156 dccp_li_hist_purge(ccid3_li_hist, &hcrx->ccid3hcrx_li_hist); 1157 } 1158 1159 static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info) 1160 { 1161 const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 1162 1163 /* Listen socks doesn't have a private CCID block */ 1164 if (sk->sk_state == DCCP_LISTEN) 1165 return; 1166 1167 BUG_ON(hcrx == NULL); 1168 1169 info->tcpi_ca_state = hcrx->ccid3hcrx_state; 1170 info->tcpi_options |= TCPI_OPT_TIMESTAMPS; 1171 info->tcpi_rcv_rtt = hcrx->ccid3hcrx_rtt; 1172 } 1173 1174 static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info) 1175 { 1176 const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 1177 1178 /* Listen socks doesn't have a private CCID block */ 1179 if (sk->sk_state == DCCP_LISTEN) 1180 return; 1181 1182 BUG_ON(hctx == NULL); 1183 1184 info->tcpi_rto = hctx->ccid3hctx_t_rto; 1185 info->tcpi_rtt = hctx->ccid3hctx_rtt; 1186 } 1187 1188 static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len, 1189 u32 __user *optval, int __user *optlen) 1190 { 1191 const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 1192 const void *val; 1193 1194 /* Listen socks doesn't have a private CCID block */ 1195 if (sk->sk_state == DCCP_LISTEN) 1196 return -EINVAL; 1197 1198 switch (optname) { 1199 case DCCP_SOCKOPT_CCID_RX_INFO: 1200 if (len < sizeof(hcrx->ccid3hcrx_tfrc)) 1201 return -EINVAL; 1202 len = sizeof(hcrx->ccid3hcrx_tfrc); 1203 val = &hcrx->ccid3hcrx_tfrc; 1204 break; 1205 default: 1206 return -ENOPROTOOPT; 1207 } 1208 1209 if (put_user(len, optlen) || copy_to_user(optval, val, len)) 1210 return -EFAULT; 1211 1212 return 0; 1213 } 1214 1215 static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len, 1216 u32 __user *optval, int __user *optlen) 1217 { 1218 const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 1219 const void *val; 1220 1221 /* Listen socks doesn't have a private CCID block */ 1222 if (sk->sk_state == DCCP_LISTEN) 1223 return -EINVAL; 1224 1225 switch (optname) { 1226 case DCCP_SOCKOPT_CCID_TX_INFO: 1227 if (len < sizeof(hctx->ccid3hctx_tfrc)) 1228 return -EINVAL; 1229 len = sizeof(hctx->ccid3hctx_tfrc); 1230 val = &hctx->ccid3hctx_tfrc; 1231 break; 1232 default: 1233 return -ENOPROTOOPT; 1234 } 1235 1236 if (put_user(len, optlen) || copy_to_user(optval, val, len)) 1237 return -EFAULT; 1238 1239 return 0; 1240 } 1241 1242 static struct ccid_operations ccid3 = { 1243 .ccid_id = 3, 1244 .ccid_name = "ccid3", 1245 .ccid_owner = THIS_MODULE, 1246 .ccid_hc_tx_obj_size = sizeof(struct ccid3_hc_tx_sock), 1247 .ccid_hc_tx_init = ccid3_hc_tx_init, 1248 .ccid_hc_tx_exit = ccid3_hc_tx_exit, 1249 .ccid_hc_tx_send_packet = ccid3_hc_tx_send_packet, 1250 .ccid_hc_tx_packet_sent = ccid3_hc_tx_packet_sent, 1251 .ccid_hc_tx_packet_recv = ccid3_hc_tx_packet_recv, 1252 .ccid_hc_tx_insert_options = ccid3_hc_tx_insert_options, 1253 .ccid_hc_tx_parse_options = ccid3_hc_tx_parse_options, 1254 .ccid_hc_rx_obj_size = sizeof(struct ccid3_hc_rx_sock), 1255 .ccid_hc_rx_init = ccid3_hc_rx_init, 1256 .ccid_hc_rx_exit = ccid3_hc_rx_exit, 1257 .ccid_hc_rx_insert_options = ccid3_hc_rx_insert_options, 1258 .ccid_hc_rx_packet_recv = ccid3_hc_rx_packet_recv, 1259 .ccid_hc_rx_get_info = ccid3_hc_rx_get_info, 1260 .ccid_hc_tx_get_info = ccid3_hc_tx_get_info, 1261 .ccid_hc_rx_getsockopt = ccid3_hc_rx_getsockopt, 1262 .ccid_hc_tx_getsockopt = ccid3_hc_tx_getsockopt, 1263 }; 1264 1265 module_param(ccid3_debug, int, 0444); 1266 MODULE_PARM_DESC(ccid3_debug, "Enable debug messages"); 1267 1268 static __init int ccid3_module_init(void) 1269 { 1270 int rc = -ENOBUFS; 1271 1272 ccid3_rx_hist = dccp_rx_hist_new("ccid3"); 1273 if (ccid3_rx_hist == NULL) 1274 goto out; 1275 1276 ccid3_tx_hist = dccp_tx_hist_new("ccid3"); 1277 if (ccid3_tx_hist == NULL) 1278 goto out_free_rx; 1279 1280 ccid3_li_hist = dccp_li_hist_new("ccid3"); 1281 if (ccid3_li_hist == NULL) 1282 goto out_free_tx; 1283 1284 rc = ccid_register(&ccid3); 1285 if (rc != 0) 1286 goto out_free_loss_interval_history; 1287 out: 1288 return rc; 1289 1290 out_free_loss_interval_history: 1291 dccp_li_hist_delete(ccid3_li_hist); 1292 ccid3_li_hist = NULL; 1293 out_free_tx: 1294 dccp_tx_hist_delete(ccid3_tx_hist); 1295 ccid3_tx_hist = NULL; 1296 out_free_rx: 1297 dccp_rx_hist_delete(ccid3_rx_hist); 1298 ccid3_rx_hist = NULL; 1299 goto out; 1300 } 1301 module_init(ccid3_module_init); 1302 1303 static __exit void ccid3_module_exit(void) 1304 { 1305 ccid_unregister(&ccid3); 1306 1307 if (ccid3_tx_hist != NULL) { 1308 dccp_tx_hist_delete(ccid3_tx_hist); 1309 ccid3_tx_hist = NULL; 1310 } 1311 if (ccid3_rx_hist != NULL) { 1312 dccp_rx_hist_delete(ccid3_rx_hist); 1313 ccid3_rx_hist = NULL; 1314 } 1315 if (ccid3_li_hist != NULL) { 1316 dccp_li_hist_delete(ccid3_li_hist); 1317 ccid3_li_hist = NULL; 1318 } 1319 } 1320 module_exit(ccid3_module_exit); 1321 1322 MODULE_AUTHOR("Ian McDonald <ian.mcdonald@jandi.co.nz>, " 1323 "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>"); 1324 MODULE_DESCRIPTION("DCCP TFRC CCID3 CCID"); 1325 MODULE_LICENSE("GPL"); 1326 MODULE_ALIAS("net-dccp-ccid-3"); 1327