NTP_int64 ntv1, ntv2;
int r;
- UTI_TimevalToInt64(&tv1, &ntv1, 0);
- UTI_TimevalToInt64(&tv2, &ntv2, 0);
+ UTI_TimevalToInt64(&tv1, &ntv1, NULL);
+ UTI_TimevalToInt64(&tv2, &ntv2, NULL);
UTI_Int64ToTimeval(&ntv1, &tv1);
UTI_Int64ToTimeval(&ntv2, &tv2);
NTP_Packet message;
int leap, auth_len, length, ret;
struct timeval local_receive, local_transmit;
+ NTP_int64 ts_fuzz;
/* Parameters read from reference module */
int are_we_synchronised, our_stratum, smooth_time;
NTP_Leap leap_status;
- uint32_t our_ref_id, ts_fuzz;
+ uint32_t our_ref_id;
struct timeval our_ref_time;
double our_root_delay, our_root_dispersion, smooth_offset;
/* Now fill in timestamps */
- UTI_TimevalToInt64(&our_ref_time, &message.reference_ts, 0);
+ UTI_TimevalToInt64(&our_ref_time, &message.reference_ts, NULL);
/* Originate - this comes from the last packet the source sent us */
message.originate_ts = *orig_ts;
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_receive, &message.receive_ts, 0);
+ UTI_TimevalToInt64(&local_receive, &message.receive_ts, NULL);
/* Prepare random bits which will be added to the transmit timestamp. */
- ts_fuzz = UTI_GetNTPTsFuzz(message.precision);
+ UTI_GetInt64Fuzz(&ts_fuzz, 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
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, ts_fuzz);
+ UTI_TimevalToInt64(&local_transmit, &message.transmit_ts, &ts_fuzz);
auth_len = KEY_GenerateAuth(key_id, (unsigned char *) &message,
offsetof(NTP_Packet, auth_keyid),
message.auth_keyid = 0;
length += sizeof (message.auth_keyid);
}
- UTI_TimevalToInt64(&local_transmit, &message.transmit_ts, ts_fuzz);
+ UTI_TimevalToInt64(&local_transmit, &message.transmit_ts, &ts_fuzz);
}
ret = NIO_SendPacket(&message, where_to, from, length);
/* ================================================== */
-uint32_t
-UTI_GetNTPTsFuzz(int precision)
+void
+UTI_GetInt64Fuzz(NTP_int64 *ts, int precision)
{
- uint32_t fuzz;
- int fuzz_bits;
-
- fuzz_bits = 32 - 1 + precision;
- fuzz = random() % (1 << fuzz_bits);
+ int start, bits;
+
+ assert(precision >= -32 && precision <= 32);
+
+ start = sizeof (*ts) - (precision + 32 + 7) / 8;
+ ts->hi = ts->lo = 0;
- return fuzz;
+ UTI_GetRandomBytes((unsigned char *)ts + start, sizeof (*ts) - start);
+
+ bits = (precision + 32) % 8;
+ if (bits)
+ ((unsigned char *)ts)[start] %= 1U << bits;
}
/* ================================================== */
void
UTI_TimevalToInt64(struct timeval *src,
- NTP_int64 *dest, uint32_t fuzz)
+ NTP_int64 *dest, NTP_int64 *fuzz)
{
- uint32_t lo, sec, usec;
+ uint32_t hi, lo, sec, usec;
sec = (uint32_t)src->tv_sec;
usec = (uint32_t)src->tv_usec;
/* Recognize zero as a special case - it always signifies
an 'unknown' value */
if (!usec && !sec) {
- dest->hi = dest->lo = 0;
+ hi = lo = 0;
} else {
- dest->hi = htonl(sec + JAN_1970);
+ hi = htonl(sec + JAN_1970);
/* This formula gives an error of about 0.1us worst case */
- lo = 4295 * usec - (usec>>5) - (usec>>9);
+ lo = htonl(4295 * usec - (usec >> 5) - (usec >> 9));
/* Add the fuzz */
- lo ^= fuzz;
-
- dest->lo = htonl(lo);
+ if (fuzz) {
+ hi ^= fuzz->hi;
+ lo ^= fuzz->lo;
+ }
}
+
+ dest->hi = hi;
+ dest->lo = lo;
}
/* ================================================== */
/* 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);
+/* Get zero NTP timestamp with random bits below precision */
+extern void UTI_GetInt64Fuzz(NTP_int64 *ts, int precision);
extern double UTI_Int32ToDouble(NTP_int32 x);
extern NTP_int32 UTI_DoubleToInt32(double x);
-extern void UTI_TimevalToInt64(struct timeval *src, NTP_int64 *dest, uint32_t fuzz);
+extern void UTI_TimevalToInt64(struct timeval *src, NTP_int64 *dest, NTP_int64 *fuzz);
extern void UTI_Int64ToTimeval(NTP_int64 *src, struct timeval *dest);