diff options
Diffstat (limited to 'net/dccp/options.c')
-rw-r--r-- | net/dccp/options.c | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/net/dccp/options.c b/net/dccp/options.c index 34b230a00875..d4c4242d8dd7 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c | |||
@@ -140,7 +140,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) | |||
140 | opt_recv->dccpor_timestamp = ntohl(*(u32 *)value); | 140 | opt_recv->dccpor_timestamp = ntohl(*(u32 *)value); |
141 | 141 | ||
142 | dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp; | 142 | dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp; |
143 | do_gettimeofday(&dp->dccps_timestamp_time); | 143 | dccp_timestamp(sk, &dp->dccps_timestamp_time); |
144 | 144 | ||
145 | dccp_pr_debug("%sTIMESTAMP=%u, ackno=%llu\n", | 145 | dccp_pr_debug("%sTIMESTAMP=%u, ackno=%llu\n", |
146 | debug_prefix, opt_recv->dccpor_timestamp, | 146 | debug_prefix, opt_recv->dccpor_timestamp, |
@@ -361,9 +361,13 @@ static void dccp_insert_option_ack_vector(struct sock *sk, struct sk_buff *skb) | |||
361 | #endif | 361 | #endif |
362 | struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts; | 362 | struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts; |
363 | int len = ap->dccpap_buf_vector_len + 2; | 363 | int len = ap->dccpap_buf_vector_len + 2; |
364 | const u32 elapsed_time = timeval_now_delta(&ap->dccpap_time) / 10; | 364 | struct timeval now; |
365 | u32 elapsed_time; | ||
365 | unsigned char *to, *from; | 366 | unsigned char *to, *from; |
366 | 367 | ||
368 | dccp_timestamp(sk, &now); | ||
369 | elapsed_time = timeval_delta(&now, &ap->dccpap_time) / 10; | ||
370 | |||
367 | if (elapsed_time != 0) | 371 | if (elapsed_time != 0) |
368 | dccp_insert_option_elapsed_time(sk, skb, elapsed_time); | 372 | dccp_insert_option_elapsed_time(sk, skb, elapsed_time); |
369 | 373 | ||
@@ -428,13 +432,29 @@ static void dccp_insert_option_ack_vector(struct sock *sk, struct sk_buff *skb) | |||
428 | (unsigned long long) ap->dccpap_ack_ackno); | 432 | (unsigned long long) ap->dccpap_ack_ackno); |
429 | } | 433 | } |
430 | 434 | ||
435 | void dccp_timestamp(const struct sock *sk, struct timeval *tv) | ||
436 | { | ||
437 | const struct dccp_sock *dp = dccp_sk(sk); | ||
438 | |||
439 | do_gettimeofday(tv); | ||
440 | tv->tv_sec -= dp->dccps_epoch.tv_sec; | ||
441 | tv->tv_usec -= dp->dccps_epoch.tv_usec; | ||
442 | |||
443 | while (tv->tv_usec < 0) { | ||
444 | tv->tv_sec--; | ||
445 | tv->tv_usec += USEC_PER_SEC; | ||
446 | } | ||
447 | } | ||
448 | |||
449 | EXPORT_SYMBOL_GPL(dccp_timestamp); | ||
450 | |||
431 | void dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb) | 451 | void dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb) |
432 | { | 452 | { |
433 | struct timeval tv; | 453 | struct timeval tv; |
434 | u32 now; | 454 | u32 now; |
435 | 455 | ||
436 | do_gettimeofday(&tv); | 456 | dccp_timestamp(sk, &tv); |
437 | now = (tv.tv_sec * USEC_PER_SEC + tv.tv_usec) / 10; | 457 | now = timeval_usecs(&tv) / 10; |
438 | /* yes this will overflow but that is the point as we want a | 458 | /* yes this will overflow but that is the point as we want a |
439 | * 10 usec 32 bit timer which mean it wraps every 11.9 hours */ | 459 | * 10 usec 32 bit timer which mean it wraps every 11.9 hours */ |
440 | 460 | ||
@@ -452,13 +472,17 @@ static void dccp_insert_option_timestamp_echo(struct sock *sk, | |||
452 | const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? | 472 | const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? |
453 | "CLIENT TX opt: " : "server TX opt: "; | 473 | "CLIENT TX opt: " : "server TX opt: "; |
454 | #endif | 474 | #endif |
475 | struct timeval now; | ||
455 | u32 tstamp_echo; | 476 | u32 tstamp_echo; |
456 | const u32 elapsed_time = | 477 | u32 elapsed_time; |
457 | timeval_now_delta(&dp->dccps_timestamp_time) / 10; | 478 | int len, elapsed_time_len; |
458 | const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time); | ||
459 | const int len = 6 + elapsed_time_len; | ||
460 | unsigned char *to; | 479 | unsigned char *to; |
461 | 480 | ||
481 | dccp_timestamp(sk, &now); | ||
482 | elapsed_time = timeval_delta(&now, &dp->dccps_timestamp_time) / 10; | ||
483 | elapsed_time_len = dccp_elapsed_time_len(elapsed_time); | ||
484 | len = 6 + elapsed_time_len; | ||
485 | |||
462 | if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) { | 486 | if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) { |
463 | LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert " | 487 | LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert " |
464 | "timestamp echo!\n"); | 488 | "timestamp echo!\n"); |
@@ -623,7 +647,8 @@ static inline int dccp_ackpkts_set_buf_head_state(struct dccp_ackpkts *ap, | |||
623 | /* | 647 | /* |
624 | * Implements the draft-ietf-dccp-spec-11.txt Appendix A | 648 | * Implements the draft-ietf-dccp-spec-11.txt Appendix A |
625 | */ | 649 | */ |
626 | int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state) | 650 | int dccp_ackpkts_add(struct dccp_ackpkts *ap, const struct sock *sk, |
651 | u64 ackno, u8 state) | ||
627 | { | 652 | { |
628 | /* | 653 | /* |
629 | * Check at the right places if the buffer is full, if it is, tell the | 654 | * Check at the right places if the buffer is full, if it is, tell the |
@@ -704,7 +729,7 @@ int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state) | |||
704 | } | 729 | } |
705 | 730 | ||
706 | ap->dccpap_buf_ackno = ackno; | 731 | ap->dccpap_buf_ackno = ackno; |
707 | do_gettimeofday(&ap->dccpap_time); | 732 | dccp_timestamp(sk, &ap->dccpap_time); |
708 | out: | 733 | out: |
709 | dccp_pr_debug(""); | 734 | dccp_pr_debug(""); |
710 | dccp_ackpkts_print(ap); | 735 | dccp_ackpkts_print(ap); |