aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/ccids/ccid3.c
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2007-12-12 11:06:14 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:57:20 -0500
commit954c2db868ce896325dced91d5fba5e2226897a4 (patch)
treed74b480530878c25eb770293d786f2e78ace90e7 /net/dccp/ccids/ccid3.c
parentde0d411cb8ea51175f52d935faead5c542b6e007 (diff)
[CCID3]: Interface CCID3 code with newer Loss Intervals Database
This hooks up the TFRC Loss Interval database with CCID 3 packet reception. In addition, it makes the CCID-specific computation of the first loss interval (which requires access to all the guts of CCID3) local to ccid3.c. The patch also fixes an omission in the DCCP code, that of a default / fallback RTT value (defined in section 3.4 of RFC 4340 as 0.2 sec); while at it, the upper bound of 4 seconds for an RTT sample has been reduced to match the initial TCP RTO value of 3 seconds from[RFC 1122, 4.2.3.1]. 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/ccids/ccid3.c')
-rw-r--r--net/dccp/ccids/ccid3.c72
1 files changed, 60 insertions, 12 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 8266dfde89c1..8f112d18d450 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>
@@ -757,6 +754,46 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
757 return 0; 754 return 0;
758} 755}
759 756
757/** ccid3_first_li - Implements [RFC 3448, 6.3.1]
758 *
759 * Determine the length of the first loss interval via inverse lookup.
760 * Assume that X_recv can be computed by the throughput equation
761 * s
762 * X_recv = --------
763 * R * fval
764 * Find some p such that f(p) = fval; return 1/p (scaled).
765 */
766static u32 ccid3_first_li(struct sock *sk)
767{
768 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
769 u32 x_recv, p, delta;
770 u64 fval;
771
772 if (hcrx->ccid3hcrx_rtt == 0) {
773 DCCP_WARN("No RTT estimate available, using fallback RTT\n");
774 hcrx->ccid3hcrx_rtt = DCCP_FALLBACK_RTT;
775 }
776
777 delta = ktime_to_us(net_timedelta(hcrx->ccid3hcrx_tstamp_last_feedback));
778 x_recv = scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
779 if (x_recv == 0) { /* would also trigger divide-by-zero */
780 DCCP_WARN("X_recv==0\n");
781 if ((x_recv = hcrx->ccid3hcrx_x_recv) == 0) {
782 DCCP_BUG("stored value of X_recv is zero");
783 return ~0U;
784 }
785 }
786
787 fval = scaled_div(hcrx->ccid3hcrx_s, hcrx->ccid3hcrx_rtt);
788 fval = scaled_div32(fval, x_recv);
789 p = tfrc_calc_x_reverse_lookup(fval);
790
791 ccid3_pr_debug("%s(%p), receive rate=%u bytes/s, implied "
792 "loss rate=%u\n", dccp_role(sk), sk, x_recv, p);
793
794 return p == 0 ? ~0U : scaled_div(1, p);
795}
796
760static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) 797static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
761{ 798{
762 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 799 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
@@ -794,6 +831,14 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
794 /* 831 /*
795 * Handle pending losses and otherwise check for new loss 832 * Handle pending losses and otherwise check for new loss
796 */ 833 */
834 if (tfrc_rx_hist_loss_pending(&hcrx->ccid3hcrx_hist) &&
835 tfrc_rx_handle_loss(&hcrx->ccid3hcrx_hist,
836 &hcrx->ccid3hcrx_li_hist,
837 skb, ndp, ccid3_first_li, sk) ) {
838 do_feedback = CCID3_FBACK_PARAM_CHANGE;
839 goto done_receiving;
840 }
841
797 if (tfrc_rx_hist_new_loss_indicated(&hcrx->ccid3hcrx_hist, skb, ndp)) 842 if (tfrc_rx_hist_new_loss_indicated(&hcrx->ccid3hcrx_hist, skb, ndp))
798 goto update_records; 843 goto update_records;
799 844
@@ -803,7 +848,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
803 if (unlikely(!is_data_packet)) 848 if (unlikely(!is_data_packet))
804 goto update_records; 849 goto update_records;
805 850
806 if (list_empty(&hcrx->ccid3hcrx_li_hist)) { /* no loss so far: p = 0 */ 851 if (!tfrc_lh_is_initialised(&hcrx->ccid3hcrx_li_hist)) {
807 const u32 sample = tfrc_rx_hist_sample_rtt(&hcrx->ccid3hcrx_hist, skb); 852 const u32 sample = tfrc_rx_hist_sample_rtt(&hcrx->ccid3hcrx_hist, skb);
808 /* 853 /*
809 * Empty loss history: no loss so far, hence p stays 0. 854 * Empty loss history: no loss so far, hence p stays 0.
@@ -812,6 +857,13 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
812 */ 857 */
813 if (sample != 0) 858 if (sample != 0)
814 hcrx->ccid3hcrx_rtt = tfrc_ewma(hcrx->ccid3hcrx_rtt, sample, 9); 859 hcrx->ccid3hcrx_rtt = tfrc_ewma(hcrx->ccid3hcrx_rtt, sample, 9);
860
861 } else if (tfrc_lh_update_i_mean(&hcrx->ccid3hcrx_li_hist, skb)) {
862 /*
863 * Step (3) of [RFC 3448, 6.1]: Recompute I_mean and, if I_mean
864 * has decreased (resp. p has increased), send feedback now.
865 */
866 do_feedback = CCID3_FBACK_PARAM_CHANGE;
815 } 867 }
816 868
817 /* 869 /*
@@ -823,6 +875,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
823update_records: 875update_records:
824 tfrc_rx_hist_add_packet(&hcrx->ccid3hcrx_hist, skb, ndp); 876 tfrc_rx_hist_add_packet(&hcrx->ccid3hcrx_hist, skb, ndp);
825 877
878done_receiving:
826 if (do_feedback) 879 if (do_feedback)
827 ccid3_hc_rx_send_feedback(sk, skb, do_feedback); 880 ccid3_hc_rx_send_feedback(sk, skb, do_feedback);
828} 881}
@@ -831,10 +884,8 @@ static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk)
831{ 884{
832 struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid); 885 struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid);
833 886
834 ccid3_pr_debug("entry\n");
835
836 hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA; 887 hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA;
837 INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist); 888 tfrc_lh_init(&hcrx->ccid3hcrx_li_hist);
838 return tfrc_rx_hist_alloc(&hcrx->ccid3hcrx_hist); 889 return tfrc_rx_hist_alloc(&hcrx->ccid3hcrx_hist);
839} 890}
840 891
@@ -844,11 +895,8 @@ static void ccid3_hc_rx_exit(struct sock *sk)
844 895
845 ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM); 896 ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);
846 897
847 /* Empty packet history */
848 tfrc_rx_hist_purge(&hcrx->ccid3hcrx_hist); 898 tfrc_rx_hist_purge(&hcrx->ccid3hcrx_hist);
849 899 tfrc_lh_cleanup(&hcrx->ccid3hcrx_li_hist);
850 /* Empty loss interval history */
851 dccp_li_hist_purge(&hcrx->ccid3hcrx_li_hist);
852} 900}
853 901
854static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info) 902static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)