From eb75ce7d07c6326f7a5633ccb86f5643ade63638 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Wed, 30 Mar 2016 11:02:04 +0200 Subject: [PATCH] ntp: add function to get local reference ID When a valid NTP reply is received, save the local address (e.g. from IP_PKTINFO), so the reference ID which would the source use for this host can be calculated when needed. --- ntp_core.c | 21 +++++++++++++++++++-- ntp_core.h | 2 ++ ntp_sources.c | 20 ++++++++++++++++++++ ntp_sources.h | 3 +++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/ntp_core.c b/ntp_core.c index f13ea16..8bcd292 100644 --- a/ntp_core.c +++ b/ntp_core.c @@ -602,6 +602,7 @@ NCR_ChangeRemoteAddress(NCR_Instance inst, NTP_Remote_Address *remote_addr) close_client_socket(inst); else { NIO_CloseServerSocket(inst->local_addr.sock_fd); + inst->local_addr.ip_addr.family = IPADDR_UNSPEC; inst->local_addr.sock_fd = NIO_OpenServerSocket(remote_addr); } @@ -961,6 +962,7 @@ static void transmit_timeout(void *arg) { NCR_Instance inst = (NCR_Instance) arg; + NTP_Local_Address local_addr; int sent; inst->tx_timeout_id = 0; @@ -996,6 +998,10 @@ transmit_timeout(void *arg) inst->local_addr.sock_fd = NIO_OpenClientSocket(&inst->remote_addr); } + /* Don't require the packet to be sent from the same address as before */ + local_addr.ip_addr.family = IPADDR_UNSPEC; + local_addr.sock_fd = inst->local_addr.sock_fd; + /* Check whether we need to 'warm up' the link to the other end by sending an NTP exchange to ensure both ends' ARP caches are primed. On loaded systems this might also help ensure that bits @@ -1009,7 +1015,7 @@ transmit_timeout(void *arg) as the reply will be ignored */ transmit_packet(MODE_CLIENT, inst->local_poll, inst->version, 0, 0, &inst->remote_orig, &inst->local_rx, NULL, NULL, - &inst->remote_addr, &inst->local_addr); + &inst->remote_addr, &local_addr); inst->presend_done = 1; @@ -1027,7 +1033,7 @@ transmit_timeout(void *arg) &inst->remote_orig, &inst->local_rx, &inst->local_tx, &inst->local_ntp_tx, &inst->remote_addr, - &inst->local_addr); + &local_addr); ++inst->tx_count; @@ -1450,6 +1456,9 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins server and the socket can be closed */ close_client_socket(inst); + /* Update the local address */ + inst->local_addr.ip_addr = local_addr->ip_addr; + requeue_transmit = 1; } @@ -2008,6 +2017,14 @@ NCR_GetRemoteAddress(NCR_Instance inst) /* ================================================== */ +uint32_t +NCR_GetLocalRefid(NCR_Instance inst) +{ + return UTI_IPToRefid(&inst->local_addr.ip_addr); +} + +/* ================================================== */ + int NCR_IsSyncPeer(NCR_Instance inst) { return SRC_IsSyncPeer(inst->source); diff --git a/ntp_core.h b/ntp_core.h index db624e1..d0af70f 100644 --- a/ntp_core.h +++ b/ntp_core.h @@ -105,6 +105,8 @@ extern void NCR_IncrementActivityCounters(NCR_Instance inst, int *online, int *o extern NTP_Remote_Address *NCR_GetRemoteAddress(NCR_Instance instance); +extern uint32_t NCR_GetLocalRefid(NCR_Instance inst); + extern int NCR_IsSyncPeer(NCR_Instance instance); extern void NCR_AddBroadcastDestination(IPAddr *addr, unsigned short port, int interval); diff --git a/ntp_sources.c b/ntp_sources.c index 96fb142..1ea1936 100644 --- a/ntp_sources.c +++ b/ntp_sources.c @@ -733,6 +733,26 @@ static void remove_tentative_pool_sources(int pool) rehash_records(); } +/* ================================================== */ + +uint32_t +NSR_GetLocalRefid(IPAddr *address) +{ + NTP_Remote_Address remote_addr; + int slot, found; + + remote_addr.ip_addr = *address; + remote_addr.port = 0; + + find_slot(&remote_addr, &slot, &found); + if (!found) + return 0; + + return NCR_GetLocalRefid(get_record(slot)->data); +} + +/* ================================================== */ + /* This routine is called by ntp_io when a new packet arrives off the network, possibly with an authentication tail */ void diff --git a/ntp_sources.h b/ntp_sources.h index 9bd2d3b..4d9bbbe 100644 --- a/ntp_sources.h +++ b/ntp_sources.h @@ -83,6 +83,9 @@ extern void NSR_HandleBadSource(IPAddr *address); /* Procedure to resolve all names again */ extern void NSR_RefreshAddresses(void); +/* Procedure to get local reference ID corresponding to a source */ +extern uint32_t NSR_GetLocalRefid(IPAddr *address); + /* This routine is called by ntp_io when a new packet arrives off the network */ extern void NSR_ProcessReceive(NTP_Packet *message, struct timeval *now, double now_err, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int length);