diff options
-rw-r--r-- | include/linux/dccp.h | 2 | ||||
-rw-r--r-- | net/dccp/ccids/ccid3.c | 12 | ||||
-rw-r--r-- | net/dccp/dccp.h | 19 | ||||
-rw-r--r-- | net/dccp/options.c | 87 |
4 files changed, 79 insertions, 41 deletions
diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 3dccdd5108b5..9e3a1370b906 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h | |||
@@ -415,7 +415,7 @@ struct dccp_sock { | |||
415 | __u64 dccps_gsr; | 415 | __u64 dccps_gsr; |
416 | __u64 dccps_gar; | 416 | __u64 dccps_gar; |
417 | unsigned long dccps_service; | 417 | unsigned long dccps_service; |
418 | unsigned long dccps_timestamp_time; | 418 | struct timeval dccps_timestamp_time; |
419 | __u32 dccps_timestamp_echo; | 419 | __u32 dccps_timestamp_echo; |
420 | __u32 dccps_avg_packet_size; | 420 | __u32 dccps_avg_packet_size; |
421 | unsigned long dccps_ndp_count; | 421 | unsigned long dccps_ndp_count; |
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 2dd3e94ba8f4..694149061b8b 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -2,12 +2,12 @@ | |||
2 | * net/dccp/ccids/ccid3.c | 2 | * net/dccp/ccids/ccid3.c |
3 | * | 3 | * |
4 | * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. | 4 | * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. |
5 | * Copyright (c) 2005 Ian McDonald <iam4@cs.waikato.ac.nz> | ||
5 | * | 6 | * |
6 | * An implementation of the DCCP protocol | 7 | * An implementation of the DCCP protocol |
7 | * | 8 | * |
8 | * This code has been developed by the University of Waikato WAND | 9 | * This code has been developed by the University of Waikato WAND |
9 | * research group. For further information please see http://www.wand.net.nz/ | 10 | * research group. For further information please see http://www.wand.net.nz/ |
10 | * or e-mail Ian McDonald - iam4@cs.waikato.ac.nz | ||
11 | * | 11 | * |
12 | * This code also uses code from Lulea University, rereleased as GPL by its | 12 | * This code also uses code from Lulea University, rereleased as GPL by its |
13 | * authors: | 13 | * authors: |
@@ -174,14 +174,6 @@ static inline void timeval_fix(struct timeval *tv) | |||
174 | } | 174 | } |
175 | } | 175 | } |
176 | 176 | ||
177 | /* returns the difference in usecs between timeval passed in and current time */ | ||
178 | static inline u32 now_delta(struct timeval tv) { | ||
179 | struct timeval now; | ||
180 | |||
181 | do_gettimeofday(&now); | ||
182 | return ((now.tv_sec-tv.tv_sec)*1000000+now.tv_usec-tv.tv_usec); | ||
183 | } | ||
184 | |||
185 | #define CALCX_ARRSIZE 500 | 177 | #define CALCX_ARRSIZE 500 |
186 | 178 | ||
187 | #define CALCX_SPLIT 50000 | 179 | #define CALCX_SPLIT 50000 |
@@ -1110,7 +1102,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
1110 | struct ccid3_options_received *opt_recv; | 1102 | struct ccid3_options_received *opt_recv; |
1111 | struct dccp_tx_hist_entry *packet; | 1103 | struct dccp_tx_hist_entry *packet; |
1112 | unsigned long next_tmout; | 1104 | unsigned long next_tmout; |
1113 | u16 t_elapsed; | 1105 | u32 t_elapsed; |
1114 | u32 pinv; | 1106 | u32 pinv; |
1115 | u32 x_recv; | 1107 | u32 x_recv; |
1116 | u32 r_sample; | 1108 | u32 r_sample; |
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 4efdce47000b..aab72b8d0703 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h | |||
@@ -4,7 +4,8 @@ | |||
4 | * net/dccp/dccp.h | 4 | * net/dccp/dccp.h |
5 | * | 5 | * |
6 | * An implementation of the DCCP protocol | 6 | * An implementation of the DCCP protocol |
7 | * Arnaldo Carvalho de Melo <acme@conectiva.com.br> | 7 | * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br> |
8 | * Copyright (c) 2005 Ian McDonald <iam4@cs.waikato.ac.nz> | ||
8 | * | 9 | * |
9 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU General Public License version 2 as | 11 | * under the terms of the GNU General Public License version 2 as |
@@ -404,6 +405,7 @@ extern struct socket *dccp_ctl_socket; | |||
404 | * @dccpap_ack_nonce - the one-bit sum of the ECN Nonces for all State 0. | 405 | * @dccpap_ack_nonce - the one-bit sum of the ECN Nonces for all State 0. |
405 | * | 406 | * |
406 | * @dccpap_buf_len - circular buffer length | 407 | * @dccpap_buf_len - circular buffer length |
408 | * @dccpap_time - the time in usecs | ||
407 | * @dccpap_buf - circular buffer of acknowledgeable packets | 409 | * @dccpap_buf - circular buffer of acknowledgeable packets |
408 | */ | 410 | */ |
409 | struct dccp_ackpkts { | 411 | struct dccp_ackpkts { |
@@ -416,7 +418,7 @@ struct dccp_ackpkts { | |||
416 | unsigned int dccpap_buf_vector_len; | 418 | unsigned int dccpap_buf_vector_len; |
417 | unsigned int dccpap_ack_vector_len; | 419 | unsigned int dccpap_ack_vector_len; |
418 | unsigned int dccpap_buf_len; | 420 | unsigned int dccpap_buf_len; |
419 | unsigned long dccpap_time; | 421 | struct timeval dccpap_time; |
420 | u8 dccpap_buf_nonce; | 422 | u8 dccpap_buf_nonce; |
421 | u8 dccpap_ack_nonce; | 423 | u8 dccpap_ack_nonce; |
422 | u8 dccpap_buf[0]; | 424 | u8 dccpap_buf[0]; |
@@ -430,6 +432,19 @@ extern int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state); | |||
430 | extern void dccp_ackpkts_check_rcv_ackno(struct dccp_ackpkts *ap, | 432 | extern void dccp_ackpkts_check_rcv_ackno(struct dccp_ackpkts *ap, |
431 | struct sock *sk, u64 ackno); | 433 | struct sock *sk, u64 ackno); |
432 | 434 | ||
435 | /* | ||
436 | * Returns the difference in usecs between timeval | ||
437 | * passed in and current time | ||
438 | */ | ||
439 | static inline u32 now_delta(struct timeval tv) | ||
440 | { | ||
441 | struct timeval now; | ||
442 | |||
443 | do_gettimeofday(&now); | ||
444 | return (now.tv_sec - tv.tv_sec) * USEC_PER_SEC + | ||
445 | (now.tv_usec - tv.tv_usec); | ||
446 | } | ||
447 | |||
433 | #ifdef CONFIG_IP_DCCP_DEBUG | 448 | #ifdef CONFIG_IP_DCCP_DEBUG |
434 | extern void dccp_ackvector_print(const u64 ackno, | 449 | extern void dccp_ackvector_print(const u64 ackno, |
435 | const unsigned char *vector, int len); | 450 | const unsigned char *vector, int len); |
diff --git a/net/dccp/options.c b/net/dccp/options.c index 85a86bd61f44..7ecffdf85756 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c | |||
@@ -2,8 +2,9 @@ | |||
2 | * net/dccp/options.c | 2 | * net/dccp/options.c |
3 | * | 3 | * |
4 | * An implementation of the DCCP protocol | 4 | * An implementation of the DCCP protocol |
5 | * Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org> | 5 | * Copyright (c) 2005 Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org> |
6 | * Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 6 | * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@ghostprotocols.net> |
7 | * Copyright (c) 2005 Ian McDonald <iam4@cs.waikato.ac.nz> | ||
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU General Public License | 10 | * modify it under the terms of the GNU General Public License |
@@ -138,7 +139,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | |||
138 | opt_recv->dccpor_timestamp = ntohl(*(u32 *)value); | 139 | opt_recv->dccpor_timestamp = ntohl(*(u32 *)value); |
139 | 140 | ||
140 | dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp; | 141 | dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp; |
141 | dp->dccps_timestamp_time = jiffies; | 142 | do_gettimeofday(&dp->dccps_timestamp_time); |
142 | 143 | ||
143 | dccp_pr_debug("%sTIMESTAMP=%u, ackno=%llu\n", | 144 | dccp_pr_debug("%sTIMESTAMP=%u, ackno=%llu\n", |
144 | debug_prefix, opt_recv->dccpor_timestamp, | 145 | debug_prefix, opt_recv->dccpor_timestamp, |
@@ -146,36 +147,45 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | |||
146 | DCCP_SKB_CB(skb)->dccpd_ack_seq); | 147 | DCCP_SKB_CB(skb)->dccpd_ack_seq); |
147 | break; | 148 | break; |
148 | case DCCPO_TIMESTAMP_ECHO: | 149 | case DCCPO_TIMESTAMP_ECHO: |
149 | if (len < 4 || len > 8) | 150 | if (len != 4 && len != 6 && len != 8) |
150 | goto out_invalid_option; | 151 | goto out_invalid_option; |
151 | 152 | ||
152 | opt_recv->dccpor_timestamp_echo = ntohl(*(u32 *)value); | 153 | opt_recv->dccpor_timestamp_echo = ntohl(*(u32 *)value); |
153 | 154 | ||
154 | dccp_pr_debug("%sTIMESTAMP_ECHO=%u, len=%d, ackno=%llu, " | 155 | dccp_pr_debug("%sTIMESTAMP_ECHO=%u, len=%d, ackno=%llu, ", |
155 | "diff=%u\n", | ||
156 | debug_prefix, | 156 | debug_prefix, |
157 | opt_recv->dccpor_timestamp_echo, | 157 | opt_recv->dccpor_timestamp_echo, |
158 | len + 2, | 158 | len + 2, |
159 | (unsigned long long) | 159 | (unsigned long long) |
160 | DCCP_SKB_CB(skb)->dccpd_ack_seq, | 160 | DCCP_SKB_CB(skb)->dccpd_ack_seq); |
161 | (tcp_time_stamp - | 161 | |
162 | opt_recv->dccpor_timestamp_echo)); | 162 | if (len > 4) { |
163 | 163 | if (len == 6) | |
164 | opt_recv->dccpor_elapsed_time = | 164 | opt_recv->dccpor_elapsed_time = |
165 | dccp_decode_value_var(value + 4, | 165 | ntohs(*(u16 *)(value + 4)); |
166 | len - 4); | 166 | else |
167 | dccp_pr_debug("%sTIMESTAMP_ECHO ELAPSED_TIME=%d\n", | 167 | opt_recv->dccpor_elapsed_time = |
168 | ntohl(*(u32 *)(value + 4)); | ||
169 | |||
170 | dccp_pr_debug("%sTIMESTAMP_ECHO ELAPSED_TIME=%d\n", | ||
168 | debug_prefix, | 171 | debug_prefix, |
169 | opt_recv->dccpor_elapsed_time); | 172 | opt_recv->dccpor_elapsed_time); |
173 | } | ||
170 | break; | 174 | break; |
171 | case DCCPO_ELAPSED_TIME: | 175 | case DCCPO_ELAPSED_TIME: |
172 | if (len > 4) | 176 | if (len != 2 && len != 4) |
173 | goto out_invalid_option; | 177 | goto out_invalid_option; |
174 | 178 | ||
175 | if (pkt_type == DCCP_PKT_DATA) | 179 | if (pkt_type == DCCP_PKT_DATA) |
176 | continue; | 180 | continue; |
177 | opt_recv->dccpor_elapsed_time = | 181 | |
178 | dccp_decode_value_var(value, len); | 182 | if (len == 2) |
183 | opt_recv->dccpor_elapsed_time = | ||
184 | ntohs(*(u16 *)value); | ||
185 | else | ||
186 | opt_recv->dccpor_elapsed_time = | ||
187 | ntohl(*(u32 *)value); | ||
188 | |||
179 | dccp_pr_debug("%sELAPSED_TIME=%d\n", debug_prefix, | 189 | dccp_pr_debug("%sELAPSED_TIME=%d\n", debug_prefix, |
180 | opt_recv->dccpor_elapsed_time); | 190 | opt_recv->dccpor_elapsed_time); |
181 | break; | 191 | break; |
@@ -309,8 +319,7 @@ void dccp_insert_option_elapsed_time(struct sock *sk, | |||
309 | const int len = 2 + elapsed_time_len; | 319 | const int len = 2 + elapsed_time_len; |
310 | unsigned char *to; | 320 | unsigned char *to; |
311 | 321 | ||
312 | /* If elapsed_time == 0... */ | 322 | if (elapsed_time_len == 0) |
313 | if (elapsed_time_len == 2) | ||
314 | return; | 323 | return; |
315 | 324 | ||
316 | if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) { | 325 | if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) { |
@@ -325,7 +334,13 @@ void dccp_insert_option_elapsed_time(struct sock *sk, | |||
325 | *to++ = DCCPO_ELAPSED_TIME; | 334 | *to++ = DCCPO_ELAPSED_TIME; |
326 | *to++ = len; | 335 | *to++ = len; |
327 | 336 | ||
328 | dccp_encode_value_var(elapsed_time, to, elapsed_time_len); | 337 | if (elapsed_time_len == 2) { |
338 | const u16 var16 = htons((u16)elapsed_time); | ||
339 | memcpy(to, &var16, 2); | ||
340 | } else { | ||
341 | const u32 var32 = htonl(elapsed_time); | ||
342 | memcpy(to, &var32, 4); | ||
343 | } | ||
329 | 344 | ||
330 | dccp_pr_debug("%sELAPSED_TIME=%u, len=%d, seqno=%llu\n", | 345 | dccp_pr_debug("%sELAPSED_TIME=%u, len=%d, seqno=%llu\n", |
331 | debug_prefix, elapsed_time, | 346 | debug_prefix, elapsed_time, |
@@ -344,7 +359,7 @@ static void dccp_insert_option_ack_vector(struct sock *sk, struct sk_buff *skb) | |||
344 | #endif | 359 | #endif |
345 | struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts; | 360 | struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts; |
346 | int len = ap->dccpap_buf_vector_len + 2; | 361 | int len = ap->dccpap_buf_vector_len + 2; |
347 | const u32 elapsed_time = jiffies_to_usecs(jiffies - ap->dccpap_time) / 10; | 362 | const u32 elapsed_time = now_delta(ap->dccpap_time) / 10; |
348 | unsigned char *to, *from; | 363 | unsigned char *to, *from; |
349 | 364 | ||
350 | if (elapsed_time != 0) | 365 | if (elapsed_time != 0) |
@@ -414,7 +429,15 @@ static void dccp_insert_option_ack_vector(struct sock *sk, struct sk_buff *skb) | |||
414 | static inline void dccp_insert_option_timestamp(struct sock *sk, | 429 | static inline void dccp_insert_option_timestamp(struct sock *sk, |
415 | struct sk_buff *skb) | 430 | struct sk_buff *skb) |
416 | { | 431 | { |
417 | const u32 now = htonl(tcp_time_stamp); | 432 | struct timeval tv; |
433 | u32 now; | ||
434 | |||
435 | do_gettimeofday(&tv); | ||
436 | now = (tv.tv_sec * USEC_PER_SEC + tv.tv_usec) / 10; | ||
437 | /* yes this will overflow but that is the point as we want a | ||
438 | * 10 usec 32 bit timer which mean it wraps every 11.9 hours */ | ||
439 | |||
440 | now = htonl(now); | ||
418 | dccp_insert_option(sk, skb, DCCPO_TIMESTAMP, &now, sizeof(now)); | 441 | dccp_insert_option(sk, skb, DCCPO_TIMESTAMP, &now, sizeof(now)); |
419 | } | 442 | } |
420 | 443 | ||
@@ -427,8 +450,7 @@ static void dccp_insert_option_timestamp_echo(struct sock *sk, | |||
427 | "CLIENT TX opt: " : "server TX opt: "; | 450 | "CLIENT TX opt: " : "server TX opt: "; |
428 | #endif | 451 | #endif |
429 | u32 tstamp_echo; | 452 | u32 tstamp_echo; |
430 | const u32 elapsed_time = jiffies_to_usecs(jiffies - | 453 | const u32 elapsed_time = now_delta(dp->dccps_timestamp_time) / 10; |
431 | dp->dccps_timestamp_time) / 10; | ||
432 | const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time); | 454 | const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time); |
433 | const int len = 6 + elapsed_time_len; | 455 | const int len = 6 + elapsed_time_len; |
434 | unsigned char *to; | 456 | unsigned char *to; |
@@ -448,7 +470,14 @@ static void dccp_insert_option_timestamp_echo(struct sock *sk, | |||
448 | tstamp_echo = htonl(dp->dccps_timestamp_echo); | 470 | tstamp_echo = htonl(dp->dccps_timestamp_echo); |
449 | memcpy(to, &tstamp_echo, 4); | 471 | memcpy(to, &tstamp_echo, 4); |
450 | to += 4; | 472 | to += 4; |
451 | dccp_encode_value_var(elapsed_time, to, elapsed_time_len); | 473 | |
474 | if (elapsed_time_len == 2) { | ||
475 | const u16 var16 = htons((u16)elapsed_time); | ||
476 | memcpy(to, &var16, 2); | ||
477 | } else if (elapsed_time_len == 4) { | ||
478 | const u32 var32 = htonl(elapsed_time); | ||
479 | memcpy(to, &var32, 4); | ||
480 | } | ||
452 | 481 | ||
453 | dccp_pr_debug("%sTIMESTAMP_ECHO=%u, len=%d, seqno=%llu\n", | 482 | dccp_pr_debug("%sTIMESTAMP_ECHO=%u, len=%d, seqno=%llu\n", |
454 | debug_prefix, dp->dccps_timestamp_echo, | 483 | debug_prefix, dp->dccps_timestamp_echo, |
@@ -456,7 +485,8 @@ static void dccp_insert_option_timestamp_echo(struct sock *sk, | |||
456 | (unsigned long long) DCCP_SKB_CB(skb)->dccpd_seq); | 485 | (unsigned long long) DCCP_SKB_CB(skb)->dccpd_seq); |
457 | 486 | ||
458 | dp->dccps_timestamp_echo = 0; | 487 | dp->dccps_timestamp_echo = 0; |
459 | dp->dccps_timestamp_time = 0; | 488 | dp->dccps_timestamp_time.tv_sec = 0; |
489 | dp->dccps_timestamp_time.tv_usec = 0; | ||
460 | } | 490 | } |
461 | 491 | ||
462 | void dccp_insert_options(struct sock *sk, struct sk_buff *skb) | 492 | void dccp_insert_options(struct sock *sk, struct sk_buff *skb) |
@@ -514,7 +544,8 @@ struct dccp_ackpkts *dccp_ackpkts_alloc(const unsigned int len, | |||
514 | ap->dccpap_ack_seqno = DCCP_MAX_SEQNO + 1; | 544 | ap->dccpap_ack_seqno = DCCP_MAX_SEQNO + 1; |
515 | ap->dccpap_buf_nonce = ap->dccpap_buf_nonce = 0; | 545 | ap->dccpap_buf_nonce = ap->dccpap_buf_nonce = 0; |
516 | ap->dccpap_ack_ptr = 0; | 546 | ap->dccpap_ack_ptr = 0; |
517 | ap->dccpap_time = 0; | 547 | ap->dccpap_time.tv_sec = 0; |
548 | ap->dccpap_time.tv_usec = 0; | ||
518 | ap->dccpap_buf_vector_len = ap->dccpap_ack_vector_len = 0; | 549 | ap->dccpap_buf_vector_len = ap->dccpap_ack_vector_len = 0; |
519 | } | 550 | } |
520 | 551 | ||
@@ -665,7 +696,7 @@ int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state) | |||
665 | } | 696 | } |
666 | 697 | ||
667 | ap->dccpap_buf_ackno = ackno; | 698 | ap->dccpap_buf_ackno = ackno; |
668 | ap->dccpap_time = jiffies; | 699 | do_gettimeofday(&ap->dccpap_time); |
669 | out: | 700 | out: |
670 | dccp_pr_debug(""); | 701 | dccp_pr_debug(""); |
671 | dccp_ackpkts_print(ap); | 702 | dccp_ackpkts_print(ap); |