diff options
-rw-r--r-- | net/dccp/ccids/ccid3.c | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 122a716eb877..1a2ffa1d8794 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -161,6 +161,33 @@ static inline void ccid3_hc_tx_update_s(struct ccid3_hc_tx_sock *hctx, int len) | |||
161 | */ | 161 | */ |
162 | } | 162 | } |
163 | 163 | ||
164 | /* | ||
165 | * Update Window Counter using the algorithm from [RFC 4342, 8.1]. | ||
166 | * The algorithm is not applicable if RTT < 4 microseconds. | ||
167 | */ | ||
168 | static inline void ccid3_hc_tx_update_win_count(struct ccid3_hc_tx_sock *hctx, | ||
169 | struct timeval *now) | ||
170 | { | ||
171 | suseconds_t delta; | ||
172 | u32 quarter_rtts; | ||
173 | |||
174 | if (unlikely(hctx->ccid3hctx_rtt < 4)) /* avoid divide-by-zero */ | ||
175 | return; | ||
176 | |||
177 | delta = timeval_delta(now, &hctx->ccid3hctx_t_last_win_count); | ||
178 | DCCP_BUG_ON(delta < 0); | ||
179 | |||
180 | quarter_rtts = (u32)delta / (hctx->ccid3hctx_rtt / 4); | ||
181 | |||
182 | if (quarter_rtts > 0) { | ||
183 | hctx->ccid3hctx_t_last_win_count = *now; | ||
184 | hctx->ccid3hctx_last_win_count += min_t(u32, quarter_rtts, 5); | ||
185 | hctx->ccid3hctx_last_win_count &= 0xF; /* mod 16 */ | ||
186 | |||
187 | ccid3_pr_debug("now at %#X\n", hctx->ccid3hctx_last_win_count); | ||
188 | } | ||
189 | } | ||
190 | |||
164 | static void ccid3_hc_tx_no_feedback_timer(unsigned long data) | 191 | static void ccid3_hc_tx_no_feedback_timer(unsigned long data) |
165 | { | 192 | { |
166 | struct sock *sk = (struct sock *)data; | 193 | struct sock *sk = (struct sock *)data; |
@@ -333,6 +360,8 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) | |||
333 | */ | 360 | */ |
334 | if (delay - (suseconds_t)hctx->ccid3hctx_delta >= 0) | 361 | if (delay - (suseconds_t)hctx->ccid3hctx_delta >= 0) |
335 | return delay / 1000L; | 362 | return delay / 1000L; |
363 | |||
364 | ccid3_hc_tx_update_win_count(hctx, &now); | ||
336 | break; | 365 | break; |
337 | case TFRC_SSTATE_TERM: | 366 | case TFRC_SSTATE_TERM: |
338 | DCCP_BUG("Illegal %s state TERM, sk=%p", dccp_role(sk), sk); | 367 | DCCP_BUG("Illegal %s state TERM, sk=%p", dccp_role(sk), sk); |
@@ -353,7 +382,6 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len) | |||
353 | const struct dccp_sock *dp = dccp_sk(sk); | 382 | const struct dccp_sock *dp = dccp_sk(sk); |
354 | struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); | 383 | struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); |
355 | struct timeval now; | 384 | struct timeval now; |
356 | suseconds_t quarter_rtt; | ||
357 | struct dccp_tx_hist_entry *packet; | 385 | struct dccp_tx_hist_entry *packet; |
358 | 386 | ||
359 | BUG_ON(hctx == NULL); | 387 | BUG_ON(hctx == NULL); |
@@ -373,25 +401,6 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len) | |||
373 | } | 401 | } |
374 | packet->dccphtx_tstamp = now; | 402 | packet->dccphtx_tstamp = now; |
375 | packet->dccphtx_seqno = dp->dccps_gss; | 403 | packet->dccphtx_seqno = dp->dccps_gss; |
376 | /* | ||
377 | * Check if win_count have changed | ||
378 | * Algorithm in "8.1. Window Counter Value" in RFC 4342. | ||
379 | */ | ||
380 | quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count); | ||
381 | if (likely(hctx->ccid3hctx_rtt > 8)) | ||
382 | quarter_rtt /= hctx->ccid3hctx_rtt / 4; | ||
383 | |||
384 | if (quarter_rtt > 0) { | ||
385 | hctx->ccid3hctx_t_last_win_count = now; | ||
386 | hctx->ccid3hctx_last_win_count = (hctx->ccid3hctx_last_win_count + | ||
387 | min_t(unsigned long, quarter_rtt, 5)) % 16; | ||
388 | ccid3_pr_debug("%s, sk=%p, window changed from " | ||
389 | "%u to %u!\n", | ||
390 | dccp_role(sk), sk, | ||
391 | packet->dccphtx_ccval, | ||
392 | hctx->ccid3hctx_last_win_count); | ||
393 | } | ||
394 | |||
395 | hctx->ccid3hctx_idle = 0; | 404 | hctx->ccid3hctx_idle = 0; |
396 | packet->dccphtx_rtt = hctx->ccid3hctx_rtt; | 405 | packet->dccphtx_rtt = hctx->ccid3hctx_rtt; |
397 | packet->dccphtx_sent = 1; | 406 | packet->dccphtx_sent = 1; |