/contrib/ntp/ntpd/ntp_io.c
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