mirror of
https://github.com/pi-hole/FTL.git
synced 2024-10-26 16:52:18 +02:00
Copy root delay/dispersion errors from upstream server (after first upstream NTP synchronization)
Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
+36
-10
@@ -122,24 +122,29 @@ void print_debug_time(const char *label, const uint32_t *u32p, const uint64_t nt
|
||||
(timevar >> 32) & 0xFFFFFFFF, timevar & 0xFFFFFFFF, time_str);
|
||||
}
|
||||
|
||||
static bool settime_step(const double offset)
|
||||
static uint64_t get_new_time(struct timeval *unix_time, const double offset)
|
||||
{
|
||||
// Get current time
|
||||
struct timeval unix_time;
|
||||
gettimeofday(&unix_time, NULL);
|
||||
gettimeofday(unix_time, NULL);
|
||||
|
||||
// Convert from double to native format (signed) and add to the
|
||||
// current time. Note the addition is done in native format to
|
||||
// avoid overflow or loss of precision.
|
||||
const uint64_t ntp_time = U2LFP(unix_time) + D2LFP(offset);
|
||||
const uint64_t ntp_time = U2LFP(*unix_time) + D2LFP(offset);
|
||||
|
||||
// Convert NTP to native format
|
||||
unix_time.tv_sec = NTPtoSEC(ntp_time);
|
||||
unix_time.tv_usec = NTPtoUSEC(ntp_time);
|
||||
unix_time->tv_sec = NTPtoSEC(ntp_time);
|
||||
unix_time->tv_usec = NTPtoUSEC(ntp_time);
|
||||
|
||||
return ntp_time;
|
||||
}
|
||||
|
||||
static bool settime_step(struct timeval *unix_time, const double offset)
|
||||
{
|
||||
log_debug(DEBUG_NTP, "Stepping system time by %e s", offset);
|
||||
|
||||
// Set time immediately
|
||||
if(settimeofday(&unix_time, NULL) != 0)
|
||||
if(settimeofday(unix_time, NULL) != 0)
|
||||
{
|
||||
log_err("Failed to set time: %s",
|
||||
errno == EPERM ? "Insufficient permissions, try running with sudo" : strerror(errno));
|
||||
@@ -221,9 +226,16 @@ static bool reply(int fd, struct ntp_sync *ntp, const bool verbose)
|
||||
// Compute precision of server clock in seconds 2^rho
|
||||
ntp->precision = pow(2, rho);
|
||||
|
||||
// Get root delay and dispersion (in network-byte-order !)
|
||||
memcpy(&ntp_root_delay, &buf[4], sizeof(ntp_root_delay));
|
||||
memcpy(&ntp_root_dispersion, &buf[8], sizeof(ntp_root_dispersion));
|
||||
|
||||
// Extract Transmit Timestamp
|
||||
// org = Origin Timestamp (Transmit Timestamp @ Client)
|
||||
uint64_t netbuffer;
|
||||
// ref = Reference Timestamp (Time at which the clock was last set or corrected)
|
||||
memcpy(&netbuffer, &buf[16], sizeof(netbuffer));
|
||||
const uint64_t ref = ntoh64(netbuffer);
|
||||
// org = Origin Timestamp (Transmit Timestamp @ Client)
|
||||
memcpy(&netbuffer, &buf[24], sizeof(netbuffer));
|
||||
const uint64_t org = ntoh64(netbuffer);
|
||||
// rec = Receive Timestamp (Receive Timestamp @ Server)
|
||||
@@ -287,6 +299,9 @@ static bool reply(int fd, struct ntp_sync *ntp, const bool verbose)
|
||||
if(!config.debug.ntp.v.b)
|
||||
return true;
|
||||
|
||||
// Print current time at server
|
||||
print_debug_time("Server reference time", NULL, ref);
|
||||
|
||||
// Print current time at client
|
||||
print_debug_time("Current time at client", NULL, dst);
|
||||
|
||||
@@ -296,6 +311,10 @@ static bool reply(int fd, struct ntp_sync *ntp, const bool verbose)
|
||||
// Print offset and delay
|
||||
log_debug(DEBUG_NTP, "Time offset: %e s", ntp->theta);
|
||||
log_debug(DEBUG_NTP, "Round-trip delay: %e s", ntp->delta);
|
||||
const uint32_t root_delay = ntohl(ntp_root_delay);
|
||||
log_debug(DEBUG_NTP, "Root delay: %e s", LFP2D(root_delay));
|
||||
const uint32_t root_dispersion = ntohl(ntp_root_dispersion);
|
||||
log_debug(DEBUG_NTP, "Root dispersion: %e s", LFP2D(root_dispersion));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -398,7 +417,7 @@ bool ntp_client(const char *server, const bool settime, const bool print)
|
||||
free(ntp);
|
||||
return false;
|
||||
}
|
||||
log_info("Received %u/%u valid NTP replies", valid, count);
|
||||
log_info("Received %u/%u valid NTP replies from %s", valid, count, server);
|
||||
|
||||
theta_avg /= valid;
|
||||
delta_avg /= valid;
|
||||
@@ -466,6 +485,10 @@ bool ntp_client(const char *server, const bool settime, const bool print)
|
||||
// Set time if requested
|
||||
if(settime)
|
||||
{
|
||||
// Calculate corrected time
|
||||
struct timeval unix_time;
|
||||
const uint64_t ntp_time = get_new_time(&unix_time, theta_trim);
|
||||
|
||||
// If the clock deviates more than 0.5 seconds from the NTP server,
|
||||
// the time is updated immediately. Otherwise, the time is updated
|
||||
// gradually to avoid sudden jumps in the system clock.
|
||||
@@ -473,7 +496,7 @@ bool ntp_client(const char *server, const bool settime, const bool print)
|
||||
// since Linux 2.6.26, see man ntp_adjtime(2) for details.
|
||||
bool success;
|
||||
if(fabs(theta_trim) > 0.5)
|
||||
success = settime_step(theta_trim);
|
||||
success = settime_step(&unix_time, theta_trim);
|
||||
else
|
||||
success = settime_skew(theta_trim);
|
||||
|
||||
@@ -481,6 +504,9 @@ bool ntp_client(const char *server, const bool settime, const bool print)
|
||||
if(!success)
|
||||
return false;
|
||||
|
||||
// Update last NTP sync time
|
||||
ntp_last_sync = ntp_time;
|
||||
|
||||
// Finally, adjust RTC if configured
|
||||
if(config.ntp.rtc.set.v.b)
|
||||
ntp_sync_rtc();
|
||||
|
||||
@@ -65,6 +65,10 @@ bool ntp_sync_rtc(void);
|
||||
#define hton64(x) ((((uint64_t)htonl(x)) << 32) + htonl((x) >> 32))
|
||||
#define ntoh64(x) ((((uint64_t)ntohl(x)) << 32) + ntohl((x) >> 32))
|
||||
|
||||
extern uint64_t ntp_last_sync;
|
||||
extern uint32_t ntp_root_delay;
|
||||
extern uint32_t ntp_root_dispersion;
|
||||
|
||||
#endif // NTP_H
|
||||
|
||||
|
||||
|
||||
+14
-12
@@ -38,6 +38,10 @@
|
||||
// PRIi64
|
||||
#include <inttypes.h>
|
||||
|
||||
uint64_t ntp_last_sync = 0u;
|
||||
uint32_t ntp_root_delay = 0u;
|
||||
uint32_t ntp_root_dispersion = 0u;
|
||||
|
||||
// RFC 5905 Appendix A.4: Kernel System Clock Interface
|
||||
uint64_t gettime64(void)
|
||||
{
|
||||
@@ -100,11 +104,12 @@ static bool ntp_reply(const int socket_fd, const struct sockaddr *saddr_p, const
|
||||
// | Root Dispersion |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
// Assume Root Delay (total roundtrip delay to the primary reference
|
||||
// source) = 0, Root Dispersion (the nominal error relative to the
|
||||
// primary reference source) = 0 as we don't have these numbers
|
||||
*u32p++ = 0.0;
|
||||
*u32p++ = 0.0;
|
||||
// Set Root Delay (total roundtrip delay to the primary reference
|
||||
// source) and Root Dispersion (the nominal error relative to the
|
||||
// primary reference source) to the values obtained from the upstream
|
||||
// NTP server. These values are already in network byte order.
|
||||
*u32p++ = ntp_root_delay;
|
||||
*u32p++ = ntp_root_dispersion;
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
@@ -115,7 +120,7 @@ static bool ntp_reply(const int socket_fd, const struct sockaddr *saddr_p, const
|
||||
// Reference ID = 'LOCL" (LOCAL CLOCK)
|
||||
// A four-octet, left-justified, zero-padded ASCII string assigned to
|
||||
// the reference clock
|
||||
memcpy(u32p++, "LOCL", 4);
|
||||
memcpy(u32p++, "LOCL", sizeof(uint32_t));
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
@@ -126,12 +131,9 @@ static bool ntp_reply(const int socket_fd, const struct sockaddr *saddr_p, const
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
// Time when the system clock was last set or corrected, in NTP
|
||||
// timestamp format. As this is not a stratum 1 server, we don't have
|
||||
// a hardware clock to set this value.
|
||||
// A stateless server copies T3 and T4 from the client packet to T1 and
|
||||
// T2 of the server packet and tacks on the transmit timestamp T3 before
|
||||
// sending it to the client.
|
||||
memcpy(u32p, &u32r[8], sizeof(uint64_t));
|
||||
// timestamp format.
|
||||
const uint64_t last_sync = hton64(ntp_last_sync);
|
||||
memcpy(u32p, &last_sync, sizeof(uint64_t));
|
||||
if(config.debug.ntp.v.b)
|
||||
print_debug_time("Reference Timestamp", u32p, 0);
|
||||
u32p += 2;
|
||||
|
||||
Reference in New Issue
Block a user