ntp icon indicating copy to clipboard operation
ntp copied to clipboard

NTP timestamp construction is incorrect

Open ccbrown opened this issue 2 years ago • 0 comments

This library currently constructs NTP timestamps like so:

const NTP_SCALE: f64 = std::u32::MAX as f64;

impl From<Instant> for protocol::TimestampFormat {
    fn from(t: Instant) -> Self {
        let sec = t.secs() + EPOCH_DELTA;
        let frac = t.subsec_nanos() as f64 * NTP_SCALE / 1e9;
        protocol::TimestampFormat {
            seconds: sec as u32,
            fraction: frac as u32,
        }
    }
}

RFC 5905 does it like so:

#define FRAC       4294967296.             /* 2^32 as a double */
#define U2LFP(a)   (((unsigned long long) \
                       ((a).tv_sec + JAN_1970) << 32) + \
                       (unsigned long long) \
                       ((a).tv_usec / 1e6 * FRAC))

The key difference is this library is multiplying the fractional component by 4294967295 (std::u32::MAX) while the RFC dictates it should be multiplied by 4294967296. Hence this library's timestamps are sometimes slightly off.

ccbrown avatar May 26 '22 21:05 ccbrown