]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
Fuzz transmit timestamp
authorMiroslav Lichvar <mlichvar@redhat.com>
Tue, 22 May 2012 15:16:41 +0000 (17:16 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Wed, 23 May 2012 10:06:16 +0000 (12:06 +0200)
Add random bits below clock precision to the timestamp to make
it less predictable.

acquire.c
broadcast.c
ntp_core.c
sched.c
util.c
util.h

index 250dca28772cc5e1d90fbcbaa105a42b74b94936..6b479f83d526223170aeb3496811da229551e075 100644 (file)
--- a/acquire.c
+++ b/acquire.c
@@ -256,6 +256,7 @@ probe_source(SourceRecord *src)
   union sockaddr_in46 his_addr;
   int sock_fd;
   socklen_t addrlen;
+  uint32_t ts_fuzz;
 
 #if 0
   printf("Sending probe to %s sent=%d samples=%d\n", UTI_IPToString(&src->ip_addr), src->n_probes_sent, src->n_samples);
@@ -304,8 +305,9 @@ probe_source(SourceRecord *src)
   }
 
 
+  ts_fuzz = UTI_GetNTPTsFuzz(LCL_GetSysPrecisionAsLog());
   LCL_ReadCookedTime(&cooked, NULL);
-  UTI_TimevalToInt64(&cooked, &pkt.transmit_ts);
+  UTI_TimevalToInt64(&cooked, &pkt.transmit_ts, ts_fuzz);
 
   if (sendto(sock_fd, (void *) &pkt, NTP_NORMAL_PACKET_SIZE,
              0,
index 4004195eb1559e45e56f0d2bea642938da874923..8a8e3276826c4261ee692c94deba6bddfd480c2d 100644 (file)
@@ -73,7 +73,7 @@ timeout_handler(void *arbitrary)
   int leap;
   int are_we_synchronised, our_stratum;
   NTP_Leap leap_status;
-  uint32_t our_ref_id;
+  uint32_t our_ref_id, ts_fuzz;
   struct timeval our_ref_time;
   double our_root_delay, our_root_dispersion;
   struct timeval local_transmit;
@@ -107,14 +107,15 @@ timeout_handler(void *arbitrary)
   message.reference_id = htonl((NTP_int32) our_ref_id);
 
   /* Now fill in timestamps */
-  UTI_TimevalToInt64(&our_ref_time, &message.reference_ts);
+  UTI_TimevalToInt64(&our_ref_time, &message.reference_ts, 0);
   message.originate_ts.hi = 0UL;
   message.originate_ts.lo = 0UL;
   message.receive_ts.hi = 0UL;
   message.receive_ts.lo = 0UL;
 
+  ts_fuzz = UTI_GetNTPTsFuzz(message.precision);
   LCL_ReadCookedTime(&local_transmit, NULL);
-  UTI_TimevalToInt64(&local_transmit, &message.transmit_ts);
+  UTI_TimevalToInt64(&local_transmit, &message.transmit_ts, ts_fuzz);
   NIO_SendNormalPacket(&message, &d->addr);
 
   /* Requeue timeout.  Don't care if interval drifts gradually, so just do it
index 3827dddf16079cb815fe0bcc3a126766e03e5513..0fb93e172c0322fed60710fa4093b95b168fb7a8 100644 (file)
@@ -419,7 +419,7 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
   /* Parameters read from reference module */
   int are_we_synchronised, our_stratum;
   NTP_Leap leap_status;
-  uint32_t our_ref_id;
+  uint32_t our_ref_id, ts_fuzz;
   struct timeval our_ref_time;
   double our_root_delay, our_root_dispersion;
 
@@ -458,7 +458,7 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
   message.reference_id = htonl((NTP_int32) our_ref_id);
 
   /* Now fill in timestamps */
-  UTI_TimevalToInt64(&our_ref_time, &message.reference_ts);
+  UTI_TimevalToInt64(&our_ref_time, &message.reference_ts, 0);
 
   /* Originate - this comes from the last packet the source sent us */
   message.originate_ts = *orig_ts;
@@ -467,7 +467,10 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
      This timestamp will have been adjusted so that it will now look to
      the source like we have been running on our latest estimate of
      frequency all along */
-  UTI_TimevalToInt64(local_rx, &message.receive_ts);
+  UTI_TimevalToInt64(local_rx, &message.receive_ts, 0);
+
+  /* Prepare random bits which will be added to the transmit timestamp. */
+  ts_fuzz = UTI_GetNTPTsFuzz(message.precision);
 
   /* Transmit - this our local time right now!  Also, we might need to
      store this for our own use later, next time we receive a message
@@ -481,7 +484,7 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
        take to generate the authentication data. */
     local_transmit.tv_usec += KEY_GetAuthDelay(key_id);
     UTI_NormaliseTimeval(&local_transmit);
-    UTI_TimevalToInt64(&local_transmit, &message.transmit_ts);
+    UTI_TimevalToInt64(&local_transmit, &message.transmit_ts, ts_fuzz);
 
     auth_len = KEY_GenerateAuth(key_id, (unsigned char *) &message,
         offsetof(NTP_Packet, auth_keyid),
@@ -492,7 +495,7 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
           sizeof (message.auth_keyid) + auth_len);
     }
   } else {
-    UTI_TimevalToInt64(&local_transmit, &message.transmit_ts);
+    UTI_TimevalToInt64(&local_transmit, &message.transmit_ts, ts_fuzz);
     NIO_SendNormalPacket(&message, where_to);
   }
 
