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 */
typedef struct {
NTP_Remote_Address addr;
+ NTP_Local_Address local_addr;
int interval;
} Destination;
static Destination *destinations = 0;
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. */
}
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,
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);
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);
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
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;
(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;
(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,
}
} else {
UTI_TimevalToInt64(&local_transmit, &message.transmit_ts, ts_fuzz);
- NIO_SendNormalPacket(&message, where_to);
+ NIO_SendNormalPacket(&message, where_to, from);
}
if (local_tx) {
!inst->presend_done) {
/* Send */
- NIO_SendEcho(&inst->remote_addr);
+ NIO_SendEcho(&inst->remote_addr, &inst->local_addr);
inst->presend_done = 1;
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:
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;
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 */
)
{
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()) {
/* 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);
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;
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;
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
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
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 {
/* 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;
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;
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;
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
/* 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);
}
/* ================================================== */
#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;
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);
}
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 */
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; ) {
/* 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;
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);
}
}
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);