diff options
author | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2007-12-17 09:48:47 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:58:22 -0500 |
commit | d8d1252f744cb7cebd6ba3a4b7feec31ff23ccde (patch) | |
tree | acb47c9a5e654a6b5ca3ebf60c8c60d783fb3a65 /net/dccp | |
parent | 5bd370a63daf62bb5520c258f04e91a4d9d274dd (diff) |
[CCID3]: Implement rfc3448bis changes to feedback reception
This implements the algorithm to update the allowed sending rate X upon
receiving feedback packets, as described in draft rfc3448bis, 4.2/4.3.
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Signed-off-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dccp')
-rw-r--r-- | net/dccp/ccids/ccid3.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index a93a556ad03d..1156fef17471 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -429,40 +429,46 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
429 | if (pinv == ~0U || pinv == 0) /* see RFC 4342, 8.5 */ | 429 | if (pinv == ~0U || pinv == 0) /* see RFC 4342, 8.5 */ |
430 | hctx->ccid3hctx_p = 0; | 430 | hctx->ccid3hctx_p = 0; |
431 | else /* can not exceed 100% */ | 431 | else /* can not exceed 100% */ |
432 | hctx->ccid3hctx_p = 1000000 / pinv; | 432 | hctx->ccid3hctx_p = scaled_div(1, pinv); |
433 | /* | 433 | /* |
434 | * Validate new RTT sample and update moving average | 434 | * Validate new RTT sample and update moving average |
435 | */ | 435 | */ |
436 | r_sample = dccp_sample_rtt(sk, r_sample); | 436 | r_sample = dccp_sample_rtt(sk, r_sample); |
437 | hctx->ccid3hctx_rtt = tfrc_ewma(hctx->ccid3hctx_rtt, r_sample, 9); | 437 | hctx->ccid3hctx_rtt = tfrc_ewma(hctx->ccid3hctx_rtt, r_sample, 9); |
438 | 438 | /* | |
439 | * Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3 | ||
440 | */ | ||
439 | if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) { | 441 | if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) { |
440 | /* | 442 | ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK); |
441 | * Larger Initial Windows [RFC 4342, sec. 5] | ||
442 | */ | ||
443 | hctx->ccid3hctx_x = rfc3390_initial_rate(sk); | ||
444 | hctx->ccid3hctx_t_ld = now; | ||
445 | 443 | ||
446 | ccid3_update_send_interval(hctx); | 444 | if (hctx->ccid3hctx_t_rto == 0) { |
445 | /* | ||
446 | * Initial feedback packet: Larger Initial Windows (4.2) | ||
447 | */ | ||
448 | hctx->ccid3hctx_x = rfc3390_initial_rate(sk); | ||
449 | hctx->ccid3hctx_t_ld = now; | ||
447 | 450 | ||
448 | ccid3_pr_debug("%s(%p), s=%u, MSS=%u, " | 451 | ccid3_update_send_interval(hctx); |
449 | "R_sample=%uus, X=%u\n", dccp_role(sk), | ||
450 | sk, hctx->ccid3hctx_s, | ||
451 | dccp_sk(sk)->dccps_mss_cache, r_sample, | ||
452 | (unsigned)(hctx->ccid3hctx_x >> 6)); | ||
453 | 452 | ||
454 | ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK); | 453 | goto done_computing_x; |
455 | } else { | 454 | } else if (hctx->ccid3hctx_p == 0) { |
455 | /* | ||
456 | * First feedback after nofeedback timer expiry (4.3) | ||
457 | */ | ||
458 | goto done_computing_x; | ||
459 | } | ||
460 | } | ||
456 | 461 | ||
457 | /* Update sending rate (step 4 of [RFC 3448, 4.3]) */ | 462 | /* Update sending rate (step 4 of [RFC 3448, 4.3]) */ |
458 | if (hctx->ccid3hctx_p > 0) | 463 | if (hctx->ccid3hctx_p > 0) |
459 | hctx->ccid3hctx_x_calc = | 464 | hctx->ccid3hctx_x_calc = |
460 | tfrc_calc_x(hctx->ccid3hctx_s, | 465 | tfrc_calc_x(hctx->ccid3hctx_s, |
461 | hctx->ccid3hctx_rtt, | 466 | hctx->ccid3hctx_rtt, |
462 | hctx->ccid3hctx_p); | 467 | hctx->ccid3hctx_p); |
463 | ccid3_hc_tx_update_x(sk, &now); | 468 | ccid3_hc_tx_update_x(sk, &now); |
464 | 469 | ||
465 | ccid3_pr_debug("%s(%p), RTT=%uus (sample=%uus), s=%u, " | 470 | done_computing_x: |
471 | ccid3_pr_debug("%s(%p), RTT=%uus (sample=%uus), s=%u, " | ||
466 | "p=%u, X_calc=%u, X_recv=%u, X=%u\n", | 472 | "p=%u, X_calc=%u, X_recv=%u, X=%u\n", |
467 | dccp_role(sk), | 473 | dccp_role(sk), |
468 | sk, hctx->ccid3hctx_rtt, r_sample, | 474 | sk, hctx->ccid3hctx_rtt, r_sample, |
@@ -470,7 +476,6 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
470 | hctx->ccid3hctx_x_calc, | 476 | hctx->ccid3hctx_x_calc, |
471 | (unsigned)(hctx->ccid3hctx_x_recv >> 6), | 477 | (unsigned)(hctx->ccid3hctx_x_recv >> 6), |
472 | (unsigned)(hctx->ccid3hctx_x >> 6)); | 478 | (unsigned)(hctx->ccid3hctx_x >> 6)); |
473 | } | ||
474 | 479 | ||
475 | /* unschedule no feedback timer */ | 480 | /* unschedule no feedback timer */ |
476 | sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer); | 481 | sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer); |