diff --git a/sched.c b/sched.c
index ae17783d6f82b207b2c64f316e4096f61bf151dc..4dea13d2c34cbf2cc31c805e7faf25e5d9b6a637 100644 (file)
--- a/sched.c
+++ b/sched.c
@@ -147,7 +147,7 @@ SCH_Initialise(void)
   LCL_AddParameterChangeHandler(handle_slew, NULL);
 
   LCL_ReadRawTime(&tv);
-  srandom(tv.tv_sec * tv.tv_usec);
+  srandom(tv.tv_sec << 16 ^ tv.tv_usec);
 
   initialised = 1;
 
diff --git a/util.c b/util.c
index 689e4da1f30f246f3fb4b50961e28376054434c6..2c4a98dc6e7768e7329efb751a24d25a152b8486 100644 (file)
--- a/util.c
+++ b/util.c
@@ -459,16 +459,31 @@ UTI_AdjustTimeval(struct timeval *old_tv, struct timeval *when, struct timeval *
 
 /* ================================================== */
 
+uint32_t
+UTI_GetNTPTsFuzz(int precision)
+{
+  uint32_t fuzz;
+  int fuzz_bits;
+  
+  fuzz_bits = 32 - 1 + precision;
+  fuzz = random() % (1 << fuzz_bits);
+
+  return fuzz;
+}
+
+/* ================================================== */
+
 /* Seconds part of RFC1305 timestamp correponding to the origin of the
    struct timeval format. */
 #define JAN_1970 0x83aa7e80UL
 
 void
 UTI_TimevalToInt64(struct timeval *src,
-                   NTP_int64 *dest)
+                   NTP_int64 *dest, uint32_t fuzz)
 {
   unsigned long usec = src->tv_usec;
   unsigned long sec = src->tv_sec;
+  uint32_t lo;
 
   /* Recognize zero as a special case - it always signifies
      an 'unknown' value */
@@ -478,7 +493,12 @@ UTI_TimevalToInt64(struct timeval *src,
     dest->hi = htonl(src->tv_sec + JAN_1970);
 
     /* This formula gives an error of about 0.1us worst case */
-    dest->lo = htonl(4295 * usec - (usec>>5) - (usec>>9));
+    lo = 4295 * usec - (usec>>5) - (usec>>9);
+
+    /* Add the fuzz */
+    lo ^= fuzz;
+
+    dest->lo = htonl(lo);
   }
 }
 
diff --git a/util.h b/util.h
index e2014b8cae8439264e77de7aad8844948adf5258..3f94f77e5e1492ea236ac44b435e097bfabc12ed 100644 (file)
--- a/util.h
+++ b/util.h
@@ -88,8 +88,10 @@ extern char *UTI_TimeToLogForm(time_t t);
 /* Adjust time following a frequency/offset change */
 extern void UTI_AdjustTimeval(struct timeval *old_tv, struct timeval *when, struct timeval *new_tv, double *delta, double dfreq, double doffset);
 
+/* Get a random value to fuzz an NTP timestamp in the given precision */
+extern uint32_t UTI_GetNTPTsFuzz(int precision);
 
-extern void UTI_TimevalToInt64(struct timeval *src, NTP_int64 *dest);
+extern void UTI_TimevalToInt64(struct timeval *src, NTP_int64 *dest, uint32_t fuzz);
 
 extern void UTI_Int64ToTimeval(NTP_int64 *src, struct timeval *dest);