diff options
Diffstat (limited to 'net/dccp/ccids/ccid3.c')
-rw-r--r-- | net/dccp/ccids/ccid3.c | 43 |
1 files changed, 14 insertions, 29 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 04b183548aa8..8e64d9665a21 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -556,8 +556,8 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk, | |||
556 | * would bring X down to s/t_mbi. That is why we return | 556 | * would bring X down to s/t_mbi. That is why we return |
557 | * X_recv according to rfc3448bis-06 for the moment. | 557 | * X_recv according to rfc3448bis-06 for the moment. |
558 | */ | 558 | */ |
559 | u32 rtt = hcrx->rtt ? : DCCP_FALLBACK_RTT, | 559 | u32 s = tfrc_rx_hist_packet_size(&hcrx->hist), |
560 | s = tfrc_rx_hist_packet_size(&hcrx->hist); | 560 | rtt = tfrc_rx_hist_rtt(&hcrx->hist); |
561 | 561 | ||
562 | hcrx->x_recv = scaled_div32(s, 2 * rtt); | 562 | hcrx->x_recv = scaled_div32(s, 2 * rtt); |
563 | break; | 563 | break; |
@@ -576,6 +576,11 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk, | |||
576 | break; | 576 | break; |
577 | /* fall through */ | 577 | /* fall through */ |
578 | case CCID3_FBACK_PERIODIC: | 578 | case CCID3_FBACK_PERIODIC: |
579 | /* | ||
580 | * FIXME: check if delta is less than or equal to 1 RTT using | ||
581 | * the receiver RTT sample. This is described in Errata 610/611 | ||
582 | * of RFC 4342 which reference section 6.2 of RFC 3448. | ||
583 | */ | ||
579 | delta = ktime_us_delta(now, hcrx->tstamp_last_feedback); | 584 | delta = ktime_us_delta(now, hcrx->tstamp_last_feedback); |
580 | if (delta <= 0) | 585 | if (delta <= 0) |
581 | DCCP_BUG("delta (%ld) <= 0", (long)delta); | 586 | DCCP_BUG("delta (%ld) <= 0", (long)delta); |
@@ -633,8 +638,8 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb) | |||
633 | static u32 ccid3_first_li(struct sock *sk) | 638 | static u32 ccid3_first_li(struct sock *sk) |
634 | { | 639 | { |
635 | struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); | 640 | struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); |
636 | u32 x_recv, p, delta, | 641 | u32 s = tfrc_rx_hist_packet_size(&hcrx->hist), |
637 | s = tfrc_rx_hist_packet_size(&hcrx->hist); | 642 | rtt = tfrc_rx_hist_rtt(&hcrx->hist), x_recv, p, delta; |
638 | u64 fval; | 643 | u64 fval; |
639 | 644 | ||
640 | /* | 645 | /* |
@@ -645,11 +650,6 @@ static u32 ccid3_first_li(struct sock *sk) | |||
645 | if (unlikely(hcrx->feedback == CCID3_FBACK_NONE)) | 650 | if (unlikely(hcrx->feedback == CCID3_FBACK_NONE)) |
646 | return 5; | 651 | return 5; |
647 | 652 | ||
648 | if (hcrx->rtt == 0) { | ||
649 | DCCP_WARN("No RTT estimate available, using fallback RTT\n"); | ||
650 | hcrx->rtt = DCCP_FALLBACK_RTT; | ||
651 | } | ||
652 | |||
653 | delta = ktime_to_us(net_timedelta(hcrx->tstamp_last_feedback)); | 653 | delta = ktime_to_us(net_timedelta(hcrx->tstamp_last_feedback)); |
654 | x_recv = scaled_div32(hcrx->hist.bytes_recvd, delta); | 654 | x_recv = scaled_div32(hcrx->hist.bytes_recvd, delta); |
655 | if (x_recv == 0) { /* would also trigger divide-by-zero */ | 655 | if (x_recv == 0) { /* would also trigger divide-by-zero */ |
@@ -661,7 +661,7 @@ static u32 ccid3_first_li(struct sock *sk) | |||
661 | x_recv = hcrx->x_recv; | 661 | x_recv = hcrx->x_recv; |
662 | } | 662 | } |
663 | 663 | ||
664 | fval = scaled_div32(scaled_div(s, hcrx->rtt), x_recv); | 664 | fval = scaled_div32(scaled_div(s, rtt), x_recv); |
665 | p = tfrc_calc_x_reverse_lookup(fval); | 665 | p = tfrc_calc_x_reverse_lookup(fval); |
666 | 666 | ||
667 | ccid3_pr_debug("%s(%p), receive rate=%u bytes/s, implied " | 667 | ccid3_pr_debug("%s(%p), receive rate=%u bytes/s, implied " |
@@ -696,25 +696,10 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
696 | return; /* done receiving */ | 696 | return; /* done receiving */ |
697 | 697 | ||
698 | /* | 698 | /* |
699 | * Handle data packets: RTT sampling and monitoring p | ||
700 | */ | ||
701 | if (unlikely(!is_data_packet)) | ||
702 | goto update_records; | ||
703 | |||
704 | if (!tfrc_lh_is_initialised(&hcrx->li_hist)) { | ||
705 | const u32 sample = tfrc_rx_hist_sample_rtt(&hcrx->hist, skb); | ||
706 | /* | ||
707 | * Empty loss history: no loss so far, hence p stays 0. | ||
708 | * Sample RTT values, since an RTT estimate is required for the | ||
709 | * computation of p when the first loss occurs; RFC 3448, 6.3.1. | ||
710 | */ | ||
711 | if (sample != 0) | ||
712 | hcrx->rtt = tfrc_ewma(hcrx->rtt, sample, 9); | ||
713 | } | ||
714 | /* | ||
715 | * Check if the periodic once-per-RTT feedback is due; RFC 4342, 10.3 | 699 | * Check if the periodic once-per-RTT feedback is due; RFC 4342, 10.3 |
716 | */ | 700 | */ |
717 | if (SUB16(dccp_hdr(skb)->dccph_ccval, hcrx->last_counter) > 3) | 701 | if (is_data_packet && |
702 | SUB16(dccp_hdr(skb)->dccph_ccval, hcrx->last_counter) > 3) | ||
718 | do_feedback = CCID3_FBACK_PERIODIC; | 703 | do_feedback = CCID3_FBACK_PERIODIC; |
719 | 704 | ||
720 | update_records: | 705 | update_records: |
@@ -744,7 +729,7 @@ static void ccid3_hc_rx_exit(struct sock *sk) | |||
744 | static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info) | 729 | static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info) |
745 | { | 730 | { |
746 | info->tcpi_options |= TCPI_OPT_TIMESTAMPS; | 731 | info->tcpi_options |= TCPI_OPT_TIMESTAMPS; |
747 | info->tcpi_rcv_rtt = ccid3_hc_rx_sk(sk)->rtt; | 732 | info->tcpi_rcv_rtt = tfrc_rx_hist_rtt(&ccid3_hc_rx_sk(sk)->hist); |
748 | } | 733 | } |
749 | 734 | ||
750 | static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len, | 735 | static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len, |
@@ -759,7 +744,7 @@ static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len, | |||
759 | if (len < sizeof(rx_info)) | 744 | if (len < sizeof(rx_info)) |
760 | return -EINVAL; | 745 | return -EINVAL; |
761 | rx_info.tfrcrx_x_recv = hcrx->x_recv; | 746 | rx_info.tfrcrx_x_recv = hcrx->x_recv; |
762 | rx_info.tfrcrx_rtt = hcrx->rtt; | 747 | rx_info.tfrcrx_rtt = tfrc_rx_hist_rtt(&hcrx->hist); |
763 | rx_info.tfrcrx_p = tfrc_invert_loss_event_rate(hcrx->p_inverse); | 748 | rx_info.tfrcrx_p = tfrc_invert_loss_event_rate(hcrx->p_inverse); |
764 | len = sizeof(rx_info); | 749 | len = sizeof(rx_info); |
765 | val = &rx_info; | 750 | val = &rx_info; |