aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/dccp/ccids/ccid3.c8
-rw-r--r--net/dccp/ccids/lib/loss_interval.c20
-rw-r--r--net/dccp/ccids/lib/loss_interval.h2
-rw-r--r--net/dccp/ccids/lib/packet_history.c5
4 files changed, 17 insertions, 18 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 0a7c22598d62..50dac01e48c5 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -767,15 +767,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
767 */ 767 */
768 if (sample != 0) 768 if (sample != 0)
769 hcrx->rtt = tfrc_ewma(hcrx->rtt, sample, 9); 769 hcrx->rtt = tfrc_ewma(hcrx->rtt, sample, 9);
770
771 } else if (tfrc_lh_update_i_mean(&hcrx->li_hist, skb)) {
772 /*
773 * Step (3) of [RFC 3448, 6.1]: Recompute I_mean and, if I_mean
774 * has decreased (resp. p has increased), send feedback now.
775 */
776 do_feedback = CCID3_FBACK_PARAM_CHANGE;
777 } 770 }
778
779 /* 771 /*
780 * Check if the periodic once-per-RTT feedback is due; RFC 4342, 10.3 772 * Check if the periodic once-per-RTT feedback is due; RFC 4342, 10.3
781 */ 773 */
diff --git a/net/dccp/ccids/lib/loss_interval.c b/net/dccp/ccids/lib/loss_interval.c
index 5b3ce0688c5c..fe5c2a31c770 100644
--- a/net/dccp/ccids/lib/loss_interval.c
+++ b/net/dccp/ccids/lib/loss_interval.c
@@ -86,21 +86,26 @@ static void tfrc_lh_calc_i_mean(struct tfrc_loss_hist *lh)
86 86
87/** 87/**
88 * tfrc_lh_update_i_mean - Update the `open' loss interval I_0 88 * tfrc_lh_update_i_mean - Update the `open' loss interval I_0
89 * For recomputing p: returns `true' if p > p_prev <=> 1/p < 1/p_prev 89 * This updates I_mean as the sequence numbers increase. As a consequence, the
90 * open loss interval I_0 increases, hence p = W_tot/max(I_tot0, I_tot1)
91 * decreases, and thus there is no need to send renewed feedback.
90 */ 92 */
91u8 tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *skb) 93void tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *skb)
92{ 94{
93 struct tfrc_loss_interval *cur = tfrc_lh_peek(lh); 95 struct tfrc_loss_interval *cur = tfrc_lh_peek(lh);
94 u32 old_i_mean = lh->i_mean;
95 s64 len; 96 s64 len;
96 97
97 if (cur == NULL) /* not initialised */ 98 if (cur == NULL) /* not initialised */
98 return 0; 99 return;
100
101 /* FIXME: should probably also count non-data packets (RFC 4342, 6.1) */
102 if (!dccp_data_packet(skb))
103 return;
99 104
100 len = dccp_delta_seqno(cur->li_seqno, DCCP_SKB_CB(skb)->dccpd_seq) + 1; 105 len = dccp_delta_seqno(cur->li_seqno, DCCP_SKB_CB(skb)->dccpd_seq) + 1;
101 106
102 if (len - (s64)cur->li_length <= 0) /* duplicate or reordered */ 107 if (len - (s64)cur->li_length <= 0) /* duplicate or reordered */
103 return 0; 108 return;
104 109
105 if (SUB16(dccp_hdr(skb)->dccph_ccval, cur->li_ccval) > 4) 110 if (SUB16(dccp_hdr(skb)->dccph_ccval, cur->li_ccval) > 4)
106 /* 111 /*
@@ -114,14 +119,11 @@ u8 tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *skb)
114 cur->li_is_closed = 1; 119 cur->li_is_closed = 1;
115 120
116 if (tfrc_lh_length(lh) == 1) /* due to RFC 3448, 6.3.1 */ 121 if (tfrc_lh_length(lh) == 1) /* due to RFC 3448, 6.3.1 */
117 return 0; 122 return;
118 123
119 cur->li_length = len; 124 cur->li_length = len;
120 tfrc_lh_calc_i_mean(lh); 125 tfrc_lh_calc_i_mean(lh);
121
122 return (lh->i_mean < old_i_mean);
123} 126}
124EXPORT_SYMBOL_GPL(tfrc_lh_update_i_mean);
125 127
126/* Determine if `new_loss' does begin a new loss interval [RFC 4342, 10.2] */ 128/* Determine if `new_loss' does begin a new loss interval [RFC 4342, 10.2] */
127static inline u8 tfrc_lh_is_new_loss(struct tfrc_loss_interval *cur, 129static inline u8 tfrc_lh_is_new_loss(struct tfrc_loss_interval *cur,
diff --git a/net/dccp/ccids/lib/loss_interval.h b/net/dccp/ccids/lib/loss_interval.h
index 246018a3b269..f101ae2cf528 100644
--- a/net/dccp/ccids/lib/loss_interval.h
+++ b/net/dccp/ccids/lib/loss_interval.h
@@ -69,7 +69,7 @@ struct tfrc_rx_hist;
69 69
70extern int tfrc_lh_interval_add(struct tfrc_loss_hist *, struct tfrc_rx_hist *, 70extern int tfrc_lh_interval_add(struct tfrc_loss_hist *, struct tfrc_rx_hist *,
71 u32 (*first_li)(struct sock *), struct sock *); 71 u32 (*first_li)(struct sock *), struct sock *);
72extern u8 tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *); 72extern void tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *);
73extern void tfrc_lh_cleanup(struct tfrc_loss_hist *lh); 73extern void tfrc_lh_cleanup(struct tfrc_loss_hist *lh);
74 74
75#endif /* _DCCP_LI_HIST_ */ 75#endif /* _DCCP_LI_HIST_ */
diff --git a/net/dccp/ccids/lib/packet_history.c b/net/dccp/ccids/lib/packet_history.c
index 8db34225c002..8ea96903033d 100644
--- a/net/dccp/ccids/lib/packet_history.c
+++ b/net/dccp/ccids/lib/packet_history.c
@@ -351,6 +351,11 @@ int tfrc_rx_handle_loss(struct tfrc_rx_hist *h,
351 is_new_loss = tfrc_lh_interval_add(lh, h, calc_first_li, sk); 351 is_new_loss = tfrc_lh_interval_add(lh, h, calc_first_li, sk);
352 __three_after_loss(h); 352 __three_after_loss(h);
353 } 353 }
354
355 /* RFC 3448, 6.1: update I_0, whose growth implies p <= p_prev */
356 if (!is_new_loss)
357 tfrc_lh_update_i_mean(lh, skb);
358
354 return is_new_loss; 359 return is_new_loss;
355} 360}
356EXPORT_SYMBOL_GPL(tfrc_rx_handle_loss); 361EXPORT_SYMBOL_GPL(tfrc_rx_handle_loss);