aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2008-09-04 01:30:19 -0400
committerGerrit Renker <gerrit@erg.abdn.ac.uk>2008-09-04 01:45:40 -0400
commitd20ed95f8bf3d98d31dbbab8b00bb4c1a4a140f3 (patch)
treea740d35fd710618863a63e4b86ecaedc2ea5497b
parent24b8d343215919c7a2ba18b9f89a0961e1459cad (diff)
dccp tfrc: Perform early loss detection
This enables the TFRC code to begin loss detection (as soon as the module is loaded), using the latest updates from rfc3448bis-06, 6.3.1: * when the first data packet(s) are lost or marked, set * X_target = s/(2*R) => f(p) = s/(R * X_target) = 2, * corresponding to a loss rate of ~ 20.64%. The handle_loss() function is now called right at the begin of rx_packet_recv() and thus no longer protected against duplicates: hence a call to rx_duplicate() has been added. Such a call makes sense now, as the previous patch initialises the first entry with a sequence number of GSR. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
-rw-r--r--net/dccp/ccids/ccid3.c48
-rw-r--r--net/dccp/ccids/lib/packet_history.c3
2 files changed, 42 insertions, 9 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 36f4992f3c38..0a7c22598d62 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -577,6 +577,28 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk,
577 hcrx->p_inverse = ~0U; /* see RFC 4342, 8.5 */ 577 hcrx->p_inverse = ~0U; /* see RFC 4342, 8.5 */
578 break; 578 break;
579 case CCID3_FBACK_PARAM_CHANGE: 579 case CCID3_FBACK_PARAM_CHANGE:
580 if (unlikely(hcrx->state == TFRC_RSTATE_NO_DATA)) {
581 /*
582 * rfc3448bis-06, 6.3.1: First packet(s) lost or marked
583 * FIXME: in rfc3448bis the receiver returns X_recv=0
584 * here as it normally would in the first feedback packet.
585 * However this is not possible yet, since the code still
586 * uses RFC 3448, i.e.
587 * If (p > 0)
588 * Calculate X_calc using the TCP throughput equation.
589 * X = max(min(X_calc, 2*X_recv), s/t_mbi);
590 * would bring X down to s/t_mbi. That is why we return
591 * X_recv according to rfc3448bis-06 for the moment.
592 */
593 u32 rtt = hcrx->rtt ? : DCCP_FALLBACK_RTT, s = hcrx->s;
594
595 if (s == 0) {
596 DCCP_WARN("No sample for s, using fallback\n");
597 s = TCP_MIN_RCVMSS;
598 }
599 hcrx->x_recv = scaled_div32(s, 2 * rtt);
600 break;
601 }
580 /* 602 /*
581 * When parameters change (new loss or p > p_prev), we do not 603 * When parameters change (new loss or p > p_prev), we do not
582 * have a reliable estimate for R_m of [RFC 3448, 6.2] and so 604 * have a reliable estimate for R_m of [RFC 3448, 6.2] and so
@@ -650,6 +672,14 @@ static u32 ccid3_first_li(struct sock *sk)
650 u32 x_recv, p, delta; 672 u32 x_recv, p, delta;
651 u64 fval; 673 u64 fval;
652 674
675 /*
676 * rfc3448bis-06, 6.3.1: First data packet(s) are marked or lost. Set p
677 * to give the equivalent of X_target = s/(2*R). Thus fval = 2 and so p
678 * is about 20.64%. This yields an interval length of 4.84 (rounded up).
679 */
680 if (unlikely(hcrx->state == TFRC_RSTATE_NO_DATA))
681 return 5;
682
653 if (hcrx->rtt == 0) { 683 if (hcrx->rtt == 0) {
654 DCCP_WARN("No RTT estimate available, using fallback RTT\n"); 684 DCCP_WARN("No RTT estimate available, using fallback RTT\n");
655 hcrx->rtt = DCCP_FALLBACK_RTT; 685 hcrx->rtt = DCCP_FALLBACK_RTT;
@@ -683,6 +713,15 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
683 const u64 ndp = dccp_sk(sk)->dccps_options_received.dccpor_ndp; 713 const u64 ndp = dccp_sk(sk)->dccps_options_received.dccpor_ndp;
684 const bool is_data_packet = dccp_data_packet(skb); 714 const bool is_data_packet = dccp_data_packet(skb);
685 715
716 /*
717 * Perform loss detection and handle pending losses
718 */
719 if (tfrc_rx_handle_loss(&hcrx->hist, &hcrx->li_hist,
720 skb, ndp, ccid3_first_li, sk)) {
721 do_feedback = CCID3_FBACK_PARAM_CHANGE;
722 goto done_receiving;
723 }
724
686 if (unlikely(hcrx->state == TFRC_RSTATE_NO_DATA)) { 725 if (unlikely(hcrx->state == TFRC_RSTATE_NO_DATA)) {
687 if (is_data_packet) { 726 if (is_data_packet) {
688 const u32 payload = skb->len - dccp_hdr(skb)->dccph_doff * 4; 727 const u32 payload = skb->len - dccp_hdr(skb)->dccph_doff * 4;
@@ -710,15 +749,6 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
710 hcrx->bytes_recv += payload; 749 hcrx->bytes_recv += payload;
711 } 750 }
712 751
713 /*
714 * Perform loss detection and handle pending losses
715 */
716 if (tfrc_rx_handle_loss(&hcrx->hist, &hcrx->li_hist,
717 skb, ndp, ccid3_first_li, sk)) {
718 do_feedback = CCID3_FBACK_PARAM_CHANGE;
719 goto done_receiving;
720 }
721
722 if (tfrc_rx_hist_loss_pending(&hcrx->hist)) 752 if (tfrc_rx_hist_loss_pending(&hcrx->hist))
723 return; /* done receiving */ 753 return; /* done receiving */
724 754
diff --git a/net/dccp/ccids/lib/packet_history.c b/net/dccp/ccids/lib/packet_history.c
index 5b4e1cf8439d..8db34225c002 100644
--- a/net/dccp/ccids/lib/packet_history.c
+++ b/net/dccp/ccids/lib/packet_history.c
@@ -335,6 +335,9 @@ int tfrc_rx_handle_loss(struct tfrc_rx_hist *h,
335{ 335{
336 int is_new_loss = 0; 336 int is_new_loss = 0;
337 337
338 if (tfrc_rx_hist_duplicate(h, skb))
339 return 0;
340
338 if (h->loss_count == 0) { 341 if (h->loss_count == 0) {
339 __do_track_loss(h, skb, ndp); 342 __do_track_loss(h, skb, ndp);
340 } else if (h->loss_count == 1) { 343 } else if (h->loss_count == 1) {