aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/ccids
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/ccids')
-rw-r--r--net/dccp/ccids/Kconfig25
-rw-r--r--net/dccp/ccids/ccid2.c45
-rw-r--r--net/dccp/ccids/ccid2.h3
-rw-r--r--net/dccp/ccids/ccid3.c549
-rw-r--r--net/dccp/ccids/ccid3.h119
-rw-r--r--net/dccp/ccids/lib/loss_interval.c6
-rw-r--r--net/dccp/ccids/lib/tfrc_equation.c7
7 files changed, 380 insertions, 374 deletions
diff --git a/net/dccp/ccids/Kconfig b/net/dccp/ccids/Kconfig
index 8533dabfb9f8..dac89166eb18 100644
--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -28,13 +28,20 @@ config IP_DCCP_CCID2
28 This text was extracted from RFC 4340 (sec. 10.1), 28 This text was extracted from RFC 4340 (sec. 10.1),
29 http://www.ietf.org/rfc/rfc4340.txt 29 http://www.ietf.org/rfc/rfc4340.txt
30 30
31 To compile this CCID as a module, choose M here: the module will be
32 called dccp_ccid2.
33
31 If in doubt, say M. 34 If in doubt, say M.
32 35
33config IP_DCCP_CCID2_DEBUG 36config IP_DCCP_CCID2_DEBUG
34 bool "CCID2 debug" 37 bool "CCID2 debugging messages"
35 depends on IP_DCCP_CCID2 38 depends on IP_DCCP_CCID2
36 ---help--- 39 ---help---
37 Enable CCID2 debug messages. 40 Enable CCID2-specific debugging messages.
41
42 When compiling CCID2 as a module, this debugging output can
43 additionally be toggled by setting the ccid2_debug module
44 parameter to 0 or 1.
38 45
39 If in doubt, say N. 46 If in doubt, say N.
40 47
@@ -62,10 +69,24 @@ config IP_DCCP_CCID3
62 This text was extracted from RFC 4340 (sec. 10.2), 69 This text was extracted from RFC 4340 (sec. 10.2),
63 http://www.ietf.org/rfc/rfc4340.txt 70 http://www.ietf.org/rfc/rfc4340.txt
64 71
72 To compile this CCID as a module, choose M here: the module will be
73 called dccp_ccid3.
74
65 If in doubt, say M. 75 If in doubt, say M.
66 76
67config IP_DCCP_TFRC_LIB 77config IP_DCCP_TFRC_LIB
68 depends on IP_DCCP_CCID3 78 depends on IP_DCCP_CCID3
69 def_tristate IP_DCCP_CCID3 79 def_tristate IP_DCCP_CCID3
70 80
81config IP_DCCP_CCID3_DEBUG
82 bool "CCID3 debugging messages"
83 depends on IP_DCCP_CCID3
84 ---help---
85 Enable CCID3-specific debugging messages.
86
87 When compiling CCID3 as a module, this debugging output can
88 additionally be toggled by setting the ccid3_debug module
89 parameter to 0 or 1.
90
91 If in doubt, say N.
71endmenu 92endmenu
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index 162032baeac0..2555be8f4790 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -33,18 +33,11 @@
33#include "../dccp.h" 33#include "../dccp.h"
34#include "ccid2.h" 34#include "ccid2.h"
35 35
36static int ccid2_debug;
37 36
38#ifdef CONFIG_IP_DCCP_CCID2_DEBUG 37#ifdef CONFIG_IP_DCCP_CCID2_DEBUG
39#define ccid2_pr_debug(format, a...) \ 38static int ccid2_debug;
40 do { if (ccid2_debug) \ 39#define ccid2_pr_debug(format, a...) DCCP_PR_DEBUG(ccid2_debug, format, ##a)
41 printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \
42 } while (0)
43#else
44#define ccid2_pr_debug(format, a...)
45#endif
46 40
47#ifdef CONFIG_IP_DCCP_CCID2_DEBUG
48static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx) 41static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx)
49{ 42{
50 int len = 0; 43 int len = 0;
@@ -86,7 +79,8 @@ static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx)
86 BUG_ON(len != hctx->ccid2hctx_seqbufc * CCID2_SEQBUF_LEN); 79 BUG_ON(len != hctx->ccid2hctx_seqbufc * CCID2_SEQBUF_LEN);
87} 80}
88#else 81#else
89#define ccid2_hc_tx_check_sanity(hctx) do {} while (0) 82#define ccid2_pr_debug(format, a...)
83#define ccid2_hc_tx_check_sanity(hctx)
90#endif 84#endif
91 85
92static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hctx, int num, 86static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hctx, int num,
@@ -131,8 +125,7 @@ static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hctx, int num,
131 return 0; 125 return 0;
132} 126}
133 127
134static int ccid2_hc_tx_send_packet(struct sock *sk, 128static int ccid2_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
135 struct sk_buff *skb, int len)
136{ 129{
137 struct ccid2_hc_tx_sock *hctx; 130 struct ccid2_hc_tx_sock *hctx;
138 131
@@ -274,7 +267,7 @@ static void ccid2_start_rto_timer(struct sock *sk)
274 jiffies + hctx->ccid2hctx_rto); 267 jiffies + hctx->ccid2hctx_rto);
275} 268}
276 269
277static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, int len) 270static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
278{ 271{
279 struct dccp_sock *dp = dccp_sk(sk); 272 struct dccp_sock *dp = dccp_sk(sk);
280 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk); 273 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
@@ -426,7 +419,7 @@ static int ccid2_ackvector(struct sock *sk, struct sk_buff *skb, int offset,
426 return -1; 419 return -1;
427 420
428out_invalid_option: 421out_invalid_option:
429 BUG_ON(1); /* should never happen... options were previously parsed ! */ 422 DCCP_BUG("Invalid option - this should not happen (previous parsing)!");
430 return -1; 423 return -1;
431} 424}
432 425
@@ -619,7 +612,17 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
619 } 612 }
620 613
621 ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq; 614 ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq;
622 seqp = hctx->ccid2hctx_seqh->ccid2s_prev; 615 if (after48(ackno, hctx->ccid2hctx_high_ack))
616 hctx->ccid2hctx_high_ack = ackno;
617
618 seqp = hctx->ccid2hctx_seqt;
619 while (before48(seqp->ccid2s_seq, ackno)) {
620 seqp = seqp->ccid2s_next;
621 if (seqp == hctx->ccid2hctx_seqh) {
622 seqp = hctx->ccid2hctx_seqh->ccid2s_prev;
623 break;
624 }
625 }
623 626
624 /* If in slow-start, cwnd can increase at most Ack Ratio / 2 packets for 627 /* If in slow-start, cwnd can increase at most Ack Ratio / 2 packets for
625 * this single ack. I round up. 628 * this single ack. I round up.
@@ -697,7 +700,14 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
697 /* The state about what is acked should be correct now 700 /* The state about what is acked should be correct now
698 * Check for NUMDUPACK 701 * Check for NUMDUPACK
699 */ 702 */
700 seqp = hctx->ccid2hctx_seqh->ccid2s_prev; 703 seqp = hctx->ccid2hctx_seqt;
704 while (before48(seqp->ccid2s_seq, hctx->ccid2hctx_high_ack)) {
705 seqp = seqp->ccid2s_next;
706 if (seqp == hctx->ccid2hctx_seqh) {
707 seqp = hctx->ccid2hctx_seqh->ccid2s_prev;
708 break;
709 }
710 }
701 done = 0; 711 done = 0;
702 while (1) { 712 while (1) {
703 if (seqp->ccid2s_acked) { 713 if (seqp->ccid2s_acked) {
@@ -771,6 +781,7 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
771 hctx->ccid2hctx_lastrtt = 0; 781 hctx->ccid2hctx_lastrtt = 0;
772 hctx->ccid2hctx_rpdupack = -1; 782 hctx->ccid2hctx_rpdupack = -1;
773 hctx->ccid2hctx_last_cong = jiffies; 783 hctx->ccid2hctx_last_cong = jiffies;
784 hctx->ccid2hctx_high_ack = 0;
774 785
775 hctx->ccid2hctx_rtotimer.function = &ccid2_hc_tx_rto_expire; 786 hctx->ccid2hctx_rtotimer.function = &ccid2_hc_tx_rto_expire;
776 hctx->ccid2hctx_rtotimer.data = (unsigned long)sk; 787 hctx->ccid2hctx_rtotimer.data = (unsigned long)sk;
@@ -823,8 +834,10 @@ static struct ccid_operations ccid2 = {
823 .ccid_hc_rx_packet_recv = ccid2_hc_rx_packet_recv, 834 .ccid_hc_rx_packet_recv = ccid2_hc_rx_packet_recv,
824}; 835};
825 836
837#ifdef CONFIG_IP_DCCP_CCID2_DEBUG
826module_param(ccid2_debug, int, 0444); 838module_param(ccid2_debug, int, 0444);
827MODULE_PARM_DESC(ccid2_debug, "Enable debug messages"); 839MODULE_PARM_DESC(ccid2_debug, "Enable debug messages");
840#endif
828 841
829static __init int ccid2_module_init(void) 842static __init int ccid2_module_init(void)
830{ 843{
diff --git a/net/dccp/ccids/ccid2.h b/net/dccp/ccids/ccid2.h
index 5b2ef4acb300..ebd79499c85a 100644
--- a/net/dccp/ccids/ccid2.h
+++ b/net/dccp/ccids/ccid2.h
@@ -35,7 +35,7 @@ struct ccid2_seq {
35 struct ccid2_seq *ccid2s_next; 35 struct ccid2_seq *ccid2s_next;
36}; 36};
37 37
38#define CCID2_SEQBUF_LEN 256 38#define CCID2_SEQBUF_LEN 1024
39#define CCID2_SEQBUF_MAX 128 39#define CCID2_SEQBUF_MAX 128
40 40
41/** struct ccid2_hc_tx_sock - CCID2 TX half connection 41/** struct ccid2_hc_tx_sock - CCID2 TX half connection
@@ -72,6 +72,7 @@ struct ccid2_hc_tx_sock {
72 int ccid2hctx_rpdupack; 72 int ccid2hctx_rpdupack;
73 int ccid2hctx_sendwait; 73 int ccid2hctx_sendwait;
74 unsigned long ccid2hctx_last_cong; 74 unsigned long ccid2hctx_last_cong;
75 u64 ccid2hctx_high_ack;
75}; 76};
76 77
77struct ccid2_hc_rx_sock { 78struct ccid2_hc_rx_sock {
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index cec23ad286de..70ebe705eb75 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -60,13 +60,11 @@ static u32 usecs_div(const u32 a, const u32 b)
60 return (b >= 2 * div) ? tmp / (b / div) : tmp; 60 return (b >= 2 * div) ? tmp / (b / div) : tmp;
61} 61}
62 62
63static int ccid3_debug;
64 63
65#ifdef CCID3_DEBUG 64
66#define ccid3_pr_debug(format, a...) \ 65#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
67 do { if (ccid3_debug) \ 66static int ccid3_debug;
68 printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \ 67#define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
69 } while (0)
70#else 68#else
71#define ccid3_pr_debug(format, a...) 69#define ccid3_pr_debug(format, a...)
72#endif 70#endif
@@ -75,15 +73,7 @@ static struct dccp_tx_hist *ccid3_tx_hist;
75static struct dccp_rx_hist *ccid3_rx_hist; 73static struct dccp_rx_hist *ccid3_rx_hist;
76static struct dccp_li_hist *ccid3_li_hist; 74static struct dccp_li_hist *ccid3_li_hist;
77 75
78/* TFRC sender states */ 76#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
79enum ccid3_hc_tx_states {
80 TFRC_SSTATE_NO_SENT = 1,
81 TFRC_SSTATE_NO_FBACK,
82 TFRC_SSTATE_FBACK,
83 TFRC_SSTATE_TERM,
84};
85
86#ifdef CCID3_DEBUG
87static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state) 77static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state)
88{ 78{
89 static char *ccid3_state_names[] = { 79 static char *ccid3_state_names[] = {
@@ -110,25 +100,24 @@ static void ccid3_hc_tx_set_state(struct sock *sk,
110 hctx->ccid3hctx_state = state; 100 hctx->ccid3hctx_state = state;
111} 101}
112 102
113/* Calculate new t_ipi (inter packet interval) by t_ipi = s / X_inst */ 103/*
114static inline void ccid3_calc_new_t_ipi(struct ccid3_hc_tx_sock *hctx) 104 * Recalculate scheduled nominal send time t_nom, inter-packet interval
105 * t_ipi, and delta value. Should be called after each change to X.
106 */
107static inline void ccid3_update_send_time(struct ccid3_hc_tx_sock *hctx)
115{ 108{
116 /* 109 timeval_sub_usecs(&hctx->ccid3hctx_t_nom, hctx->ccid3hctx_t_ipi);
117 * If no feedback spec says t_ipi is 1 second (set elsewhere and then
118 * doubles after every no feedback timer (separate function)
119 */
120 if (hctx->ccid3hctx_state != TFRC_SSTATE_NO_FBACK)
121 hctx->ccid3hctx_t_ipi = usecs_div(hctx->ccid3hctx_s,
122 hctx->ccid3hctx_x);
123}
124 110
125/* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */ 111 /* Calculate new t_ipi (inter packet interval) by t_ipi = s / X_inst */
126static inline void ccid3_calc_new_delta(struct ccid3_hc_tx_sock *hctx) 112 hctx->ccid3hctx_t_ipi = usecs_div(hctx->ccid3hctx_s, hctx->ccid3hctx_x);
127{ 113
114 /* Update nominal send time with regard to the new t_ipi */
115 timeval_add_usecs(&hctx->ccid3hctx_t_nom, hctx->ccid3hctx_t_ipi);
116
117 /* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */
128 hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2, 118 hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2,
129 TFRC_OPSYS_HALF_TIME_GRAN); 119 TFRC_OPSYS_HALF_TIME_GRAN);
130} 120}
131
132/* 121/*
133 * Update X by 122 * Update X by
134 * If (p > 0) 123 * If (p > 0)
@@ -139,76 +128,85 @@ static inline void ccid3_calc_new_delta(struct ccid3_hc_tx_sock *hctx)
139 * X = max(min(2 * X, 2 * X_recv), s / R); 128 * X = max(min(2 * X, 2 * X_recv), s / R);
140 * tld = now; 129 * tld = now;
141 */ 130 */
142static void ccid3_hc_tx_update_x(struct sock *sk) 131static void ccid3_hc_tx_update_x(struct sock *sk, struct timeval *now)
132
143{ 133{
144 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 134 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
135 const __u32 old_x = hctx->ccid3hctx_x;
145 136
146 /* To avoid large error in calcX */ 137 /* To avoid large error in calcX */
147 if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) { 138 if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) {
148 hctx->ccid3hctx_x_calc = tfrc_calc_x(hctx->ccid3hctx_s, 139 hctx->ccid3hctx_x_calc = tfrc_calc_x(hctx->ccid3hctx_s,
149 hctx->ccid3hctx_rtt, 140 hctx->ccid3hctx_rtt,
150 hctx->ccid3hctx_p); 141 hctx->ccid3hctx_p);
151 hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_calc, 142 hctx->ccid3hctx_x = max_t(u32, min(hctx->ccid3hctx_x_calc,
152 2 * hctx->ccid3hctx_x_recv), 143 hctx->ccid3hctx_x_recv * 2),
153 (hctx->ccid3hctx_s / 144 hctx->ccid3hctx_s / TFRC_T_MBI);
154 TFRC_MAX_BACK_OFF_TIME)); 145
155 } else { 146 } else if (timeval_delta(now, &hctx->ccid3hctx_t_ld) >=
156 struct timeval now; 147 hctx->ccid3hctx_rtt) {
148 hctx->ccid3hctx_x = max(min(hctx->ccid3hctx_x_recv,
149 hctx->ccid3hctx_x ) * 2,
150 usecs_div(hctx->ccid3hctx_s,
151 hctx->ccid3hctx_rtt) );
152 hctx->ccid3hctx_t_ld = *now;
153 } else
154 ccid3_pr_debug("Not changing X\n");
157 155
158 dccp_timestamp(sk, &now); 156 if (hctx->ccid3hctx_x != old_x)
159 if (timeval_delta(&now, &hctx->ccid3hctx_t_ld) >= 157 ccid3_update_send_time(hctx);
160 hctx->ccid3hctx_rtt) { 158}
161 hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_recv, 159
162 hctx->ccid3hctx_x) * 2, 160/*
163 usecs_div(hctx->ccid3hctx_s, 161 * Track the mean packet size `s' (cf. RFC 4342, 5.3 and RFC 3448, 4.1)
164 hctx->ccid3hctx_rtt)); 162 * @len: DCCP packet payload size in bytes
165 hctx->ccid3hctx_t_ld = now; 163 */
166 } 164static inline void ccid3_hc_tx_update_s(struct ccid3_hc_tx_sock *hctx, int len)
167 } 165{
166 if (unlikely(len == 0))
167 ccid3_pr_debug("Packet payload length is 0 - not updating\n");
168 else
169 hctx->ccid3hctx_s = hctx->ccid3hctx_s == 0 ? len :
170 (9 * hctx->ccid3hctx_s + len) / 10;
171 /*
172 * Note: We could do a potential optimisation here - when `s' changes,
173 * recalculate sending rate and consequently t_ipi, t_delta, and
174 * t_now. This is however non-standard, and the benefits are not
175 * clear, so it is currently left out.
176 */
168} 177}
169 178
170static void ccid3_hc_tx_no_feedback_timer(unsigned long data) 179static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
171{ 180{
172 struct sock *sk = (struct sock *)data; 181 struct sock *sk = (struct sock *)data;
173 unsigned long next_tmout = 0;
174 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 182 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
183 unsigned long t_nfb = USEC_PER_SEC / 5;
175 184
176 bh_lock_sock(sk); 185 bh_lock_sock(sk);
177 if (sock_owned_by_user(sk)) { 186 if (sock_owned_by_user(sk)) {
178 /* Try again later. */ 187 /* Try again later. */
179 /* XXX: set some sensible MIB */ 188 /* XXX: set some sensible MIB */
180 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 189 goto restart_timer;
181 jiffies + HZ / 5);
182 goto out;
183 } 190 }
184 191
185 ccid3_pr_debug("%s, sk=%p, state=%s\n", dccp_role(sk), sk, 192 ccid3_pr_debug("%s, sk=%p, state=%s\n", dccp_role(sk), sk,
186 ccid3_tx_state_name(hctx->ccid3hctx_state)); 193 ccid3_tx_state_name(hctx->ccid3hctx_state));
187 194
188 switch (hctx->ccid3hctx_state) { 195 switch (hctx->ccid3hctx_state) {
189 case TFRC_SSTATE_TERM:
190 goto out;
191 case TFRC_SSTATE_NO_FBACK: 196 case TFRC_SSTATE_NO_FBACK:
192 /* Halve send rate */ 197 /* RFC 3448, 4.4: Halve send rate directly */
193 hctx->ccid3hctx_x /= 2; 198 hctx->ccid3hctx_x = min_t(u32, hctx->ccid3hctx_x / 2,
194 if (hctx->ccid3hctx_x < (hctx->ccid3hctx_s / 199 hctx->ccid3hctx_s / TFRC_T_MBI);
195 TFRC_MAX_BACK_OFF_TIME))
196 hctx->ccid3hctx_x = (hctx->ccid3hctx_s /
197 TFRC_MAX_BACK_OFF_TIME);
198 200
199 ccid3_pr_debug("%s, sk=%p, state=%s, updated tx rate to %d " 201 ccid3_pr_debug("%s, sk=%p, state=%s, updated tx rate to %d "
200 "bytes/s\n", 202 "bytes/s\n",
201 dccp_role(sk), sk, 203 dccp_role(sk), sk,
202 ccid3_tx_state_name(hctx->ccid3hctx_state), 204 ccid3_tx_state_name(hctx->ccid3hctx_state),
203 hctx->ccid3hctx_x); 205 hctx->ccid3hctx_x);
204 next_tmout = max_t(u32, 2 * usecs_div(hctx->ccid3hctx_s, 206 /* The value of R is still undefined and so we can not recompute
205 hctx->ccid3hctx_x), 207 * the timout value. Keep initial value as per [RFC 4342, 5]. */
206 TFRC_INITIAL_TIMEOUT); 208 t_nfb = TFRC_INITIAL_TIMEOUT;
207 /* 209 ccid3_update_send_time(hctx);
208 * FIXME - not sure above calculation is correct. See section
209 * 5 of CCID3 11 should adjust tx_t_ipi and double that to
210 * achieve it really
211 */
212 break; 210 break;
213 case TFRC_SSTATE_FBACK: 211 case TFRC_SSTATE_FBACK:
214 /* 212 /*
@@ -218,6 +216,8 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
218 if (!hctx->ccid3hctx_idle || 216 if (!hctx->ccid3hctx_idle ||
219 (hctx->ccid3hctx_x_recv >= 217 (hctx->ccid3hctx_x_recv >=
220 4 * usecs_div(hctx->ccid3hctx_s, hctx->ccid3hctx_rtt))) { 218 4 * usecs_div(hctx->ccid3hctx_s, hctx->ccid3hctx_rtt))) {
219 struct timeval now;
220
221 ccid3_pr_debug("%s, sk=%p, state=%s, not idle\n", 221 ccid3_pr_debug("%s, sk=%p, state=%s, not idle\n",
222 dccp_role(sk), sk, 222 dccp_role(sk), sk,
223 ccid3_tx_state_name(hctx->ccid3hctx_state)); 223 ccid3_tx_state_name(hctx->ccid3hctx_state));
@@ -235,55 +235,60 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
235 if (hctx->ccid3hctx_p < TFRC_SMALLEST_P || 235 if (hctx->ccid3hctx_p < TFRC_SMALLEST_P ||
236 hctx->ccid3hctx_x_calc > 2 * hctx->ccid3hctx_x_recv) 236 hctx->ccid3hctx_x_calc > 2 * hctx->ccid3hctx_x_recv)
237 hctx->ccid3hctx_x_recv = max_t(u32, hctx->ccid3hctx_x_recv / 2, 237 hctx->ccid3hctx_x_recv = max_t(u32, hctx->ccid3hctx_x_recv / 2,
238 hctx->ccid3hctx_s / (2 * TFRC_MAX_BACK_OFF_TIME)); 238 hctx->ccid3hctx_s / (2 * TFRC_T_MBI));
239 else 239 else
240 hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc / 4; 240 hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc / 4;
241 241
242 /* Update sending rate */ 242 /* Update sending rate */
243 ccid3_hc_tx_update_x(sk); 243 dccp_timestamp(sk, &now);
244 ccid3_hc_tx_update_x(sk, &now);
244 } 245 }
245 /* 246 /*
246 * Schedule no feedback timer to expire in 247 * Schedule no feedback timer to expire in
247 * max(4 * R, 2 * s / X) 248 * max(4 * R, 2 * s/X) = max(4 * R, 2 * t_ipi)
248 */ 249 */
249 next_tmout = max_t(u32, hctx->ccid3hctx_t_rto, 250 t_nfb = max(4 * hctx->ccid3hctx_rtt, 2 * hctx->ccid3hctx_t_ipi);
250 2 * usecs_div(hctx->ccid3hctx_s,
251 hctx->ccid3hctx_x));
252 break; 251 break;
253 default: 252 case TFRC_SSTATE_NO_SENT:
254 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 253 DCCP_BUG("Illegal %s state NO_SENT, sk=%p", dccp_role(sk), sk);
255 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state); 254 /* fall through */
256 dump_stack(); 255 case TFRC_SSTATE_TERM:
257 goto out; 256 goto out;
258 } 257 }
259 258
260 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
261 jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout)));
262 hctx->ccid3hctx_idle = 1; 259 hctx->ccid3hctx_idle = 1;
260
261restart_timer:
262 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
263 jiffies + usecs_to_jiffies(t_nfb));
263out: 264out:
264 bh_unlock_sock(sk); 265 bh_unlock_sock(sk);
265 sock_put(sk); 266 sock_put(sk);
266} 267}
267 268
268static int ccid3_hc_tx_send_packet(struct sock *sk, 269/*
269 struct sk_buff *skb, int len) 270 * returns
271 * > 0: delay (in msecs) that should pass before actually sending
272 * = 0: can send immediately
273 * < 0: error condition; do not send packet
274 */
275static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
270{ 276{
271 struct dccp_sock *dp = dccp_sk(sk); 277 struct dccp_sock *dp = dccp_sk(sk);
272 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 278 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
273 struct dccp_tx_hist_entry *new_packet; 279 struct dccp_tx_hist_entry *new_packet;
274 struct timeval now; 280 struct timeval now;
275 long delay; 281 long delay;
276 int rc = -ENOTCONN;
277 282
278 BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM); 283 BUG_ON(hctx == NULL);
279 284
280 /* Check if pure ACK or Terminating*/
281 /* 285 /*
282 * XXX: We only call this function for DATA and DATAACK, on, these 286 * This function is called only for Data and DataAck packets. Sending
283 * packets can have zero length, but why the comment about "pure ACK"? 287 * zero-sized Data(Ack)s is theoretically possible, but for congestion
288 * control this case is pathological - ignore it.
284 */ 289 */
285 if (unlikely(len == 0)) 290 if (unlikely(skb->len == 0))
286 goto out; 291 return -EBADMSG;
287 292
288 /* See if last packet allocated was not sent */ 293 /* See if last packet allocated was not sent */
289 new_packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist); 294 new_packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
@@ -291,12 +296,10 @@ static int ccid3_hc_tx_send_packet(struct sock *sk,
291 new_packet = dccp_tx_hist_entry_new(ccid3_tx_hist, 296 new_packet = dccp_tx_hist_entry_new(ccid3_tx_hist,
292 SLAB_ATOMIC); 297 SLAB_ATOMIC);
293 298
294 rc = -ENOBUFS;
295 if (unlikely(new_packet == NULL)) { 299 if (unlikely(new_packet == NULL)) {
296 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, not enough " 300 DCCP_WARN("%s, sk=%p, not enough mem to add to history,"
297 "mem to add to history, send refused\n", 301 "send refused\n", dccp_role(sk), sk);
298 __FUNCTION__, dccp_role(sk), sk); 302 return -ENOBUFS;
299 goto out;
300 } 303 }
301 304
302 dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet); 305 dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet);
@@ -311,123 +314,94 @@ static int ccid3_hc_tx_send_packet(struct sock *sk,
311 hctx->ccid3hctx_last_win_count = 0; 314 hctx->ccid3hctx_last_win_count = 0;
312 hctx->ccid3hctx_t_last_win_count = now; 315 hctx->ccid3hctx_t_last_win_count = now;
313 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK); 316 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
314 hctx->ccid3hctx_t_ipi = TFRC_INITIAL_IPI;
315 317
316 /* Set nominal send time for initial packet */ 318 /* Set initial sending rate to 1 packet per second */
319 ccid3_hc_tx_update_s(hctx, skb->len);
320 hctx->ccid3hctx_x = hctx->ccid3hctx_s;
321
322 /* First timeout, according to [RFC 3448, 4.2], is 1 second */
323 hctx->ccid3hctx_t_ipi = USEC_PER_SEC;
324 /* Initial delta: minimum of 0.5 sec and t_gran/2 */
325 hctx->ccid3hctx_delta = TFRC_OPSYS_HALF_TIME_GRAN;
326
327 /* Set t_0 for initial packet */
317 hctx->ccid3hctx_t_nom = now; 328 hctx->ccid3hctx_t_nom = now;
318 timeval_add_usecs(&hctx->ccid3hctx_t_nom,
319 hctx->ccid3hctx_t_ipi);
320 ccid3_calc_new_delta(hctx);
321 rc = 0;
322 break; 329 break;
323 case TFRC_SSTATE_NO_FBACK: 330 case TFRC_SSTATE_NO_FBACK:
324 case TFRC_SSTATE_FBACK: 331 case TFRC_SSTATE_FBACK:
325 delay = (timeval_delta(&now, &hctx->ccid3hctx_t_nom) - 332 delay = timeval_delta(&hctx->ccid3hctx_t_nom, &now);
326 hctx->ccid3hctx_delta); 333 /*
327 delay /= -1000; 334 * Scheduling of packet transmissions [RFC 3448, 4.6]
328 /* divide by -1000 is to convert to ms and get sign right */ 335 *
329 rc = delay > 0 ? delay : 0; 336 * if (t_now > t_nom - delta)
330 break; 337 * // send the packet now
331 default: 338 * else
332 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 339 * // send the packet in (t_nom - t_now) milliseconds.
333 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state); 340 */
334 dump_stack(); 341 if (delay >= hctx->ccid3hctx_delta)
335 rc = -EINVAL; 342 return delay / 1000L;
336 break; 343 break;
344 case TFRC_SSTATE_TERM:
345 DCCP_BUG("Illegal %s state TERM, sk=%p", dccp_role(sk), sk);
346 return -EINVAL;
337 } 347 }
338 348
339 /* Can we send? if so add options and add to packet history */ 349 /* prepare to send now (add options etc.) */
340 if (rc == 0) { 350 dp->dccps_hc_tx_insert_options = 1;
341 dp->dccps_hc_tx_insert_options = 1; 351 new_packet->dccphtx_ccval = DCCP_SKB_CB(skb)->dccpd_ccval =
342 new_packet->dccphtx_ccval = 352 hctx->ccid3hctx_last_win_count;
343 DCCP_SKB_CB(skb)->dccpd_ccval = 353 timeval_add_usecs(&hctx->ccid3hctx_t_nom, hctx->ccid3hctx_t_ipi);
344 hctx->ccid3hctx_last_win_count; 354
345 timeval_add_usecs(&hctx->ccid3hctx_t_nom, 355 return 0;
346 hctx->ccid3hctx_t_ipi);
347 }
348out:
349 return rc;
350} 356}
351 357
352static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len) 358static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
353{ 359{
354 const struct dccp_sock *dp = dccp_sk(sk); 360 const struct dccp_sock *dp = dccp_sk(sk);
355 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 361 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
356 struct timeval now; 362 struct timeval now;
363 unsigned long quarter_rtt;
364 struct dccp_tx_hist_entry *packet;
357 365
358 BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM); 366 BUG_ON(hctx == NULL);
359 367
360 dccp_timestamp(sk, &now); 368 dccp_timestamp(sk, &now);
361 369
362 /* check if we have sent a data packet */ 370 ccid3_hc_tx_update_s(hctx, len);
363 if (len > 0) {
364 unsigned long quarter_rtt;
365 struct dccp_tx_hist_entry *packet;
366 371
367 packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist); 372 packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
368 if (unlikely(packet == NULL)) { 373 if (unlikely(packet == NULL)) {
369 LIMIT_NETDEBUG(KERN_WARNING "%s: packet doesn't " 374 DCCP_WARN("packet doesn't exist in history!\n");
370 "exists in history!\n", __FUNCTION__);
371 return;
372 }
373 if (unlikely(packet->dccphtx_sent)) {
374 LIMIT_NETDEBUG(KERN_WARNING "%s: no unsent packet in "
375 "history!\n", __FUNCTION__);
376 return;
377 }
378 packet->dccphtx_tstamp = now;
379 packet->dccphtx_seqno = dp->dccps_gss;
380 /*
381 * Check if win_count have changed
382 * Algorithm in "8.1. Window Counter Value" in RFC 4342.
383 */
384 quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count);
385 if (likely(hctx->ccid3hctx_rtt > 8))
386 quarter_rtt /= hctx->ccid3hctx_rtt / 4;
387
388 if (quarter_rtt > 0) {
389 hctx->ccid3hctx_t_last_win_count = now;
390 hctx->ccid3hctx_last_win_count = (hctx->ccid3hctx_last_win_count +
391 min_t(unsigned long, quarter_rtt, 5)) % 16;
392 ccid3_pr_debug("%s, sk=%p, window changed from "
393 "%u to %u!\n",
394 dccp_role(sk), sk,
395 packet->dccphtx_ccval,
396 hctx->ccid3hctx_last_win_count);
397 }
398
399 hctx->ccid3hctx_idle = 0;
400 packet->dccphtx_rtt = hctx->ccid3hctx_rtt;
401 packet->dccphtx_sent = 1;
402 } else
403 ccid3_pr_debug("%s, sk=%p, seqno=%llu NOT inserted!\n",
404 dccp_role(sk), sk, dp->dccps_gss);
405
406 switch (hctx->ccid3hctx_state) {
407 case TFRC_SSTATE_NO_SENT:
408 /* if first wasn't pure ack */
409 if (len != 0)
410 printk(KERN_CRIT "%s: %s, First packet sent is noted "
411 "as a data packet\n",
412 __FUNCTION__, dccp_role(sk));
413 return; 375 return;
414 case TFRC_SSTATE_NO_FBACK:
415 case TFRC_SSTATE_FBACK:
416 if (len > 0) {
417 timeval_sub_usecs(&hctx->ccid3hctx_t_nom,
418 hctx->ccid3hctx_t_ipi);
419 ccid3_calc_new_t_ipi(hctx);
420 ccid3_calc_new_delta(hctx);
421 timeval_add_usecs(&hctx->ccid3hctx_t_nom,
422 hctx->ccid3hctx_t_ipi);
423 }
424 break;
425 default:
426 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
427 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
428 dump_stack();
429 break;
430 } 376 }
377 if (unlikely(packet->dccphtx_sent)) {
378 DCCP_WARN("no unsent packet in history!\n");
379 return;
380 }
381 packet->dccphtx_tstamp = now;
382 packet->dccphtx_seqno = dp->dccps_gss;
383 /*
384 * Check if win_count have changed
385 * Algorithm in "8.1. Window Counter Value" in RFC 4342.
386 */
387 quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count);
388 if (likely(hctx->ccid3hctx_rtt > 8))
389 quarter_rtt /= hctx->ccid3hctx_rtt / 4;
390
391 if (quarter_rtt > 0) {
392 hctx->ccid3hctx_t_last_win_count = now;
393 hctx->ccid3hctx_last_win_count = (hctx->ccid3hctx_last_win_count +
394 min_t(unsigned long, quarter_rtt, 5)) % 16;
395 ccid3_pr_debug("%s, sk=%p, window changed from "
396 "%u to %u!\n",
397 dccp_role(sk), sk,
398 packet->dccphtx_ccval,
399 hctx->ccid3hctx_last_win_count);
400 }
401
402 hctx->ccid3hctx_idle = 0;
403 packet->dccphtx_rtt = hctx->ccid3hctx_rtt;
404 packet->dccphtx_sent = 1;
431} 405}
432 406
433static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) 407static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
@@ -437,13 +411,13 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
437 struct ccid3_options_received *opt_recv; 411 struct ccid3_options_received *opt_recv;
438 struct dccp_tx_hist_entry *packet; 412 struct dccp_tx_hist_entry *packet;
439 struct timeval now; 413 struct timeval now;
440 unsigned long next_tmout; 414 unsigned long t_nfb;
441 u32 t_elapsed; 415 u32 t_elapsed;
442 u32 pinv; 416 u32 pinv;
443 u32 x_recv; 417 u32 x_recv;
444 u32 r_sample; 418 u32 r_sample;
445 419
446 BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM); 420 BUG_ON(hctx == NULL);
447 421
448 /* we are only interested in ACKs */ 422 /* we are only interested in ACKs */
449 if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK || 423 if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK ||
@@ -457,9 +431,6 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
457 pinv = opt_recv->ccid3or_loss_event_rate; 431 pinv = opt_recv->ccid3or_loss_event_rate;
458 432
459 switch (hctx->ccid3hctx_state) { 433 switch (hctx->ccid3hctx_state) {
460 case TFRC_SSTATE_NO_SENT:
461 /* FIXME: what to do here? */
462 return;
463 case TFRC_SSTATE_NO_FBACK: 434 case TFRC_SSTATE_NO_FBACK:
464 case TFRC_SSTATE_FBACK: 435 case TFRC_SSTATE_FBACK:
465 /* Calculate new round trip sample by 436 /* Calculate new round trip sample by
@@ -468,11 +439,10 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
468 packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist, 439 packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist,
469 DCCP_SKB_CB(skb)->dccpd_ack_seq); 440 DCCP_SKB_CB(skb)->dccpd_ack_seq);
470 if (unlikely(packet == NULL)) { 441 if (unlikely(packet == NULL)) {
471 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, seqno " 442 DCCP_WARN("%s, sk=%p, seqno %llu(%s) does't exist "
472 "%llu(%s) does't exist in history!\n", 443 "in history!\n", dccp_role(sk), sk,
473 __FUNCTION__, dccp_role(sk), sk,
474 (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq, 444 (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq,
475 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type)); 445 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
476 return; 446 return;
477 } 447 }
478 448
@@ -480,9 +450,8 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
480 dccp_timestamp(sk, &now); 450 dccp_timestamp(sk, &now);
481 r_sample = timeval_delta(&now, &packet->dccphtx_tstamp); 451 r_sample = timeval_delta(&now, &packet->dccphtx_tstamp);
482 if (unlikely(r_sample <= t_elapsed)) 452 if (unlikely(r_sample <= t_elapsed))
483 LIMIT_NETDEBUG(KERN_WARNING "%s: r_sample=%uus, " 453 DCCP_WARN("r_sample=%uus,t_elapsed=%uus\n",
484 "t_elapsed=%uus\n", 454 r_sample, t_elapsed);
485 __FUNCTION__, r_sample, t_elapsed);
486 else 455 else
487 r_sample -= t_elapsed; 456 r_sample -= t_elapsed;
488 457
@@ -495,20 +464,26 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
495 * q is a constant, RFC 3448 recomments 0.9 464 * q is a constant, RFC 3448 recomments 0.9
496 */ 465 */
497 if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) { 466 if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) {
467 /* Use Larger Initial Windows [RFC 4342, sec. 5]
468 * We deviate in that we use `s' instead of `MSS'. */
469 u16 w_init = max( 4 * hctx->ccid3hctx_s,
470 max(2 * hctx->ccid3hctx_s, 4380));
471 hctx->ccid3hctx_rtt = r_sample;
472 hctx->ccid3hctx_x = usecs_div(w_init, r_sample);
473 hctx->ccid3hctx_t_ld = now;
474
475 ccid3_update_send_time(hctx);
498 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK); 476 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
499 hctx->ccid3hctx_rtt = r_sample; 477 } else {
500 } else
501 hctx->ccid3hctx_rtt = (hctx->ccid3hctx_rtt * 9) / 10 + 478 hctx->ccid3hctx_rtt = (hctx->ccid3hctx_rtt * 9) / 10 +
502 r_sample / 10; 479 r_sample / 10;
480 ccid3_hc_tx_update_x(sk, &now);
481 }
503 482
504 ccid3_pr_debug("%s, sk=%p, New RTT estimate=%uus, " 483 ccid3_pr_debug("%s, sk=%p, New RTT estimate=%uus, "
505 "r_sample=%us\n", dccp_role(sk), sk, 484 "r_sample=%us\n", dccp_role(sk), sk,
506 hctx->ccid3hctx_rtt, r_sample); 485 hctx->ccid3hctx_rtt, r_sample);
507 486
508 /* Update timeout interval */
509 hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
510 USEC_PER_SEC);
511
512 /* Update receive rate */ 487 /* Update receive rate */
513 hctx->ccid3hctx_x_recv = x_recv;/* X_recv in bytes per sec */ 488 hctx->ccid3hctx_x_recv = x_recv;/* X_recv in bytes per sec */
514 489
@@ -528,49 +503,41 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
528 /* unschedule no feedback timer */ 503 /* unschedule no feedback timer */
529 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer); 504 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
530 505
531 /* Update sending rate */
532 ccid3_hc_tx_update_x(sk);
533
534 /* Update next send time */
535 timeval_sub_usecs(&hctx->ccid3hctx_t_nom,
536 hctx->ccid3hctx_t_ipi);
537 ccid3_calc_new_t_ipi(hctx);
538 timeval_add_usecs(&hctx->ccid3hctx_t_nom,
539 hctx->ccid3hctx_t_ipi);
540 ccid3_calc_new_delta(hctx);
541
542 /* remove all packets older than the one acked from history */ 506 /* remove all packets older than the one acked from history */
543 dccp_tx_hist_purge_older(ccid3_tx_hist, 507 dccp_tx_hist_purge_older(ccid3_tx_hist,
544 &hctx->ccid3hctx_hist, packet); 508 &hctx->ccid3hctx_hist, packet);
545 /* 509 /*
546 * As we have calculated new ipi, delta, t_nom it is possible that 510 * As we have calculated new ipi, delta, t_nom it is possible that
547 * we now can send a packet, so wake up dccp_wait_for_ccids. 511 * we now can send a packet, so wake up dccp_wait_for_ccid
548 */ 512 */
549 sk->sk_write_space(sk); 513 sk->sk_write_space(sk);
550 514
515 /* Update timeout interval. We use the alternative variant of
516 * [RFC 3448, 3.1] which sets the upper bound of t_rto to one
517 * second, as it is suggested for TCP (see RFC 2988, 2.4). */
518 hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
519 USEC_PER_SEC );
551 /* 520 /*
552 * Schedule no feedback timer to expire in 521 * Schedule no feedback timer to expire in
553 * max(4 * R, 2 * s / X) 522 * max(4 * R, 2 * s/X) = max(4 * R, 2 * t_ipi)
554 */ 523 */
555 next_tmout = max(hctx->ccid3hctx_t_rto, 524 t_nfb = max(4 * hctx->ccid3hctx_rtt, 2 * hctx->ccid3hctx_t_ipi);
556 2 * usecs_div(hctx->ccid3hctx_s,
557 hctx->ccid3hctx_x));
558 525
559 ccid3_pr_debug("%s, sk=%p, Scheduled no feedback timer to " 526 ccid3_pr_debug("%s, sk=%p, Scheduled no feedback timer to "
560 "expire in %lu jiffies (%luus)\n", 527 "expire in %lu jiffies (%luus)\n",
561 dccp_role(sk), sk, 528 dccp_role(sk), sk,
562 usecs_to_jiffies(next_tmout), next_tmout); 529 usecs_to_jiffies(t_nfb), t_nfb);
563 530
564 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 531 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
565 jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout))); 532 jiffies + usecs_to_jiffies(t_nfb));
566 533
567 /* set idle flag */ 534 /* set idle flag */
568 hctx->ccid3hctx_idle = 1; 535 hctx->ccid3hctx_idle = 1;
569 break; 536 break;
570 default: 537 case TFRC_SSTATE_NO_SENT:
571 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 538 DCCP_WARN("Illegal ACK received - no packet has been sent\n");
572 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state); 539 /* fall through */
573 dump_stack(); 540 case TFRC_SSTATE_TERM: /* ignore feedback when closing */
574 break; 541 break;
575 } 542 }
576} 543}
@@ -610,9 +577,9 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
610 switch (option) { 577 switch (option) {
611 case TFRC_OPT_LOSS_EVENT_RATE: 578 case TFRC_OPT_LOSS_EVENT_RATE:
612 if (unlikely(len != 4)) { 579 if (unlikely(len != 4)) {
613 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, invalid " 580 DCCP_WARN("%s, sk=%p, invalid len %d "
614 "len for TFRC_OPT_LOSS_EVENT_RATE\n", 581 "for TFRC_OPT_LOSS_EVENT_RATE\n",
615 __FUNCTION__, dccp_role(sk), sk); 582 dccp_role(sk), sk, len);
616 rc = -EINVAL; 583 rc = -EINVAL;
617 } else { 584 } else {
618 opt_recv->ccid3or_loss_event_rate = ntohl(*(__be32 *)value); 585 opt_recv->ccid3or_loss_event_rate = ntohl(*(__be32 *)value);
@@ -631,9 +598,9 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
631 break; 598 break;
632 case TFRC_OPT_RECEIVE_RATE: 599 case TFRC_OPT_RECEIVE_RATE:
633 if (unlikely(len != 4)) { 600 if (unlikely(len != 4)) {
634 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, invalid " 601 DCCP_WARN("%s, sk=%p, invalid len %d "
635 "len for TFRC_OPT_RECEIVE_RATE\n", 602 "for TFRC_OPT_RECEIVE_RATE\n",
636 __FUNCTION__, dccp_role(sk), sk); 603 dccp_role(sk), sk, len);
637 rc = -EINVAL; 604 rc = -EINVAL;
638 } else { 605 } else {
639 opt_recv->ccid3or_receive_rate = ntohl(*(__be32 *)value); 606 opt_recv->ccid3or_receive_rate = ntohl(*(__be32 *)value);
@@ -649,18 +616,9 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
649 616
650static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk) 617static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk)
651{ 618{
652 struct dccp_sock *dp = dccp_sk(sk);
653 struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid); 619 struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid);
654 620
655 if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && 621 hctx->ccid3hctx_s = 0;
656 dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE)
657 hctx->ccid3hctx_s = dp->dccps_packet_size;
658 else
659 hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE;
660
661 /* Set transmission rate to 1 packet per second */
662 hctx->ccid3hctx_x = hctx->ccid3hctx_s;
663 hctx->ccid3hctx_t_rto = USEC_PER_SEC;
664 hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT; 622 hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
665 INIT_LIST_HEAD(&hctx->ccid3hctx_hist); 623 INIT_LIST_HEAD(&hctx->ccid3hctx_hist);
666 624
@@ -688,14 +646,7 @@ static void ccid3_hc_tx_exit(struct sock *sk)
688 * RX Half Connection methods 646 * RX Half Connection methods
689 */ 647 */
690 648
691/* TFRC receiver states */ 649#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
692enum ccid3_hc_rx_states {
693 TFRC_RSTATE_NO_DATA = 1,
694 TFRC_RSTATE_DATA,
695 TFRC_RSTATE_TERM = 127,
696};
697
698#ifdef CCID3_DEBUG
699static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state) 650static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
700{ 651{
701 static char *ccid3_rx_state_names[] = { 652 static char *ccid3_rx_state_names[] = {
@@ -721,6 +672,15 @@ static void ccid3_hc_rx_set_state(struct sock *sk,
721 hcrx->ccid3hcrx_state = state; 672 hcrx->ccid3hcrx_state = state;
722} 673}
723 674
675static inline void ccid3_hc_rx_update_s(struct ccid3_hc_rx_sock *hcrx, int len)
676{
677 if (unlikely(len == 0)) /* don't update on empty packets (e.g. ACKs) */
678 ccid3_pr_debug("Packet payload length is 0 - not updating\n");
679 else
680 hcrx->ccid3hcrx_s = hcrx->ccid3hcrx_s == 0 ? len :
681 (9 * hcrx->ccid3hcrx_s + len) / 10;
682}
683
724static void ccid3_hc_rx_send_feedback(struct sock *sk) 684static void ccid3_hc_rx_send_feedback(struct sock *sk)
725{ 685{
726 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 686 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
@@ -743,18 +703,15 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk)
743 delta); 703 delta);
744 } 704 }
745 break; 705 break;
746 default: 706 case TFRC_RSTATE_TERM:
747 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 707 DCCP_BUG("Illegal %s state TERM, sk=%p", dccp_role(sk), sk);
748 __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
749 dump_stack();
750 return; 708 return;
751 } 709 }
752 710
753 packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist); 711 packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist);
754 if (unlikely(packet == NULL)) { 712 if (unlikely(packet == NULL)) {
755 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, no data packet " 713 DCCP_WARN("%s, sk=%p, no data packet in history!\n",
756 "in history!\n", 714 dccp_role(sk), sk);
757 __FUNCTION__, dccp_role(sk), sk);
758 return; 715 return;
759 } 716 }
760 717
@@ -842,29 +799,29 @@ static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
842 } 799 }
843 800
844 if (unlikely(step == 0)) { 801 if (unlikely(step == 0)) {
845 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, packet history " 802 DCCP_WARN("%s, sk=%p, packet history has no data packets!\n",
846 "contains no data packets!\n", 803 dccp_role(sk), sk);
847 __FUNCTION__, dccp_role(sk), sk);
848 return ~0; 804 return ~0;
849 } 805 }
850 806
851 if (unlikely(interval == 0)) { 807 if (unlikely(interval == 0)) {
852 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, Could not find a " 808 DCCP_WARN("%s, sk=%p, Could not find a win_count interval > 0."
853 "win_count interval > 0. Defaulting to 1\n", 809 "Defaulting to 1\n", dccp_role(sk), sk);
854 __FUNCTION__, dccp_role(sk), sk);
855 interval = 1; 810 interval = 1;
856 } 811 }
857found: 812found:
858 if (!tail) { 813 if (!tail) {
859 LIMIT_NETDEBUG(KERN_WARNING "%s: tail is null\n", 814 DCCP_CRIT("tail is null\n");
860 __FUNCTION__);
861 return ~0; 815 return ~0;
862 } 816 }
863 rtt = timeval_delta(&tstamp, &tail->dccphrx_tstamp) * 4 / interval; 817 rtt = timeval_delta(&tstamp, &tail->dccphrx_tstamp) * 4 / interval;
864 ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n", 818 ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n",
865 dccp_role(sk), sk, rtt); 819 dccp_role(sk), sk, rtt);
866 if (rtt == 0) 820
867 rtt = 1; 821 if (rtt == 0) {
822 DCCP_WARN("RTT==0, setting to 1\n");
823 rtt = 1;
824 }
868 825
869 dccp_timestamp(sk, &tstamp); 826 dccp_timestamp(sk, &tstamp);
870 delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback); 827 delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
@@ -878,9 +835,7 @@ found:
878 tmp2 = (u32)tmp1; 835 tmp2 = (u32)tmp1;
879 836
880 if (!tmp2) { 837 if (!tmp2) {
881 LIMIT_NETDEBUG(KERN_WARNING "tmp2 = 0 " 838 DCCP_CRIT("tmp2 = 0, x_recv = %u, rtt =%u\n", x_recv, rtt);
882 "%s: x_recv = %u, rtt =%u\n",
883 __FUNCTION__, x_recv, rtt);
884 return ~0; 839 return ~0;
885 } 840 }
886 841
@@ -926,8 +881,7 @@ static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
926 entry = dccp_li_hist_entry_new(ccid3_li_hist, SLAB_ATOMIC); 881 entry = dccp_li_hist_entry_new(ccid3_li_hist, SLAB_ATOMIC);
927 882
928 if (entry == NULL) { 883 if (entry == NULL) {
929 printk(KERN_CRIT "%s: out of memory\n",__FUNCTION__); 884 DCCP_BUG("out of memory - can not allocate entry");
930 dump_stack();
931 return; 885 return;
932 } 886 }
933 887
@@ -1002,13 +956,10 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
1002 const struct dccp_options_received *opt_recv; 956 const struct dccp_options_received *opt_recv;
1003 struct dccp_rx_hist_entry *packet; 957 struct dccp_rx_hist_entry *packet;
1004 struct timeval now; 958 struct timeval now;
1005 u8 win_count;
1006 u32 p_prev, rtt_prev, r_sample, t_elapsed; 959 u32 p_prev, rtt_prev, r_sample, t_elapsed;
1007 int loss; 960 int loss, payload_size;
1008 961
1009 BUG_ON(hcrx == NULL || 962 BUG_ON(hcrx == NULL);
1010 !(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA ||
1011 hcrx->ccid3hcrx_state == TFRC_RSTATE_DATA));
1012 963
1013 opt_recv = &dccp_sk(sk)->dccps_options_received; 964 opt_recv = &dccp_sk(sk)->dccps_options_received;
1014 965
@@ -1026,9 +977,8 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
1026 t_elapsed = opt_recv->dccpor_elapsed_time * 10; 977 t_elapsed = opt_recv->dccpor_elapsed_time * 10;
1027 978
1028 if (unlikely(r_sample <= t_elapsed)) 979 if (unlikely(r_sample <= t_elapsed))
1029 LIMIT_NETDEBUG(KERN_WARNING "%s: r_sample=%uus, " 980 DCCP_WARN("r_sample=%uus, t_elapsed=%uus\n",
1030 "t_elapsed=%uus\n", 981 r_sample, t_elapsed);
1031 __FUNCTION__, r_sample, t_elapsed);
1032 else 982 else
1033 r_sample -= t_elapsed; 983 r_sample -= t_elapsed;
1034 984
@@ -1052,19 +1002,19 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
1052 packet = dccp_rx_hist_entry_new(ccid3_rx_hist, sk, opt_recv->dccpor_ndp, 1002 packet = dccp_rx_hist_entry_new(ccid3_rx_hist, sk, opt_recv->dccpor_ndp,
1053 skb, SLAB_ATOMIC); 1003 skb, SLAB_ATOMIC);
1054 if (unlikely(packet == NULL)) { 1004 if (unlikely(packet == NULL)) {
1055 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, Not enough mem to " 1005 DCCP_WARN("%s, sk=%p, Not enough mem to add rx packet "
1056 "add rx packet to history, consider it lost!\n", 1006 "to history, consider it lost!\n", dccp_role(sk), sk);
1057 __FUNCTION__, dccp_role(sk), sk);
1058 return; 1007 return;
1059 } 1008 }
1060 1009
1061 win_count = packet->dccphrx_ccval;
1062
1063 loss = ccid3_hc_rx_detect_loss(sk, packet); 1010 loss = ccid3_hc_rx_detect_loss(sk, packet);
1064 1011
1065 if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK) 1012 if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK)
1066 return; 1013 return;
1067 1014
1015 payload_size = skb->len - dccp_hdr(skb)->dccph_doff * 4;
1016 ccid3_hc_rx_update_s(hcrx, payload_size);
1017
1068 switch (hcrx->ccid3hcrx_state) { 1018 switch (hcrx->ccid3hcrx_state) {
1069 case TFRC_RSTATE_NO_DATA: 1019 case TFRC_RSTATE_NO_DATA:
1070 ccid3_pr_debug("%s, sk=%p(%s), skb=%p, sending initial " 1020 ccid3_pr_debug("%s, sk=%p(%s), skb=%p, sending initial "
@@ -1075,8 +1025,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
1075 ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA); 1025 ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
1076 return; 1026 return;
1077 case TFRC_RSTATE_DATA: 1027 case TFRC_RSTATE_DATA:
1078 hcrx->ccid3hcrx_bytes_recv += skb->len - 1028 hcrx->ccid3hcrx_bytes_recv += payload_size;
1079 dccp_hdr(skb)->dccph_doff * 4;
1080 if (loss) 1029 if (loss)
1081 break; 1030 break;
1082 1031
@@ -1087,10 +1036,8 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
1087 ccid3_hc_rx_send_feedback(sk); 1036 ccid3_hc_rx_send_feedback(sk);
1088 } 1037 }
1089 return; 1038 return;
1090 default: 1039 case TFRC_RSTATE_TERM:
1091 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 1040 DCCP_BUG("Illegal %s state TERM, sk=%p", dccp_role(sk), sk);
1092 __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
1093 dump_stack();
1094 return; 1041 return;
1095 } 1042 }
1096 1043
@@ -1107,10 +1054,8 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
1107 /* Scaling up by 1000000 as fixed decimal */ 1054 /* Scaling up by 1000000 as fixed decimal */
1108 if (i_mean != 0) 1055 if (i_mean != 0)
1109 hcrx->ccid3hcrx_p = 1000000 / i_mean; 1056 hcrx->ccid3hcrx_p = 1000000 / i_mean;
1110 } else { 1057 } else
1111 printk(KERN_CRIT "%s: empty loss hist\n",__FUNCTION__); 1058 DCCP_BUG("empty loss history");
1112 dump_stack();
1113 }
1114 1059
1115 if (hcrx->ccid3hcrx_p > p_prev) { 1060 if (hcrx->ccid3hcrx_p > p_prev) {
1116 ccid3_hc_rx_send_feedback(sk); 1061 ccid3_hc_rx_send_feedback(sk);
@@ -1120,22 +1065,16 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
1120 1065
1121static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk) 1066static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk)
1122{ 1067{
1123 struct dccp_sock *dp = dccp_sk(sk);
1124 struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid); 1068 struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid);
1125 1069
1126 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 1070 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
1127 1071
1128 if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
1129 dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE)
1130 hcrx->ccid3hcrx_s = dp->dccps_packet_size;
1131 else
1132 hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE;
1133
1134 hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA; 1072 hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA;
1135 INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist); 1073 INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist);
1136 INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist); 1074 INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist);
1137 dccp_timestamp(sk, &hcrx->ccid3hcrx_tstamp_last_ack); 1075 dccp_timestamp(sk, &hcrx->ccid3hcrx_tstamp_last_ack);
1138 hcrx->ccid3hcrx_tstamp_last_feedback = hcrx->ccid3hcrx_tstamp_last_ack; 1076 hcrx->ccid3hcrx_tstamp_last_feedback = hcrx->ccid3hcrx_tstamp_last_ack;
1077 hcrx->ccid3hcrx_s = 0;
1139 hcrx->ccid3hcrx_rtt = 5000; /* XXX 5ms for now... */ 1078 hcrx->ccid3hcrx_rtt = 5000; /* XXX 5ms for now... */
1140 return 0; 1079 return 0;
1141} 1080}
@@ -1261,8 +1200,10 @@ static struct ccid_operations ccid3 = {
1261 .ccid_hc_tx_getsockopt = ccid3_hc_tx_getsockopt, 1200 .ccid_hc_tx_getsockopt = ccid3_hc_tx_getsockopt,
1262}; 1201};
1263 1202
1203#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
1264module_param(ccid3_debug, int, 0444); 1204module_param(ccid3_debug, int, 0444);
1265MODULE_PARM_DESC(ccid3_debug, "Enable debug messages"); 1205MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");
1206#endif
1266 1207
1267static __init int ccid3_module_init(void) 1208static __init int ccid3_module_init(void)
1268{ 1209{
diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h
index 0a2cb7536d26..27cb20ae1da8 100644
--- a/net/dccp/ccids/ccid3.h
+++ b/net/dccp/ccids/ccid3.h
@@ -42,20 +42,14 @@
42#include <linux/tfrc.h> 42#include <linux/tfrc.h>
43#include "../ccid.h" 43#include "../ccid.h"
44 44
45#define TFRC_MIN_PACKET_SIZE 16 45/* Two seconds as per RFC 3448 4.2 */
46#define TFRC_STD_PACKET_SIZE 256
47#define TFRC_MAX_PACKET_SIZE 65535
48
49/* Two seconds as per CCID3 spec */
50#define TFRC_INITIAL_TIMEOUT (2 * USEC_PER_SEC) 46#define TFRC_INITIAL_TIMEOUT (2 * USEC_PER_SEC)
51 47
52#define TFRC_INITIAL_IPI (USEC_PER_SEC / 4)
53
54/* In usecs - half the scheduling granularity as per RFC3448 4.6 */ 48/* In usecs - half the scheduling granularity as per RFC3448 4.6 */
55#define TFRC_OPSYS_HALF_TIME_GRAN (USEC_PER_SEC / (2 * HZ)) 49#define TFRC_OPSYS_HALF_TIME_GRAN (USEC_PER_SEC / (2 * HZ))
56 50
57/* In seconds */ 51/* Parameter t_mbi from [RFC 3448, 4.3]: backoff interval in seconds */
58#define TFRC_MAX_BACK_OFF_TIME 64 52#define TFRC_T_MBI 64
59 53
60#define TFRC_SMALLEST_P 40 54#define TFRC_SMALLEST_P 40
61 55
@@ -73,26 +67,36 @@ struct ccid3_options_received {
73 u32 ccid3or_receive_rate; 67 u32 ccid3or_receive_rate;
74}; 68};
75 69
76/** struct ccid3_hc_tx_sock - CCID3 sender half connection sock 70/* TFRC sender states */
71enum ccid3_hc_tx_states {
72 TFRC_SSTATE_NO_SENT = 1,
73 TFRC_SSTATE_NO_FBACK,
74 TFRC_SSTATE_FBACK,
75 TFRC_SSTATE_TERM,
76};
77
78/** struct ccid3_hc_tx_sock - CCID3 sender half-connection socket
77 * 79 *
78 * @ccid3hctx_state - Sender state 80 * @ccid3hctx_x - Current sending rate
79 * @ccid3hctx_x - Current sending rate 81 * @ccid3hctx_x_recv - Receive rate
80 * @ccid3hctx_x_recv - Receive rate 82 * @ccid3hctx_x_calc - Calculated send rate (RFC 3448, 3.1)
81 * @ccid3hctx_x_calc - Calculated send (?) rate 83 * @ccid3hctx_rtt - Estimate of current round trip time in usecs
82 * @ccid3hctx_s - Packet size 84 * @ccid3hctx_p - Current loss event rate (0-1) scaled by 1000000
83 * @ccid3hctx_rtt - Estimate of current round trip time in usecs 85 * @ccid3hctx_s - Packet size
84 * @@ccid3hctx_p - Current loss event rate (0-1) scaled by 1000000 86 * @ccid3hctx_t_rto - Retransmission Timeout (RFC 3448, 3.1)
85 * @ccid3hctx_last_win_count - Last window counter sent 87 * @ccid3hctx_t_ipi - Interpacket (send) interval (RFC 3448, 4.6)
86 * @ccid3hctx_t_last_win_count - Timestamp of earliest packet 88 * @ccid3hctx_state - Sender state, one of %ccid3_hc_tx_states
87 * with last_win_count value sent 89 * @ccid3hctx_last_win_count - Last window counter sent
88 * @ccid3hctx_no_feedback_timer - Handle to no feedback timer 90 * @ccid3hctx_t_last_win_count - Timestamp of earliest packet
89 * @ccid3hctx_idle - FIXME 91 * with last_win_count value sent
90 * @ccid3hctx_t_ld - Time last doubled during slow start 92 * @ccid3hctx_no_feedback_timer - Handle to no feedback timer
91 * @ccid3hctx_t_nom - Nominal send time of next packet 93 * @ccid3hctx_idle - Flag indicating that sender is idling
92 * @ccid3hctx_t_ipi - Interpacket (send) interval 94 * @ccid3hctx_t_ld - Time last doubled during slow start
93 * @ccid3hctx_delta - Send timer delta 95 * @ccid3hctx_t_nom - Nominal send time of next packet
94 * @ccid3hctx_hist - Packet history 96 * @ccid3hctx_delta - Send timer delta
95 */ 97 * @ccid3hctx_hist - Packet history
98 * @ccid3hctx_options_received - Parsed set of retrieved options
99 */
96struct ccid3_hc_tx_sock { 100struct ccid3_hc_tx_sock {
97 struct tfrc_tx_info ccid3hctx_tfrc; 101 struct tfrc_tx_info ccid3hctx_tfrc;
98#define ccid3hctx_x ccid3hctx_tfrc.tfrctx_x 102#define ccid3hctx_x ccid3hctx_tfrc.tfrctx_x
@@ -103,7 +107,7 @@ struct ccid3_hc_tx_sock {
103#define ccid3hctx_t_rto ccid3hctx_tfrc.tfrctx_rto 107#define ccid3hctx_t_rto ccid3hctx_tfrc.tfrctx_rto
104#define ccid3hctx_t_ipi ccid3hctx_tfrc.tfrctx_ipi 108#define ccid3hctx_t_ipi ccid3hctx_tfrc.tfrctx_ipi
105 u16 ccid3hctx_s; 109 u16 ccid3hctx_s;
106 u8 ccid3hctx_state; 110 enum ccid3_hc_tx_states ccid3hctx_state:8;
107 u8 ccid3hctx_last_win_count; 111 u8 ccid3hctx_last_win_count;
108 u8 ccid3hctx_idle; 112 u8 ccid3hctx_idle;
109 struct timeval ccid3hctx_t_last_win_count; 113 struct timeval ccid3hctx_t_last_win_count;
@@ -115,23 +119,48 @@ struct ccid3_hc_tx_sock {
115 struct ccid3_options_received ccid3hctx_options_received; 119 struct ccid3_options_received ccid3hctx_options_received;
116}; 120};
117 121
122/* TFRC receiver states */
123enum ccid3_hc_rx_states {
124 TFRC_RSTATE_NO_DATA = 1,
125 TFRC_RSTATE_DATA,
126 TFRC_RSTATE_TERM = 127,
127};
128
129/** struct ccid3_hc_rx_sock - CCID3 receiver half-connection socket
130 *
131 * @ccid3hcrx_x_recv - Receiver estimate of send rate (RFC 3448 4.3)
132 * @ccid3hcrx_rtt - Receiver estimate of rtt (non-standard)
133 * @ccid3hcrx_p - current loss event rate (RFC 3448 5.4)
134 * @ccid3hcrx_seqno_nonloss - Last received non-loss sequence number
135 * @ccid3hcrx_ccval_nonloss - Last received non-loss Window CCVal
136 * @ccid3hcrx_ccval_last_counter - Tracks window counter (RFC 4342, 8.1)
137 * @ccid3hcrx_state - receiver state, one of %ccid3_hc_rx_states
138 * @ccid3hcrx_bytes_recv - Total sum of DCCP payload bytes
139 * @ccid3hcrx_tstamp_last_feedback - Time at which last feedback was sent
140 * @ccid3hcrx_tstamp_last_ack - Time at which last feedback was sent
141 * @ccid3hcrx_hist - Packet history
142 * @ccid3hcrx_li_hist - Loss Interval History
143 * @ccid3hcrx_s - Received packet size in bytes
144 * @ccid3hcrx_pinv - Inverse of Loss Event Rate (RFC 4342, sec. 8.5)
145 * @ccid3hcrx_elapsed_time - Time since packet reception
146 */
118struct ccid3_hc_rx_sock { 147struct ccid3_hc_rx_sock {
119 struct tfrc_rx_info ccid3hcrx_tfrc; 148 struct tfrc_rx_info ccid3hcrx_tfrc;
120#define ccid3hcrx_x_recv ccid3hcrx_tfrc.tfrcrx_x_recv 149#define ccid3hcrx_x_recv ccid3hcrx_tfrc.tfrcrx_x_recv
121#define ccid3hcrx_rtt ccid3hcrx_tfrc.tfrcrx_rtt 150#define ccid3hcrx_rtt ccid3hcrx_tfrc.tfrcrx_rtt
122#define ccid3hcrx_p ccid3hcrx_tfrc.tfrcrx_p 151#define ccid3hcrx_p ccid3hcrx_tfrc.tfrcrx_p
123 u64 ccid3hcrx_seqno_nonloss:48, 152 u64 ccid3hcrx_seqno_nonloss:48,
124 ccid3hcrx_ccval_nonloss:4, 153 ccid3hcrx_ccval_nonloss:4,
125 ccid3hcrx_state:8, 154 ccid3hcrx_ccval_last_counter:4;
126 ccid3hcrx_ccval_last_counter:4; 155 enum ccid3_hc_rx_states ccid3hcrx_state:8;
127 u32 ccid3hcrx_bytes_recv; 156 u32 ccid3hcrx_bytes_recv;
128 struct timeval ccid3hcrx_tstamp_last_feedback; 157 struct timeval ccid3hcrx_tstamp_last_feedback;
129 struct timeval ccid3hcrx_tstamp_last_ack; 158 struct timeval ccid3hcrx_tstamp_last_ack;
130 struct list_head ccid3hcrx_hist; 159 struct list_head ccid3hcrx_hist;
131 struct list_head ccid3hcrx_li_hist; 160 struct list_head ccid3hcrx_li_hist;
132 u16 ccid3hcrx_s; 161 u16 ccid3hcrx_s;
133 u32 ccid3hcrx_pinv; 162 u32 ccid3hcrx_pinv;
134 u32 ccid3hcrx_elapsed_time; 163 u32 ccid3hcrx_elapsed_time;
135}; 164};
136 165
137static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk) 166static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk)
diff --git a/net/dccp/ccids/lib/loss_interval.c b/net/dccp/ccids/lib/loss_interval.c
index 906c81ab9d4f..48b9b93f8acb 100644
--- a/net/dccp/ccids/lib/loss_interval.c
+++ b/net/dccp/ccids/lib/loss_interval.c
@@ -13,7 +13,7 @@
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <net/sock.h> 15#include <net/sock.h>
16 16#include "../../dccp.h"
17#include "loss_interval.h" 17#include "loss_interval.h"
18 18
19struct dccp_li_hist *dccp_li_hist_new(const char *name) 19struct dccp_li_hist *dccp_li_hist_new(const char *name)
@@ -109,7 +109,7 @@ u32 dccp_li_hist_calc_i_mean(struct list_head *list)
109 i_tot = max(i_tot0, i_tot1); 109 i_tot = max(i_tot0, i_tot1);
110 110
111 if (!w_tot) { 111 if (!w_tot) {
112 LIMIT_NETDEBUG(KERN_WARNING "%s: w_tot = 0\n", __FUNCTION__); 112 DCCP_WARN("w_tot = 0\n");
113 return 1; 113 return 1;
114 } 114 }
115 115
@@ -128,7 +128,7 @@ int dccp_li_hist_interval_new(struct dccp_li_hist *hist,
128 entry = dccp_li_hist_entry_new(hist, SLAB_ATOMIC); 128 entry = dccp_li_hist_entry_new(hist, SLAB_ATOMIC);
129 if (entry == NULL) { 129 if (entry == NULL) {
130 dccp_li_hist_purge(hist, list); 130 dccp_li_hist_purge(hist, list);
131 dump_stack(); 131 DCCP_BUG("loss interval list entry is NULL");
132 return 0; 132 return 0;
133 } 133 }
134 entry->dccplih_interval = ~0; 134 entry->dccplih_interval = ~0;
diff --git a/net/dccp/ccids/lib/tfrc_equation.c b/net/dccp/ccids/lib/tfrc_equation.c
index 44076e0c6591..2601012383fb 100644
--- a/net/dccp/ccids/lib/tfrc_equation.c
+++ b/net/dccp/ccids/lib/tfrc_equation.c
@@ -13,9 +13,8 @@
13 */ 13 */
14 14
15#include <linux/module.h> 15#include <linux/module.h>
16
17#include <asm/div64.h> 16#include <asm/div64.h>
18 17#include "../../dccp.h"
19#include "tfrc.h" 18#include "tfrc.h"
20 19
21#define TFRC_CALC_X_ARRSIZE 500 20#define TFRC_CALC_X_ARRSIZE 500
@@ -588,8 +587,10 @@ u32 tfrc_calc_x(u16 s, u32 R, u32 p)
588 /* p should be 0 unless there is a bug in my code */ 587 /* p should be 0 unless there is a bug in my code */
589 index = 0; 588 index = 0;
590 589
591 if (R == 0) 590 if (R == 0) {
591 DCCP_WARN("RTT==0, setting to 1\n");
592 R = 1; /* RTT can't be zero or else divide by zero */ 592 R = 1; /* RTT can't be zero or else divide by zero */
593 }
593 594
594 BUG_ON(index >= TFRC_CALC_X_ARRSIZE); 595 BUG_ON(index >= TFRC_CALC_X_ARRSIZE);
595 596