diff --git a/addressing.h b/addressing.h index c816cb4..8e301e1 100644 --- a/addressing.h +++ b/addressing.h @@ -46,9 +46,12 @@ typedef struct { typedef struct { IPAddr ip_addr; - IPAddr local_ip_addr; unsigned short port; } NTP_Remote_Address; +typedef struct { + IPAddr ip_addr; +} NTP_Local_Address; + #endif /* GOT_ADDRESSING_H */ diff --git a/broadcast.c b/broadcast.c index 04ef4d3..4b33d8d 100644 --- a/broadcast.c +++ b/broadcast.c @@ -40,6 +40,7 @@ typedef struct { NTP_Remote_Address addr; + NTP_Local_Address local_addr; int interval; } Destination; static Destination *destinations = 0; @@ -114,7 +115,7 @@ timeout_handler(void *arbitrary) ts_fuzz = UTI_GetNTPTsFuzz(message.precision); LCL_ReadCookedTime(&local_transmit, NULL); UTI_TimevalToInt64(&local_transmit, &message.transmit_ts, ts_fuzz); - NIO_SendNormalPacket(&message, &d->addr); + NIO_SendNormalPacket(&message, &d->addr, &d->local_addr); /* Requeue timeout. Don't care if interval drifts gradually, so just do it * at the end. */ @@ -141,8 +142,8 @@ BRD_AddDestination(IPAddr *addr, unsigned short port, int interval) } destinations[n_destinations].addr.ip_addr = *addr; - destinations[n_destinations].addr.local_ip_addr.family = IPADDR_UNSPEC; destinations[n_destinations].addr.port = port; + destinations[n_destinations].local_addr.ip_addr.family = IPADDR_UNSPEC; destinations[n_destinations].interval = interval; SCH_AddTimeoutInClass((double) interval, 1.0, 0.0, diff --git a/cmdmon.c b/cmdmon.c index 4de2c1c..e3ec9e0 100644 --- a/cmdmon.c +++ b/cmdmon.c @@ -1276,7 +1276,6 @@ handle_add_source(NTP_Source_Type type, CMD_Request *rx_message, CMD_Reply *tx_m NSR_Status status; UTI_IPNetworkToHost(&rx_message->data.ntp_source.ip_addr, &rem_addr.ip_addr); - rem_addr.local_ip_addr.family = IPADDR_UNSPEC; rem_addr.port = (unsigned short)(ntohl(rx_message->data.ntp_source.port)); params.minpoll = ntohl(rx_message->data.ntp_source.minpoll); params.maxpoll = ntohl(rx_message->data.ntp_source.maxpoll); @@ -1324,7 +1323,6 @@ handle_del_source(CMD_Request *rx_message, CMD_Reply *tx_message) NSR_Status status; UTI_IPNetworkToHost(&rx_message->data.del_source.ip_addr, &rem_addr.ip_addr); - rem_addr.local_ip_addr.family = IPADDR_UNSPEC; rem_addr.port = 0; status = NSR_RemoveSource(&rem_addr); diff --git a/ntp_core.c b/ntp_core.c index 96f7e3a..f1f237f 100644 --- a/ntp_core.c +++ b/ntp_core.c @@ -64,6 +64,7 @@ typedef enum { struct NCR_Instance_Record { NTP_Remote_Address remote_addr; /* Needed for routing transmit packets */ + NTP_Local_Address local_addr; /* Local address used when sending packets */ NTP_Mode mode; /* The source's NTP mode (client/server or symmetric active peer) */ OperatingMode opmode; /* Whether we are sampling this source @@ -282,6 +283,8 @@ NCR_GetInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourcePar result = MallocNew(struct NCR_Instance_Record); result->remote_addr = *remote_addr; + result->local_addr.ip_addr.family = IPADDR_UNSPEC; + switch (type) { case NTP_SERVER: result->mode = MODE_CLIENT; @@ -562,7 +565,8 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */ (including adjustment to reference), ignored if NULL */ - NTP_Remote_Address *where_to /* Where to address the reponse to */ + NTP_Remote_Address *where_to, /* Where to address the reponse to */ + NTP_Local_Address *from /* From what address to send it */ ) { NTP_Packet message; @@ -650,7 +654,7 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */ (unsigned char *)&message.auth_data, sizeof (message.auth_data)); if (auth_len > 0) { message.auth_keyid = htonl(key_id); - NIO_SendAuthenticatedPacket(&message, where_to, + NIO_SendAuthenticatedPacket(&message, where_to, from, sizeof (message.auth_keyid) + auth_len); } else { DEBUG_LOG(LOGF_NtpCore, @@ -660,7 +664,7 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */ } } else { UTI_TimevalToInt64(&local_transmit, &message.transmit_ts, ts_fuzz); - NIO_SendNormalPacket(&message, where_to); + NIO_SendNormalPacket(&message, where_to, from); } if (local_tx) { @@ -714,7 +718,7 @@ transmit_timeout(void *arg) !inst->presend_done) { /* Send */ - NIO_SendEcho(&inst->remote_addr); + NIO_SendEcho(&inst->remote_addr, &inst->local_addr); inst->presend_done = 1; @@ -753,7 +757,8 @@ transmit_timeout(void *arg) inst->do_auth, inst->auth_key_id, &inst->remote_orig, &inst->local_rx, &inst->local_tx, &inst->local_ntp_tx, - &inst->remote_addr); + &inst->remote_addr, + &inst->local_addr); switch (inst->opmode) { case MD_BURST_WAS_ONLINE: @@ -1315,7 +1320,8 @@ NCR_ProcessKnown one of the secondaries to flywheel it. The behaviour coded here is required in the secondaries to make this possible. */ - NCR_ProcessUnknown(message, now, now_err, &inst->remote_addr, length); + NCR_ProcessUnknown(message, now, now_err, + &inst->remote_addr, &inst->local_addr, length); break; @@ -1428,6 +1434,7 @@ NCR_ProcessUnknown struct timeval *now, /* timestamp at time of receipt */ double now_err, /* assumed error in the timestamp */ NTP_Remote_Address *remote_addr, + NTP_Local_Address *local_addr, int length /* the length of the received packet */ ) { @@ -1488,7 +1495,8 @@ NCR_ProcessUnknown now, /* Time we received the packet */ NULL, /* Don't care when we send reply, we aren't maintaining state about this client */ NULL, /* Ditto */ - remote_addr); + remote_addr, + local_addr); } } } else if (!LOG_RateLimited()) { diff --git a/ntp_core.h b/ntp_core.h index c21199b..a035289 100644 --- a/ntp_core.h +++ b/ntp_core.h @@ -58,7 +58,7 @@ extern void NCR_ProcessKnown(NTP_Packet *message, struct timeval *now, double no /* This routine is called when a new packet arrives off the network, and we do not recognize its source */ -extern void NCR_ProcessUnknown(NTP_Packet *message, struct timeval *now, double now_err, NTP_Remote_Address *remote_addr, int length); +extern void NCR_ProcessUnknown(NTP_Packet *message, struct timeval *now, double now_err, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int length); /* Slew receive and transmit times in instance records */ extern void NCR_SlewTimes(NCR_Instance inst, struct timeval *when, double dfreq, double doffset); diff --git a/ntp_io.c b/ntp_io.c index 4628781..f277985 100644 --- a/ntp_io.c +++ b/ntp_io.c @@ -301,6 +301,7 @@ read_from_socket(void *anything) struct timeval now, now_raw; double now_err; NTP_Remote_Address remote_addr; + NTP_Local_Address local_addr; char cmsgbuf[256]; struct msghdr msg; struct iovec iov; @@ -331,8 +332,6 @@ read_from_socket(void *anything) reponse on a subsequent recvfrom). */ if (status > 0) { - memset(&remote_addr, 0, sizeof (remote_addr)); - switch (where_from.u.sa_family) { case AF_INET: remote_addr.ip_addr.family = IPADDR_INET4; @@ -351,14 +350,16 @@ read_from_socket(void *anything) assert(0); } + local_addr.ip_addr.family = IPADDR_UNSPEC; + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { #ifdef IP_PKTINFO if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) { struct in_pktinfo ipi; memcpy(&ipi, CMSG_DATA(cmsg), sizeof(ipi)); - remote_addr.local_ip_addr.addr.in4 = ntohl(ipi.ipi_spec_dst.s_addr); - remote_addr.local_ip_addr.family = IPADDR_INET4; + local_addr.ip_addr.addr.in4 = ntohl(ipi.ipi_spec_dst.s_addr); + local_addr.ip_addr.family = IPADDR_INET4; } #endif @@ -367,9 +368,9 @@ read_from_socket(void *anything) struct in6_pktinfo ipi; memcpy(&ipi, CMSG_DATA(cmsg), sizeof(ipi)); - memcpy(&remote_addr.local_ip_addr.addr.in6, &ipi.ipi6_addr.s6_addr, - sizeof (remote_addr.local_ip_addr.addr.in6)); - remote_addr.local_ip_addr.family = IPADDR_INET6; + memcpy(&local_addr.ip_addr.addr.in6, &ipi.ipi6_addr.s6_addr, + sizeof (local_addr.ip_addr.addr.in6)); + local_addr.ip_addr.family = IPADDR_INET6; } #endif @@ -387,7 +388,8 @@ read_from_socket(void *anything) if (status >= NTP_NORMAL_PACKET_SIZE && status <= sizeof(NTP_Packet)) { - NSR_ProcessReceive((NTP_Packet *) &message.ntp_pkt, &now, now_err, &remote_addr, status); + NSR_ProcessReceive((NTP_Packet *) &message.ntp_pkt, &now, now_err, + &remote_addr, &local_addr, status); } else { @@ -401,7 +403,7 @@ read_from_socket(void *anything) /* Send a packet to given address */ static void -send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr) +send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr) { union sockaddr_in46 remote; struct msghdr msg; @@ -452,7 +454,7 @@ send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr) cmsglen = 0; #ifdef IP_PKTINFO - if (remote_addr->local_ip_addr.family == IPADDR_INET4) { + if (local_addr->ip_addr.family == IPADDR_INET4) { struct cmsghdr *cmsg; struct in_pktinfo *ipi; @@ -465,12 +467,12 @@ send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr) cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); ipi = (struct in_pktinfo *) CMSG_DATA(cmsg); - ipi->ipi_spec_dst.s_addr = htonl(remote_addr->local_ip_addr.addr.in4); + ipi->ipi_spec_dst.s_addr = htonl(local_addr->ip_addr.addr.in4); } #endif #if defined(IPV6_PKTINFO) && defined(HAVE_IN6_PKTINFO) - if (remote_addr->local_ip_addr.family == IPADDR_INET6) { + if (local_addr->ip_addr.family == IPADDR_INET6) { struct cmsghdr *cmsg; struct in6_pktinfo *ipi; @@ -483,7 +485,7 @@ send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr) cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); ipi = (struct in6_pktinfo *) CMSG_DATA(cmsg); - memcpy(&ipi->ipi6_addr.s6_addr, &remote_addr->local_ip_addr.addr.in6, + memcpy(&ipi->ipi6_addr.s6_addr, &local_addr->ip_addr.addr.in6, sizeof(ipi->ipi6_addr.s6_addr)); } #endif @@ -515,18 +517,18 @@ send_packet(void *packet, int packetlen, NTP_Remote_Address *remote_addr) /* Send an unauthenticated packet to a given address */ void -NIO_SendNormalPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr) +NIO_SendNormalPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr) { - send_packet((void *) packet, NTP_NORMAL_PACKET_SIZE, remote_addr); + send_packet((void *) packet, NTP_NORMAL_PACKET_SIZE, remote_addr, local_addr); } /* ================================================== */ /* Send an authenticated packet to a given address */ void -NIO_SendAuthenticatedPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr, int auth_len) +NIO_SendAuthenticatedPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int auth_len) { - send_packet((void *) packet, NTP_NORMAL_PACKET_SIZE + auth_len, remote_addr); + send_packet((void *) packet, NTP_NORMAL_PACKET_SIZE + auth_len, remote_addr, local_addr); } /* ================================================== */ @@ -535,7 +537,7 @@ NIO_SendAuthenticatedPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr, #define ECHO_PORT 7 void -NIO_SendEcho(NTP_Remote_Address *remote_addr) +NIO_SendEcho(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr) { unsigned long magic_message = 0xbe7ab1e7UL; NTP_Remote_Address addr; @@ -543,5 +545,5 @@ NIO_SendEcho(NTP_Remote_Address *remote_addr) addr = *remote_addr; addr.port = ECHO_PORT; - send_packet((void *) &magic_message, sizeof(unsigned long), &addr); + send_packet((void *) &magic_message, sizeof(unsigned long), &addr, local_addr); } diff --git a/ntp_io.h b/ntp_io.h index cbbe638..41e2956 100644 --- a/ntp_io.h +++ b/ntp_io.h @@ -38,12 +38,12 @@ extern void NIO_Initialise(int family); extern void NIO_Finalise(void); /* Function to transmit a packet */ -extern void NIO_SendNormalPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr); +extern void NIO_SendNormalPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr); /* Function to transmit an authenticated packet */ -extern void NIO_SendAuthenticatedPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr, int auth_len); +extern void NIO_SendAuthenticatedPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int auth_len); /* Function to send a datagram to a remote machine's UDP echo port. */ -extern void NIO_SendEcho(NTP_Remote_Address *remote_addr); +extern void NIO_SendEcho(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr); #endif /* GOT_NTP_IO_H */ diff --git a/ntp_sources.c b/ntp_sources.c index 0ebd287..7391e54 100644 --- a/ntp_sources.c +++ b/ntp_sources.c @@ -220,8 +220,6 @@ resolve_sources(void *arg) struct UnresolvedSource *us, **i; DNS_Status s; - memset(&address.local_ip_addr, 0, sizeof (address.local_ip_addr)); - DNS_Reload(); for (i = &unresolved_sources; *i; ) { @@ -344,7 +342,7 @@ NSR_RemoveSource(NTP_Remote_Address *remote_addr) /* This routine is called by ntp_io when a new packet arrives off the network, possibly with an authentication tail */ void -NSR_ProcessReceive(NTP_Packet *message, struct timeval *now, double now_err, NTP_Remote_Address *remote_addr, int length) +NSR_ProcessReceive(NTP_Packet *message, struct timeval *now, double now_err, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int length) { int slot, found; @@ -360,7 +358,7 @@ NSR_ProcessReceive(NTP_Packet *message, struct timeval *now, double now_err, NTP if (found == 2) { /* Must match IP address AND port number */ NCR_ProcessKnown(message, now, now_err, records[slot].data, length); } else { - NCR_ProcessUnknown(message, now, now_err, remote_addr, length); + NCR_ProcessUnknown(message, now, now_err, remote_addr, local_addr, length); } } diff --git a/ntp_sources.h b/ntp_sources.h index 7914f92..596c040 100644 --- a/ntp_sources.h +++ b/ntp_sources.h @@ -61,7 +61,7 @@ extern void NSR_ResolveSources(void); extern NSR_Status NSR_RemoveSource(NTP_Remote_Address *remote_addr); /* 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, int length); +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); /* Initialisation function */ extern void NSR_Initialise(void);