diff options
author | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2008-09-04 01:30:19 -0400 |
---|---|---|
committer | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2008-09-04 01:45:40 -0400 |
commit | d20ed95f8bf3d98d31dbbab8b00bb4c1a4a140f3 (patch) | |
tree | a740d35fd710618863a63e4b86ecaedc2ea5497b | |
parent | 24b8d343215919c7a2ba18b9f89a0961e1459cad (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.c | 48 | ||||
-rw-r--r-- | net/dccp/ccids/lib/packet_history.c | 3 |
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) { |