[Git][NTPsec/ntpsec][master] 3 commits: Remove more broadcast/multicast code

Hal Murray (@hal.murray) gitlab at mg.gitlab.com
Thu May 2 09:12:21 UTC 2024



Hal Murray pushed to branch master at NTPsec / ntpsec


Commits:
21d2ff55 by Hal Murray at 2024-04-30T23:52:46-07:00
Remove more broadcast/multicast code

- - - - -
b09442d4 by Hal Murray at 2024-04-30T23:52:46-07:00
Fix extra_port

The code turns SO_REUSEADDR on and off for the catchall socket
that grabs all arriving packets that aren't caught by a socket
for each individual IP Address.

The bug was that I wasn't keeping track of the new catchall
sockets for the extra port so it was turning SO_REUSEADDR on/off
for the socket for the wrong port.

- - - - -
e2812791 by Hal Murray at 2024-05-02T02:04:38-07:00
More fixes to extra port.  It now works for me.

Needs lots of testing.

- - - - -


16 changed files:

- NEWS.adoc
- devel/ifdex-ignores
- docs/includes/misc-options.adoc
- docs/includes/nts-commands.adoc
- include/isc_interfaceiter.h
- include/ntp.h
- include/ntp_control.h
- include/ntp_net.h
- include/ntpd.h
- libntp/isc_interfaceiter.c
- libntp/statestr.c
- ntpd/ntp_control.c
- ntpd/ntp_io.c
- ntpd/ntp_peer.c
- ntpd/ntp_timer.c
- pylib/util.py


Changes:

=====================================
NEWS.adoc
=====================================
@@ -12,6 +12,16 @@ on user-visible changes.
 
 ## Repository Head
 
+* ntpd can now listen on a second port.  Add either "nts port xxxx"
+  or "extra port xxxx" in your config file. If either is specified,
+  the NTS-KE server will tell the client to use that port.  This might
+  help get around some of the blocking or filtering that ISPs are
+  doing to port 123.  (Don't forget to let UDP traffic for that port
+  through your firewall.) I've been testing with port 8123.
+
+* Client requests will also be sent from that port.  Again, that will
+  bypass some port 123 filtering.
+
 ## 2023-12-30: 1.2.3
 
 * Change mode6 alignment to four, which may


=====================================
devel/ifdex-ignores
=====================================
@@ -156,10 +156,6 @@ __SIZE_TYPE__		# In ntpd/ntp_parser.tab.c
 EREALLOC_.*
 INTPTR_MAX		# Unity
 __TMS470__		# Unity
-HAVE_STRUCT_TIMEX_MODES
-HAVE_STRUCT_TIMEX_TIME_TICK
-HAVE_STRUCT_NTPTIMEVAL_TAI
-HAVE_STRUCT_NTPTIMEVAL_TIME_TV_NSEC
 DoSLOW			# Cruft from the attic
 
 # seccomp-related symbols that may not be available on all systems


=====================================
docs/includes/misc-options.adoc
=====================================
@@ -214,12 +214,15 @@ the log file.
   peer variables and the +clock_var_list+ holds the names of the reference
   clock variables.
 
-[[extra]]+extra+ [+port+ _portnum ]::
-  This is a catchall for various adjustments.  There is only one slow now.
+[[extra]]+extra+ [+port+ _portnum_ ]::
+  This is a catchall for various adjustments.  There is only one now.
+
 +port+ _portnum_;; (same as +nts port+ _portnum_)
-  This opens another port which will be used for NTP+NTS traffic.
+  This opens another port.  NTS-KE will tell clients to use this port.
   This might help bypass ISP blocking on port 123.  Be sure that
   your firewall doesn't block traffic arriving on this new port.
+  It will also be used as the return port when sending requests.
+  Again, that bypasses blocking on port 123.
 
 [[tinker]]+tinker+ [+allan+ _allan_ | +dispersion+ _dispersion_ | +freq+ _freq_ | +huffpuff+ _huffpuff_ | +panic+ _panic_ | +step+ _step_ | +stepback+ _stepback_ | +stepfwd+ _stepfwd_ | +stepout+ _stepout_]::
   This command can be used to alter several system variables in very


=====================================
docs/includes/nts-commands.adoc
=====================================
@@ -50,9 +50,11 @@ The options are as follows:
   testing. Format is as for +mintls+.
 
 +port+ _portnum_:: (same as +extra port+ _portnum_)
-  This opens another port which will be used for NTP+NTS traffic.
+  This opens another port.  NTS-KE will tell clients to use this port.
   This might help bypass ISP blocking on port 123.  Be sure that
   your firewall doesn't block traffic arriving on this new port.
+  It will also be used as the return port when sending requests.
+  Again, that bypasses blocking on port 123.
 
 // https://crypto.stackexchange.com/questions/8964/sending-tls-messages-with-out-encryption-using-openssl-code
 


