aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/ccids/ccid3.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/ccids/ccid3.c')
-rw-r--r--net/dccp/ccids/ccid3.c710
1 files changed, 299 insertions, 411 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 19b33586333d..e76f460af0ea 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * net/dccp/ccids/ccid3.c 2 * net/dccp/ccids/ccid3.c
3 * 3 *
4 * Copyright (c) 2007 The University of Aberdeen, Scotland, UK
4 * Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand. 5 * Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
5 * Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz> 6 * Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
6 * 7 *
@@ -33,11 +34,7 @@
33 * along with this program; if not, write to the Free Software 34 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 35 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 */ 36 */
36#include "../ccid.h"
37#include "../dccp.h" 37#include "../dccp.h"
38#include "lib/packet_history.h"
39#include "lib/loss_interval.h"
40#include "lib/tfrc.h"
41#include "ccid3.h" 38#include "ccid3.h"
42 39
43#include <asm/unaligned.h> 40#include <asm/unaligned.h>
@@ -49,9 +46,6 @@ static int ccid3_debug;
49#define ccid3_pr_debug(format, a...) 46#define ccid3_pr_debug(format, a...)
50#endif 47#endif
51 48
52static struct dccp_tx_hist *ccid3_tx_hist;
53static struct dccp_rx_hist *ccid3_rx_hist;
54
55/* 49/*
56 * Transmitter Half-Connection Routines 50 * Transmitter Half-Connection Routines
57 */ 51 */
@@ -83,24 +77,27 @@ static void ccid3_hc_tx_set_state(struct sock *sk,
83} 77}
84 78
85/* 79/*
86 * Compute the initial sending rate X_init according to RFC 3390: 80 * Compute the initial sending rate X_init in the manner of RFC 3390:
87 * w_init = min(4 * MSS, max(2 * MSS, 4380 bytes)) 81 *
88 * X_init = w_init / RTT 82 * X_init = min(4 * s, max(2 * s, 4380 bytes)) / RTT
83 *
84 * Note that RFC 3390 uses MSS, RFC 4342 refers to RFC 3390, and rfc3448bis
85 * (rev-02) clarifies the use of RFC 3390 with regard to the above formula.
89 * For consistency with other parts of the code, X_init is scaled by 2^6. 86 * For consistency with other parts of the code, X_init is scaled by 2^6.
90 */ 87 */
91static inline u64 rfc3390_initial_rate(struct sock *sk) 88static inline u64 rfc3390_initial_rate(struct sock *sk)
92{ 89{
93 const struct dccp_sock *dp = dccp_sk(sk); 90 const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
94 const __u32 w_init = min(4 * dp->dccps_mss_cache, 91 const __u32 w_init = min_t(__u32, 4 * hctx->ccid3hctx_s,
95 max(2 * dp->dccps_mss_cache, 4380U)); 92 max_t(__u32, 2 * hctx->ccid3hctx_s, 4380));
96 93
97 return scaled_div(w_init << 6, ccid3_hc_tx_sk(sk)->ccid3hctx_rtt); 94 return scaled_div(w_init << 6, hctx->ccid3hctx_rtt);
98} 95}
99 96
100/* 97/*
101 * Recalculate t_ipi and delta (should be called whenever X changes) 98 * Recalculate t_ipi and delta (should be called whenever X changes)
102 */ 99 */
103static inline void ccid3_update_send_interval(struct ccid3_hc_tx_sock *hctx) 100static void ccid3_update_send_interval(struct ccid3_hc_tx_sock *hctx)
104{ 101{
105 /* Calculate new t_ipi = s / X_inst (X_inst is in 64 * bytes/second) */ 102 /* Calculate new t_ipi = s / X_inst (X_inst is in 64 * bytes/second) */
106 hctx->ccid3hctx_t_ipi = scaled_div32(((u64)hctx->ccid3hctx_s) << 6, 103 hctx->ccid3hctx_t_ipi = scaled_div32(((u64)hctx->ccid3hctx_s) << 6,
@@ -116,6 +113,13 @@ static inline void ccid3_update_send_interval(struct ccid3_hc_tx_sock *hctx)
116 113
117} 114}
118 115
116static u32 ccid3_hc_tx_idle_rtt(struct ccid3_hc_tx_sock *hctx, ktime_t now)
117{
118 u32 delta = ktime_us_delta(now, hctx->ccid3hctx_t_last_win_count);
119
120 return delta / hctx->ccid3hctx_rtt;
121}
122
119/** 123/**
120 * ccid3_hc_tx_update_x - Update allowed sending rate X 124 * ccid3_hc_tx_update_x - Update allowed sending rate X
121 * @stamp: most recent time if available - can be left NULL. 125 * @stamp: most recent time if available - can be left NULL.
@@ -127,19 +131,19 @@ static inline void ccid3_update_send_interval(struct ccid3_hc_tx_sock *hctx)
127 * 131 *
128 */ 132 */
129static void ccid3_hc_tx_update_x(struct sock *sk, ktime_t *stamp) 133static void ccid3_hc_tx_update_x(struct sock *sk, ktime_t *stamp)
130
131{ 134{
132 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 135 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
133 __u64 min_rate = 2 * hctx->ccid3hctx_x_recv; 136 __u64 min_rate = 2 * hctx->ccid3hctx_x_recv;
134 const __u64 old_x = hctx->ccid3hctx_x; 137 const __u64 old_x = hctx->ccid3hctx_x;
135 ktime_t now = stamp? *stamp : ktime_get_real(); 138 ktime_t now = stamp ? *stamp : ktime_get_real();
136 139
137 /* 140 /*
138 * Handle IDLE periods: do not reduce below RFC3390 initial sending rate 141 * Handle IDLE periods: do not reduce below RFC3390 initial sending rate
139 * when idling [RFC 4342, 5.1]. See also draft-ietf-dccp-rfc3448bis. 142 * when idling [RFC 4342, 5.1]. Definition of idling is from rfc3448bis:
143 * a sender is idle if it has not sent anything over a 2-RTT-period.
140 * For consistency with X and X_recv, min_rate is also scaled by 2^6. 144 * For consistency with X and X_recv, min_rate is also scaled by 2^6.
141 */ 145 */
142 if (unlikely(hctx->ccid3hctx_idle)) { 146 if (ccid3_hc_tx_idle_rtt(hctx, now) >= 2) {
143 min_rate = rfc3390_initial_rate(sk); 147 min_rate = rfc3390_initial_rate(sk);
144 min_rate = max(min_rate, 2 * hctx->ccid3hctx_x_recv); 148 min_rate = max(min_rate, 2 * hctx->ccid3hctx_x_recv);
145 } 149 }
@@ -181,7 +185,7 @@ static inline void ccid3_hc_tx_update_s(struct ccid3_hc_tx_sock *hctx, int len)
181{ 185{
182 const u16 old_s = hctx->ccid3hctx_s; 186 const u16 old_s = hctx->ccid3hctx_s;
183 187
184 hctx->ccid3hctx_s = old_s == 0 ? len : (9 * old_s + len) / 10; 188 hctx->ccid3hctx_s = tfrc_ewma(hctx->ccid3hctx_s, len, 9);
185 189
186 if (hctx->ccid3hctx_s != old_s) 190 if (hctx->ccid3hctx_s != old_s)
187 ccid3_update_send_interval(hctx); 191 ccid3_update_send_interval(hctx);
@@ -225,29 +229,27 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
225 ccid3_pr_debug("%s(%p, state=%s) - entry \n", dccp_role(sk), sk, 229 ccid3_pr_debug("%s(%p, state=%s) - entry \n", dccp_role(sk), sk,
226 ccid3_tx_state_name(hctx->ccid3hctx_state)); 230 ccid3_tx_state_name(hctx->ccid3hctx_state));
227 231
228 hctx->ccid3hctx_idle = 1; 232 if (hctx->ccid3hctx_state == TFRC_SSTATE_FBACK)
233 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
234 else if (hctx->ccid3hctx_state != TFRC_SSTATE_NO_FBACK)
235 goto out;
229 236
230 switch (hctx->ccid3hctx_state) { 237 /*
231 case TFRC_SSTATE_NO_FBACK: 238 * Determine new allowed sending rate X as per draft rfc3448bis-00, 4.4
232 /* RFC 3448, 4.4: Halve send rate directly */ 239 */
240 if (hctx->ccid3hctx_t_rto == 0 || /* no feedback received yet */
241 hctx->ccid3hctx_p == 0) {
242
243 /* halve send rate directly */
233 hctx->ccid3hctx_x = max(hctx->ccid3hctx_x / 2, 244 hctx->ccid3hctx_x = max(hctx->ccid3hctx_x / 2,
234 (((__u64)hctx->ccid3hctx_s) << 6) / 245 (((__u64)hctx->ccid3hctx_s) << 6) /
235 TFRC_T_MBI); 246 TFRC_T_MBI);
236
237 ccid3_pr_debug("%s(%p, state=%s), updated tx rate to %u "
238 "bytes/s\n", dccp_role(sk), sk,
239 ccid3_tx_state_name(hctx->ccid3hctx_state),
240 (unsigned)(hctx->ccid3hctx_x >> 6));
241 /* The value of R is still undefined and so we can not recompute
242 * the timout value. Keep initial value as per [RFC 4342, 5]. */
243 t_nfb = TFRC_INITIAL_TIMEOUT;
244 ccid3_update_send_interval(hctx); 247 ccid3_update_send_interval(hctx);
245 break; 248 } else {
246 case TFRC_SSTATE_FBACK:
247 /* 249 /*
248 * Modify the cached value of X_recv [RFC 3448, 4.4] 250 * Modify the cached value of X_recv
249 * 251 *
250 * If (p == 0 || X_calc > 2 * X_recv) 252 * If (X_calc > 2 * X_recv)
251 * X_recv = max(X_recv / 2, s / (2 * t_mbi)); 253 * X_recv = max(X_recv / 2, s / (2 * t_mbi));
252 * Else 254 * Else
253 * X_recv = X_calc / 4; 255 * X_recv = X_calc / 4;
@@ -256,32 +258,28 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
256 */ 258 */
257 BUG_ON(hctx->ccid3hctx_p && !hctx->ccid3hctx_x_calc); 259 BUG_ON(hctx->ccid3hctx_p && !hctx->ccid3hctx_x_calc);
258 260
259 if (hctx->ccid3hctx_p == 0 || 261 if (hctx->ccid3hctx_x_calc > (hctx->ccid3hctx_x_recv >> 5))
260 (hctx->ccid3hctx_x_calc > (hctx->ccid3hctx_x_recv >> 5))) {
261
262 hctx->ccid3hctx_x_recv = 262 hctx->ccid3hctx_x_recv =
263 max(hctx->ccid3hctx_x_recv / 2, 263 max(hctx->ccid3hctx_x_recv / 2,
264 (((__u64)hctx->ccid3hctx_s) << 6) / 264 (((__u64)hctx->ccid3hctx_s) << 6) /
265 (2 * TFRC_T_MBI)); 265 (2 * TFRC_T_MBI));
266 } else { 266 else {
267 hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc; 267 hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc;
268 hctx->ccid3hctx_x_recv <<= 4; 268 hctx->ccid3hctx_x_recv <<= 4;
269 } 269 }
270 /* Now recalculate X [RFC 3448, 4.3, step (4)] */
271 ccid3_hc_tx_update_x(sk, NULL); 270 ccid3_hc_tx_update_x(sk, NULL);
272 /*
273 * Schedule no feedback timer to expire in
274 * max(t_RTO, 2 * s/X) = max(t_RTO, 2 * t_ipi)
275 * See comments in packet_recv() regarding the value of t_RTO.
276 */
277 t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
278 break;
279 case TFRC_SSTATE_NO_SENT:
280 DCCP_BUG("%s(%p) - Illegal state NO_SENT", dccp_role(sk), sk);
281 /* fall through */
282 case TFRC_SSTATE_TERM:
283 goto out;
284 } 271 }
272 ccid3_pr_debug("Reduced X to %llu/64 bytes/sec\n",
273 (unsigned long long)hctx->ccid3hctx_x);
274
275 /*
276 * Set new timeout for the nofeedback timer.
277 * See comments in packet_recv() regarding the value of t_RTO.
278 */
279 if (unlikely(hctx->ccid3hctx_t_rto == 0)) /* no feedback yet */
280 t_nfb = TFRC_INITIAL_TIMEOUT;
281 else
282 t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
285 283
286restart_timer: 284restart_timer:
287 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 285 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
@@ -336,8 +334,8 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
336 hctx->ccid3hctx_x = rfc3390_initial_rate(sk); 334 hctx->ccid3hctx_x = rfc3390_initial_rate(sk);
337 hctx->ccid3hctx_t_ld = now; 335 hctx->ccid3hctx_t_ld = now;
338 } else { 336 } else {
339 /* Sender does not have RTT sample: X = MSS/second */ 337 /* Sender does not have RTT sample: X_pps = 1 pkt/sec */
340 hctx->ccid3hctx_x = dp->dccps_mss_cache; 338 hctx->ccid3hctx_x = hctx->ccid3hctx_s;
341 hctx->ccid3hctx_x <<= 6; 339 hctx->ccid3hctx_x <<= 6;
342 } 340 }
343 ccid3_update_send_interval(hctx); 341 ccid3_update_send_interval(hctx);
@@ -369,7 +367,6 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
369 /* prepare to send now (add options etc.) */ 367 /* prepare to send now (add options etc.) */
370 dp->dccps_hc_tx_insert_options = 1; 368 dp->dccps_hc_tx_insert_options = 1;
371 DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count; 369 DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
372 hctx->ccid3hctx_idle = 0;
373 370
374 /* set the nominal send time for the next following packet */ 371 /* set the nominal send time for the next following packet */
375 hctx->ccid3hctx_t_nom = ktime_add_us(hctx->ccid3hctx_t_nom, 372 hctx->ccid3hctx_t_nom = ktime_add_us(hctx->ccid3hctx_t_nom,
@@ -381,28 +378,17 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more,
381 unsigned int len) 378 unsigned int len)
382{ 379{
383 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 380 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
384 struct dccp_tx_hist_entry *packet;
385 381
386 ccid3_hc_tx_update_s(hctx, len); 382 ccid3_hc_tx_update_s(hctx, len);
387 383
388 packet = dccp_tx_hist_entry_new(ccid3_tx_hist, GFP_ATOMIC); 384 if (tfrc_tx_hist_add(&hctx->ccid3hctx_hist, dccp_sk(sk)->dccps_gss))
389 if (unlikely(packet == NULL)) {
390 DCCP_CRIT("packet history - out of memory!"); 385 DCCP_CRIT("packet history - out of memory!");
391 return;
392 }
393 dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, packet);
394
395 packet->dccphtx_tstamp = ktime_get_real();
396 packet->dccphtx_seqno = dccp_sk(sk)->dccps_gss;
397 packet->dccphtx_rtt = hctx->ccid3hctx_rtt;
398 packet->dccphtx_sent = 1;
399} 386}
400 387
401static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) 388static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
402{ 389{
403 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 390 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
404 struct ccid3_options_received *opt_recv; 391 struct ccid3_options_received *opt_recv;
405 struct dccp_tx_hist_entry *packet;
406 ktime_t now; 392 ktime_t now;
407 unsigned long t_nfb; 393 unsigned long t_nfb;
408 u32 pinv, r_sample; 394 u32 pinv, r_sample;
@@ -411,131 +397,112 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
411 if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK || 397 if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK ||
412 DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK)) 398 DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK))
413 return; 399 return;
400 /* ... and only in the established state */
401 if (hctx->ccid3hctx_state != TFRC_SSTATE_FBACK &&
402 hctx->ccid3hctx_state != TFRC_SSTATE_NO_FBACK)
403 return;
414 404
415 opt_recv = &hctx->ccid3hctx_options_received; 405 opt_recv = &hctx->ccid3hctx_options_received;
406 now = ktime_get_real();
416 407
417 switch (hctx->ccid3hctx_state) { 408 /* Estimate RTT from history if ACK number is valid */
418 case TFRC_SSTATE_NO_FBACK: 409 r_sample = tfrc_tx_hist_rtt(hctx->ccid3hctx_hist,
419 case TFRC_SSTATE_FBACK: 410 DCCP_SKB_CB(skb)->dccpd_ack_seq, now);
420 /* get packet from history to look up t_recvdata */ 411 if (r_sample == 0) {
421 packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist, 412 DCCP_WARN("%s(%p): %s with bogus ACK-%llu\n", dccp_role(sk), sk,
422 DCCP_SKB_CB(skb)->dccpd_ack_seq); 413 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type),
423 if (unlikely(packet == NULL)) { 414 (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq);
424 DCCP_WARN("%s(%p), seqno %llu(%s) doesn't exist " 415 return;
425 "in history!\n", dccp_role(sk), sk, 416 }
426 (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq,
427 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
428 return;
429 }
430
431 /* Update receive rate in units of 64 * bytes/second */
432 hctx->ccid3hctx_x_recv = opt_recv->ccid3or_receive_rate;
433 hctx->ccid3hctx_x_recv <<= 6;
434 417
435 /* Update loss event rate */ 418 /* Update receive rate in units of 64 * bytes/second */
436 pinv = opt_recv->ccid3or_loss_event_rate; 419 hctx->ccid3hctx_x_recv = opt_recv->ccid3or_receive_rate;
437 if (pinv == ~0U || pinv == 0) /* see RFC 4342, 8.5 */ 420 hctx->ccid3hctx_x_recv <<= 6;
438 hctx->ccid3hctx_p = 0;
439 else /* can not exceed 100% */
440 hctx->ccid3hctx_p = 1000000 / pinv;
441 421
442 now = ktime_get_real(); 422 /* Update loss event rate (which is scaled by 1e6) */
443 /* 423 pinv = opt_recv->ccid3or_loss_event_rate;
444 * Calculate new round trip sample as per [RFC 3448, 4.3] by 424 if (pinv == ~0U || pinv == 0) /* see RFC 4342, 8.5 */
445 * R_sample = (now - t_recvdata) - t_elapsed 425 hctx->ccid3hctx_p = 0;
446 */ 426 else /* can not exceed 100% */
447 r_sample = dccp_sample_rtt(sk, ktime_us_delta(now, packet->dccphtx_tstamp)); 427 hctx->ccid3hctx_p = scaled_div(1, pinv);
428 /*
429 * Validate new RTT sample and update moving average
430 */
431 r_sample = dccp_sample_rtt(sk, r_sample);
432 hctx->ccid3hctx_rtt = tfrc_ewma(hctx->ccid3hctx_rtt, r_sample, 9);
433 /*
434 * Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3
435 */
436 if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) {
437 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
448 438
449 /* 439 if (hctx->ccid3hctx_t_rto == 0) {
450 * Update RTT estimate by
451 * If (No feedback recv)
452 * R = R_sample;
453 * Else
454 * R = q * R + (1 - q) * R_sample;
455 *
456 * q is a constant, RFC 3448 recomments 0.9
457 */
458 if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) {
459 /* 440 /*
460 * Larger Initial Windows [RFC 4342, sec. 5] 441 * Initial feedback packet: Larger Initial Windows (4.2)
461 */ 442 */
462 hctx->ccid3hctx_rtt = r_sample;
463 hctx->ccid3hctx_x = rfc3390_initial_rate(sk); 443 hctx->ccid3hctx_x = rfc3390_initial_rate(sk);
464 hctx->ccid3hctx_t_ld = now; 444 hctx->ccid3hctx_t_ld = now;
465 445
466 ccid3_update_send_interval(hctx); 446 ccid3_update_send_interval(hctx);
467 447
468 ccid3_pr_debug("%s(%p), s=%u, MSS=%u, " 448 goto done_computing_x;
469 "R_sample=%uus, X=%u\n", dccp_role(sk), 449 } else if (hctx->ccid3hctx_p == 0) {
470 sk, hctx->ccid3hctx_s, 450 /*
471 dccp_sk(sk)->dccps_mss_cache, r_sample, 451 * First feedback after nofeedback timer expiry (4.3)
472 (unsigned)(hctx->ccid3hctx_x >> 6)); 452 */
473 453 goto done_computing_x;
474 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
475 } else {
476 hctx->ccid3hctx_rtt = (9 * hctx->ccid3hctx_rtt +
477 r_sample) / 10;
478
479 /* Update sending rate (step 4 of [RFC 3448, 4.3]) */
480 if (hctx->ccid3hctx_p > 0)
481 hctx->ccid3hctx_x_calc =
482 tfrc_calc_x(hctx->ccid3hctx_s,
483 hctx->ccid3hctx_rtt,
484 hctx->ccid3hctx_p);
485 ccid3_hc_tx_update_x(sk, &now);
486
487 ccid3_pr_debug("%s(%p), RTT=%uus (sample=%uus), s=%u, "
488 "p=%u, X_calc=%u, X_recv=%u, X=%u\n",
489 dccp_role(sk),
490 sk, hctx->ccid3hctx_rtt, r_sample,
491 hctx->ccid3hctx_s, hctx->ccid3hctx_p,
492 hctx->ccid3hctx_x_calc,
493 (unsigned)(hctx->ccid3hctx_x_recv >> 6),
494 (unsigned)(hctx->ccid3hctx_x >> 6));
495 } 454 }
455 }
496 456
497 /* unschedule no feedback timer */ 457 /* Update sending rate (step 4 of [RFC 3448, 4.3]) */
498 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer); 458 if (hctx->ccid3hctx_p > 0)
459 hctx->ccid3hctx_x_calc =
460 tfrc_calc_x(hctx->ccid3hctx_s,
461 hctx->ccid3hctx_rtt,
462 hctx->ccid3hctx_p);
463 ccid3_hc_tx_update_x(sk, &now);
464
465done_computing_x:
466 ccid3_pr_debug("%s(%p), RTT=%uus (sample=%uus), s=%u, "
467 "p=%u, X_calc=%u, X_recv=%u, X=%u\n",
468 dccp_role(sk),
469 sk, hctx->ccid3hctx_rtt, r_sample,
470 hctx->ccid3hctx_s, hctx->ccid3hctx_p,
471 hctx->ccid3hctx_x_calc,
472 (unsigned)(hctx->ccid3hctx_x_recv >> 6),
473 (unsigned)(hctx->ccid3hctx_x >> 6));
499 474
500 /* remove all packets older than the one acked from history */ 475 /* unschedule no feedback timer */
501 dccp_tx_hist_purge_older(ccid3_tx_hist, 476 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
502 &hctx->ccid3hctx_hist, packet);
503 /*
504 * As we have calculated new ipi, delta, t_nom it is possible
505 * that we now can send a packet, so wake up dccp_wait_for_ccid
506 */
507 sk->sk_write_space(sk);
508 477
509 /* 478 /*
510 * Update timeout interval for the nofeedback timer. 479 * As we have calculated new ipi, delta, t_nom it is possible
511 * We use a configuration option to increase the lower bound. 480 * that we now can send a packet, so wake up dccp_wait_for_ccid
512 * This can help avoid triggering the nofeedback timer too 481 */
513 * often ('spinning') on LANs with small RTTs. 482 sk->sk_write_space(sk);
514 */
515 hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
516 CONFIG_IP_DCCP_CCID3_RTO *
517 (USEC_PER_SEC/1000));
518 /*
519 * Schedule no feedback timer to expire in
520 * max(t_RTO, 2 * s/X) = max(t_RTO, 2 * t_ipi)
521 */
522 t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
523 483
524 ccid3_pr_debug("%s(%p), Scheduled no feedback timer to " 484 /*
525 "expire in %lu jiffies (%luus)\n", 485 * Update timeout interval for the nofeedback timer.
526 dccp_role(sk), 486 * We use a configuration option to increase the lower bound.
527 sk, usecs_to_jiffies(t_nfb), t_nfb); 487 * This can help avoid triggering the nofeedback timer too
488 * often ('spinning') on LANs with small RTTs.
489 */
490 hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
491 (CONFIG_IP_DCCP_CCID3_RTO *
492 (USEC_PER_SEC / 1000)));
493 /*
494 * Schedule no feedback timer to expire in
495 * max(t_RTO, 2 * s/X) = max(t_RTO, 2 * t_ipi)
496 */
497 t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
528 498
529 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 499 ccid3_pr_debug("%s(%p), Scheduled no feedback timer to "
530 jiffies + usecs_to_jiffies(t_nfb)); 500 "expire in %lu jiffies (%luus)\n",
501 dccp_role(sk),
502 sk, usecs_to_jiffies(t_nfb), t_nfb);
531 503
532 /* set idle flag */ 504 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
533 hctx->ccid3hctx_idle = 1; 505 jiffies + usecs_to_jiffies(t_nfb));
534 break;
535 case TFRC_SSTATE_NO_SENT: /* fall through */
536 case TFRC_SSTATE_TERM: /* ignore feedback when closing */
537 break;
538 }
539} 506}
540 507
541static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, 508static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
@@ -605,12 +572,9 @@ static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk)
605 struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid); 572 struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid);
606 573
607 hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT; 574 hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
608 INIT_LIST_HEAD(&hctx->ccid3hctx_hist); 575 hctx->ccid3hctx_hist = NULL;
609 576 setup_timer(&hctx->ccid3hctx_no_feedback_timer,
610 hctx->ccid3hctx_no_feedback_timer.function = 577 ccid3_hc_tx_no_feedback_timer, (unsigned long)sk);
611 ccid3_hc_tx_no_feedback_timer;
612 hctx->ccid3hctx_no_feedback_timer.data = (unsigned long)sk;
613 init_timer(&hctx->ccid3hctx_no_feedback_timer);
614 578
615 return 0; 579 return 0;
616} 580}
@@ -622,8 +586,7 @@ static void ccid3_hc_tx_exit(struct sock *sk)
622 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM); 586 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM);
623 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer); 587 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
624 588
625 /* Empty packet history */ 589 tfrc_tx_hist_purge(&hctx->ccid3hctx_hist);
626 dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist);
627} 590}
628 591
629static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info) 592static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info)
@@ -670,6 +633,15 @@ static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len,
670/* 633/*
671 * Receiver Half-Connection Routines 634 * Receiver Half-Connection Routines
672 */ 635 */
636
637/* CCID3 feedback types */
638enum ccid3_fback_type {
639 CCID3_FBACK_NONE = 0,
640 CCID3_FBACK_INITIAL,
641 CCID3_FBACK_PERIODIC,
642 CCID3_FBACK_PARAM_CHANGE
643};
644
673#ifdef CONFIG_IP_DCCP_CCID3_DEBUG 645#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
674static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state) 646static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
675{ 647{
@@ -696,67 +668,58 @@ static void ccid3_hc_rx_set_state(struct sock *sk,
696 hcrx->ccid3hcrx_state = state; 668 hcrx->ccid3hcrx_state = state;
697} 669}
698 670
699static inline void ccid3_hc_rx_update_s(struct ccid3_hc_rx_sock *hcrx, int len) 671static void ccid3_hc_rx_send_feedback(struct sock *sk,
700{ 672 const struct sk_buff *skb,
701 if (unlikely(len == 0)) /* don't update on empty packets (e.g. ACKs) */ 673 enum ccid3_fback_type fbtype)
702 ccid3_pr_debug("Packet payload length is 0 - not updating\n");
703 else
704 hcrx->ccid3hcrx_s = hcrx->ccid3hcrx_s == 0 ? len :
705 (9 * hcrx->ccid3hcrx_s + len) / 10;
706}
707
708static void ccid3_hc_rx_send_feedback(struct sock *sk)
709{ 674{
710 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 675 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
711 struct dccp_sock *dp = dccp_sk(sk); 676 struct dccp_sock *dp = dccp_sk(sk);
712 struct dccp_rx_hist_entry *packet;
713 ktime_t now; 677 ktime_t now;
714 suseconds_t delta; 678 s64 delta = 0;
715 679
716 ccid3_pr_debug("%s(%p) - entry \n", dccp_role(sk), sk); 680 if (unlikely(hcrx->ccid3hcrx_state == TFRC_RSTATE_TERM))
681 return;
717 682
718 now = ktime_get_real(); 683 now = ktime_get_real();
719 684
720 switch (hcrx->ccid3hcrx_state) { 685 switch (fbtype) {
721 case TFRC_RSTATE_NO_DATA: 686 case CCID3_FBACK_INITIAL:
722 hcrx->ccid3hcrx_x_recv = 0; 687 hcrx->ccid3hcrx_x_recv = 0;
688 hcrx->ccid3hcrx_pinv = ~0U; /* see RFC 4342, 8.5 */
723 break; 689 break;
724 case TFRC_RSTATE_DATA: 690 case CCID3_FBACK_PARAM_CHANGE:
725 delta = ktime_us_delta(now, 691 /*
726 hcrx->ccid3hcrx_tstamp_last_feedback); 692 * When parameters change (new loss or p > p_prev), we do not
727 DCCP_BUG_ON(delta < 0); 693 * have a reliable estimate for R_m of [RFC 3448, 6.2] and so
728 hcrx->ccid3hcrx_x_recv = 694 * need to reuse the previous value of X_recv. However, when
729 scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta); 695 * X_recv was 0 (due to early loss), this would kill X down to
696 * s/t_mbi (i.e. one packet in 64 seconds).
697 * To avoid such drastic reduction, we approximate X_recv as
698 * the number of bytes since last feedback.
699 * This is a safe fallback, since X is bounded above by X_calc.
700 */
701 if (hcrx->ccid3hcrx_x_recv > 0)
702 break;
703 /* fall through */
704 case CCID3_FBACK_PERIODIC:
705 delta = ktime_us_delta(now, hcrx->ccid3hcrx_tstamp_last_feedback);
706 if (delta <= 0)
707 DCCP_BUG("delta (%ld) <= 0", (long)delta);
708 else
709 hcrx->ccid3hcrx_x_recv =
710 scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
730 break; 711 break;
731 case TFRC_RSTATE_TERM: 712 default:
732 DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk);
733 return; 713 return;
734 } 714 }
735 715
736 packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist); 716 ccid3_pr_debug("Interval %ldusec, X_recv=%u, 1/p=%u\n", (long)delta,
737 if (unlikely(packet == NULL)) { 717 hcrx->ccid3hcrx_x_recv, hcrx->ccid3hcrx_pinv);
738 DCCP_WARN("%s(%p), no data packet in history!\n",
739 dccp_role(sk), sk);
740 return;
741 }
742 718
743 hcrx->ccid3hcrx_tstamp_last_feedback = now; 719 hcrx->ccid3hcrx_tstamp_last_feedback = now;
744 hcrx->ccid3hcrx_ccval_last_counter = packet->dccphrx_ccval; 720 hcrx->ccid3hcrx_last_counter = dccp_hdr(skb)->dccph_ccval;
745 hcrx->ccid3hcrx_bytes_recv = 0; 721 hcrx->ccid3hcrx_bytes_recv = 0;
746 722
747 /* Elapsed time information [RFC 4340, 13.2] in units of 10 * usecs */
748 delta = ktime_us_delta(now, packet->dccphrx_tstamp);
749 DCCP_BUG_ON(delta < 0);
750 hcrx->ccid3hcrx_elapsed_time = delta / 10;
751
752 if (hcrx->ccid3hcrx_p == 0)
753 hcrx->ccid3hcrx_pinv = ~0U; /* see RFC 4342, 8.5 */
754 else if (hcrx->ccid3hcrx_p > 1000000) {
755 DCCP_WARN("p (%u) > 100%%\n", hcrx->ccid3hcrx_p);
756 hcrx->ccid3hcrx_pinv = 1; /* use 100% in this case */
757 } else
758 hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p;
759
760 dp->dccps_hc_rx_insert_options = 1; 723 dp->dccps_hc_rx_insert_options = 1;
761 dccp_send_ack(sk); 724 dccp_send_ack(sk);
762} 725}
@@ -770,7 +733,6 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
770 return 0; 733 return 0;
771 734
772 hcrx = ccid3_hc_rx_sk(sk); 735 hcrx = ccid3_hc_rx_sk(sk);
773 DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_ccval_last_counter;
774 736
775 if (dccp_packet_without_ack(skb)) 737 if (dccp_packet_without_ack(skb))
776 return 0; 738 return 0;
@@ -778,11 +740,7 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
778 x_recv = htonl(hcrx->ccid3hcrx_x_recv); 740 x_recv = htonl(hcrx->ccid3hcrx_x_recv);
779 pinv = htonl(hcrx->ccid3hcrx_pinv); 741 pinv = htonl(hcrx->ccid3hcrx_pinv);
780 742
781 if ((hcrx->ccid3hcrx_elapsed_time != 0 && 743 if (dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE,
782 dccp_insert_option_elapsed_time(sk, skb,
783 hcrx->ccid3hcrx_elapsed_time)) ||
784 dccp_insert_option_timestamp(sk, skb) ||
785 dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE,
786 &pinv, sizeof(pinv)) || 744 &pinv, sizeof(pinv)) ||
787 dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE, 745 dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE,
788 &x_recv, sizeof(x_recv))) 746 &x_recv, sizeof(x_recv)))
@@ -791,180 +749,139 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
791 return 0; 749 return 0;
792} 750}
793 751
794static int ccid3_hc_rx_detect_loss(struct sock *sk, 752/** ccid3_first_li - Implements [RFC 3448, 6.3.1]
795 struct dccp_rx_hist_entry *packet) 753 *
754 * Determine the length of the first loss interval via inverse lookup.
755 * Assume that X_recv can be computed by the throughput equation
756 * s
757 * X_recv = --------
758 * R * fval
759 * Find some p such that f(p) = fval; return 1/p (scaled).
760 */
761static u32 ccid3_first_li(struct sock *sk)
796{ 762{
797 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 763 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
798 struct dccp_rx_hist_entry *rx_hist = 764 u32 x_recv, p, delta;
799 dccp_rx_hist_head(&hcrx->ccid3hcrx_hist); 765 u64 fval;
800 u64 seqno = packet->dccphrx_seqno;
801 u64 tmp_seqno;
802 int loss = 0;
803 u8 ccval;
804
805
806 tmp_seqno = hcrx->ccid3hcrx_seqno_nonloss;
807 766
808 if (!rx_hist || 767 if (hcrx->ccid3hcrx_rtt == 0) {
809 follows48(packet->dccphrx_seqno, hcrx->ccid3hcrx_seqno_nonloss)) { 768 DCCP_WARN("No RTT estimate available, using fallback RTT\n");
810 hcrx->ccid3hcrx_seqno_nonloss = seqno; 769 hcrx->ccid3hcrx_rtt = DCCP_FALLBACK_RTT;
811 hcrx->ccid3hcrx_ccval_nonloss = packet->dccphrx_ccval;
812 goto detect_out;
813 } 770 }
814 771
815 772 delta = ktime_to_us(net_timedelta(hcrx->ccid3hcrx_tstamp_last_feedback));
816 while (dccp_delta_seqno(hcrx->ccid3hcrx_seqno_nonloss, seqno) 773 x_recv = scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
817 > TFRC_RECV_NUM_LATE_LOSS) { 774 if (x_recv == 0) { /* would also trigger divide-by-zero */
818 loss = 1; 775 DCCP_WARN("X_recv==0\n");
819 dccp_li_update_li(sk, 776 if ((x_recv = hcrx->ccid3hcrx_x_recv) == 0) {
820 &hcrx->ccid3hcrx_li_hist, 777 DCCP_BUG("stored value of X_recv is zero");
821 &hcrx->ccid3hcrx_hist, 778 return ~0U;
822 hcrx->ccid3hcrx_tstamp_last_feedback,
823 hcrx->ccid3hcrx_s,
824 hcrx->ccid3hcrx_bytes_recv,
825 hcrx->ccid3hcrx_x_recv,
826 hcrx->ccid3hcrx_seqno_nonloss,
827 hcrx->ccid3hcrx_ccval_nonloss);
828 tmp_seqno = hcrx->ccid3hcrx_seqno_nonloss;
829 dccp_inc_seqno(&tmp_seqno);
830 hcrx->ccid3hcrx_seqno_nonloss = tmp_seqno;
831 dccp_inc_seqno(&tmp_seqno);
832 while (dccp_rx_hist_find_entry(&hcrx->ccid3hcrx_hist,
833 tmp_seqno, &ccval)) {
834 hcrx->ccid3hcrx_seqno_nonloss = tmp_seqno;
835 hcrx->ccid3hcrx_ccval_nonloss = ccval;
836 dccp_inc_seqno(&tmp_seqno);
837 } 779 }
838 } 780 }
839 781
840 /* FIXME - this code could be simplified with above while */ 782 fval = scaled_div(hcrx->ccid3hcrx_s, hcrx->ccid3hcrx_rtt);
841 /* but works at moment */ 783 fval = scaled_div32(fval, x_recv);
842 if (follows48(packet->dccphrx_seqno, hcrx->ccid3hcrx_seqno_nonloss)) { 784 p = tfrc_calc_x_reverse_lookup(fval);
843 hcrx->ccid3hcrx_seqno_nonloss = seqno;
844 hcrx->ccid3hcrx_ccval_nonloss = packet->dccphrx_ccval;
845 }
846 785
847detect_out: 786 ccid3_pr_debug("%s(%p), receive rate=%u bytes/s, implied "
848 dccp_rx_hist_add_packet(ccid3_rx_hist, &hcrx->ccid3hcrx_hist, 787 "loss rate=%u\n", dccp_role(sk), sk, x_recv, p);
849 &hcrx->ccid3hcrx_li_hist, packet, 788
850 hcrx->ccid3hcrx_seqno_nonloss); 789 return p == 0 ? ~0U : scaled_div(1, p);
851 return loss;
852} 790}
853 791
854static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) 792static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
855{ 793{
856 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 794 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
857 const struct dccp_options_received *opt_recv; 795 enum ccid3_fback_type do_feedback = CCID3_FBACK_NONE;
858 struct dccp_rx_hist_entry *packet; 796 const u32 ndp = dccp_sk(sk)->dccps_options_received.dccpor_ndp;
859 u32 p_prev, r_sample, rtt_prev; 797 const bool is_data_packet = dccp_data_packet(skb);
860 int loss, payload_size; 798
861 ktime_t now; 799 if (unlikely(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)) {
862 800 if (is_data_packet) {
863 opt_recv = &dccp_sk(sk)->dccps_options_received; 801 const u32 payload = skb->len - dccp_hdr(skb)->dccph_doff * 4;
864 802 do_feedback = CCID3_FBACK_INITIAL;
865 switch (DCCP_SKB_CB(skb)->dccpd_type) { 803 ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
866 case DCCP_PKT_ACK: 804 hcrx->ccid3hcrx_s = payload;
867 if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA) 805 /*
868 return; 806 * Not necessary to update ccid3hcrx_bytes_recv here,
869 case DCCP_PKT_DATAACK: 807 * since X_recv = 0 for the first feedback packet (cf.
870 if (opt_recv->dccpor_timestamp_echo == 0) 808 * RFC 3448, 6.3) -- gerrit
871 break; 809 */
872 r_sample = dccp_timestamp() - opt_recv->dccpor_timestamp_echo; 810 }
873 rtt_prev = hcrx->ccid3hcrx_rtt; 811 goto update_records;
874 r_sample = dccp_sample_rtt(sk, 10 * r_sample); 812 }
875 813
876 if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA) 814 if (tfrc_rx_hist_duplicate(&hcrx->ccid3hcrx_hist, skb))
877 hcrx->ccid3hcrx_rtt = r_sample; 815 return; /* done receiving */
878 else
879 hcrx->ccid3hcrx_rtt = (hcrx->ccid3hcrx_rtt * 9) / 10 +
880 r_sample / 10;
881 816
882 if (rtt_prev != hcrx->ccid3hcrx_rtt) 817 if (is_data_packet) {
883 ccid3_pr_debug("%s(%p), New RTT=%uus, elapsed time=%u\n", 818 const u32 payload = skb->len - dccp_hdr(skb)->dccph_doff * 4;
884 dccp_role(sk), sk, hcrx->ccid3hcrx_rtt, 819 /*
885 opt_recv->dccpor_elapsed_time); 820 * Update moving-average of s and the sum of received payload bytes
886 break; 821 */
887 case DCCP_PKT_DATA: 822 hcrx->ccid3hcrx_s = tfrc_ewma(hcrx->ccid3hcrx_s, payload, 9);
888 break; 823 hcrx->ccid3hcrx_bytes_recv += payload;
889 default: /* We're not interested in other packet types, move along */
890 return;
891 } 824 }
892 825
893 packet = dccp_rx_hist_entry_new(ccid3_rx_hist, opt_recv->dccpor_ndp, 826 /*
894 skb, GFP_ATOMIC); 827 * Handle pending losses and otherwise check for new loss
895 if (unlikely(packet == NULL)) { 828 */
896 DCCP_WARN("%s(%p), Not enough mem to add rx packet " 829 if (tfrc_rx_hist_loss_pending(&hcrx->ccid3hcrx_hist) &&
897 "to history, consider it lost!\n", dccp_role(sk), sk); 830 tfrc_rx_handle_loss(&hcrx->ccid3hcrx_hist,
898 return; 831 &hcrx->ccid3hcrx_li_hist,
832 skb, ndp, ccid3_first_li, sk) ) {
833 do_feedback = CCID3_FBACK_PARAM_CHANGE;
834 goto done_receiving;
899 } 835 }
900 836
901 loss = ccid3_hc_rx_detect_loss(sk, packet); 837 if (tfrc_rx_hist_new_loss_indicated(&hcrx->ccid3hcrx_hist, skb, ndp))
838 goto update_records;
902 839
903 if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK) 840 /*
904 return; 841 * Handle data packets: RTT sampling and monitoring p
905 842 */
906 payload_size = skb->len - dccp_hdr(skb)->dccph_doff * 4; 843 if (unlikely(!is_data_packet))
907 ccid3_hc_rx_update_s(hcrx, payload_size); 844 goto update_records;
908 845
909 switch (hcrx->ccid3hcrx_state) { 846 if (!tfrc_lh_is_initialised(&hcrx->ccid3hcrx_li_hist)) {
910 case TFRC_RSTATE_NO_DATA: 847 const u32 sample = tfrc_rx_hist_sample_rtt(&hcrx->ccid3hcrx_hist, skb);
911 ccid3_pr_debug("%s(%p, state=%s), skb=%p, sending initial " 848 /*
912 "feedback\n", dccp_role(sk), sk, 849 * Empty loss history: no loss so far, hence p stays 0.
913 dccp_state_name(sk->sk_state), skb); 850 * Sample RTT values, since an RTT estimate is required for the
914 ccid3_hc_rx_send_feedback(sk); 851 * computation of p when the first loss occurs; RFC 3448, 6.3.1.
915 ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA); 852 */
916 return; 853 if (sample != 0)
917 case TFRC_RSTATE_DATA: 854 hcrx->ccid3hcrx_rtt = tfrc_ewma(hcrx->ccid3hcrx_rtt, sample, 9);
918 hcrx->ccid3hcrx_bytes_recv += payload_size;
919 if (loss)
920 break;
921 855
922 now = ktime_get_real(); 856 } else if (tfrc_lh_update_i_mean(&hcrx->ccid3hcrx_li_hist, skb)) {
923 if ((ktime_us_delta(now, hcrx->ccid3hcrx_tstamp_last_ack) - 857 /*
924 (s64)hcrx->ccid3hcrx_rtt) >= 0) { 858 * Step (3) of [RFC 3448, 6.1]: Recompute I_mean and, if I_mean
925 hcrx->ccid3hcrx_tstamp_last_ack = now; 859 * has decreased (resp. p has increased), send feedback now.
926 ccid3_hc_rx_send_feedback(sk); 860 */
927 } 861 do_feedback = CCID3_FBACK_PARAM_CHANGE;
928 return;
929 case TFRC_RSTATE_TERM:
930 DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk);
931 return;
932 } 862 }
933 863
934 /* Dealing with packet loss */ 864 /*
935 ccid3_pr_debug("%s(%p, state=%s), data loss! Reacting...\n", 865 * Check if the periodic once-per-RTT feedback is due; RFC 4342, 10.3
936 dccp_role(sk), sk, dccp_state_name(sk->sk_state)); 866 */
937 867 if (SUB16(dccp_hdr(skb)->dccph_ccval, hcrx->ccid3hcrx_last_counter) > 3)
938 p_prev = hcrx->ccid3hcrx_p; 868 do_feedback = CCID3_FBACK_PERIODIC;
939
940 /* Calculate loss event rate */
941 if (!list_empty(&hcrx->ccid3hcrx_li_hist)) {
942 u32 i_mean = dccp_li_hist_calc_i_mean(&hcrx->ccid3hcrx_li_hist);
943 869
944 /* Scaling up by 1000000 as fixed decimal */ 870update_records:
945 if (i_mean != 0) 871 tfrc_rx_hist_add_packet(&hcrx->ccid3hcrx_hist, skb, ndp);
946 hcrx->ccid3hcrx_p = 1000000 / i_mean;
947 } else
948 DCCP_BUG("empty loss history");
949 872
950 if (hcrx->ccid3hcrx_p > p_prev) { 873done_receiving:
951 ccid3_hc_rx_send_feedback(sk); 874 if (do_feedback)
952 return; 875 ccid3_hc_rx_send_feedback(sk, skb, do_feedback);
953 }
954} 876}
955 877
956static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk) 878static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk)
957{ 879{
958 struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid); 880 struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid);
959 881
960 ccid3_pr_debug("entry\n");
961
962 hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA; 882 hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA;
963 INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist); 883 tfrc_lh_init(&hcrx->ccid3hcrx_li_hist);
964 INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist); 884 return tfrc_rx_hist_alloc(&hcrx->ccid3hcrx_hist);
965 hcrx->ccid3hcrx_tstamp_last_feedback =
966 hcrx->ccid3hcrx_tstamp_last_ack = ktime_get_real();
967 return 0;
968} 885}
969 886
970static void ccid3_hc_rx_exit(struct sock *sk) 887static void ccid3_hc_rx_exit(struct sock *sk)
@@ -973,11 +890,8 @@ static void ccid3_hc_rx_exit(struct sock *sk)
973 890
974 ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM); 891 ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);
975 892
976 /* Empty packet history */ 893 tfrc_rx_hist_purge(&hcrx->ccid3hcrx_hist);
977 dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist); 894 tfrc_lh_cleanup(&hcrx->ccid3hcrx_li_hist);
978
979 /* Empty loss interval history */
980 dccp_li_hist_purge(&hcrx->ccid3hcrx_li_hist);
981} 895}
982 896
983static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info) 897static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
@@ -998,6 +912,7 @@ static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
998 u32 __user *optval, int __user *optlen) 912 u32 __user *optval, int __user *optlen)
999{ 913{
1000 const struct ccid3_hc_rx_sock *hcrx; 914 const struct ccid3_hc_rx_sock *hcrx;
915 struct tfrc_rx_info rx_info;
1001 const void *val; 916 const void *val;
1002 917
1003 /* Listen socks doesn't have a private CCID block */ 918 /* Listen socks doesn't have a private CCID block */
@@ -1007,10 +922,14 @@ static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
1007 hcrx = ccid3_hc_rx_sk(sk); 922 hcrx = ccid3_hc_rx_sk(sk);
1008 switch (optname) { 923 switch (optname) {
1009 case DCCP_SOCKOPT_CCID_RX_INFO: 924 case DCCP_SOCKOPT_CCID_RX_INFO:
1010 if (len < sizeof(hcrx->ccid3hcrx_tfrc)) 925 if (len < sizeof(rx_info))
1011 return -EINVAL; 926 return -EINVAL;
1012 len = sizeof(hcrx->ccid3hcrx_tfrc); 927 rx_info.tfrcrx_x_recv = hcrx->ccid3hcrx_x_recv;
1013 val = &hcrx->ccid3hcrx_tfrc; 928 rx_info.tfrcrx_rtt = hcrx->ccid3hcrx_rtt;
929 rx_info.tfrcrx_p = hcrx->ccid3hcrx_pinv == 0 ? ~0U :
930 scaled_div(1, hcrx->ccid3hcrx_pinv);
931 len = sizeof(rx_info);
932 val = &rx_info;
1014 break; 933 break;
1015 default: 934 default:
1016 return -ENOPROTOOPT; 935 return -ENOPROTOOPT;
@@ -1024,7 +943,7 @@ static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
1024 943
1025static struct ccid_operations ccid3 = { 944static struct ccid_operations ccid3 = {
1026 .ccid_id = DCCPC_CCID3, 945 .ccid_id = DCCPC_CCID3,
1027 .ccid_name = "ccid3", 946 .ccid_name = "TCP-Friendly Rate Control",
1028 .ccid_owner = THIS_MODULE, 947 .ccid_owner = THIS_MODULE,
1029 .ccid_hc_tx_obj_size = sizeof(struct ccid3_hc_tx_sock), 948 .ccid_hc_tx_obj_size = sizeof(struct ccid3_hc_tx_sock),
1030 .ccid_hc_tx_init = ccid3_hc_tx_init, 949 .ccid_hc_tx_init = ccid3_hc_tx_init,
@@ -1051,44 +970,13 @@ MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");
1051 970
1052static __init int ccid3_module_init(void) 971static __init int ccid3_module_init(void)
1053{ 972{
1054 int rc = -ENOBUFS; 973 return ccid_register(&ccid3);
1055
1056 ccid3_rx_hist = dccp_rx_hist_new("ccid3");
1057 if (ccid3_rx_hist == NULL)
1058 goto out;
1059
1060 ccid3_tx_hist = dccp_tx_hist_new("ccid3");
1061 if (ccid3_tx_hist == NULL)
1062 goto out_free_rx;
1063
1064 rc = ccid_register(&ccid3);
1065 if (rc != 0)
1066 goto out_free_tx;
1067out:
1068 return rc;
1069
1070out_free_tx:
1071 dccp_tx_hist_delete(ccid3_tx_hist);
1072 ccid3_tx_hist = NULL;
1073out_free_rx:
1074 dccp_rx_hist_delete(ccid3_rx_hist);
1075 ccid3_rx_hist = NULL;
1076 goto out;
1077} 974}
1078module_init(ccid3_module_init); 975module_init(ccid3_module_init);
1079 976
1080static __exit void ccid3_module_exit(void) 977static __exit void ccid3_module_exit(void)
1081{ 978{
1082 ccid_unregister(&ccid3); 979 ccid_unregister(&ccid3);
1083
1084 if (ccid3_tx_hist != NULL) {
1085 dccp_tx_hist_delete(ccid3_tx_hist);
1086 ccid3_tx_hist = NULL;
1087 }
1088 if (ccid3_rx_hist != NULL) {
1089 dccp_rx_hist_delete(ccid3_rx_hist);
1090 ccid3_rx_hist = NULL;
1091 }
1092} 980}
1093module_exit(ccid3_module_exit); 981module_exit(ccid3_module_exit);
1094 982