tree 8be8f0e0e19f58cc5cc9cb7d789f3283436712ed
parent bf0ff9e578ba7dd8331005f00ad7310122011f43
author Ian McDonald <[EMAIL PROTECTED]> Sat, 20 Aug 2005 06:23:43 -0300
committer David S. Miller <[EMAIL PROTECTED]> Tue, 30 Aug 2005 06:02:34 -0700

[DCCP]: Fix the timestamp options

This changes timestamp, timestamp echo, and elapsed time to use units of 10
usecs as per DCCP spec. This has been tested to verify that times are correct.
Also fixed up length and used hton/ntoh more.

Still to add in later patches:
- actually use elapsed time to adjust RTT
(commented out as was prior to this patch)
- send options at times more closely following the spec
(content is now correct)

Signed-off-by: Ian McDonald <[EMAIL PROTECTED]>
Signed-off-by: Arnaldo Carvalho de Melo <[EMAIL PROTECTED]>
Signed-off-by: David S. Miller <[EMAIL PROTECTED]>

 include/linux/dccp.h   |    2 -
 net/dccp/ccids/ccid3.c |   12 +-----
 net/dccp/dccp.h        |   19 +++++++++-
 net/dccp/options.c     |   87 +++++++++++++++++++++++++++++++++----------------
 4 files changed, 79 insertions(+), 41 deletions(-)

diff --git a/include/linux/dccp.h b/include/linux/dccp.h
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -415,7 +415,7 @@ struct dccp_sock {
        __u64                           dccps_gsr;
        __u64                           dccps_gar;
        unsigned long                   dccps_service;
-       unsigned long                   dccps_timestamp_time;
+       struct timeval                  dccps_timestamp_time;
        __u32                           dccps_timestamp_echo;
        __u32                           dccps_avg_packet_size;
        unsigned long                   dccps_ndp_count;
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -2,12 +2,12 @@
  *  net/dccp/ccids/ccid3.c
  *
  *  Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
+ *  Copyright (c) 2005 Ian McDonald <[EMAIL PROTECTED]>
  *
  *  An implementation of the DCCP protocol
  *
  *  This code has been developed by the University of Waikato WAND
  *  research group. For further information please see http://www.wand.net.nz/
- *  or e-mail Ian McDonald - [EMAIL PROTECTED]
  *
  *  This code also uses code from Lulea University, rereleased as GPL by its
  *  authors:
@@ -174,14 +174,6 @@ static inline void timeval_fix(struct ti
        }
 }
 
-/* returns the difference in usecs between timeval passed in and current time 
*/
-static inline u32 now_delta(struct timeval tv) {
-       struct timeval now;
-       
-       do_gettimeofday(&now);
-       return ((now.tv_sec-tv.tv_sec)*1000000+now.tv_usec-tv.tv_usec);
-}
-
 #define CALCX_ARRSIZE 500
 
 #define CALCX_SPLIT 50000