=====================================
include/isc_interfaceiter.h
=====================================
@@ -66,7 +66,7 @@ typedef struct isc_interface {
 #define INTERFACE_F_POINTTOPOINT	0x00000002U
 #define INTERFACE_F_LOOPBACK		0x00000004U
 #define INTERFACE_F_BROADCAST		0x00000008U
-#define INTERFACE_F_MULTICAST		0x00000010U
+// #define INTERFACE_F_MULTICAST	0x00000010U
 // #define INTERFACE_F_PRIVACY		0x00000020U	/* RFC 4941 */
 /*@}*/
 


=====================================
include/ntp.h
=====================================
@@ -143,11 +143,9 @@ typedef struct netendpt {
 	SOCKET		fd;		/* socket descriptor */
 	uint32_t	ifnum;		/* endpt instance count */
 	sockaddr_u	sin;		/* unicast address */
-	sockaddr_u	mask;		/* subnet mask */
-	sockaddr_u	bcast;		/* broadcast address */
 	char		name[32];	/* name of interface */
 	unsigned short	family;		/* AF_INET/AF_INET6 */
-	unsigned short	phase;		/* phase in update cycle */
+	bool		inuse;		/* needed to drop unused */
 	uint32_t	flags;		/* interface flags */
 	refid_t		addr_refid;	/* IPv4 addr or IPv6 hash */
 	unsigned long	starttime;	/* current_time at creation */
@@ -155,7 +153,7 @@ typedef struct netendpt {
 	long		sent;		/* number of outgoing packets */
 	long		notsent;	/* number of send failures */
 	unsigned int	ifindex;	/* for IPV6_MULTICAST_IF */
-	bool	ignore_packets; /* listen-read-drop this? */
+	bool		ignore_packets; /* listen-read-drop this? */
 	struct peer *	peers;		/* list of peers using endpt */
 	unsigned int	peercnt;	/* count of same */
 } endpt;
@@ -167,9 +165,9 @@ typedef struct netendpt {
 #define INT_UP		0x001	/* Interface is up */
 /* #define	INT_PPP		0x002	** Point-to-point interface */
 #define	INT_LOOPBACK	0x004U	/* the loopback interface */
-#define	INT_BROADCAST	0x008	/* can broadcast out this interface */
+/* #define	INT_BROADCAST	0x008	** can broadcast out this interface */
 /* #define INT_MULTICAST	0x010	** can multicast out this interface */
-#define	INT_BCASTOPEN	0x020U	/* broadcast receive socket is open */
+/* #define	INT_BCASTOPEN	0x020U	** broadcast receive socket is open */
 /* #define INT_MCASTOPEN	0x040	** multicasting enabled */
 #define INT_WILDCARD	0x080	/* wildcard interface - usually skipped */
 /* #define INT_MCASTIF	0x100	** bound directly to MCAST address */
@@ -587,7 +585,7 @@ struct pkt {
  * Configuration items for the loop filter
  */
 #define	LOOP_DRIFTINIT		1	/* iniitialize frequency */
-// #define LOOP_KERN_CLEAR	2	/* set initial frequency offset */
+/* #define LOOP_KERN_CLEAR	2	** set initial frequency offset */
 #define LOOP_MAX		3	/* set both step offsets */
 #define LOOP_MAX_BACK		4	/* set bacward-step offset */
 #define LOOP_MAX_FWD		5	/* set forward-step offset */
@@ -628,8 +626,7 @@ struct mon_data {
 };
 
 /*
- * Values for cast_flags in mon_entry and struct peer.  mon_entry uses
- * only MDF_UCAST and MDF_BCAST.
+ * Values for cast_flags in struct peer.
  */
 #define	MDF_UCAST	0x01	/* unicast client */
 /* #define MDF_MCAST	0x02	** multicast server (not used) */
@@ -638,16 +635,7 @@ struct mon_data {
 /* #define MDF_ACAST	0x10	** manycast client solicitor (not used) */
 /* #define MDF_BCLNT	0x20	** eph. broadcast/multicast client */
 /* #define MDF_UCLNT	0x40	** preemptible manycast or pool client */
-/*
- * In the context of struct peer in ntpd, one cast_flags bit
- * represent configured associations which never receive packets, and
- * whose reach is always 0: MDF_BCAST  (Historical)
- */
-#define MDF_TXONLY_MASK	(MDF_POOL)
-/*
- * manycastclient-like solicitor association cast_flags bits
- */
-#define MDF_SOLICIT_MASK	MDF_POOL
+
 /*
  * Values used with mon_enabled to indicate reason for enabling monitoring
  */


=====================================
include/ntp_control.h
=====================================
@@ -100,7 +100,7 @@ struct ntp_control {
 #define	CTL_PST_AUTHENABLE	0x40
 #define	CTL_PST_AUTHENTIC	0x20
 #define	CTL_PST_REACH		0x10
-#define	CTL_PST_BCAST		0x08
+#define	CTL_PST_BCASTx		0x08
 
 #define	CTL_PST_SEL_REJECT	0	/*   reject */
 #define	CTL_PST_SEL_SANE	1	/* x falsetick */
@@ -164,7 +164,7 @@ struct ntp_control {
  * IFSTATS_FIELDS is the number of fields ntpd supplies for each ifstats
  * row.  Similarly RESLIST_FIELDS for reslist.
  */
-#define	IFSTATS_FIELDS	12
+#define	IFSTATS_FIELDS	9
 #define	RESLIST_FIELDS	4
 
 /*


=====================================
include/ntp_net.h
=====================================
@@ -178,16 +178,6 @@ typedef union {				/* On Linux, these come from: */
 #define SOCK_UNSPEC_S(psau)					\
 	(SOCK_UNSPEC(psau) && !SCOPE(psau))
 
-/* choose a default net interface (endpt) for v4 or v6 */
-#define ANY_INTERFACE_BYFAM(family) \
-	((AF_INET == family) \
-	     ? io_data.any_interface \
-	     : io_data.any6_interface)
-
-/* choose a default interface for addresses' protocol (addr family) */
-#define ANY_INTERFACE_CHOOSE(psau)				\
-	ANY_INTERFACE_BYFAM(AF(psau))
-
 
 /*
  * Macro for checking for invalid addresses.  This is really, really


=====================================
include/ntpd.h
=====================================
@@ -96,14 +96,14 @@ typedef struct interface_info {
 	uint8_t	action;
 } interface_info_t;
 
-typedef void	(*interface_receiver_t)	(void *, interface_info_t *);
 
 extern  bool listen_to_virtual_ips;
 extern	endpt *	getinterface		(sockaddr_u *, uint32_t);
 extern	endpt *	select_peerinterface	(struct peer *, sockaddr_u *,
 					 endpt *);
 extern	endpt *	findinterface		(sockaddr_u *);
-extern	void	interface_update	(interface_receiver_t, void *);
+extern  endpt * wildcard_interface(const sockaddr_u *);
+extern	void	interface_update	(void);
 extern  void    io_handler              (void);
 extern	void	init_io		(void);
 extern	void	io_open_sockets	(void);
@@ -300,8 +300,10 @@ extern keyid_t	ctl_auth_keyid;		/* keyid used for authenticating write requests
 struct ntp_io_data {
   bool disable_dynamic_updates; /* if true, scan interfaces once only */
   unsigned int sys_ifnum;       /* next .ifnum to assign */
-  endpt *any_interface;         /* IPv4 wildcard */
-  endpt *any6_interface;        /* IPv6 wildcard */
+  endpt *wild_interface_NTP;    /* IPv4 wildcard, port 123 */
+  endpt *wild_interface_extra;  /* IPv4 wildcard, extra_port */
+  endpt *wild6_interface_NTP;   /* IPv6 wildcard, port 123*/
+  endpt *wild6_interface_extra; /* IPv6 wildcard, extra_port */
   endpt *loopback_interface;    /* IPv4 loopback for refclocks */
   endpt *ep_list;               /* complete endpt list */
 };


=====================================
libntp/isc_interfaceiter.c
=====================================
@@ -382,14 +382,6 @@ internal_current(isc_interfaceiter_t *iter) {
         if ((ifa->ifa_flags & IFF_LOOPBACK) != 0)
                 iter->current.flags |= INTERFACE_F_LOOPBACK;
 
-        if ((ifa->ifa_flags & IFF_BROADCAST) != 0)
-                iter->current.flags |= INTERFACE_F_BROADCAST;
-
-#ifdef IFF_MULTICAST
-        if ((ifa->ifa_flags & IFF_MULTICAST) != 0)
-                iter->current.flags |= INTERFACE_F_MULTICAST;
-#endif
-
         iter->current.af = (unsigned int)family;
 
         get_addr((unsigned int)family, &iter->current.address,
@@ -405,12 +397,6 @@ internal_current(isc_interfaceiter_t *iter) {
                          ifa->ifa_dstaddr,
                          ifa->ifa_name);
 
-        if (ifa->ifa_broadaddr != NULL &&
-            (iter->current.flags & INTERFACE_F_BROADCAST) != 0)
-                get_addr((unsigned int)family, &iter->current.broadcast,
-                         ifa->ifa_broadaddr,
-                         ifa->ifa_name);
-
         iter->current.ifindex = if_nametoindex(iter->current.name);
         return (ISC_R_SUCCESS);
 }
@@ -616,14 +602,6 @@ internal_current(isc_interfaceiter_t *iter) {
                 if ((ifam->ifam_flags & IFF_LOOPBACK) != 0)
                         iter->current.flags |= INTERFACE_F_LOOPBACK;
 
-                if ((ifam->ifam_flags & IFF_BROADCAST) != 0)
-                        iter->current.flags |= INTERFACE_F_BROADCAST;
-
-#ifdef IFF_MULTICAST
-                if ((ifam->ifam_flags & IFF_MULTICAST) != 0)
-                        iter->current.flags |= INTERFACE_F_MULTICAST;
-#endif
-
                 /*
                  * This is not an interface address.
                  * Force another iteration.
@@ -688,11 +666,6 @@ internal_current(isc_interfaceiter_t *iter) {
                         get_addr(family, &iter->current.dstaddress, dst_sa,
                                  iter->current.name);
 
-                if (dst_sa != NULL &&
-                    (iter->current.flags & INTERFACE_F_BROADCAST) != 0)
-                        get_addr(family, &iter->current.broadcast, dst_sa,
-                                 iter->current.name);
-
                 return (ISC_R_SUCCESS);
         } else {
                 printf("warning: unexpected interface list message type\n");
@@ -1156,14 +1129,6 @@ internal_current4(isc_interfaceiter_t *iter) {
         if ((ifreq.ifr_flags & IFF_LOOPBACK) != 0)
                 iter->current.flags |= INTERFACE_F_LOOPBACK;
 
-        if ((ifreq.ifr_flags & IFF_BROADCAST) != 0)
-                iter->current.flags |= INTERFACE_F_BROADCAST;
-
-#ifdef IFF_MULTICAST
-        if ((ifreq.ifr_flags & IFF_MULTICAST) != 0)
-                iter->current.flags |= INTERFACE_F_MULTICAST;
-#endif
-
         if (family == AF_INET) {
                 goto inet;
 	}
@@ -1223,23 +1188,6 @@ internal_current4(isc_interfaceiter_t *iter) {
         }
 #endif
 
-        if ((iter->current.flags & INTERFACE_F_BROADCAST) != 0) {
-                /*
-                 * Ignore the HP/UX warning about "integer overflow during
-                 * conversion.  It comes from its own macro definition,
-                 * and is really hard to shut up.
-                 */
-                if (isc_ioctl(iter->socket, SIOCGIFBRDADDR, (char *)&ifreq)
-                    < 0) {
-                        ntp_strerror_r(errno, strbuf, sizeof(strbuf));
-                        msyslog(LOG_ERR, "%s: getting broadcast address: %s",
-                                         ifreq.ifr_name, strbuf);
-                        return (ISC_R_IGNORE);
-                }
-                get_addr(family, &iter->current.broadcast,
-                         (struct sockaddr *)&ifreq.ifr_broadaddr, ifreq.ifr_name);
-        }
-
         /*
          * Get the network mask.
          */
@@ -1348,16 +1296,8 @@ internal_current6(isc_interfaceiter_t *iter) {
         if ((lifreq.lifr_flags & IFF_LOOPBACK) != 0)
                 iter->current.flags |= INTERFACE_F_LOOPBACK;
 
-        if ((lifreq.lifr_flags & IFF_BROADCAST) != 0) {
-                iter->current.flags |= INTERFACE_F_BROADCAST;
         }
 
-#ifdef IFF_MULTICAST
-        if ((lifreq.lifr_flags & IFF_MULTICAST) != 0) {
-                iter->current.flags |= INTERFACE_F_MULTICAST;
-        }
-#endif
-
 #ifdef IFF_POINTOPOINT
         /*
          * If the interface is point-to-point, get the destination address.
@@ -1381,26 +1321,6 @@ internal_current6(isc_interfaceiter_t *iter) {
         }
 #endif
 
-#ifdef SIOCGLIFBRDADDR
-        if ((iter->current.flags & INTERFACE_F_BROADCAST) != 0) {
-                /*
-                 * Ignore the HP/UX warning about "integer overflow during
-                 * conversion.  It comes from its own macro definition,
-                 * and is really hard to shut up.
-                 */
-                if (isc_ioctl(iter->socket, SIOCGLIFBRDADDR, (char *)&lifreq)
-                    < 0) {
-                        ntp_strerror_r(errno, strbuf, sizeof(strbuf));
-                        msyslog(LOG_ERR, "%s: getting broadcast address: %s",
-                                         lifreq.lifr_name, strbuf);
-                        return (ISC_R_IGNORE);
-                }
-                get_addr(family, &iter->current.broadcast,
-                         (struct sockaddr *)&lifreq.lifr_broadaddr,
-                         lifreq.lifr_name);
-        }
-#endif  /* SIOCGLIFBRDADDR */
-
         /*
          * Get the network mask.  Netmask already zeroed.
          */


=====================================
libntp/statestr.c
=====================================
@@ -155,7 +155,7 @@ static const struct codestring peer_st_bits[] = {
 	{ CTL_PST_AUTHENABLE,		"authenb" },
 	{ CTL_PST_AUTHENTIC,		"auth" },
 	{ CTL_PST_REACH,		"reach" },
-	{ CTL_PST_BCAST,		"bcast" },
+	{ CTL_PST_BCASTx,		"bcast" },
 	/* not used with getcode(), no terminating entry needed */
 };
 


=====================================
ntpd/ntp_control.c
=====================================
@@ -968,8 +968,6 @@ ctlpeerstatus(
 		status |= CTL_PST_AUTHENTIC;
 	if (p->reach)
 		status |= CTL_PST_REACH;
-	if (MDF_TXONLY_MASK & p->cast_flags)
-		status |= CTL_PST_BCAST;
 
 	return CTL_PEER_STATUS(status, p->num_events, p->last_event);
 }
@@ -3226,7 +3224,6 @@ send_ifstats_entry(
 	)
 {
 	const char addr_fmtu[] =	"addr.%u";
-	const char bcast_fmt[] =	"bcast.%u";
 	const char en_fmt[] =		"en.%u";	/* enabled */
 	const char name_fmt[] =		"name.%u";
 	const char flags_fmt[] =	"flags.%u";
@@ -3236,7 +3233,7 @@ send_ifstats_entry(
 	const char pc_fmt[] =		"pc.%u";	/* peer count */
 	const char up_fmt[] =		"up.%u";	/* uptime */
 	char	tag[32];
-	uint8_t	sent[IFSTATS_FIELDS]; /* 12 tag=value pairs */
+	uint8_t	sent[IFSTATS_FIELDS]; /* 9 tag=value pairs */
 	int	noisebits;
 	uint32_t noise;
 	unsigned int	which = 0;
@@ -3271,50 +3268,41 @@ send_ifstats_entry(
 			break;
 
 		case 1:
-			snprintf(tag, sizeof(tag), bcast_fmt, ifnum);
-			if (INT_BCASTOPEN & la->flags)
-				pch = sockporttoa(&la->bcast);
-			else
-				pch = "";
-			ctl_putunqstr(tag, pch, strlen(pch));
-			break;
-
-		case 2:
 			snprintf(tag, sizeof(tag), en_fmt, ifnum);
 			ctl_putint(tag, !la->ignore_packets);
 			break;
 
-		case 3:
+		case 2:
 			snprintf(tag, sizeof(tag), name_fmt, ifnum);
 			ctl_putstr(tag, la->name, strlen(la->name));
 			break;
 
-		case 4:
+		case 3:
 			snprintf(tag, sizeof(tag), flags_fmt, ifnum);
 			ctl_puthex(tag, la->flags);
 			break;
 
-		case 5:
+		case 4:
 			snprintf(tag, sizeof(tag), rx_fmt, ifnum);
 			ctl_putint(tag, la->received);
 			break;
 
-		case 6:
+		case 5:
 			snprintf(tag, sizeof(tag), tx_fmt, ifnum);
 			ctl_putint(tag, la->sent);
 			break;
 
-		case 7:
+		case 6:
 			snprintf(tag, sizeof(tag), txerr_fmt, ifnum);
 			ctl_putint(tag, la->notsent);
 			break;
 
-		case 8:
+		case 7:
 			snprintf(tag, sizeof(tag), pc_fmt, ifnum);
 			ctl_putuint(tag, la->peercnt);
 			break;
 
-		case 9:
+		case 8:
 			snprintf(tag, sizeof(tag), up_fmt, ifnum);
 			ctl_putuint(tag, current_time - la->starttime);
 			break;


=====================================
ntpd/ntp_io.c
=====================================
@@ -112,11 +112,11 @@ uptime_t io_timereset;	/* time counters were reset */
 struct ntp_io_data io_data;
 static int ninterfaces;			/* total # of interfaces */
 
-extern  SOCKET  open_socket     (sockaddr_u *, bool, endpt *);
+static  SOCKET  open_socket     (sockaddr_u *, bool, endpt *);
 
 static bool
 netaddr_eqprefix(const isc_netaddr_t *, const isc_netaddr_t *,
-                    unsigned int) __attribute__((pure));
+		unsigned int) __attribute__((pure));
 
 /* Socket Address */
 typedef struct isc_sockaddr {
@@ -126,13 +126,12 @@ typedef struct isc_sockaddr {
 		struct sockaddr_in6	sin6;
 	}				type;
 	unsigned int			length;		/* XXXRTH beginning? */
-        struct { struct isc_sockaddr *prev, *next; } link;
+	struct { struct isc_sockaddr *prev, *next; } link;
 } isc_sockaddr_t;
 
 static void
 netaddr_fromsockaddr(isc_netaddr_t *netaddr, const isc_sockaddr_t *source);
 
-
 #ifdef REFCLOCK
 /*
  * Refclock stuff.	We keep a chain of structures with data concerning
@@ -148,14 +147,12 @@ static	struct refclockio *refio;
 static fd_set activefds;
 static int maxactivefd;
 
-/*
- * bit alternating value to detect verified interfaces during an update cycle
- */
-static unsigned short		sys_interphase = 0;
-
 static void	add_interface(endpt *);
-static bool	update_interfaces(unsigned short, interface_receiver_t,
-				  void *);
+static bool	update_interfaces(void);
+static void	update_interfaces_phase0(void);
+static bool	update_interfaces_phase1(uint16_t port);
+static void	update_interfaces_phase2(void);
+static void	update_interfaces_phase3(void);
 static void	remove_interface(endpt *);
 static endpt *	create_interface(unsigned short, endpt *);
 
@@ -228,9 +225,6 @@ struct remaddr {
 
 static remaddr_t * remoteaddr_list;
 
-static endpt *	wildipv4;
-static endpt *	wildipv6;
-
 static const int accept_wildcard_if_for_winnt = false;
 
 static void	add_fd_to_list		(SOCKET, enum desc_type);
@@ -398,10 +392,6 @@ interface_dump(const endpt *itf)
 	printf("fd = %d\n", itf->fd);
 	printf("sin = %s,\n", socktoa(&itf->sin));
 	sockaddr_dump(&itf->sin);
-	printf("bcast = %s,\n", socktoa(&itf->bcast));
-	sockaddr_dump(&itf->bcast);
-	printf("mask = %s,\n", socktoa(&itf->mask));
-	sockaddr_dump(&itf->mask);
 	printf("name = %s\n", itf->name);
 	printf("flags = 0x%08x\n", itf->flags);
 	printf("addr_refid = %08x\n", itf->addr_refid);
@@ -410,7 +400,6 @@ interface_dump(const endpt *itf)
 	printf("notsent = %ld\n", itf->notsent);
 	printf("ifindex = %u\n", itf->ifindex);
 	printf("peercnt = %u\n", itf->peercnt);
-	printf("phase = %u\n", itf->phase);
 }
 
 /*
@@ -441,24 +430,18 @@ static void
 print_interface(const endpt *iface, const char *pfx, const char *sfx)
 {
 	printf("%sinterface #%u: fd=%d, name=%s, "
-               "flags=0x%x, ifindex=%u, sin=%s",
-	       pfx,
-	       iface->ifnum,
-	       iface->fd,
-	       iface->name,
-	       iface->flags,
-	       iface->ifindex,
-	       socktoa(&iface->sin));
-	if (AF_INET == iface->family) {
-		if (iface->flags & INT_BROADCAST)
-			printf(", bcast=%s", socktoa(&iface->bcast));
-		printf(", mask=%s", socktoa(&iface->mask));
-	}
+		"flags=0x%x, ifindex=%u, sin=%s",
+		pfx,
+		iface->ifnum,
+		iface->fd,
+		iface->name,
+		iface->flags,
+		iface->ifindex,
+		sockporttoa(&iface->sin));
 	printf(", %s:%s",
-	       (iface->ignore_packets)
-		   ? "Disabled"
-		   : "Enabled",
-	       sfx);
+		(iface->ignore_packets)
+		? "Disabled" : "Enabled",
+		sfx);
 	if (debug > 4)	/* in-depth debugging only */ /* SPECIAL DEBUG */
 		interface_dump(iface);
 }
@@ -708,7 +691,6 @@ init_interface(
 {
 	ZERO(*ep);
 	ep->fd = INVALID_SOCKET;
-	ep->phase = sys_interphase;
 }
 
 
@@ -785,8 +767,8 @@ remove_interface(
 	if (ep->fd != INVALID_SOCKET) {
 		msyslog(LOG_INFO,
 			"IO: Deleting interface #%u %s, %s#%d, interface stats: "
-                        "received=%ld, sent=%ld, dropped=%ld, "
-                        "active_time=%lu secs",
+			"received=%ld, sent=%ld, dropped=%ld, "
+			"active_time=%lu secs",
 			ep->ifnum,
 			ep->name,
 			socktoa(&ep->sin),
@@ -866,26 +848,26 @@ create_wildcards(
 		strlcpy(wildif->name, "v6wildcard", sizeof(wildif->name));
 		memcpy(&wildif->sin, &wildaddr, sizeof(wildif->sin));
 		wildif->family = AF_INET6;
-		AF(&wildif->mask) = AF_INET6;
-		SET_ONESMASK(&wildif->mask);
 
 		wildif->flags = INT_UP | INT_WILDCARD;
 		wildif->ignore_packets = (ACTION_DROP == action);
 
 		wildif->fd = open_socket(&wildif->sin, true, wildif);
 
-		if (wildif->fd != INVALID_SOCKET) {
-			wildipv6 = wildif;
-			io_data.any6_interface = wildif;
-			add_addr_to_list(&wildif->sin, wildif);
-			add_interface(wildif);
-			log_listen_address(wildif);
-		} else {
+		if (wildif->fd == INVALID_SOCKET) {
 			msyslog(LOG_ERR,
 				"IO: unable to bind to wildcard address %s - another process may be running: %s; EXITING",
 				socktoa(&wildif->sin), strerror(errno));
 			exit(1);
 		}
+		if (NTP_PORT == port) {
+			io_data.wild6_interface_NTP = wildif;
+		} else {
+			io_data.wild6_interface_extra = wildif;
+		}
+		add_addr_to_list(&wildif->sin, wildif);
+		add_interface(wildif);
+		log_listen_address(wildif);
 		DPRINT_INTERFACE(2, (wildif, "created ", "\n"));
 	}
 
@@ -909,26 +891,25 @@ create_wildcards(
 		strlcpy(wildif->name, "v4wildcard", sizeof(wildif->name));
 		memcpy(&wildif->sin, &wildaddr, sizeof(wildif->sin));
 		wildif->family = AF_INET;
-		AF(&wildif->mask) = AF_INET;
-		SET_ONESMASK(&wildif->mask);
 
-		wildif->flags = INT_BROADCAST | INT_UP | INT_WILDCARD;
+		wildif->flags = INT_UP | INT_WILDCARD;
 		wildif->ignore_packets = (ACTION_DROP == action);
 		wildif->fd = open_socket(&wildif->sin, true, wildif);
 
-		if (wildif->fd != INVALID_SOCKET) {
-			wildipv4 = wildif;
-			io_data.any_interface = wildif;
-
-			add_addr_to_list(&wildif->sin, wildif);
-			add_interface(wildif);
-			log_listen_address(wildif);
-		} else {
+		if (wildif->fd == INVALID_SOCKET) {
 			msyslog(LOG_ERR,
 				"IO: unable to bind to wildcard address %s - another process may be running: %s; EXITING",
 				socktoa(&wildif->sin), strerror(errno));
 			exit(1);
 		}
+		if (NTP_PORT == port) {
+			io_data.wild_interface_NTP = wildif;
+		} else {
+			io_data.wild_interface_extra = wildif;
+		}
+		add_addr_to_list(&wildif->sin, wildif);
+		add_interface(wildif);
+		log_listen_address(wildif);
 		DPRINT_INTERFACE(2, (wildif, "created ", "\n"));
 	}
 }
@@ -1007,12 +988,12 @@ static nic_rule_action
 interface_action(
 	char *		if_name,
 	sockaddr_u *	if_addr,
-	uint32_t		if_flags
+	uint32_t	if_flags
 	)
 {
 	nic_rule *	rule;
-	int		isloopback;
-	int		iswildcard;
+	bool		isloopback;
+	bool		iswildcard;
 
 	DPRINT(4, ("interface_action: interface %s ",
 		   (if_name != NULL) ? if_name : "wildcard"));
@@ -1027,8 +1008,8 @@ interface_action(
 	for (rule = nic_rule_list; rule != NULL; rule = rule->next) {
 
 		switch (rule->match_type) {
-                default:
-                        /* huh? */
+		default:
+			/* huh? */
 		case MATCH_ALL:
 			/* loopback and wildcard excluded from "all" */
 			if (isloopback || iswildcard)
@@ -1162,26 +1143,13 @@ convert_isc_if(
 	itf->ifindex = isc_if->ifindex;
 	itf->family = (unsigned short)isc_if->af;
 	AF(&itf->sin) = (sa_family_t)itf->family;
-	AF(&itf->mask) = (sa_family_t)itf->family;
-	AF(&itf->bcast) = (sa_family_t)itf->family;
 	SET_PORT(&itf->sin, port);
-	SET_PORT(&itf->mask, port);
-	SET_PORT(&itf->bcast, port);
 
 	if (IS_IPV4(&itf->sin)) {
 		NSRCADR(&itf->sin) = isc_if->address.type.in.s_addr;
-		NSRCADR(&itf->mask) = isc_if->netmask.type.in.s_addr;
-
-		if (isc_if->flags & INTERFACE_F_BROADCAST) {
-			itf->flags |= INT_BROADCAST;
-			NSRCADR(&itf->bcast) =
-			    isc_if->broadcast.type.in.s_addr;
-		}
 	}
 	else if (IS_IPV6(&itf->sin)) {
 		SET_ADDR6N(&itf->sin, isc_if->address.type.in6);
-		SET_ADDR6N(&itf->mask, isc_if->netmask.type.in6);
-
 		SET_SCOPE(&itf->sin, isc_if->address.zone);
 	}
 
@@ -1248,18 +1216,14 @@ refresh_interface(
  * interface_update - externally callable update function
  */
 void
-interface_update(
-	interface_receiver_t	receiver,
-	void *			data)
+interface_update(void)
 {
 	bool new_interface_found;
 
 	if (io_data.disable_dynamic_updates)
 		return;
 
-	new_interface_found = update_interfaces(NTP_PORT, receiver, data);
-	if (extra_port)
-		new_interface_found |= update_interfaces(extra_port, receiver, data);
+	new_interface_found = update_interfaces();
 
 	if (!new_interface_found)
 		return;
@@ -1292,14 +1256,14 @@ is_wildcard_addr(
  */
 static void
 set_wildcard_reuse(
-	unsigned short	family,
+	sockaddr_u *psau,
 	int	on
 	)
 {
 	endpt *any;
 	SOCKET fd = INVALID_SOCKET;
 
-	any = ANY_INTERFACE_BYFAM(family);
+	any = wildcard_interface(psau);
 	if (any != NULL)
 		fd = any->fd;
 
@@ -1312,7 +1276,7 @@ set_wildcard_reuse(
 
 		DPRINT(4, ("set SO_REUSEADDR to %s on %s\n",
 			   on ? "on" : "off",
-			   socktoa(&any->sin)));
+			   sockporttoa(&any->sin)));
 	}
 }
 #endif /* NEED_REUSEADDR_FOR_IFADDRBIND */
@@ -1325,7 +1289,7 @@ check_flags6(
 	uint32_t flags6
 	)
 {
-#if defined(SIOCGIFAFLAG_IN6)
+#if defined(SIOCGIFAFLAG_IN6)  /* Apple */
 	struct in6_ifreq ifr6;
 	int fd;
 
@@ -1387,13 +1351,15 @@ is_valid(
 	return check_flags6(psau, name, flags6) ? false : true;
 }
 
-/*
+/* This used to be one giant routine before adding extra_port
+ * The old code couldn't handle a second port.
+ *
  * update_interface strategy
  *
  * toggle configuration phase
  *
  * Phase 1:
- * forall currently existing interfaces
+ * forall currently existing interfaces (and all their addresses)
  *   if address is known:
  *	drop socket - rebind again
  *
@@ -1413,14 +1379,32 @@ is_valid(
  */
 
 static bool
-update_interfaces(
-	unsigned short		port,
-	interface_receiver_t	receiver,
-	void *			data
-	)
+update_interfaces(void)
+{
+  bool new_interface = false;
+  update_interfaces_phase0();
+  if (extra_port)
+    /* do first so our requests are sent from extra_port
+     * see select_peerinterface() */
+    new_interface |= update_interfaces_phase1(extra_port);
+  new_interface |= update_interfaces_phase1(NTP_PORT);
+  update_interfaces_phase2();
+  update_interfaces_phase3();
+  return new_interface;
+}
+
+void update_interfaces_phase0(void)
+{
+  endpt *ep;
+  for (ep = io_data.ep_list; ep != NULL; ep = ep->elink) {
+    ep->inuse = false;
+  }
+}
+
+static bool
+update_interfaces_phase1(uint16_t port)
 {
 	isc_mem_t *		mctx = (void *)-1;
-	interface_info_t	ifi;
 	isc_interfaceiter_t *	iter;
 	bool			result;
 	isc_interface_t		isc_if;
@@ -1428,9 +1412,8 @@ update_interfaces(
 	unsigned int		family;
 	endpt			enumep;
 	endpt *			ep;
-	endpt *			next_ep;
 
-	DPRINT(3, ("update_interfaces(%d)\n", port));
+	DPRINT(3, ("\n\nupdate_interfaces(%d)\n", port));
 
 	/*
 	 * phase one - scan interfaces
@@ -1445,12 +1428,6 @@ update_interfaces(
 	if (!result)
 		return false;
 
-	/*
-	 * Toggle system interface scan phase to find untouched
-	 * interfaces to be deleted.
-	 */
-	sys_interphase ^= 0x1;
-
 	for (result = isc_interfaceiter_first_bool(iter);
 	     result;
 	     result = isc_interfaceiter_next_bool(iter)) {
@@ -1482,21 +1459,21 @@ update_interfaces(
 		switch (interface_action(enumep.name, &enumep.sin,
 					 enumep.flags)) {
 
-                default:
+		default:
 		case ACTION_IGNORE:
 			DPRINT(4, ("ignoring interface %s (%s) - by nic rules\n",
-				   enumep.name, socktoa(&enumep.sin)));
+				   enumep.name, sockporttoa(&enumep.sin)));
 			continue;
 
 		case ACTION_LISTEN:
 			DPRINT(4, ("listen interface %s (%s) - by nic rules\n",
-				   enumep.name, socktoa(&enumep.sin)));
+				   enumep.name, sockporttoa(&enumep.sin)));
 			enumep.ignore_packets = false;
 			break;
 
 		case ACTION_DROP:
 			DPRINT(4, ("drop on interface %s (%s) - by nic rules\n",
-				   enumep.name, socktoa(&enumep.sin)));
+				   enumep.name, sockporttoa(&enumep.sin)));
 			enumep.ignore_packets = true;
 			break;
 		}
@@ -1504,7 +1481,7 @@ update_interfaces(
 		 /* interfaces must be UP to be usable */
 		if (!(enumep.flags & INT_UP)) {
 			DPRINT(4, ("skipping interface %s (%s) - DOWN\n",
-				   enumep.name, socktoa(&enumep.sin)));
+				   enumep.name, sockporttoa(&enumep.sin)));
 			continue;
 		}
 
@@ -1513,32 +1490,42 @@ update_interfaces(
 		 * address - some dhcp clients produce that in the
 		 * wild
 		 */
-		if (is_wildcard_addr(&enumep.sin))
+		if (is_wildcard_addr(&enumep.sin)) {
+			DPRINT(4, ("skipping interface %s (%s) - WILD\n",
+				   enumep.name, sockporttoa(&enumep.sin)));
 			continue;
+			}
 
-		if (is_anycast(&enumep.sin, isc_if.name))
+		if (is_anycast(&enumep.sin, isc_if.name)) {
+			DPRINT(4, ("skipping interface %s (%s) - ANYCAST\n",
+				   enumep.name, sockporttoa(&enumep.sin)));
 			continue;
+			}
 
 		/*
 		 * skip any address that is an invalid state to be used
 		 */
-		if (!is_valid(&enumep.sin, isc_if.name))
+		if (!is_valid(&enumep.sin, isc_if.name)) {
+			DPRINT(4, ("skipping interface %s (%s) - ~VALID\n",
+				   enumep.name, sockporttoa(&enumep.sin)));
 			continue;
+			}
+
 
 		/*
 		 * map to local *address* in order to map all duplicate
 		 * interfaces to an endpt structure with the appropriate
-		 * socket.  Our name space is (ip-address), NOT
+		 * socket.  Our name space is (ip-address+port), NOT
 		 * (interface name, ip-address).
 		 */
 		ep = getinterface(&enumep.sin, INT_WILDCARD);
 
-		if (ep != NULL && refresh_interface(ep)) {
+		if (ep != NULL && SRCPORT(&ep->sin)==port && refresh_interface(ep)) {
 			/*
 			 * found existing and up to date interface -
 			 * mark present.
 			 */
-			if (ep->phase != sys_interphase) {
+			if (!ep->inuse) {
 				/*
 				 * On a new round we reset the name so
 				 * the interface name shows up again if
@@ -1591,12 +1578,8 @@ update_interfaces(
 				ep->ignore_packets = true;
 			}
 
-			ep->phase = sys_interphase;
+			ep->inuse = true;
 
-			ifi.action = IFS_EXISTS;
-			ifi.ep = ep;
-			if (receiver != NULL)
-				(*receiver)(data, &ifi);
 		} else {
 			/*
 			 * This is new or refreshing failed - add to
@@ -1608,35 +1591,37 @@ update_interfaces(
 			 */
 			ep = create_interface(port, &enumep);
 
-			if (ep != NULL) {
-				ifi.action = IFS_CREATED;
-				ifi.ep = ep;
-				if (receiver != NULL)
-					(*receiver)(data, &ifi);
-
-				new_interface_found = true;
-				DPRINT_INTERFACE(3,
-					(ep, "updating ",
-					 " new - created\n"));
-			} else {
+			if (ep == NULL) {
 				DPRINT_INTERFACE(3,
 					(&enumep, "updating ",
 					 " new - creation FAILED"));
-
 				msyslog(LOG_INFO,
-					"IO: failed to init interface for address %s",
-					socktoa(&enumep.sin));
+					"IO: failed to init interface for %s",
+					sockporttoa(&enumep.sin));
 				continue;
 			}
+
+			new_interface_found = true;
+			ep->inuse = true;
+			DPRINT_INTERFACE(3,
+				(ep, "updating ", " new - created\n"));
 		}
 	}
 
 	isc_interfaceiter_destroy(&iter);
 
-	/*
-	 * phase 2 - delete gone interfaces - reassigning peers to
-	 * other interfaces
-	 */
+	return new_interface_found;
+}
+
+/*
+ * phase 2 - delete gone interfaces - reassigning peers to
+ * other interfaces
+ */
+void update_interfaces_phase2(void)
+{
+	endpt *			ep;
+	endpt *			next_ep;
+
 	for (ep = io_data.ep_list; ep != NULL; ep = next_ep) {
 		next_ep = ep->elink;
 
@@ -1646,18 +1631,13 @@ update_interfaces(
 		 * is gone and will be deleted here unless it did not
 		 * originate from interface enumeration INT_WILDCARD,
 		 */
-		if ((INT_WILDCARD & ep->flags) || ep->phase == sys_interphase)
+		if ((INT_WILDCARD & ep->flags) || ep->inuse)
 			continue;
 
 		DPRINT_INTERFACE(3, (ep, "updating ",
 				     "GONE - deleting\n"));
 		remove_interface(ep);
 
-		ifi.action = IFS_DELETED;
-		ifi.ep = ep;
-		if (receiver != NULL)
-			(*receiver)(data, &ifi);
-
 		/* disconnect peers from deleted endpt. */
 		while (ep->peers != NULL)
 			set_peerdstadr(ep->peers, NULL);
@@ -1671,16 +1651,17 @@ update_interfaces(
 
 		delete_interface(ep);
 	}
+}
 
-	/*
-	 * phase 3 - re-configure as the world has possibly changed
-	 *
-	 * never ever make this conditional again - it is needed to track
-	 * routing updates. see bug #2506
-	 */
+/*
+ * phase 3 - re-configure as the world has possibly changed
+ *
+ * never ever make this conditional again - it is needed to track
+ * routing updates. see bug #2506
+ */
+void update_interfaces_phase3(void)
+{
 	refresh_all_peerinterfaces();
-
-	return new_interface_found;
 }
 
 
@@ -1699,8 +1680,7 @@ create_sockets(void)
 	create_wildcards(NTP_PORT);
 	if (extra_port) create_wildcards(extra_port);
 
-	update_interfaces(NTP_PORT, NULL, NULL);
-	if (extra_port) update_interfaces(extra_port, NULL, NULL);
+	update_interfaces();
 
 	/*
 	 * Now that we have opened all the sockets, turn off the reuse
@@ -1725,7 +1705,7 @@ create_interface(
 {
 	sockaddr_u	resmask;
 	endpt *		iface;
-	DPRINT(2, ("create_interface(%s#%d)\n", socktoa(&protot->sin),
+	DPRINT(2, ("create_interface(%s#%d)\n", sockporttoa(&protot->sin),
 		    port));
 
 	/* build an interface */
@@ -1734,7 +1714,7 @@ create_interface(
 	/*
 	 * create socket
 	 */
-	iface->fd = open_socket(&iface->sin, false, iface);
+	iface->fd = open_socket(&iface->sin, true, iface);
 
 	if (iface->fd != INVALID_SOCKET)
 		log_listen_address(iface);
@@ -1775,7 +1755,7 @@ create_interface(
 }
 
 
-#ifdef SO_EXCLUSIVEADDRUSE
+#ifdef SO_EXCLUSIVEADDRUSE  /* Windows */
 static void
 set_excladdruse(
 	SOCKET fd
@@ -1805,7 +1785,7 @@ set_reuseaddr(
 	int flag
 	)
 {
-#ifndef SO_EXCLUSIVEADDRUSE
+#ifndef SO_EXCLUSIVEADDRUSE  /* Windows */
 	endpt *ep;
 
 	for (ep = io_data.ep_list; ep != NULL; ep = ep->elink) {
@@ -1838,7 +1818,7 @@ set_reuseaddr(
 SOCKET
 open_socket(
 	sockaddr_u *	addr,
-	bool		turn_off_reuse,
+	bool		turn_on_reuse,
 	endpt *		interf
 	)
 {
@@ -1884,24 +1864,24 @@ open_socket(
 
 	/*
 	 * set SO_REUSEADDR since we will be binding the same port
-	 * number on each interface according to turn_off_reuse.
+	 * number on each interface according to turn_on_reuse.
 	 */
 	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
-		       (const void *)((turn_off_reuse)
-				    ? &off
-				    : &on),
+		       (const void *)((turn_on_reuse)
+				    ? &on
+				    : &off),
 		       sizeof(on))) {
 
 		msyslog(LOG_ERR,
 			"IO: setsockopt SO_REUSEADDR %s fails for address %s: %s",
-			(turn_off_reuse)
-			    ? "off"
-			    : "on",
+			(turn_on_reuse)
+			    ? "on"
+			    : "off",
 			socktoa(addr), strerror(errno));
 		close(fd);
 		return INVALID_SOCKET;
 	}
-#ifdef SO_EXCLUSIVEADDRUSE
+#ifdef SO_EXCLUSIVEADDRUSE  /* Windows */
 	/*
 	 * setting SO_EXCLUSIVEADDRUSE on the wildcard we open
 	 * first will cause more specific binds to fail.
@@ -1918,7 +1898,7 @@ open_socket(
 			       sizeof(qos)))
 			msyslog(LOG_ERR,
 				"IO: setsockopt IP_TOS (%02x) fails on "
-                                "address %s: %s",
+				"address %s: %s",
 				(unsigned)qos, socktoa(addr), strerror(errno));
 	}
 
@@ -1930,8 +1910,8 @@ open_socket(
 		if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, (char*)&qos,
 			       sizeof(qos)))
 			msyslog(LOG_ERR, "IO: setsockopt IPV6_TCLASS (%02x) "
-                                         "fails on address %s: %s",
-				         (unsigned)qos, socktoa(addr), strerror(errno));
+					"fails on address %s: %s",
+					(unsigned)qos, socktoa(addr), strerror(errno));
 #endif /* IPV6_TCLASS */
 		if (isc_net_probe_ipv6only_bool()
 		    && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
@@ -1948,37 +1928,28 @@ open_socket(
 	 * to the port and SO_REUSEADDR is not set
 	 */
 	if (!is_wildcard_addr(addr))
-		set_wildcard_reuse(AF(addr), 1);
+		set_wildcard_reuse(addr, 1);
 #endif
 
 	/*
-	 * bind the local address.
+	 bind the local address.
 	 */
 	errval = bind(fd, &addr->sa, SOCKLEN(addr));
 
 #ifdef NEED_REUSEADDR_FOR_IFADDRBIND
+
 	if (!is_wildcard_addr(addr))
-		set_wildcard_reuse(AF(addr), 0);
+		set_wildcard_reuse(addr, 0);
 #endif
 
 	if (errval < 0) {
-		/*
-		 * Don't log this under all conditions
-		 */
-		if (turn_off_reuse == 0
-#ifdef DEBUG
-		    || debug > 1 /* SPECIAL DEBUG */
-#endif
-		    ) {
-			msyslog(LOG_ERR,
-				"IO: bind(%d) AF_INET%s %s#%d flags 0x%x failed: %s",
-				fd, IS_IPV6(addr) ? "6" : "",
-				socktoa(addr), SRCPORT(addr),
-				interf->flags, strerror(errno));
-		}
-
+		// FIXME: set_wildcard_reuse trashes errno??
+		msyslog(LOG_ERR,
+			"IO: bind(%d) AF_INET%s %s#%d flags 0x%x failed: %s",
+			fd, IS_IPV6(addr) ? "6" : "",
+			socktoa(addr), SRCPORT(addr),
+			interf->flags, strerror(errno));
 		close(fd);
-
 		return INVALID_SOCKET;
 	}
 
@@ -2088,7 +2059,7 @@ read_refclock_packet(
 
 	i = (rp->datalen == 0
 	     || rp->datalen > sizeof(rb->recv_buffer))
-	        ? sizeof(rb->recv_buffer)
+		? sizeof(rb->recv_buffer)
 		: rp->datalen;
 	do {
 		buflen = read(fd, (char *)&rb->recv_buffer, i);
@@ -2173,17 +2144,17 @@ read_network_packet(
 
 	fromlen = sizeof(rb->recv_srcadr);
 
-	iovec.iov_base        = &rb->recv_buffer;
-	iovec.iov_len         = sizeof(rb->recv_buffer);
+	iovec.iov_base		= &rb->recv_buffer;
+	iovec.iov_len		= sizeof(rb->recv_buffer);
 	memset(&msghdr, '\0', sizeof(msghdr));
-	msghdr.msg_name       = &rb->recv_srcadr;
-	msghdr.msg_namelen    = fromlen;
-	msghdr.msg_iov        = &iovec;
-	msghdr.msg_iovlen     = 1;
-	msghdr.msg_flags      = 0;
-	msghdr.msg_control    = (void *)&control;
-	msghdr.msg_controllen = sizeof(control);
-	buflen                = recvmsg(fd, &msghdr, 0);
+	msghdr.msg_name		= &rb->recv_srcadr;
+	msghdr.msg_namelen	= fromlen;
+	msghdr.msg_iov		= &iovec;
+	msghdr.msg_iovlen	= 1;
+	msghdr.msg_flags	= 0;
+	msghdr.msg_control	= (void *)&control;
+	msghdr.msg_controllen	= sizeof(control);
+	buflen			= recvmsg(fd, &msghdr, 0);
 
 	rb->recv_length = (size_t)buflen;
 
@@ -2413,6 +2384,10 @@ input_handler(
 
 /*
  * find an interface suitable for the src address
+ * Called by newpeer() and peer_refresh_interface()
+ * if extra_port is active,
+ *   this selects the first one on the chain
+ *   see update_interfaces().
  */
 endpt *
 select_peerinterface(
@@ -2428,8 +2403,7 @@ select_peerinterface(
 	UNUSED_ARG(peer);
 #endif
 
-
-	wild = ANY_INTERFACE_CHOOSE(srcadr);
+	wild = wildcard_interface(srcadr);
 
 	/*
 	 * Initialize the peer structure and dance the interface jig.
@@ -2464,6 +2438,38 @@ select_peerinterface(
 	return ep;
 }
 
+/* FIXME SO_REUSEADDR, Hal 2024-Apr-19
+ * I'm not sure the NULLs below are correct.  It seems to work.
+ * I'm not sure it is worth the effort to turn off SO_REUSEADDR
+ */
+
+/*
+ * find wildcard interface
+ */
+endpt * wildcard_interface(const sockaddr_u *addr) {
+  unsigned short family = AF(addr);
+  uint16_t port = SRCPORT(addr);
+  if (AF_INET == family) {
+    if (NTP_PORT == port) {
+      return io_data.wild_interface_NTP;
+    } else if (extra_port == port) {
+      return io_data.wild_interface_extra;
+    } else {
+      return NULL;
+    }
+  } else if (AF_INET6 == family) {
+    if (NTP_PORT == port) {
+      return io_data.wild6_interface_NTP;
+    } else if (extra_port == port) {
+      return io_data.wild6_interface_extra;
+    } else {
+      return NULL;
+    }
+  } else {
+    return NULL;
+  }
+}
+
 
 /*
  * findinterface - find local interface corresponding to address
@@ -2481,7 +2487,7 @@ findinterface(
 		DPRINT(4, ("Found no interface for address %s - returning wildcard\n",
 			   socktoa(addr)));
 
-		iface = ANY_INTERFACE_CHOOSE(addr);
+		iface = wildcard_interface(addr);
 	} else
 		DPRINT(4, ("Found interface #%u %s for address %s\n",
 			   iface->ifnum, iface->name, socktoa(addr)));
@@ -2490,9 +2496,7 @@ findinterface(
 }
 
 /*
- * findlocalinterface - find local interface corresponding to addr,
- * which does not have any of flags set.  If bast is nonzero, addr is
- * a broadcast address.
+ * findlocalinterface - find local interface corresponding to addr
  *
  * This code attempts to find the local sending address for an outgoing
  * address by connecting a new socket to destinationaddress:NTP_PORT
@@ -2711,7 +2715,7 @@ cmp_addr_distance(
 endpt *
 getinterface(
 	sockaddr_u *	addr,
-	uint32_t		flags
+	uint32_t	flags
 	)
 {
 	endpt *iface;
@@ -2989,7 +2993,7 @@ find_addr_in_list(
 	for (entry = remoteaddr_list;
 	     entry != NULL;
 	     entry = entry->link) {
-		if (SOCK_EQ(&entry->addr, addr)) {
+		if (ADDR_PORT_EQ(&entry->addr, addr)) {
 			DPRINT(4, ("FOUND\n"));
 			return entry->ep;
 		}
@@ -3020,7 +3024,7 @@ process_routing_msgs(struct asyncio_reader *reader)
 {
 	char buffer[5120];
 	ssize_t cnt;
-        int msg_type;
+	int msg_type;
 #ifdef HAVE_LINUX_RTNETLINK_H
 	struct nlmsghdr *nh;
 #else


=====================================
ntpd/ntp_peer.c
=====================================
@@ -278,7 +278,7 @@ clear_all(void)
 	 * previously saved time values are untrusted.
 	 */
 	for (p = peer_list; p != NULL; p = p->p_link)
-		if (!(MDF_TXONLY_MASK & p->cast_flags))
+		if (!(MDF_POOL & p->cast_flags))
 		    peer_clear(p, "STEP", false);
 
 	DPRINT(1, ("clear_all: at %u\n", current_time));
@@ -492,10 +492,6 @@ peer_refresh_interface(
 			   niface->fd, niface->name,
 			   niface->flags, niface->ifindex,
 			   socktoa(&niface->sin)));
-		if (niface->flags & INT_BROADCAST)
-			DPRINT(4, (", bcast=%s",
-				   socktoa(&niface->bcast)));
-		DPRINT(4, (", mask=%s\n", socktoa(&niface->mask)));
 	} else {
 		DPRINT(4, ("<NONE>\n"));
 	}
@@ -554,6 +550,7 @@ newpeer(
 	unsigned int	hash;
 	const char *	name;	/* for error messages */
 
+
 	if (NULL != hostname) {
 		name = hostname;
 	} else {
@@ -574,7 +571,7 @@ newpeer(
 			if (peer->dstadr == dstadr)
 				break;
 
-			if (dstadr == ANY_INTERFACE_CHOOSE(srcadr) &&
+			if (dstadr == wildcard_interface(srcadr) &&
 			    peer->dstadr == findinterface(srcadr))
 				break;
 


=====================================
ntpd/ntp_timer.c
=====================================
@@ -271,7 +271,7 @@ timer(void)
 	if (interface_interval && interface_timer <= current_time) {
 		timer_interfacetimeout(current_time + interface_interval);
 		DPRINT(2, ("timer: interface update\n"));
-		interface_update(NULL, NULL);
+		interface_update();
 	}
 
 	/*


=====================================
pylib/util.py
=====================================
@@ -723,7 +723,7 @@ class PeerStatusWord:
         else:
             self.conf = "no"
         # Reach
-        if statval & ntp.control.CTL_PST_BCAST:
+        if statval & ntp.control.CTL_PST_BCASTx:
             self.reach = "none"
         elif statval & ntp.control.CTL_PST_REACH:
             self.reach = "yes"



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/b5d1deca3a68ba19f2dee12b10e469dc5ef8acdb...e28127919b96a74eb90400be2d492bb29129dd36

-- 
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/b5d1deca3a68ba19f2dee12b10e469dc5ef8acdb...e28127919b96a74eb90400be2d492bb29129dd36
You're receiving this email because of your account on gitlab.com.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20240502/807d5c05/attachment-0001.htm>


More information about the vc mailing list