PageRenderTime 95ms CodeModel.GetById 15ms app.highlight 62ms RepoModel.GetById 1ms app.codeStats 1ms

/contrib/ntp/ntpd/ntp_io.c

https://bitbucket.org/freebsd/freebsd-head/
C | 4029 lines | 2744 code | 465 blank | 820 comment | 567 complexity | f6b7746f9e2b27cfdbf19b0d937c3239 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2 * ntp_io.c - input/output routines for ntpd.	The socket-opening code
   3 *		   was shamelessly stolen from ntpd.
   4 */
   5
   6#ifdef HAVE_CONFIG_H
   7# include <config.h>
   8#endif
   9
  10#include "ntp_machine.h"
  11#include "ntpd.h"
  12#include "ntp_io.h"
  13#include "iosignal.h"
  14#include "ntp_refclock.h"
  15#include "ntp_stdlib.h"
  16#include "ntp_request.h"
  17#include "ntp.h"
  18#include "ntp_unixtime.h"
  19
  20/* Don't include ISC's version of IPv6 variables and structures */
  21#define ISC_IPV6_H 1
  22#include <isc/interfaceiter.h>
  23#include <isc/list.h>
  24#include <isc/result.h>
  25
  26#ifdef SIM
  27#include "ntpsim.h"
  28#endif
  29
  30#include <stdio.h>
  31#include <signal.h>
  32#ifdef HAVE_SYS_PARAM_H
  33# include <sys/param.h>
  34#endif /* HAVE_SYS_PARAM_H */
  35#ifdef HAVE_SYS_IOCTL_H
  36# include <sys/ioctl.h>
  37#endif
  38#ifdef HAVE_SYS_SOCKIO_H	/* UXPV: SIOC* #defines (Frank Vance <fvance@waii.com>) */
  39# include <sys/sockio.h>
  40#endif
  41#ifdef HAVE_SYS_UIO_H
  42# include <sys/uio.h>
  43#endif
  44
  45/*
  46 * setsockopt does not always have the same arg declaration
  47 * across all platforms. If it's not defined we make it empty
  48 */
  49
  50#ifndef SETSOCKOPT_ARG_CAST
  51#define SETSOCKOPT_ARG_CAST
  52#endif
  53
  54/* 
  55 * Set up some macros to look for IPv6 and IPv6 multicast
  56 */
  57
  58#if defined(ISC_PLATFORM_HAVEIPV6) && !defined(DISABLE_IPV6)
  59
  60#define INCLUDE_IPV6_SUPPORT
  61
  62#if defined(INCLUDE_IPV6_SUPPORT) && defined(IPV6_JOIN_GROUP) && defined(IPV6_LEAVE_GROUP)
  63#define INCLUDE_IPV6_MULTICAST_SUPPORT
  64
  65#endif	/* IPV6 Multicast Support */
  66#endif  /* IPv6 Support */
  67
  68#ifdef INCLUDE_IPV6_SUPPORT
  69#include <netinet/in.h>
  70#include <net/if_var.h>
  71#include <netinet/in_var.h>
  72#endif /* !INCLUDE_IPV6_SUPPORT */
  73
  74extern int listen_to_virtual_ips;
  75extern const char *specific_interface;
  76
  77#if defined(SO_TIMESTAMP) && defined(SCM_TIMESTAMP)
  78#if defined(CMSG_FIRSTHDR)
  79#define HAVE_TIMESTAMP
  80#define USE_TIMESTAMP_CMSG
  81#ifndef TIMESTAMP_CTLMSGBUF_SIZE
  82#define TIMESTAMP_CTLMSGBUF_SIZE 1536 /* moderate default */
  83#endif
  84#else
  85/* fill in for old/other timestamp interfaces */
  86#endif
  87#endif
  88
  89#if defined(SYS_WINNT)
  90#include <transmitbuff.h>
  91#include <isc/win32os.h>
  92/*
  93 * Define this macro to control the behavior of connection
  94 * resets on UDP sockets.  See Microsoft KnowledgeBase Article Q263823
  95 * for details.
  96 * NOTE: This requires that Windows 2000 systems install Service Pack 2
  97 * or later.
  98 */
  99#ifndef SIO_UDP_CONNRESET 
 100#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12) 
 101#endif
 102
 103/*
 104 * Windows C runtime ioctl() can't deal properly with sockets, 
 105 * map to ioctlsocket for this source file.
 106 */
 107#define ioctl(fd, opt, val)  ioctlsocket((fd), (opt), (u_long *)(val))
 108#endif  /* SYS_WINNT */
 109
 110/*
 111 * We do asynchronous input using the SIGIO facility.  A number of
 112 * recvbuf buffers are preallocated for input.	In the signal
 113 * handler we poll to see which sockets are ready and read the
 114 * packets from them into the recvbuf's along with a time stamp and
 115 * an indication of the source host and the interface it was received
 116 * through.  This allows us to get as accurate receive time stamps
 117 * as possible independent of other processing going on.
 118 *
 119 * We watch the number of recvbufs available to the signal handler
 120 * and allocate more when this number drops below the low water
 121 * mark.  If the signal handler should run out of buffers in the
 122 * interim it will drop incoming frames, the idea being that it is
 123 * better to drop a packet than to be inaccurate.
 124 */
 125
 126
 127/*
 128 * Other statistics of possible interest
 129 */
 130volatile u_long packets_dropped;	/* total number of packets dropped on reception */
 131volatile u_long packets_ignored;	/* packets received on wild card interface */
 132volatile u_long packets_received;	/* total number of packets received */
 133u_long packets_sent;	/* total number of packets sent */
 134u_long packets_notsent; /* total number of packets which couldn't be sent */
 135
 136volatile u_long handler_calls;	/* number of calls to interrupt handler */
 137volatile u_long handler_pkts;	/* number of pkts received by handler */
 138u_long io_timereset;		/* time counters were reset */
 139
 140/*
 141 * Interface stuff
 142 */
 143struct interface *any_interface;	/* default ipv4 interface */
 144struct interface *any6_interface;	/* default ipv6 interface */
 145struct interface *loopback_interface;	/* loopback ipv4 interface */
 146
 147int ninterfaces;			/* Total number of interfaces */
 148
 149volatile int disable_dynamic_updates;   /* when set to != 0 dynamic updates won't happen */
 150
 151#ifdef REFCLOCK
 152/*
 153 * Refclock stuff.	We keep a chain of structures with data concerning
 154 * the guys we are doing I/O for.
 155 */
 156static	struct refclockio *refio;
 157#endif /* REFCLOCK */
 158
 159
 160/*
 161 * Define what the possible "soft" errors can be.  These are non-fatal returns
 162 * of various network related functions, like recv() and so on.
 163 *
 164 * For some reason, BSDI (and perhaps others) will sometimes return <0
 165 * from recv() but will have errno==0.  This is broken, but we have to
 166 * work around it here.
 167 */
 168#define SOFT_ERROR(e)	((e) == EAGAIN || \
 169			 (e) == EWOULDBLOCK || \
 170			 (e) == EINTR || \
 171			 (e) == 0)
 172
 173/*
 174 * File descriptor masks etc. for call to select
 175 * Not needed for I/O Completion Ports
 176 */
 177fd_set activefds;
 178int maxactivefd;
 179/*
 180 * bit alternating value to detect verified interfaces during an update cycle
 181 */
 182static  u_char          sys_interphase = 0;
 183
 184static  struct interface *new_interface P((struct interface *));
 185static  void add_interface P((struct interface *));
 186static  int update_interfaces P((u_short, interface_receiver_t, void *));
 187static  void remove_interface P((struct interface *));
 188static  struct interface *create_interface P((u_short, struct interface *));
 189
 190static int	move_fd		P((SOCKET));
 191
 192/*
 193 * Multicast functions
 194 */
 195static	isc_boolean_t	addr_ismulticast	 P((struct sockaddr_storage *));
 196/*
 197 * Not all platforms support multicast
 198 */
 199#ifdef MCAST
 200static	isc_boolean_t	socket_multicast_enable	 P((struct interface *, int, struct sockaddr_storage *));
 201static	isc_boolean_t	socket_multicast_disable P((struct interface *, struct sockaddr_storage *));
 202#endif
 203
 204#ifdef DEBUG
 205static void print_interface	P((struct interface *, char *, char *));
 206#define DPRINT_INTERFACE(_LVL_, _ARGS_) do { if (debug >= (_LVL_)) { print_interface _ARGS_; } } while (0)
 207#else
 208#define DPRINT_INTERFACE(_LVL_, _ARGS_) do {} while (0)
 209#endif
 210
 211typedef struct vsock vsock_t;
 212enum desc_type { FD_TYPE_SOCKET, FD_TYPE_FILE };
 213
 214struct vsock {
 215	SOCKET				fd;
 216	enum desc_type                  type;
 217	ISC_LINK(vsock_t)		link;
 218};
 219
 220#if !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET)
 221/*
 222 * async notification processing (e. g. routing sockets)
 223 */
 224/*
 225 * support for receiving data on fd that is not a refclock or a socket
 226 * like e. g. routing sockets
 227 */
 228struct asyncio_reader {
 229	SOCKET fd;		                    /* fd to be read */
 230	void  *data;		                    /* possibly local data */
 231	void (*receiver)(struct asyncio_reader *);  /* input handler */
 232	ISC_LINK(struct asyncio_reader) link;       /* the list this is being kept in */
 233};
 234
 235ISC_LIST(struct asyncio_reader) asyncio_reader_list;
 236
 237static void delete_asyncio_reader P((struct asyncio_reader *));
 238static struct asyncio_reader *new_asyncio_reader P((void));
 239static void add_asyncio_reader P((struct asyncio_reader *, enum desc_type));
 240static void remove_asyncio_reader P((struct asyncio_reader *));
 241
 242#endif /* !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET) */
 243
 244static void init_async_notifications P((void));
 245
 246static	int create_sockets	P((u_short));
 247static	SOCKET	open_socket	P((struct sockaddr_storage *, int, int, struct interface *));
 248static	char *	fdbits		P((int, fd_set *));
 249static	void	set_reuseaddr	P((int));
 250static	isc_boolean_t	socket_broadcast_enable	 P((struct interface *, SOCKET, struct sockaddr_storage *));
 251static	isc_boolean_t	socket_broadcast_disable P((struct interface *, struct sockaddr_storage *));
 252
 253ISC_LIST(vsock_t)	fd_list;
 254
 255typedef struct remaddr remaddr_t;
 256
 257struct remaddr {
 258      struct sockaddr_storage	 addr;
 259      struct interface               *interface;
 260      ISC_LINK(remaddr_t)	 link;
 261};
 262
 263ISC_LIST(remaddr_t)       remoteaddr_list;
 264
 265ISC_LIST(struct interface)     inter_list;
 266
 267static struct interface *wildipv4 = NULL;
 268static struct interface *wildipv6 = NULL;
 269
 270static void	add_fd_to_list	P((SOCKET, enum desc_type));
 271static void	close_and_delete_fd_from_list	P((SOCKET));
 272static void	add_addr_to_list	P((struct sockaddr_storage *, struct interface *));
 273static void	delete_addr_from_list	P((struct sockaddr_storage *));
 274static struct interface *find_addr_in_list	P((struct sockaddr_storage *));
 275static struct interface *find_flagged_addr_in_list P((struct sockaddr_storage *, int));
 276static void	create_wildcards	P((u_short));
 277static isc_boolean_t	address_okay	P((struct interface *));
 278static void		convert_isc_if		P((isc_interface_t *, struct interface *, u_short));
 279static void	delete_interface_from_list	P((struct interface *));
 280static struct interface *getinterface	P((struct sockaddr_storage *, int));
 281static struct interface *findlocalinterface	P((struct sockaddr_storage *, int));
 282static struct interface *findlocalcastinterface	P((struct sockaddr_storage *, int));
 283
 284/*
 285 * Routines to read the ntp packets
 286 */
 287#if !defined(HAVE_IO_COMPLETION_PORT)
 288static inline int     read_network_packet	P((SOCKET, struct interface *, l_fp));
 289static inline int     read_refclock_packet	P((SOCKET, struct refclockio *, l_fp));
 290#endif
 291
 292#ifdef SYS_WINNT
 293/*
 294 * Windows 2000 systems incorrectly cause UDP sockets using WASRecvFrom
 295 * to not work correctly, returning a WSACONNRESET error when a WSASendTo
 296 * fails with an "ICMP port unreachable" response and preventing the
 297 * socket from using the WSARecvFrom in subsequent operations.
 298 * The function below fixes this, but requires that Windows 2000
 299 * Service Pack 2 or later be installed on the system.  NT 4.0
 300 * systems are not affected by this and work correctly.
 301 * See Microsoft Knowledge Base Article Q263823 for details of this.
 302 */
 303void
 304connection_reset_fix(
 305	SOCKET fd,
 306	struct sockaddr_storage *addr
 307	)
 308{
 309	DWORD dwBytesReturned = 0;
 310	BOOL  bNewBehavior = FALSE;
 311	DWORD status;
 312
 313	/*
 314	 * disable bad behavior using IOCTL: SIO_UDP_CONNRESET
 315	 * NT 4.0 has no problem
 316	 */
 317	if (isc_win32os_majorversion() >= 5) {
 318		status = WSAIoctl(fd, SIO_UDP_CONNRESET, &bNewBehavior,
 319				  sizeof(bNewBehavior), NULL, 0,
 320				  &dwBytesReturned, NULL, NULL);
 321		if (SOCKET_ERROR == status)
 322			netsyslog(LOG_ERR, "connection_reset_fix() "
 323					   "failed for address %s: %m", 
 324					   stoa(addr));
 325	}
 326}
 327#endif
 328
 329/*
 330 * on Unix systems the stdio library typically
 331 * makes use of file descriptors in the lower
 332 * integer range. stdio usually will make use
 333 * of the file descriptor in the range of
 334 * [0..FOPEN_MAX)
 335 * in order to keep this range clean for socket
 336 * file descriptors we attempt to move them above
 337 * FOPEM_MAX. This is not as easy as it sounds as
 338 * FOPEN_MAX changes from implementation to implementation
 339 * and may exceed to current file decriptor limits.
 340 * We are using following strategy:
 341 * - keep a current socket fd boundary initialized with
 342 *   max(0, min(getdtablesize() - FD_CHUNK, FOPEN_MAX))
 343 * - attempt to move the descriptor to the boundary or
 344 *   above.
 345 *   - if that fails and boundary > 0 set boundary
 346 *     to min(0, socket_fd_boundary - FD_CHUNK)
 347 *     -> retry
 348 *     if failure and boundary == 0 return old fd
 349 *   - on success close old fd return new fd
 350 *
 351 * effects:
 352 *   - fds will be moved above the socket fd boundary
 353 *     if at all possible.
 354 *   - the socket boundary will be reduced until
 355 *     allocation is possible or 0 is reached - at this
 356 *     point the algrithm will be disabled
 357 */
 358static int move_fd(SOCKET fd)
 359{
 360#if !defined(SYS_WINNT) && defined(F_DUPFD)
 361#ifndef FD_CHUNK
 362#define FD_CHUNK	10
 363#endif
 364/*
 365 * number of fds we would like to have for
 366 * stdio FILE* available.
 367 * we can pick a "low" number as our use of
 368 * FILE* is limited to log files and temporarily
 369 * to data and config files. Except for log files
 370 * we don't keep the other FILE* open beyond the
 371 * scope of the function that opened it.
 372 */
 373#ifndef FD_PREFERRED_SOCKBOUNDARY
 374#define FD_PREFERRED_SOCKBOUNDARY 48
 375#endif
 376
 377#ifndef HAVE_GETDTABLESIZE
 378/*
 379 * if we have no idea about the max fd value set up things
 380 * so we will start at FOPEN_MAX
 381 */
 382#define getdtablesize() (FOPEN_MAX+FD_CHUNK)
 383#endif
 384
 385#ifndef FOPEN_MAX
 386#define FOPEN_MAX	20	/* assume that for the lack of anything better */
 387#endif
 388	static SOCKET socket_boundary = -1;
 389	SOCKET newfd;
 390
 391	/*
 392	 * check whether boundary has be set up
 393	 * already
 394	 */
 395	if (socket_boundary == -1) {
 396		socket_boundary = max(0, min(getdtablesize() - FD_CHUNK, 
 397					     min(FOPEN_MAX, FD_PREFERRED_SOCKBOUNDARY)));
 398#ifdef DEBUG
 399		msyslog(LOG_DEBUG, "ntp_io: estimated max descriptors: %d, initial socket boundary: %d",
 400			getdtablesize(), socket_boundary);
 401#endif
 402	}
 403
 404	/*
 405	 * Leave a space for stdio to work in. potentially moving the
 406	 * socket_boundary lower until allocation succeeds.
 407	 */
 408	do {
 409		if (fd >= 0 && fd < socket_boundary) {
 410			/* inside reserved range: attempt to move fd */
 411			newfd = fcntl(fd, F_DUPFD, socket_boundary);
 412			
 413			if (newfd != -1) {
 414				/* success: drop the old one - return the new one */
 415				(void)close(fd);
 416				return (newfd);
 417			}
 418		} else {
 419			/* outside reserved range: no work - return the original one */
 420			return (fd);
 421		}
 422		socket_boundary = max(0, socket_boundary - FD_CHUNK);
 423#ifdef DEBUG
 424		msyslog(LOG_DEBUG, "ntp_io: selecting new socket boundary: %d",
 425			socket_boundary);
 426#endif
 427	} while (socket_boundary > 0);
 428#endif /* !defined(SYS_WINNT) && defined(F_DUPFD) */
 429	return (fd);
 430}
 431
 432#ifdef DEBUG_TIMING
 433/*
 434 * collect timing information for various processing
 435 * paths. currently we only pass then on to the file
 436 * for later processing. this could also do histogram
 437 * based analysis in other to reduce the load (and skew)
 438 * dur to the file output
 439 */
 440void
 441collect_timing(struct recvbuf *rb, const char *tag, int count, l_fp *dts)
 442{
 443	char buf[2048];
 444
 445	snprintf(buf, sizeof(buf), "%s %d %s %s", 
 446		 (rb != NULL) ? 
 447		 ((rb->dstadr) ? stoa(&rb->recv_srcadr) : "-REFCLOCK-") : "-",
 448		 count, lfptoa(dts, 9), tag);
 449	record_timing_stats(buf);
 450}
 451#endif
 452  
 453/*
 454 * About dynamic interfaces, sockets, reception and more...
 455 *
 456 * the code solves following tasks:
 457 *
 458 *   - keep a current list of active interfaces in order
 459 *     to bind to to the interface address on NTP_PORT so that
 460 *     all wild and specific bindings for NTP_PORT are taken by ntpd
 461 *     to avoid other daemons messing with the time or sockets.
 462 *   - all interfaces keep a list of peers that are referencing 
 463 *     the interface in order to quickly re-assign the peers to
 464 *     new interface in case an interface is deleted (=> gone from system or
 465 *     down)
 466 *   - have a preconfigured socket ready with the right local address
 467 *     for transmission and reception
 468 *   - have an address list for all destination addresses used within ntpd
 469 *     to find the "right" preconfigured socket.
 470 *   - facilitate updating the internal interface list with respect to
 471 *     the current kernel state
 472 *
 473 * special issues:
 474 *
 475 *   - mapping of multicast addresses to the interface affected is not always
 476 *     one to one - especially on hosts with multiple interfaces
 477 *     the code here currently allocates a separate interface entry for those
 478 *     multicast addresses
 479 *     iff it is able to bind to a *new* socket with the multicast address (flags |= MCASTIF)
 480 *     in case of failure the multicast address is bound to an existing interface.
 481 *   - on some systems it is perfectly legal to assign the same address to
 482 *     multiple interfaces. Therefore this code does not keep a list of interfaces
 483 *     but a list of interfaces that represent a unique address as determined by the kernel
 484 *     by the procedure in findlocalinterface. Thus it is perfectly legal to see only
 485 *     one representative of a group of real interfaces if they share the same address.
 486 * 
 487 * Frank Kardel 20050910
 488 */
 489
 490/*
 491 * init_io - initialize I/O data structures and call socket creation routine
 492 */
 493void
 494init_io(void)
 495{
 496#ifdef SYS_WINNT
 497	init_io_completion_port();
 498
 499	if (!Win32InitSockets())
 500	{
 501		netsyslog(LOG_ERR, "No useable winsock.dll: %m");
 502		exit(1);
 503	}
 504	init_transmitbuff();
 505#endif /* SYS_WINNT */
 506
 507	/*
 508	 * Init buffer free list and stat counters
 509	 */
 510	init_recvbuff(RECV_INIT);
 511
 512	packets_dropped = packets_received = 0;
 513	packets_ignored = 0;
 514	packets_sent = packets_notsent = 0;
 515	handler_calls = handler_pkts = 0;
 516	io_timereset = 0;
 517	loopback_interface = NULL;
 518	any_interface = NULL;
 519	any6_interface = NULL;
 520
 521#ifdef REFCLOCK
 522	refio = NULL;
 523#endif
 524
 525#if defined(HAVE_SIGNALED_IO)
 526	(void) set_signal();
 527#endif
 528
 529	ISC_LIST_INIT(fd_list);
 530
 531#if !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET)
 532	ISC_LIST_INIT(asyncio_reader_list);
 533#endif
 534
 535        ISC_LIST_INIT(remoteaddr_list);
 536
 537	ISC_LIST_INIT(inter_list);
 538
 539	/*
 540	 * Create the sockets
 541	 */
 542	BLOCKIO();
 543	(void) create_sockets(htons(NTP_PORT));
 544	UNBLOCKIO();
 545
 546	init_async_notifications();
 547
 548	DPRINTF(3, ("init_io: maxactivefd %d\n", maxactivefd));
 549}
 550
 551#ifdef DEBUG
 552/*
 553 * function to dump the contents of the interface structure
 554 * for debugging use only.
 555 */
 556void
 557interface_dump(struct interface *itf)
 558{
 559	u_char* cp;
 560	int i;
 561	/* Limit the size of the sockaddr_storage hex dump */
 562	int maxsize = min(32, sizeof(struct sockaddr_storage));
 563
 564	printf("Dumping interface: %p\n", itf);
 565	printf("fd = %d\n", itf->fd);
 566	printf("bfd = %d\n", itf->bfd);
 567	printf("sin = %s,\n", stoa(&(itf->sin)));
 568	cp = (u_char*) &(itf->sin);
 569	for(i = 0; i < maxsize; i++)
 570	{
 571		printf("%02x", *cp++);
 572		if((i+1)%4 == 0)
 573			printf(" ");
 574	}
 575	printf("\n");
 576	printf("bcast = %s,\n", stoa(&(itf->bcast)));
 577	cp = (u_char*) &(itf->bcast);
 578	for(i = 0; i < maxsize; i++)
 579	{
 580		printf("%02x", *cp++);
 581		if((i+1)%4 == 0)
 582			printf(" ");
 583	}
 584	printf("\n");
 585	printf("mask = %s,\n", stoa(&(itf->mask)));
 586	cp = (u_char*) &(itf->mask);
 587	for(i = 0; i < maxsize; i++)
 588	{
 589		printf("%02x", *cp++);
 590		if((i+1)%4 == 0)
 591			printf(" ");
 592	}
 593	printf("\n");
 594	printf("name = %s\n", itf->name);
 595	printf("flags = 0x%08x\n", itf->flags);
 596	printf("last_ttl = %d\n", itf->last_ttl);
 597	printf("addr_refid = %08x\n", itf->addr_refid);
 598	printf("num_mcast = %d\n", itf->num_mcast);
 599	printf("received = %ld\n", itf->received);
 600	printf("sent = %ld\n", itf->sent);
 601	printf("notsent = %ld\n", itf->notsent);
 602	printf("ifindex = %u\n", itf->ifindex);
 603	printf("scopeid = %u\n", itf->scopeid);
 604	printf("peercnt = %u\n", itf->peercnt);
 605	printf("phase = %u\n", itf->phase);
 606}
 607
 608/*
 609 * print_interface - helper to output debug information
 610 */
 611static void
 612print_interface(struct interface *iface, char *pfx, char *sfx)
 613{
 614	printf("%sinterface #%d: fd=%d, bfd=%d, name=%s, flags=0x%x, scope=%d, ifindex=%d",
 615	       pfx,
 616	       iface->ifnum,
 617	       iface->fd,
 618	       iface->bfd,
 619	       iface->name,
 620	       iface->flags,
 621	       iface->scopeid,
 622	       iface->ifindex);
 623	/* Leave these as three printf calls. */
 624	printf(", sin=%s",
 625	       stoa((&iface->sin)));
 626	if (iface->flags & INT_BROADCAST)
 627		printf(", bcast=%s,",
 628		       stoa((&iface->bcast)));
 629	if (iface->family == AF_INET)
 630	  printf(", mask=%s",
 631		 stoa((&iface->mask)));
 632	printf(", %s:%s", iface->ignore_packets == ISC_FALSE ? "Enabled" : "Disabled", sfx);
 633	if (debug > 4)	/* in-depth debugging only */
 634		interface_dump(iface);
 635}
 636
 637#endif
 638
 639#if !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET)
 640/*
 641 * create an asyncio_reader structure
 642 */
 643static struct asyncio_reader *
 644new_asyncio_reader()
 645{
 646	struct asyncio_reader *reader;
 647
 648	reader = (struct asyncio_reader *)emalloc(sizeof(struct asyncio_reader));
 649
 650	memset((char *)reader, 0, sizeof(*reader));
 651	ISC_LINK_INIT(reader, link);
 652	reader->fd = INVALID_SOCKET;
 653	return reader;
 654}
 655
 656/*
 657 * delete a reader
 658 */
 659static void
 660delete_asyncio_reader(struct asyncio_reader *reader)
 661{
 662	free(reader);
 663}
 664
 665/*
 666 * add asynchio_reader
 667 */
 668static void
 669add_asyncio_reader(struct asyncio_reader *reader, enum desc_type type)
 670{
 671	ISC_LIST_APPEND(asyncio_reader_list, reader, link);
 672	add_fd_to_list(reader->fd, type);
 673}
 674	
 675/*
 676 * remove asynchio_reader
 677 */
 678static void
 679remove_asyncio_reader(struct asyncio_reader *reader)
 680{
 681	ISC_LIST_UNLINK_TYPE(asyncio_reader_list, reader, link, struct asyncio_reader);
 682
 683	if (reader->fd != INVALID_SOCKET)
 684		close_and_delete_fd_from_list(reader->fd);
 685
 686	reader->fd = INVALID_SOCKET;
 687}
 688#endif /* !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET) */
 689
 690/*
 691 * interface list enumerator - visitor pattern
 692 */
 693void
 694interface_enumerate(interface_receiver_t receiver, void *data)
 695{
 696	interface_info_t ifi;
 697        struct interface *interf;
 698
 699	ifi.action = IFS_EXISTS;
 700	
 701	for (interf = ISC_LIST_HEAD(inter_list);
 702	     interf != NULL;
 703	     interf = ISC_LIST_NEXT(interf, link)) {
 704		ifi.interface = interf;
 705		receiver(data, &ifi);
 706	}
 707}
 708
 709/*
 710 * do standard initialization of interface structure
 711 */
 712static void
 713init_interface(struct interface *interface)
 714{
 715	memset((char *)interface, 0, sizeof(struct interface));
 716	ISC_LINK_INIT(interface, link);
 717	ISC_LIST_INIT(interface->peers);
 718	interface->fd = INVALID_SOCKET;
 719	interface->bfd = INVALID_SOCKET;
 720	interface->num_mcast = 0;
 721	interface->received = 0;
 722	interface->sent = 0;
 723	interface->notsent = 0;
 724	interface->peercnt = 0;
 725	interface->phase = sys_interphase;
 726}
 727
 728/*
 729 * create new interface structure initialize from
 730 * template structure or via standard initialization
 731 * function
 732 */
 733static struct interface *
 734new_interface(struct interface *interface)
 735{
 736	static u_int sys_ifnum = 0;
 737
 738	struct interface *iface = (struct interface *)emalloc(sizeof(struct interface));
 739
 740	if (interface != NULL)
 741	{
 742		memcpy((char*)iface, (char*)interface, sizeof(*interface));
 743	}
 744	else
 745	{
 746		init_interface(iface);
 747	}
 748
 749	iface->ifnum = sys_ifnum++;  /* count every new instance of an interface in the system */
 750	iface->starttime = current_time;
 751
 752	return iface;
 753}
 754
 755/*
 756 * return interface storage into free memory pool
 757 */
 758static void
 759delete_interface(struct interface *interface)
 760{
 761	free(interface);
 762}
 763
 764/*
 765 * link interface into list of known interfaces
 766 */
 767static void
 768add_interface(struct interface *interface)
 769{
 770	static struct interface *listhead = NULL;
 771
 772	/*
 773	 * For ntpd, the first few interfaces (wildcard, localhost)
 774	 * will never be removed.  This means inter_list.head is
 775	 * unchanging once initialized.  Take advantage of that to
 776	 * watch for changes and catch corruption earlier.  This
 777	 * helped track down corruption caused by using FD_SET with
 778	 * a descriptor numerically larger than FD_SETSIZE.
 779	 */
 780	if (NULL == listhead)
 781		listhead = inter_list.head;
 782
 783	if (listhead != inter_list.head) {
 784		msyslog(LOG_ERR, "add_interface inter_list.head corrupted: was %p now %p",
 785			listhead, inter_list.head);
 786		exit(1);
 787	}
 788	/*
 789	 * Calculate the address hash
 790	 */
 791	interface->addr_refid = addr2refid(&interface->sin);
 792	
 793	ISC_LIST_APPEND(inter_list, interface, link);
 794	ninterfaces++;
 795}
 796
 797/*
 798 * remove interface from known interface list and clean up
 799 * associated resources
 800 */
 801static void
 802remove_interface(struct interface *interface)
 803{
 804	struct sockaddr_storage resmask;
 805
 806	ISC_LIST_UNLINK_TYPE(inter_list, interface, link, struct interface);
 807
 808	delete_interface_from_list(interface);
 809  
 810	if (interface->fd != INVALID_SOCKET) 
 811	{
 812		msyslog(LOG_INFO, "Deleting interface #%d %s, %s#%d, interface stats: received=%ld, sent=%ld, dropped=%ld, active_time=%ld secs",
 813			interface->ifnum,
 814			interface->name,
 815			stoa((&interface->sin)),
 816			NTP_PORT,  /* XXX should extract port from sin structure */
 817			interface->received,
 818			interface->sent,
 819			interface->notsent,
 820			current_time - interface->starttime);
 821
 822		close_and_delete_fd_from_list(interface->fd);
 823	}
 824  
 825	if (interface->bfd != INVALID_SOCKET) 
 826	{
 827		msyslog(LOG_INFO, "Deleting interface #%d %s, broadcast address %s#%d",
 828			interface->ifnum,
 829			interface->name,
 830			stoa((&interface->bcast)),
 831			(u_short) NTP_PORT);  /* XXX extract port from sin structure */
 832		close_and_delete_fd_from_list(interface->bfd);
 833	}
 834
 835	ninterfaces--;
 836	ntp_monclearinterface(interface);
 837
 838	/* remove restrict interface entry */
 839
 840	/*
 841	 * Blacklist bound interface address
 842	 */
 843	SET_HOSTMASK(&resmask, interface->sin.ss_family);
 844	hack_restrict(RESTRICT_REMOVEIF, &interface->sin, &resmask,
 845		      RESM_NTPONLY|RESM_INTERFACE, RES_IGNORE);
 846}
 847
 848static void
 849list_if_listening(struct interface *interface, u_short port)
 850{
 851	msyslog(LOG_INFO, "Listening on interface #%d %s, %s#%d %s",
 852		interface->ifnum,
 853		interface->name,
 854		stoa((&interface->sin)),
 855		ntohs( (u_short) port),
 856		(interface->ignore_packets == ISC_FALSE) ?
 857		"Enabled": "Disabled");
 858}
 859
 860static void
 861create_wildcards(u_short port) {
 862	isc_boolean_t okipv4 = ISC_TRUE;
 863	/*
 864	 * create pseudo-interface with wildcard IPv4 address
 865	 */
 866#ifdef IPV6_V6ONLY
 867	if(isc_net_probeipv4() != ISC_R_SUCCESS)
 868		okipv4 = ISC_FALSE;
 869#endif
 870
 871	if(okipv4 == ISC_TRUE) {
 872	        struct interface *interface = new_interface(NULL);
 873
 874		interface->family = AF_INET;
 875		interface->sin.ss_family = AF_INET;
 876		((struct sockaddr_in*)&interface->sin)->sin_addr.s_addr = htonl(INADDR_ANY);
 877		((struct sockaddr_in*)&interface->sin)->sin_port = port;
 878		(void) strncpy(interface->name, "wildcard", sizeof(interface->name));
 879		interface->mask.ss_family = AF_INET;
 880		((struct sockaddr_in*)&interface->mask)->sin_addr.s_addr = htonl(~(u_int32)0);
 881		interface->flags = INT_BROADCAST | INT_UP | INT_WILDCARD;
 882		interface->ignore_packets = ISC_TRUE;
 883#if defined(MCAST)
 884		/*
 885		 * enable possible multicast reception on the broadcast socket
 886		 */
 887		interface->bcast.ss_family = AF_INET;
 888		((struct sockaddr_in*)&interface->bcast)->sin_port = port;
 889		((struct sockaddr_in*)&interface->bcast)->sin_addr.s_addr = htonl(INADDR_ANY);
 890#endif /* MCAST */
 891		interface->fd = open_socket(&interface->sin,
 892				 interface->flags, 1, interface);
 893
 894		if (interface->fd != INVALID_SOCKET) {
 895			wildipv4 = interface;
 896			any_interface = interface;
 897			
 898			add_addr_to_list(&interface->sin, interface);
 899			add_interface(interface);
 900			list_if_listening(interface, port);
 901		} else {
 902			msyslog(LOG_ERR, "unable to bind to wildcard socket address %s - another process may be running - EXITING",
 903				stoa((&interface->sin)));
 904			exit(1);
 905		}
 906	}
 907
 908#ifdef INCLUDE_IPV6_SUPPORT
 909	/*
 910	 * create pseudo-interface with wildcard IPv6 address
 911	 */
 912	if (isc_net_probeipv6() == ISC_R_SUCCESS) {
 913	        struct interface *interface = new_interface(NULL);
 914
 915		interface->family = AF_INET6;
 916		interface->sin.ss_family = AF_INET6;
 917		((struct sockaddr_in6*)&interface->sin)->sin6_addr = in6addr_any;
 918 		((struct sockaddr_in6*)&interface->sin)->sin6_port = port;
 919# ifdef ISC_PLATFORM_HAVESCOPEID
 920 		((struct sockaddr_in6*)&interface->sin)->sin6_scope_id = 0;
 921# endif
 922		(void) strncpy(interface->name, "wildcard", sizeof(interface->name));
 923		interface->mask.ss_family = AF_INET6;
 924		memset(&((struct sockaddr_in6*)&interface->mask)->sin6_addr.s6_addr, 0xff, sizeof(struct in6_addr));
 925		interface->flags = INT_UP | INT_WILDCARD;
 926		interface->ignore_packets = ISC_TRUE;
 927
 928		interface->fd = open_socket(&interface->sin,
 929				 interface->flags, 1, interface);
 930
 931		if (interface->fd != INVALID_SOCKET) {
 932			wildipv6 = interface;
 933			any6_interface = interface;
 934			add_addr_to_list(&interface->sin, interface);
 935			add_interface(interface);
 936			list_if_listening(interface, port);
 937		} else {
 938			msyslog(LOG_ERR, "unable to bind to wildcard socket address %s - another process may be running - EXITING",
 939				stoa((&interface->sin)));
 940			exit(1);
 941		}
 942	}
 943#endif
 944}
 945
 946
 947static isc_boolean_t
 948address_okay(struct interface *iface) {
 949
 950	DPRINTF(4, ("address_okay: listen Virtual: %d, IF name: %s\n", 
 951		    listen_to_virtual_ips, iface->name));
 952
 953	/*
 954	 * Always allow the loopback
 955	 */
 956	if((iface->flags & INT_LOOPBACK) != 0) {
 957		DPRINTF(4, ("address_okay: loopback - OK\n"));
 958		return (ISC_TRUE);
 959	}
 960
 961	/*
 962	 * Check if the interface is specified
 963	 */
 964	if (specific_interface != NULL) {
 965		if (strcasecmp(iface->name, specific_interface) == 0) {
 966			DPRINTF(4, ("address_okay: specific interface name matched - OK\n"));
 967			return (ISC_TRUE);
 968		} else {
 969			DPRINTF(4, ("address_okay: specific interface name NOT matched - FAIL\n"));
 970			return (ISC_FALSE);
 971		}
 972	}
 973	else {
 974		if (listen_to_virtual_ips == 0  && 
 975		    (strchr(iface->name, (int)':') != NULL)) {
 976			DPRINTF(4, ("address_okay: virtual ip/alias - FAIL\n"));
 977			return (ISC_FALSE);
 978		}
 979	}
 980
 981	DPRINTF(4, ("address_okay: OK\n"));
 982	return (ISC_TRUE);
 983}
 984
 985static void
 986convert_isc_if(isc_interface_t *isc_if, struct interface *itf, u_short port)
 987{
 988	itf->scopeid = 0;
 989	itf->family = (short) isc_if->af;
 990	strcpy(itf->name, isc_if->name);
 991
 992	if(isc_if->af == AF_INET) {
 993		itf->sin.ss_family = (u_short) isc_if->af;
 994		memcpy(&(((struct sockaddr_in*)&itf->sin)->sin_addr),
 995		       &(isc_if->address.type.in),
 996		       sizeof(struct in_addr));
 997		((struct sockaddr_in*)&itf->sin)->sin_port = port;
 998
 999		if((isc_if->flags & INTERFACE_F_BROADCAST) != 0) {
1000			itf->flags |= INT_BROADCAST;
1001			itf->bcast.ss_family = itf->sin.ss_family;
1002			memcpy(&(((struct sockaddr_in*)&itf->bcast)->sin_addr),
1003			       &(isc_if->broadcast.type.in),
1004				 sizeof(struct in_addr));
1005			((struct sockaddr_in*)&itf->bcast)->sin_port = port;
1006		}
1007
1008		itf->mask.ss_family = itf->sin.ss_family;
1009		memcpy(&(((struct sockaddr_in*)&itf->mask)->sin_addr),
1010		       &(isc_if->netmask.type.in),
1011		       sizeof(struct in_addr));
1012		((struct sockaddr_in*)&itf->mask)->sin_port = port;
1013	}
1014#ifdef INCLUDE_IPV6_SUPPORT
1015	else if (isc_if->af == AF_INET6) {
1016		itf->sin.ss_family = (u_short) isc_if->af;
1017		memcpy(&(((struct sockaddr_in6 *)&itf->sin)->sin6_addr),
1018		       &(isc_if->address.type.in6),
1019		       sizeof(((struct sockaddr_in6 *)&itf->sin)->sin6_addr));
1020		((struct sockaddr_in6 *)&itf->sin)->sin6_port = port;
1021
1022#ifdef ISC_PLATFORM_HAVESCOPEID
1023		((struct sockaddr_in6 *)&itf->sin)->sin6_scope_id = isc_netaddr_getzone(&isc_if->address);
1024		itf->scopeid = isc_netaddr_getzone(&isc_if->address);
1025#endif
1026		itf->mask.ss_family = itf->sin.ss_family;
1027		memcpy(&(((struct sockaddr_in6 *)&itf->mask)->sin6_addr),
1028		       &(isc_if->netmask.type.in6),
1029		       sizeof(struct in6_addr));
1030		((struct sockaddr_in6 *)&itf->mask)->sin6_port = port;
1031		/* Copy the interface index */
1032		itf->ifindex = isc_if->ifindex;
1033	}
1034#endif /* INCLUDE_IPV6_SUPPORT */
1035
1036
1037	/* Process the rest of the flags */
1038
1039	if((isc_if->flags & INTERFACE_F_UP) != 0)
1040		itf->flags |= INT_UP;
1041	if((isc_if->flags & INTERFACE_F_LOOPBACK) != 0)
1042		itf->flags |= INT_LOOPBACK;
1043	if((isc_if->flags & INTERFACE_F_POINTTOPOINT) != 0)
1044		itf->flags |= INT_PPP;
1045	if((isc_if->flags & INTERFACE_F_MULTICAST) != 0)
1046		itf->flags |= INT_MULTICAST;
1047
1048}
1049
1050/*
1051 * refresh_interface
1052 *
1053 * some OSes have been observed to keep
1054 * cached routes even when more specific routes
1055 * become available.
1056 * this can be mitigated by re-binding
1057 * the socket.
1058 */
1059static int
1060refresh_interface(struct interface * interface)
1061{
1062#ifdef  OS_MISSES_SPECIFIC_ROUTE_UPDATES
1063	if (interface->fd != INVALID_SOCKET)
1064	{
1065		close_and_delete_fd_from_list(interface->fd);
1066		interface->fd = open_socket(&interface->sin,
1067					    interface->flags, 0, interface);
1068		 /*
1069		  * reset TTL indication so TTL is is set again 
1070		  * next time around
1071		  */
1072		interface->last_ttl = 0;
1073		return interface->fd != INVALID_SOCKET;
1074	}
1075	else
1076	{
1077		return 0;	/* invalid sockets are not refreshable */
1078	}
1079#else /* !OS_MISSES_SPECIFIC_ROUTE_UPDATES */
1080	return interface->fd != INVALID_SOCKET;
1081#endif /* !OS_MISSES_SPECIFIC_ROUTE_UPDATES */
1082}
1083
1084/*
1085 * interface_update - externally callable update function
1086 */
1087void
1088interface_update(interface_receiver_t receiver, void *data)
1089{
1090	if (!disable_dynamic_updates) {
1091		int new_interface_found;
1092
1093		BLOCKIO();
1094		new_interface_found = update_interfaces(htons(NTP_PORT), receiver, data);
1095		UNBLOCKIO();
1096
1097		if (new_interface_found) {
1098#ifdef DEBUG
1099			msyslog(LOG_DEBUG, "new interface(s) found: waking up resolver");
1100#endif
1101#ifdef SYS_WINNT
1102			/* wake up the resolver thread */
1103			if (ResolverEventHandle != NULL)
1104				SetEvent(ResolverEventHandle);
1105#else
1106			/* write any single byte to the pipe to wake up the resolver process */
1107			write( resolver_pipe_fd[1], &new_interface_found, 1 );
1108#endif
1109		}
1110	}
1111}
1112
1113/*
1114 * find out if a given interface structure contains
1115 * a wildcard address
1116 */
1117static int
1118is_wildcard_addr(struct sockaddr_storage *sas)
1119{
1120	if (sas->ss_family == AF_INET &&
1121	    ((struct sockaddr_in*)sas)->sin_addr.s_addr == htonl(INADDR_ANY))
1122		return 1;
1123
1124#ifdef INCLUDE_IPV6_SUPPORT
1125	if (sas->ss_family == AF_INET6 &&
1126	    memcmp(&((struct sockaddr_in6*)sas)->sin6_addr, &in6addr_any,
1127		   sizeof(in6addr_any) == 0))
1128		return 1;
1129#endif
1130
1131	return 0;
1132}
1133
1134#ifdef OS_NEEDS_REUSEADDR_FOR_IFADDRBIND
1135/*
1136 * enable/disable re-use of wildcard address socket
1137 */
1138static void
1139set_wildcard_reuse(int family, int on)
1140{
1141	int onvalue = 1;
1142	int offvalue = 0;
1143	int *onoff;
1144	SOCKET fd = INVALID_SOCKET;
1145
1146	onoff = on ? &onvalue : &offvalue;
1147
1148	switch (family) {
1149	case AF_INET:
1150		if (any_interface) {
1151			fd = any_interface->fd;
1152		}
1153		break;
1154
1155#ifdef INCLUDE_IPV6_SUPPORT
1156	case AF_INET6:
1157		if (any6_interface) {
1158			fd = any6_interface->fd;
1159		}
1160		break;
1161#endif /* !INCLUDE_IPV6_SUPPORT */
1162	}
1163
1164	if (fd != INVALID_SOCKET) {
1165		if (setsockopt(fd, SOL_SOCKET,
1166			       SO_REUSEADDR, (char *)onoff,
1167			       sizeof(*onoff))) {
1168			netsyslog(LOG_ERR, "set_wildcard_reuse: setsockopt(SO_REUSEADDR, %s) failed: %m", *onoff ? "on" : "off");
1169		}
1170		DPRINTF(4, ("set SO_REUSEADDR to %s on %s\n", *onoff ? "ON" : "OFF",
1171			    stoa((family == AF_INET) ?
1172				  &any_interface->sin : &any6_interface->sin)));
1173	}
1174}
1175#endif /* OS_NEEDS_REUSEADDR_FOR_IFADDRBIND */
1176
1177#ifdef INCLUDE_IPV6_SUPPORT
1178static isc_boolean_t
1179is_anycast(struct sockaddr *sa, char *name)
1180{
1181#if defined(SIOCGIFAFLAG_IN6) && defined(IN6_IFF_ANYCAST)
1182	struct in6_ifreq ifr6;
1183	int fd;
1184	u_int32_t flags6;
1185
1186	if (sa->sa_family != AF_INET6)
1187		return ISC_FALSE;
1188	if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
1189		return ISC_FALSE;
1190	memset(&ifr6, 0, sizeof(ifr6));
1191	memcpy(&ifr6.ifr_addr, (struct sockaddr_in6 *)sa,
1192	    sizeof(struct sockaddr_in6));
1193	strlcpy(ifr6.ifr_name, name, IF_NAMESIZE);
1194	if (ioctl(fd, SIOCGIFAFLAG_IN6, &ifr6) < 0) {
1195		close(fd);
1196		return ISC_FALSE;
1197	}
1198	close(fd);
1199	flags6 = ifr6.ifr_ifru.ifru_flags6;
1200	if ((flags6 & IN6_IFF_ANYCAST) != 0)
1201		return ISC_TRUE;
1202#endif /* !SIOCGIFAFLAG_IN6 || !IN6_IFF_ANYCAST */
1203	return ISC_FALSE;
1204}
1205#endif /* !INCLUDE_IPV6_SUPPORT */
1206
1207/*
1208 * update_interface strategy
1209 *
1210 * toggle configuration phase
1211 *
1212 * Phase 1:
1213 * forall currently existing interfaces
1214 *   if address is known:
1215 *       drop socket - rebind again
1216 *
1217 *   if address is NOT known:
1218 *     attempt to create a new interface entry
1219 *
1220 * Phase 2:
1221 * forall currently known non MCAST and WILDCARD interfaces
1222 *   if interface does not match configuration phase (not seen in phase 1):
1223 *     remove interface from known interface list
1224 *     forall peers associated with this interface
1225 *       disconnect peer from this interface
1226 *
1227 * Phase 3:
1228 *   attempt to re-assign interfaces to peers
1229 *
1230 */
1231
1232static int
1233update_interfaces(
1234	u_short port,
1235	interface_receiver_t receiver,
1236	void *data
1237	)
1238{
1239	interface_info_t ifi;
1240	isc_mem_t *mctx = NULL;
1241	isc_interfaceiter_t *iter = NULL;
1242	isc_boolean_t scan_ipv4 = ISC_FALSE;
1243	isc_boolean_t scan_ipv6 = ISC_FALSE;
1244	isc_result_t result;
1245	int new_interface_found = 0;
1246
1247	DPRINTF(3, ("update_interfaces(%d)\n", ntohs( (u_short) port)));
1248
1249#ifdef INCLUDE_IPV6_SUPPORT
1250	if (isc_net_probeipv6() == ISC_R_SUCCESS)
1251		scan_ipv6 = ISC_TRUE;
1252#if defined(DEBUG)
1253	else
1254		if (debug)
1255			netsyslog(LOG_ERR, "no IPv6 interfaces found");
1256#endif
1257#endif
1258	if (isc_net_probeipv6() == ISC_R_SUCCESS)
1259		scan_ipv6 = ISC_TRUE;
1260#if defined(ISC_PLATFORM_HAVEIPV6) && defined(DEBUG)
1261	else
1262		if (debug)
1263			netsyslog(LOG_ERR, "no IPv6 interfaces found");
1264#endif
1265
1266	if (isc_net_probeipv4() == ISC_R_SUCCESS)
1267		scan_ipv4 = ISC_TRUE;
1268#ifdef DEBUG
1269	else
1270		if(debug)
1271			netsyslog(LOG_ERR, "no IPv4 interfaces found");
1272#endif
1273	/*
1274	 * phase one - scan interfaces
1275	 * - create those that are not found
1276	 * - update those that are found
1277	 */
1278
1279	result = isc_interfaceiter_create(mctx, &iter);
1280
1281	if (result != ISC_R_SUCCESS)
1282		return 0;
1283
1284	sys_interphase ^= 0x1;	/* toggle system phase for finding untouched (to be deleted) interfaces */
1285	
1286	for (result = isc_interfaceiter_first(iter);
1287	     result == ISC_R_SUCCESS;
1288	     result = isc_interfaceiter_next(iter))
1289	{
1290		isc_interface_t isc_if;
1291		unsigned int family;
1292		struct interface interface;
1293		struct interface *iface;
1294		
1295		result = isc_interfaceiter_current(iter, &isc_if);
1296
1297		if (result != ISC_R_SUCCESS)
1298			break;
1299
1300		/* See if we have a valid family to use */
1301		family = isc_if.address.family;
1302		if (family != AF_INET && family != AF_INET6)
1303			continue;
1304		if (scan_ipv4 == ISC_FALSE && family == AF_INET)
1305			continue;
1306		if (scan_ipv6 == ISC_FALSE && family == AF_INET6)
1307			continue;
1308
1309		/*
1310		 * create prototype
1311		 */
1312		init_interface(&interface);
1313
1314		convert_isc_if(&isc_if, &interface, port);
1315
1316		/* 
1317		 * Check to see if we are going to use the interface
1318		 * If we don't use it we mark it to drop any packet
1319		 * received but we still must create the socket and
1320		 * bind to it. This prevents other apps binding to it
1321		 * and potentially causing problems with more than one
1322		 * process fiddling with the clock
1323		 */
1324		if (address_okay(&interface) == ISC_TRUE) {
1325			interface.ignore_packets = ISC_FALSE;
1326		}
1327		else {
1328			interface.ignore_packets = ISC_TRUE;
1329		}
1330
1331		DPRINT_INTERFACE(4, (&interface, "examining ", "\n"));
1332
1333		if (!(interface.flags & INT_UP))  { /* interfaces must be UP to be usable */
1334			DPRINTF(4, ("skipping interface %s (%s) - DOWN\n", interface.name, stoa(&interface.sin)));
1335			continue;
1336		}
1337
1338		/*
1339		 * skip any interfaces UP and bound to a wildcard
1340		 * address - some dhcp clients produce that in the
1341		 * wild
1342		 */
1343		if (is_wildcard_addr(&interface.sin))
1344			continue;
1345
1346#ifdef INCLUDE_IPV6_SUPPORT
1347		if (is_anycast((struct sockaddr *)&interface.sin, isc_if.name))
1348			continue;
1349#endif /* !INCLUDE_IPV6_SUPPORT */
1350
1351		/*
1352		 * map to local *address* in order
1353		 * to map all duplicate interfaces to an interface structure
1354		 * with the appropriate socket (our name space is
1355		 * (ip-address) - NOT (interface name, ip-address))
1356		 */
1357		iface = getinterface(&interface.sin, INT_WILDCARD);
1358		
1359		if (iface && refresh_interface(iface)) 
1360		{
1361			/*
1362			 * found existing and up to date interface - mark present
1363			 */
1364
1365			iface->phase = sys_interphase;
1366			DPRINT_INTERFACE(4, (iface, "updating ", " present\n"));
1367			ifi.action = IFS_EXISTS;
1368			ifi.interface = iface;
1369			if (receiver)
1370				receiver(data, &ifi);
1371		}
1372		else
1373		{
1374			/*
1375			 * this is new or refreshing failed - add to our interface list
1376			 * if refreshing failed we will delete the interface structure in
1377			 * phase 2 as the interface was not marked current. We can bind to
1378			 * the address as the refresh code already closed the offending socket
1379			 */
1380			
1381			iface = create_interface(port, &interface);
1382
1383			if (iface)
1384			{
1385				ifi.action = IFS_CREATED;
1386				ifi.interface = iface;
1387				if (receiver)
1388					receiver(data, &ifi);
1389
1390				new_interface_found = 1;
1391
1392				DPRINT_INTERFACE(3, (iface, "updating ", " new - created\n"));
1393			}
1394			else
1395			{
1396				DPRINT_INTERFACE(3, (&interface, "updating ", " new - creation FAILED"));
1397			
1398				msyslog(LOG_INFO, "failed to initialize interface for address %s", stoa(&interface.sin));
1399				continue;
1400			}
1401		}
1402	}
1403
1404	isc_interfaceiter_destroy(&iter);
1405
1406	/*
1407	 * phase 2 - delete gone interfaces - reassigning peers to other interfaces
1408	 */
1409	{
1410		struct interface *interf = ISC_LIST_HEAD(inter_list);
1411
1412		while (interf != NULL)
1413		{
1414			struct interface *next = ISC_LIST_NEXT(interf, link);
1415			  
1416			if (!(interf->flags & (INT_WILDCARD|INT_MCASTIF))) {
1417				/*
1418				 * if phase does not match sys_phase this interface was not
1419				 * enumerated during interface scan - so it is gone and
1420				 * will be deleted here unless it is solely an MCAST/WILDCARD interface
1421				 */
1422				if (interf->phase != sys_interphase) {
1423					struct peer *peer;
1424					DPRINT_INTERFACE(3, (interf, "updating ", "GONE - deleting\n"));
1425					remove_interface(interf);
1426
1427					ifi.action = IFS_DELETED;
1428					ifi.interface = interf;
1429					if (receiver)
1430						receiver(data, &ifi);
1431
1432					peer = ISC_LIST_HEAD(interf->peers);
1433					/*
1434					 * disconnect peer from deleted interface
1435					 */
1436					while (peer != NULL) {
1437						struct peer *npeer = ISC_LIST_NEXT(peer, ilink);
1438						
1439						/*
1440						 * this one just lost it's interface
1441						 */
1442						set_peerdstadr(peer, NULL);
1443	
1444						peer = npeer;
1445					}
1446
1447					/*
1448					 * update globals in case we lose 
1449					 * a loopback interface
1450					 */
1451					if (interf == loopback_interface)
1452						loopback_interface = NULL;
1453
1454					delete_interface(interf);
1455				}
1456			}
1457			interf = next;
1458		}
1459	}
1460
1461	/*
1462	 * phase 3 - re-configure as the world has changed if necessary
1463	 */
1464	refresh_all_peerinterfaces();
1465	return new_interface_found;
1466}
1467
1468
1469/*
1470 * create_sockets - create a socket for each interface plus a default
1471 *			socket for when we don't know where to send
1472 */
1473static int
1474create_sockets(
1475	u_short port
1476	)
1477{
1478#ifndef HAVE_IO_COMPLETION_PORT
1479	/*
1480	 * I/O Completion Ports don't care about the select and FD_SET
1481	 */
1482	maxactivefd = 0;
1483	FD_ZERO(&activefds);
1484#endif
1485
1486	DPRINTF(2, ("create_sockets(%d)\n", ntohs( (u_short) port)));
1487
1488	create_wildcards(port);
1489
1490	update_interfaces(port, NULL, NULL);
1491	
1492	/*
1493	 * Now that we have opened all the sockets, turn off the reuse
1494	 * flag for security.
1495	 */
1496	set_reuseaddr(0);
1497
1498	DPRINTF(2, ("create_sockets: Total interfaces = %d\n", ninterfaces));
1499
1500	return ninterfaces;
1501}
1502
1503/*
1504 * create_interface - create a new interface for a given prototype
1505 *		      binding the socket.
1506 */
1507static struct interface *
1508create_interface(
1509		 u_short port,
1510		 struct interface *iface
1511		 )
1512{
1513	struct sockaddr_storage resmask;
1514	struct interface *interface;
1515
1516	DPRINTF(2, ("create_interface(%s#%d)\n", stoa(&iface->sin), ntohs( (u_short) port)));
1517
1518	/* build an interface */
1519	interface = new_interface(iface);
1520	
1521	/*
1522	 * create socket
1523	 */
1524	interface->fd = open_socket(&interface->sin,
1525				 interface->flags, 0, interface);
1526
1527	if (interface->fd != INVALID_SOCKET)
1528		list_if_listening(interface, port);
1529
1530	if ((interface->flags & INT_BROADCAST) &&
1531	    interface->bfd != INVALID_SOCKET)
1532	  msyslog(LOG_INFO, "Listening on broadcast address %s#%d",
1533		  stoa((&interface->bcast)),
1534		  ntohs( (u_short) port));
1535
1536	if (interface->fd == INVALID_SOCKET &&
1537	    interface->bfd == INVALID_SOCKET) {
1538		msyslog(LOG_ERR, "unable to create socket on %s (%d) for %s#%d",
1539			interface->name,
1540			interface->ifnum,
1541			stoa((&interface->sin)),
1542			ntohs( (u_short) port));
1543		delete_interface(interface);
1544		return NULL;
1545	}
1546	
1547        /*
1548	 * Blacklist bound interface address
1549	 */
1550	
1551	SET_HOSTMASK(&resmask, interface->sin.ss_family);
1552	hack_restrict(RESTRICT_FLAGS, &interface->sin, &resmask,
1553		      RESM_NTPONLY|RESM_INTERFACE, RES_IGNORE);
1554	  
1555	/*
1556	 * set globals with the first found
1557	 * loopback interface of the appropriate class
1558	 */
1559	if ((loopback_interface == NULL) &&
1560	    (interface->family == AF_INET) &&
1561	    ((interface->flags & INT_LOOPBACK) != 0))
1562	{
1563		loopback_interface = interface;
1564	}
1565
1566	/*
1567	 * put into our interface list
1568	 */
1569	add_addr_to_list(&interface->sin, interface);
1570	add_interface(interface);
1571
1572	DPRINT_INTERFACE(2, (interface, "created ", "\n"));
1573	return interface;
1574}
1575
1576
1577#ifdef SO_EXCLUSIVEADDRUSE
1578static void
1579set_excladdruse(int fd)
1580{
1581	int one = 1;
1582	int failed;
1583
1584	failed = setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
1585			    (char *)&one, sizeof(one));
1586
1587	if (failed)
1588		netsyslog(LOG_ERR, 
1589			  "setsockopt(%d, SO_EXCLUSIVEADDRUSE, on): %m", fd);
1590}
1591#endif  /* SO_EXCLUSIVEADDRUSE */
1592
1593
1594/*
1595 * set_reuseaddr() - set/clear REUSEADDR on all sockets
1596 *			NB possible hole - should we be doing this on broadcast
1597 *			fd's also?
1598 */
1599static void
1600set_reuseaddr(int flag) {
1601	struct interface *interf;
1602
1603#ifndef SO_EXCLUSIVEADDRUSE
1604
1605	for (interf = ISC_LIST_HEAD(inter_list);
1606	     interf != NULL;
1607	     interf = ISC_LIST_NEXT(interf, link)) {
1608
1609		if (interf->flags & INT_WILDCARD)
1610			continue;
1611	  
1612		/*
1613		 * if interf->fd  is INVALID_SOCKET, we might have a adapter
1614		 * configured but not present
1615		 */
1616		DPRINTF(4, ("setting SO_REUSEADDR on %.16s@%s to %s\n", interf->name, stoa(&interf->sin), flag ? "on" : "off"));
1617		
1618		if (interf->fd != INVALID_SOCKET) {
1619			if (setsockopt(interf->fd, SOL_SOCKET,
1620					SO_REUSEADDR, (char *)&flag,
1621					sizeof(flag))) {
1622				netsyslog(LOG_ERR, "set_reuseaddr: setsockopt(SO_REUSEADDR, %s) failed: %m", flag ? "on" : "off");
1623			}
1624		}
1625	}
1626#endif /* ! SO_EXCLUSIVEADDRUSE */
1627}
1628
1629/*
1630 * This is just a wrapper around an internal function so we can
1631 * make other changes as necessary later on
1632 */
1633void
1634enable_broadcast(struct interface *iface, struct sockaddr_storage *baddr)
1635{
1636#ifdef SO_BROADCAST
1637	socket_broadcast_enable(iface, iface->fd, baddr);
1638#endif
1639}
1640
1641#ifdef OPEN_BCAST_SOCKET 
1642/*
1643 * Enable a broadcast address to a given socket
1644 * The socket is in the inter_list all we need to do is enable
1645 * broadcasting. It is not this function's job to select the socket
1646 */
1647static isc_boolean_t
1648socket_broadcast_enable(struct interface *iface, SOCKET fd, struct sockaddr_storage *maddr)
1649{
1650#ifdef SO_BROADCAST
1651	int on = 1;
1652
1653	if (maddr->ss_family == AF_INET)
1654	{
1655		/* if this interface can support broadcast, set SO_BROADCAST */
1656		if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
1657			       (char *)&on, sizeof(on)))
1658		{
1659			netsyslog(LOG_ERR, "setsockopt(SO_BROADCAST) enable failure on address %s: %m",
1660				stoa(maddr));
1661		}
1662#ifdef DEBUG
1663		else if (debug > 1) {
1664			printf("Broadcast enabled on socket %d for address %s\n",
1665				fd, stoa(maddr));
1666		}
1667#endif
1668	}
1669	iface->flags |= INT_BCASTOPEN;
1670	return ISC_TRUE;
1671#else
1672	return ISC_FALSE;
1673#endif /* SO_BROADCAST */
1674}
1675
1676/*
1677 * Remove a broadcast address from a given socket
1678 * The socket is in the inter_list all we need to do is disable
1679 * broadcasting. It is not this function's job to select the socket
1680 */
1681static isc_boolean_t
1682socket_broadcast_disable(struct interface *iface, struct sockaddr_storage *maddr)
1683{
1684#ifdef SO_BROADCAST
1685	int off = 0;	/* This seems to be OK as an int */
1686
1687	if (maddr->ss_family == AF_INET)
1688	{
1689		if (setsockopt(iface->fd, SOL_SOCKET, SO_BROADCAST,
1690			       (char *)&off, sizeof(off)))
1691		{
1692			netsyslog(LOG_ERR, "setsockopt(SO_BROADCAST) disable failure on address %s: %m",
1693				stoa(maddr));
1694		}
1695	}
1696	iface->flags &= ~INT_BCASTOPEN;
1697	return ISC_TRUE;
1698#else
1699	return ISC_FALSE;
1700#endif /* SO_BROADCAST */
1701}
1702
1703#endif /* OPEN_BCAST_SOCKET */
1704/*
1705 * Check to see if the address is a multicast address
1706 */
1707static isc_boolean_t
1708addr_ismulticast(struct sockaddr_storage *maddr)
1709{
1710	switch (maddr->ss_family)
1711	{
1712	case AF_INET :
1713		if (!IN_CLASSD(ntohl(((struct sockaddr_in*)maddr)->sin_addr.s_addr))) {
1714			DPRINTF(4, ("multicast address %s not class D\n", stoa(maddr)));
1715			return (ISC_FALSE);
1716		}
1717		else
1718		{
1719			return (ISC_TRUE);
1720		}
1721
1722	case AF_INET6 :
1723#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
1724		if (!IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)maddr)->sin6_addr)) {
1725			DPRINTF(4, ("address %s not IPv6 multicast address\n", stoa(maddr)));
1726			return (ISC_FALSE);
1727		}
1728		else
1729		{
1730			return (ISC_TRUE);
1731		}
1732
1733/*
1734 * If we don't have IPV6 support any IPV6 address is not multicast
1735 */
1736#else
1737		return (ISC_FALSE);
1738#endif
1739	/*
1740	 * Never valid
1741	 */
1742	default:
1743		return (ISC_FALSE);
1744	}
1745}
1746
1747/*
1748 * Multicast servers need to set the appropriate Multicast interface
1749 * socket option in order for it to know which interface to use for
1750 * send the multicast packet.
1751 */
1752void
1753enable_multicast_if(struct interface *iface, struct sockaddr_storage *maddr)
1754{
1755#ifdef MCAST
1756#ifdef IP_MULTICAST_LOOP
1757	/*u_char*/ TYPEOF_IP_MULTICAST_LOOP off = 0;
1758#endif
1759#ifdef IPV6_MULTICAST_LOOP
1760	u_int off6 = 0;		/* RFC 3493, 5.2. defines type unsigned int */
1761#endif
1762
1763	switch (maddr->ss_family)
1764	{
1765	case AF_INET:
1766		if (setsockopt(iface->fd, IPPROTO_IP, IP_MULTICAST_IF,
1767		   (char *)&(((struct sockaddr_in*)&iface->sin)->sin_addr.s_addr),
1768		    sizeof(struct in_addr)) == -1) {
1769			netsyslog(LOG_ERR,
1770			"setsockopt IP_MULTICAST_IF failure: %m on socket %d, addr %s for multicast address %s",
1771			iface->fd, stoa(&iface->sin), stoa(maddr));
1772			return;
1773		}
1774#ifdef IP_MULTICAST_LOOP
1775		/*
1776		 * Don't send back to itself, but allow it to fail to set it
1777		 */
1778		if (setsockopt(iface->fd, IPPROTO_IP, IP_MULTICAST_LOOP,
1779		       SETSOCKOPT_ARG_CAST &off, sizeof(off)) == -1) {
1780			netsyslog(LOG_ERR,
1781			"setsockopt IP_MULTICAST_LOOP failure: %m on socket %d, addr %s for multicast address %s",
1782			iface->fd, stoa(&iface->sin), stoa(maddr));
1783		}
1784#endif
1785	DPRINTF(4, ("Added IPv4 multicast interface on socket %d, addr %s for multicast address %s\n",
1786			    iface->fd, stoa(&iface->sin),
1787			    stoa(maddr)));
1788		break;
1789
1790	case AF_INET6:
1791#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
1792		if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
1793		    (char *) &iface->scopeid, sizeof(iface->scopeid)) == -1) {
1794			netsyslog(LOG_ERR,
1795			"setsockopt IPV6_MULTICAST_IF failure: %m on socket %d, addr %s, scope %d for multicast address %s",
1796			iface->fd, stoa(&iface->sin), iface->scopeid,
1797			stoa(maddr));
1798			return;
1799		}
1800#ifdef IPV6_MULTICAST_LOOP
1801		/*
1802		 * Don't send back to itself, but allow it to fail to set it
1803		 */
1804		if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1805		       (char *) &off6, sizeof(off6)) == -1) {
1806			netsyslog(LOG_ERR,
1807			"setsockopt IPV6_MULTICAST_LOOP failure: %m on socket %d, addr %s for multicast address %s",
1808			iface->fd, stoa(&iface->sin), stoa(maddr));
1809		}
1810#endif
1811		DPRINTF(4, ("Added IPv6 multicast interface on socket %d, addr %s, scope %d for multicast address %s\n",
1812			    iface->fd,  stoa(&iface->sin), iface->scopeid,
1813			    stoa(maddr)));
1814		break;
1815#else
1816		return;
1817#endif	/* INCLUDE_IPV6_MULTICAST_SUPPORT */
1818	}
1819	return;
1820#endif
1821}
1822
1823/*
1824 * Add a multicast address to a given socket
1825 * The socket is in the inter_list all we need to do is enable
1826 * multicasting. It is not this function's job to select the socket
1827 */
1828static isc_boolean_t
1829socket_multicast_enable(struct interface *iface, int lscope, struct sockaddr_storage *maddr)
1830{
1831#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
1832	struct ipv6_mreq mreq6;
1833	struct in6_addr iaddr6;
1834#endiā€¦

Large files files are truncated, but you can click here to view the full file