@@ -1110,7 +1102,7 @@ static void ccid3_hc_tx_packet_recv(stru
        struct ccid3_options_received *opt_recv;
        struct dccp_tx_hist_entry *packet;
        unsigned long next_tmout; 
-       u16 t_elapsed;
+       u32 t_elapsed;
        u32 pinv;
        u32 x_recv;
        u32 r_sample;
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -4,7 +4,8 @@
  *  net/dccp/dccp.h
  *
  *  An implementation of the DCCP protocol
- *  Arnaldo Carvalho de Melo <[EMAIL PROTECTED]>
+ *  Copyright (c) 2005 Arnaldo Carvalho de Melo <[EMAIL PROTECTED]>
+ *  Copyright (c) 2005 Ian McDonald <[EMAIL PROTECTED]>
  *
  *     This program is free software; you can redistribute it and/or modify it
  *     under the terms of the GNU General Public License version 2 as
@@ -404,6 +405,7 @@ extern struct socket *dccp_ctl_socket;
  * @dccpap_ack_nonce - the one-bit sum of the ECN Nonces for all State 0.
  *
  * @dccpap_buf_len - circular buffer length
+ * @dccpap_time                - the time in usecs
  * @dccpap_buf - circular buffer of acknowledgeable packets
  */
 struct dccp_ackpkts {
@@ -416,7 +418,7 @@ struct dccp_ackpkts {
        unsigned int            dccpap_buf_vector_len;
        unsigned int            dccpap_ack_vector_len;
        unsigned int            dccpap_buf_len;
-       unsigned long           dccpap_time;
+       struct timeval          dccpap_time;
        u8                      dccpap_buf_nonce;
        u8                      dccpap_ack_nonce;
        u8                      dccpap_buf[0];
@@ -430,6 +432,19 @@ extern int dccp_ackpkts_add(struct dccp_
 extern void dccp_ackpkts_check_rcv_ackno(struct dccp_ackpkts *ap,
                                         struct sock *sk, u64 ackno);
 
+/*
+ * Returns the difference in usecs between timeval
+ * passed in and current time
+ */
+static inline u32 now_delta(struct timeval tv)
+{
+       struct timeval now;
+       
+       do_gettimeofday(&now);
+       return (now.tv_sec  - tv.tv_sec) * USEC_PER_SEC +
+              (now.tv_usec - tv.tv_usec);
+}
+
 #ifdef CONFIG_IP_DCCP_DEBUG
 extern void dccp_ackvector_print(const u64 ackno,
                                 const unsigned char *vector, int len);
diff --git a/net/dccp/options.c b/net/dccp/options.c
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -2,8 +2,9 @@
  *  net/dccp/options.c
  *
  *  An implementation of the DCCP protocol
- *  Aristeu Sergio Rozanski Filho <[EMAIL PROTECTED]>
- *  Arnaldo Carvalho de Melo <[EMAIL PROTECTED]>
+ *  Copyright (c) 2005 Aristeu Sergio Rozanski Filho <[EMAIL PROTECTED]>
+ *  Copyright (c) 2005 Arnaldo Carvalho de Melo <[EMAIL PROTECTED]>
+ *  Copyright (c) 2005 Ian McDonald <[EMAIL PROTECTED]>
  *
  *      This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -138,7 +139,7 @@ int dccp_parse_options(struct sock *sk, 
                        opt_recv->dccpor_timestamp = ntohl(*(u32 *)value);
 
                        dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp;
-                       dp->dccps_timestamp_time = jiffies;
+                       do_gettimeofday(&dp->dccps_timestamp_time);
 
                        dccp_pr_debug("%sTIMESTAMP=%u, ackno=%llu\n",
                                      debug_prefix, opt_recv->dccpor_timestamp,
@@ -146,36 +147,45 @@ int dccp_parse_options(struct sock *sk, 
                                      DCCP_SKB_CB(skb)->dccpd_ack_seq);
                        break;
                case DCCPO_TIMESTAMP_ECHO:
-                       if (len < 4 || len > 8)
+                       if (len != 4 && len != 6 && len != 8)
                                goto out_invalid_option;
 
                        opt_recv->dccpor_timestamp_echo = ntohl(*(u32 *)value);
 
-                       dccp_pr_debug("%sTIMESTAMP_ECHO=%u, len=%d, ackno=%llu, 
"
-                                     "diff=%u\n",
+                       dccp_pr_debug("%sTIMESTAMP_ECHO=%u, len=%d, ackno=%llu, 
",
                                      debug_prefix,
                                      opt_recv->dccpor_timestamp_echo,
                                      len + 2,
                                      (unsigned long long)
-                                     DCCP_SKB_CB(skb)->dccpd_ack_seq,
-                                     (tcp_time_stamp -
-                                      opt_recv->dccpor_timestamp_echo));
-
-                       opt_recv->dccpor_elapsed_time =
-                                       dccp_decode_value_var(value + 4,
-                                                            len - 4);
-                       dccp_pr_debug("%sTIMESTAMP_ECHO ELAPSED_TIME=%d\n",
+                                     DCCP_SKB_CB(skb)->dccpd_ack_seq);
+
+                       if (len > 4) {
+                               if (len == 6)
+                                       opt_recv->dccpor_elapsed_time =
+                                                ntohs(*(u16 *)(value + 4));
+                               else
+                                       opt_recv->dccpor_elapsed_time =
+                                                ntohl(*(u32 *)(value + 4));
+
+                               dccp_pr_debug("%sTIMESTAMP_ECHO 
ELAPSED_TIME=%d\n",
                                      debug_prefix,
                                      opt_recv->dccpor_elapsed_time);
+                       }
                        break;
                case DCCPO_ELAPSED_TIME:
-                       if (len > 4)
+                       if (len != 2 && len != 4)
                                goto out_invalid_option;
 
                        if (pkt_type == DCCP_PKT_DATA)
                                continue;
-                       opt_recv->dccpor_elapsed_time =
-                                       dccp_decode_value_var(value, len);
+
+                       if (len == 2)
+                               opt_recv->dccpor_elapsed_time =
+                                                       ntohs(*(u16 *)value);
+                       else
+                               opt_recv->dccpor_elapsed_time =
+                                                       ntohl(*(u32 *)value);
+
                        dccp_pr_debug("%sELAPSED_TIME=%d\n", debug_prefix,
                                      opt_recv->dccpor_elapsed_time);
                        break;
@@ -309,8 +319,7 @@ void dccp_insert_option_elapsed_time(str
        const int len = 2 + elapsed_time_len;
        unsigned char *to;
 
-       /* If elapsed_time == 0... */
-       if (elapsed_time_len == 2)
+       if (elapsed_time_len == 0)
                return;
 
        if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) {
@@ -325,7 +334,13 @@ void dccp_insert_option_elapsed_time(str
        *to++ = DCCPO_ELAPSED_TIME;
        *to++ = len;
 
-       dccp_encode_value_var(elapsed_time, to, elapsed_time_len);
+       if (elapsed_time_len == 2) {
+               const u16 var16 = htons((u16)elapsed_time);
+               memcpy(to, &var16, 2);
+       } else {
+               const u32 var32 = htonl(elapsed_time);
+               memcpy(to, &var32, 4);
+       }
 
        dccp_pr_debug("%sELAPSED_TIME=%u, len=%d, seqno=%llu\n",
                      debug_prefix, elapsed_time,
@@ -344,7 +359,7 @@ static void dccp_insert_option_ack_vecto
 #endif
        struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts;
        int len = ap->dccpap_buf_vector_len + 2;
-       const u32 elapsed_time = jiffies_to_usecs(jiffies - ap->dccpap_time) / 
10;
+       const u32 elapsed_time = now_delta(ap->dccpap_time) / 10;
        unsigned char *to, *from;
 
        if (elapsed_time != 0)
@@ -414,7 +429,15 @@ static void dccp_insert_option_ack_vecto
 static inline void dccp_insert_option_timestamp(struct sock *sk,
                                                struct sk_buff *skb)
 {
-       const u32 now = htonl(tcp_time_stamp);
+       struct timeval tv;
+       u32 now;
+       
+       do_gettimeofday(&tv);
+       now = (tv.tv_sec * USEC_PER_SEC + tv.tv_usec) / 10;
+       /* yes this will overflow but that is the point as we want a
+        * 10 usec 32 bit timer which mean it wraps every 11.9 hours */
+
+       now = htonl(now);
        dccp_insert_option(sk, skb, DCCPO_TIMESTAMP, &now, sizeof(now));
 }
 
@@ -427,8 +450,7 @@ static void dccp_insert_option_timestamp
                                        "CLIENT TX opt: " : "server TX opt: ";
 #endif
        u32 tstamp_echo;
-       const u32 elapsed_time = jiffies_to_usecs(jiffies -
-                                                 dp->dccps_timestamp_time) / 
10;
+       const u32 elapsed_time = now_delta(dp->dccps_timestamp_time) / 10;
        const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
        const int len = 6 + elapsed_time_len;
        unsigned char *to;
@@ -448,7 +470,14 @@ static void dccp_insert_option_timestamp
        tstamp_echo = htonl(dp->dccps_timestamp_echo);
        memcpy(to, &tstamp_echo, 4);
        to += 4;
-       dccp_encode_value_var(elapsed_time, to, elapsed_time_len);
+       
+       if (elapsed_time_len == 2) {
+               const u16 var16 = htons((u16)elapsed_time);
+               memcpy(to, &var16, 2);
+       } else if (elapsed_time_len == 4) {
+               const u32 var32 = htonl(elapsed_time);
+               memcpy(to, &var32, 4);
+       }
 
        dccp_pr_debug("%sTIMESTAMP_ECHO=%u, len=%d, seqno=%llu\n",
                      debug_prefix, dp->dccps_timestamp_echo,
@@ -456,7 +485,8 @@ static void dccp_insert_option_timestamp
                      (unsigned long long) DCCP_SKB_CB(skb)->dccpd_seq);
 
        dp->dccps_timestamp_echo = 0;
-       dp->dccps_timestamp_time = 0;
+       dp->dccps_timestamp_time.tv_sec = 0;
+       dp->dccps_timestamp_time.tv_usec = 0;
 }
 
 void dccp_insert_options(struct sock *sk, struct sk_buff *skb)
@@ -514,7 +544,8 @@ struct dccp_ackpkts *dccp_ackpkts_alloc(
                                ap->dccpap_ack_seqno = DCCP_MAX_SEQNO + 1;
                ap->dccpap_buf_nonce = ap->dccpap_buf_nonce = 0;
                ap->dccpap_ack_ptr   = 0;
-               ap->dccpap_time      = 0;
+               ap->dccpap_time.tv_sec = 0;
+               ap->dccpap_time.tv_usec = 0;
                ap->dccpap_buf_vector_len = ap->dccpap_ack_vector_len = 0;
        }
 
@@ -665,7 +696,7 @@ int dccp_ackpkts_add(struct dccp_ackpkts
        }
 
        ap->dccpap_buf_ackno = ackno;
-       ap->dccpap_time = jiffies;
+       do_gettimeofday(&ap->dccpap_time);
 out:
        dccp_pr_debug("");
        dccp_ackpkts_print(ap);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to