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_if.h" 16 #include "ntp_stdlib.h" 17 #include "ntp.h" 18 19 /* Don't include ISC's version of IPv6 variables and structures */ 20 #define ISC_IPV6_H 1 21 #include <isc/interfaceiter.h> 22 #include <isc/list.h> 23 #include <isc/result.h> 24 25 #ifdef SIM 26 #include "ntpsim.h" 27 #endif 28 29 #include <stdio.h> 30 #include <signal.h> 31 #ifdef HAVE_SYS_PARAM_H 32 # include <sys/param.h> 33 #endif /* HAVE_SYS_PARAM_H */ 34 #ifdef HAVE_NETINET_IN_H 35 # include <netinet/in.h> 36 #endif 37 #ifdef HAVE_NETINET_IN_SYSTM_H 38 # include <netinet/in_systm.h> 39 #else /* Some old linux systems at least have in_system.h instead. */ 40 # ifdef HAVE_NETINET_IN_SYSTEM_H 41 # include <netinet/in_system.h> 42 # endif 43 #endif /* HAVE_NETINET_IN_SYSTM_H */ 44 #ifdef HAVE_NETINET_IP_H 45 # include <netinet/ip.h> 46 #endif 47 #ifdef HAVE_SYS_IOCTL_H 48 # include <sys/ioctl.h> 49 #endif 50 #ifdef HAVE_SYS_SOCKIO_H /* UXPV: SIOC* #defines (Frank Vance <fvance@waii.com>) */ 51 # include <sys/sockio.h> 52 #endif 53 #include <arpa/inet.h> 54 55 extern int listen_to_virtual_ips; 56 57 #if defined(SYS_WINNT) 58 #include <transmitbuff.h> 59 #include <isc/win32os.h> 60 /* 61 * Define this macro to control the behavior of connection 62 * resets on UDP sockets. See Microsoft KnowledgeBase Article Q263823 63 * for details. 64 * NOTE: This requires that Windows 2000 systems install Service Pack 2 65 * or later. 66 */ 67 #ifndef SIO_UDP_CONNRESET 68 #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12) 69 #endif 70 71 #endif 72 73 /* 74 * We do asynchronous input using the SIGIO facility. A number of 75 * recvbuf buffers are preallocated for input. In the signal 76 * handler we poll to see which sockets are ready and read the 77 * packets from them into the recvbuf's along with a time stamp and 78 * an indication of the source host and the interface it was received 79 * through. This allows us to get as accurate receive time stamps 80 * as possible independent of other processing going on. 81 * 82 * We watch the number of recvbufs available to the signal handler 83 * and allocate more when this number drops below the low water 84 * mark. If the signal handler should run out of buffers in the 85 * interim it will drop incoming frames, the idea being that it is 86 * better to drop a packet than to be inaccurate. 87 */ 88 89 90 /* 91 * Other statistics of possible interest 92 */ 93 volatile u_long packets_dropped; /* total number of packets dropped on reception */ 94 volatile u_long packets_ignored; /* packets received on wild card interface */ 95 volatile u_long packets_received; /* total number of packets received */ 96 u_long packets_sent; /* total number of packets sent */ 97 u_long packets_notsent; /* total number of packets which couldn't be sent */ 98 99 volatile u_long handler_calls; /* number of calls to interrupt handler */ 100 volatile u_long handler_pkts; /* number of pkts received by handler */ 101 u_long io_timereset; /* time counters were reset */ 102 103 /* 104 * Interface stuff 105 */ 106 struct interface *any_interface; /* default ipv4 interface */ 107 struct interface *any6_interface; /* default ipv6 interface */ 108 struct interface *loopback_interface; /* loopback ipv4 interface */ 109 struct interface *loopback6_interface; /* loopback ipv6 interface */ 110 struct interface inter_list[MAXINTERFACES]; /* Interface list */ 111 int ninterfaces; /* Total number of interfaces */ 112 int nwilds; /* Total number of wildcard intefaces */ 113 int wildipv4 = -1; /* Index into inter_list for IPv4 wildcard */ 114 int wildipv6 = -1; /* Index into inter_list for IPv6 wildcard */ 115 116 #ifdef REFCLOCK 117 /* 118 * Refclock stuff. We keep a chain of structures with data concerning 119 * the guys we are doing I/O for. 120 */ 121 static struct refclockio *refio; 122 #endif /* REFCLOCK */ 123 124 125 /* 126 * Define what the possible "soft" errors can be. These are non-fatal returns 127 * of various network related functions, like recv() and so on. 128 * 129 * For some reason, BSDI (and perhaps others) will sometimes return <0 130 * from recv() but will have errno==0. This is broken, but we have to 131 * work around it here. 132 */ 133 #define SOFT_ERROR(e) ((e) == EAGAIN || \ 134 (e) == EWOULDBLOCK || \ 135 (e) == EINTR || \ 136 (e) == 0) 137 138 /* 139 * File descriptor masks etc. for call to select 140 * Not needed for I/O Completion Ports 141 */ 142 fd_set activefds; 143 int maxactivefd; 144 145 static int create_sockets P((u_short)); 146 static SOCKET open_socket P((struct sockaddr_storage *, int, int)); 147 static void close_socket P((SOCKET)); 148 #ifdef REFCLOCK 149 static void close_file P((SOCKET)); 150 #endif 151 static char * fdbits P((int, fd_set *)); 152 static void set_reuseaddr P((int)); 153 154 typedef struct vsock vsock_t; 155 156 struct vsock { 157 SOCKET fd; 158 ISC_LINK(vsock_t) link; 159 }; 160 161 ISC_LIST(vsock_t) sockets_list; 162 163 typedef struct remaddr remaddr_t; 164 165 struct remaddr { 166 struct sockaddr_storage addr; 167 int if_index; 168 ISC_LINK(remaddr_t) link; 169 }; 170 171 ISC_LIST(remaddr_t) remoteaddr_list; 172 173 void add_socket_to_list P((SOCKET)); 174 void delete_socket_from_list P((SOCKET)); 175 void add_addr_to_list P((struct sockaddr_storage *, int)); 176 void delete_addr_from_list P((struct sockaddr_storage *)); 177 int find_addr_in_list P((struct sockaddr_storage *)); 178 int create_wildcards P((u_short)); 179 isc_boolean_t address_okay P((isc_interface_t *)); 180 void convert_isc_if P((isc_interface_t *, struct interface *, u_short)); 181 182 #ifdef SYS_WINNT 183 /* 184 * Windows 2000 systems incorrectly cause UDP sockets using WASRecvFrom 185 * to not work correctly, returning a WSACONNRESET error when a WSASendTo 186 * fails with an "ICMP port unreachable" response and preventing the 187 * socket from using the WSARecvFrom in subsequent operations. 188 * The function below fixes this, but requires that Windows 2000 189 * Service Pack 2 or later be installed on the system. NT 4.0 190 * systems are not affected by this and work correctly. 191 * See Microsoft Knowledge Base Article Q263823 for details of this. 192 */ 193 isc_result_t 194 connection_reset_fix(SOCKET fd) { 195 DWORD dwBytesReturned = 0; 196 BOOL bNewBehavior = FALSE; 197 DWORD status; 198 199 if(isc_win32os_majorversion() < 5) 200 return (ISC_R_SUCCESS); /* NT 4.0 has no problem */ 201 202 /* disable bad behavior using IOCTL: SIO_UDP_CONNRESET */ 203 status = WSAIoctl(fd, SIO_UDP_CONNRESET, &bNewBehavior, 204 sizeof(bNewBehavior), NULL, 0, 205 &dwBytesReturned, NULL, NULL); 206 if (status != SOCKET_ERROR) 207 return (ISC_R_SUCCESS); 208 else 209 return (ISC_R_UNEXPECTED); 210 } 211 #endif 212 /* 213 * init_io - initialize I/O data structures and call socket creation routine 214 */ 215 void 216 init_io(void) 217 { 218 #ifdef SYS_WINNT 219 init_transmitbuff(); 220 #endif /* SYS_WINNT */ 221 222 /* 223 * Init buffer free list and stat counters 224 */ 225 init_recvbuff(RECV_INIT); 226 227 packets_dropped = packets_received = 0; 228 packets_ignored = 0; 229 packets_sent = packets_notsent = 0; 230 handler_calls = handler_pkts = 0; 231 io_timereset = 0; 232 loopback_interface = NULL; 233 loopback6_interface = NULL; 234 235 #ifdef REFCLOCK 236 refio = 0; 237 #endif 238 239 #if defined(HAVE_SIGNALED_IO) 240 (void) set_signal(); 241 #endif 242 243 #ifdef SYS_WINNT 244 if (!Win32InitSockets()) 245 { 246 netsyslog(LOG_ERR, "No useable winsock.dll: %m"); 247 exit(1); 248 } 249 #endif /* SYS_WINNT */ 250 251 ISC_LIST_INIT(sockets_list); 252 253 ISC_LIST_INIT(remoteaddr_list); 254 255 /* 256 * Create the sockets 257 */ 258 BLOCKIO(); 259 (void) create_sockets(htons(NTP_PORT)); 260 UNBLOCKIO(); 261 262 #ifdef DEBUG 263 if (debug) 264 printf("init_io: maxactivefd %d\n", maxactivefd); 265 #endif 266 } 267 268 int 269 create_wildcards(u_short port) { 270 271 int idx = 0; 272 /* 273 * create pseudo-interface with wildcard IPv4 address 274 */ 275 inter_list[idx].sin.ss_family = AF_INET; 276 ((struct sockaddr_in*)&inter_list[idx].sin)->sin_addr.s_addr = htonl(INADDR_ANY); 277 ((struct sockaddr_in*)&inter_list[idx].sin)->sin_port = port; 278 (void) strncpy(inter_list[idx].name, "wildcard", sizeof(inter_list[idx].name)); 279 inter_list[idx].mask.ss_family = AF_INET; 280 ((struct sockaddr_in*)&inter_list[idx].mask)->sin_addr.s_addr = htonl(~(u_int32)0); 281 inter_list[idx].bfd = INVALID_SOCKET; 282 inter_list[idx].num_mcast = 0; 283 inter_list[idx].received = 0; 284 inter_list[idx].sent = 0; 285 inter_list[idx].notsent = 0; 286 inter_list[idx].flags = INT_BROADCAST; 287 any_interface = &inter_list[idx]; 288 #if defined(MCAST) 289 /* 290 * enable possible multicast reception on the broadcast socket 291 */ 292 inter_list[idx].bcast.ss_family = AF_INET; 293 ((struct sockaddr_in*)&inter_list[idx].bcast)->sin_port = port; 294 ((struct sockaddr_in*)&inter_list[idx].bcast)->sin_addr.s_addr = htonl(INADDR_ANY); 295 #endif /* MCAST */ 296 wildipv4 = idx; 297 idx++; 298 299 #ifdef HAVE_IPV6 300 /* 301 * create pseudo-interface with wildcard IPv6 address 302 */ 303 if (isc_net_probeipv6() == ISC_R_SUCCESS) { 304 inter_list[idx].sin.ss_family = AF_INET6; 305 ((struct sockaddr_in6*)&inter_list[idx].sin)->sin6_addr = in6addr_any; 306 ((struct sockaddr_in6*)&inter_list[idx].sin)->sin6_port = port; 307 (void) strncpy(inter_list[idx].name, "wildcard", sizeof(inter_list[idx].name)); 308 inter_list[idx].mask.ss_family = AF_INET6; 309 memset(&((struct sockaddr_in6*)&inter_list[idx].mask)->sin6_addr.s6_addr, 0xff, sizeof(struct in6_addr)); 310 inter_list[idx].bfd = INVALID_SOCKET; 311 inter_list[idx].num_mcast = 0; 312 inter_list[idx].received = 0; 313 inter_list[idx].sent = 0; 314 inter_list[idx].notsent = 0; 315 inter_list[idx].flags = 0; 316 any6_interface = &inter_list[idx]; 317 wildipv6 = idx; 318 idx++; 319 } 320 #endif 321 return (idx); 322 } 323 324 isc_boolean_t 325 address_okay(isc_interface_t *isc_if) { 326 327 #ifdef DEBUG 328 if (debug > 2) 329 printf("address_okay: listen Virtual: %d, IF name: %s, Up Flag: %d\n", 330 listen_to_virtual_ips, isc_if->name, (isc_if->flags & INTERFACE_F_UP)); 331 #endif 332 333 if (listen_to_virtual_ips == 0 && (strchr(isc_if->name, (int)':') != NULL)) 334 return (ISC_FALSE); 335 336 /* XXXPDM This should be fixed later, but since we may not have set 337 * the UP flag, we at least get to use the interface. 338 * The UP flag is not always set so we don't do this right now. 339 */ 340 /* if ((isc_if->flags & INTERFACE_F_UP) == 0) 341 return (ISC_FALSE); 342 */ 343 return (ISC_TRUE); 344 } 345 void 346 convert_isc_if(isc_interface_t *isc_if, struct interface *itf, u_short port) { 347 348 if(isc_if->af == AF_INET) { 349 itf->sin.ss_family = (u_short) isc_if->af; 350 strcpy(itf->name, isc_if->name); 351 memcpy(&(((struct sockaddr_in*)&itf->sin)->sin_addr), 352 &(isc_if->address.type.in), 353 sizeof(struct in_addr)); 354 ((struct sockaddr_in*)&itf->sin)->sin_port = port; 355 356 if((isc_if->flags & INTERFACE_F_BROADCAST) != 0) { 357 itf->flags |= INT_BROADCAST; 358 itf->bcast.ss_family = itf->sin.ss_family; 359 memcpy(&(((struct sockaddr_in*)&itf->bcast)->sin_addr), 360 &(isc_if->broadcast.type.in), 361 sizeof(struct in_addr)); 362 ((struct sockaddr_in*)&itf->bcast)->sin_port = port; 363 } 364 365 itf->mask.ss_family = itf->sin.ss_family; 366 memcpy(&(((struct sockaddr_in*)&itf->mask)->sin_addr), 367 &(isc_if->netmask.type.in), 368 sizeof(struct in_addr)); 369 ((struct sockaddr_in*)&itf->mask)->sin_port = port; 370 371 if (((isc_if->flags & INTERFACE_F_LOOPBACK) != 0) && (loopback_interface == NULL)) 372 { 373 loopback_interface = itf; 374 } 375 } 376 #ifdef HAVE_IPV6 377 else if (isc_if->af == AF_INET6) { 378 itf->sin.ss_family = (u_short) isc_if->af; 379 strcpy(itf->name, isc_if->name); 380 memcpy(&(((struct sockaddr_in6 *)&itf->sin)->sin6_addr), 381 &(isc_if->address.type.in6), 382 sizeof(struct in6_addr)); 383 ((struct sockaddr_in6 *)&itf->sin)->sin6_port = port; 384 385 itf->mask.ss_family = itf->sin.ss_family; 386 memcpy(&(((struct sockaddr_in6 *)&itf->mask)->sin6_addr), 387 &(isc_if->netmask.type.in6), 388 sizeof(struct in6_addr)); 389 ((struct sockaddr_in6 *)&itf->mask)->sin6_port = port; 390 391 if (((isc_if->flags & INTERFACE_F_LOOPBACK) != 0) && (loopback6_interface == NULL)) 392 { 393 loopback6_interface = itf; 394 } 395 } 396 #endif /* HAVE_IPV6 */ 397 398 /* Process the rest of the flags */ 399 400 if((isc_if->flags & INTERFACE_F_UP) != 0) 401 itf->flags |= INT_UP; 402 if((isc_if->flags & INTERFACE_F_LOOPBACK) != 0) 403 itf->flags |= INT_LOOPBACK; 404 if((isc_if->flags & INTERFACE_F_POINTTOPOINT) != 0) 405 itf->flags |= INT_PPP; 406 } 407 /* 408 * create_sockets - create a socket for each interface plus a default 409 * socket for when we don't know where to send 410 */ 411 static int 412 create_sockets( 413 u_short port 414 ) 415 { 416 struct sockaddr_storage resmask; 417 int i; 418 isc_mem_t *mctx = NULL; 419 isc_interfaceiter_t *iter = NULL; 420 isc_boolean_t scan_ipv4 = ISC_FALSE; 421 isc_boolean_t scan_ipv6 = ISC_FALSE; 422 isc_result_t result; 423 int idx = 0; 424 425 #ifdef DEBUG 426 if (debug) 427 printf("create_sockets(%d)\n", ntohs( (u_short) port)); 428 #endif 429 430 if (isc_net_probeipv6() == ISC_R_SUCCESS) 431 scan_ipv6 = ISC_TRUE; 432 #ifdef HAVE_IPV6 433 else 434 netsyslog(LOG_ERR, "no IPv6 interfaces found"); 435 #endif 436 437 if (isc_net_probeipv4() == ISC_R_SUCCESS) 438 scan_ipv4 = ISC_TRUE; 439 else 440 netsyslog(LOG_ERR, "no IPv4 interfaces found"); 441 442 nwilds = create_wildcards(port); 443 idx = nwilds; 444 445 result = isc_interfaceiter_create(mctx, &iter); 446 if (result != ISC_R_SUCCESS) 447 return (result); 448 449 for (result = isc_interfaceiter_first(iter); 450 result == ISC_R_SUCCESS; 451 result = isc_interfaceiter_next(iter)) 452 { 453 isc_interface_t isc_if; 454 unsigned int family; 455 456 result = isc_interfaceiter_current(iter, &isc_if); 457 if (result != ISC_R_SUCCESS) 458 break; 459 460 /* See if we have a valid family to use */ 461 family = isc_if.address.family; 462 if (family != AF_INET && family != AF_INET6) 463 continue; 464 if (scan_ipv4 == ISC_FALSE && family == AF_INET) 465 continue; 466 if (scan_ipv6 == ISC_FALSE && family == AF_INET6) 467 continue; 468 469 /* Check to see if we are going to use the interface */ 470 if (address_okay(&isc_if) == ISC_TRUE) { 471 convert_isc_if(&isc_if, &inter_list[idx], port); 472 inter_list[idx].fd = INVALID_SOCKET; 473 inter_list[idx].bfd = INVALID_SOCKET; 474 inter_list[idx].num_mcast = 0; 475 inter_list[idx].received = 0; 476 inter_list[idx].sent = 0; 477 inter_list[idx].notsent = 0; 478 idx++; 479 } 480 } 481 isc_interfaceiter_destroy(&iter); 482 483 ninterfaces = idx; 484 /* 485 * I/O Completion Ports don't care about the select and FD_SET 486 */ 487 #ifndef HAVE_IO_COMPLETION_PORT 488 maxactivefd = 0; 489 FD_ZERO(&activefds); 490 #endif 491 for (i = 0; i < ninterfaces; i++) { 492 inter_list[i].fd = open_socket(&inter_list[i].sin, 493 inter_list[i].flags & INT_BROADCAST, 0); 494 if (inter_list[i].bfd != INVALID_SOCKET) 495 msyslog(LOG_INFO, "Listening on interface %s, %s#%d", 496 inter_list[i].name, 497 stoa((&inter_list[i].sin)), 498 NTP_PORT); 499 if ((inter_list[i].flags & INT_BROADCAST) && 500 inter_list[i].bfd != INVALID_SOCKET) 501 msyslog(LOG_INFO, "Listening on broadcast address %s#%d", 502 stoa((&inter_list[i].bcast)), 503 NTP_PORT); 504 #if defined (HAVE_IO_COMPLETION_PORT) 505 if (inter_list[i].fd != INVALID_SOCKET) { 506 io_completion_port_add_socket(inter_list[i].fd, &inter_list[i]); 507 } 508 #endif 509 } 510 511 /* 512 * Now that we have opened all the sockets, turn off the reuse 513 * flag for security. 514 */ 515 set_reuseaddr(0); 516 517 /* 518 * Blacklist all bound interface addresses 519 * Wildcard interfaces are ignored. 520 */ 521 522 for (i = nwilds; i < ninterfaces; i++) { 523 SET_HOSTMASK(&resmask, inter_list[i].sin.ss_family); 524 hack_restrict(RESTRICT_FLAGS, &inter_list[i].sin, &resmask, 525 RESM_NTPONLY|RESM_INTERFACE, RES_IGNORE); 526 } 527 528 /* 529 * Calculate the address hash for each interface address. 530 */ 531 for (i = 0; i < ninterfaces; i++) { 532 inter_list[i].addr_refid = addr2refid(&inter_list[i].sin); 533 } 534 535 536 #ifdef DEBUG 537 if (debug > 1) { 538 printf("create_sockets: ninterfaces=%d\n", ninterfaces); 539 for (i = 0; i < ninterfaces; i++) { 540 printf("interface %d: fd=%d, bfd=%d, name=%.8s, flags=0x%x\n", 541 i, 542 inter_list[i].fd, 543 inter_list[i].bfd, 544 inter_list[i].name, 545 inter_list[i].flags); 546 /* Leave these as three printf calls. */ 547 printf(" sin=%s", 548 stoa((&inter_list[i].sin))); 549 if (inter_list[i].flags & INT_BROADCAST) 550 printf(" bcast=%s,", 551 stoa((&inter_list[i].bcast))); 552 printf(" mask=%s\n", 553 stoa((&inter_list[i].mask))); 554 } 555 } 556 #endif 557 return ninterfaces; 558 } 559 560 /* 561 * io_setbclient - open the broadcast client sockets 562 */ 563 void 564 io_setbclient(void) 565 { 566 int i; 567 568 #ifdef OPEN_BCAST_SOCKET 569 set_reuseaddr(1); 570 #endif 571 for (i = nwilds; i < ninterfaces; i++) { 572 /* Only IPv4 addresses are valid for broadcast */ 573 if (inter_list[i].bcast.ss_family != AF_INET) 574 continue; 575 576 /* Is this a broadcast address? */ 577 if (!(inter_list[i].flags & INT_BROADCAST)) 578 continue; 579 580 /* Do we already have the broadcast address open? */ 581 if (inter_list[i].flags & INT_BCASTOPEN) 582 continue; 583 584 #ifdef SYS_SOLARIS 585 inter_list[i].bcast.sin_addr.s_addr = htonl(INADDR_ANY); 586 #endif 587 #ifdef OPEN_BCAST_SOCKET /* Was: !SYS_DOMAINOS && !SYS_LINUX */ 588 inter_list[i].bfd = open_socket(&inter_list[i].bcast, 589 INT_BROADCAST, 1); 590 if (inter_list[i].bfd != INVALID_SOCKET) { 591 inter_list[i].flags |= INT_BCASTOPEN; 592 #if defined (HAVE_IO_COMPLETION_PORT) 593 io_completion_port_add_socket(inter_list[i].bfd, &inter_list[i]); 594 #endif 595 } 596 #ifdef DEBUG 597 if (debug) { 598 if (inter_list[i].bfd != INVALID_SOCKET) 599 printf("io_setbclient: Opened broadcast client on interface %d, socket: %d\n", 600 i, inter_list[i].bfd); 601 else 602 printf("io_setbclient: Unable to Open broadcast client on interface %d\n", 603 i); 604 } 605 #endif 606 #endif 607 } 608 #ifdef OPEN_BCAST_SOCKET 609 set_reuseaddr(0); 610 #endif 611 #ifdef DEBUG 612 if (debug) 613 printf("io_setbclient: Opened broadcast clients\n"); 614 #endif 615 } 616 617 /* 618 * set_reuseaddr() - set/clear REUSEADDR on all sockets 619 * NB possible hole - should we be doing this on broadcast 620 * fd's also? 621 */ 622 static void 623 set_reuseaddr(int flag) { 624 int i; 625 626 for (i=0; i < ninterfaces; i++) { 627 /* 628 * if inter_list[ n ].fd is -1, we might have a adapter 629 * configured but not present 630 */ 631 if (inter_list[i].fd != INVALID_SOCKET) { 632 if (setsockopt(inter_list[i].fd, SOL_SOCKET, 633 SO_REUSEADDR, (char *)&flag, 634 sizeof(flag))) { 635 netsyslog(LOG_ERR, "set_reuseaddr: setsockopt(SO_REUSEADDR, %s) failed: %m", flag ? "on" : "off"); 636 } 637 } 638 } 639 } 640 641 642 /* 643 * io_multicast_add() - add multicast group address 644 */ 645 void 646 io_multicast_add( 647 struct sockaddr_storage addr 648 ) 649 { 650 #ifdef MCAST 651 struct ip_mreq mreq; 652 int i = ninterfaces; /* Use the next interface */ 653 u_int32 haddr = ntohl(((struct sockaddr_in*)&addr)->sin_addr.s_addr); 654 struct in_addr iaddr; 655 SOCKET s; 656 struct sockaddr_in *sinp; 657 658 #ifdef HAVE_IPV6 659 struct ipv6_mreq mreq6; 660 struct in6_addr iaddr6; 661 struct sockaddr_in6 *sin6p; 662 #endif /* HAVE_IPV6 */ 663 664 switch (addr.ss_family) 665 { 666 case AF_INET : 667 iaddr = (((struct sockaddr_in*)&addr)->sin_addr); 668 if (!IN_CLASSD(haddr)) { 669 netsyslog(LOG_ERR, 670 "multicast address %s not class D", 671 inet_ntoa(iaddr)); 672 return; 673 } 674 for (i = nwilds; i < ninterfaces; i++) { 675 /* Be sure it's the correct family */ 676 if (inter_list[i].sin.ss_family != AF_INET) 677 continue; 678 /* Already have this address */ 679 if (SOCKCMP(&inter_list[i].sin, &addr)) 680 return; 681 /* found a free slot */ 682 if (SOCKNUL(&inter_list[i].sin) && 683 inter_list[i].fd <= 0 && inter_list[i].bfd <= 0 && 684 inter_list[i].flags == 0) 685 break; 686 } 687 sinp = (struct sockaddr_in*)&(inter_list[i].sin); 688 memset((char *)&mreq, 0, sizeof(mreq)); 689 memset((char *)&inter_list[i], 0, sizeof(struct interface)); 690 sinp->sin_family = AF_INET; 691 sinp->sin_addr = iaddr; 692 sinp->sin_port = htons(NTP_PORT); 693 694 /* 695 * Try opening a socket for the specified class D address. This 696 * works under SunOS 4.x, but not OSF1 .. :-( 697 */ 698 set_reuseaddr(1); 699 s = open_socket((struct sockaddr_storage*)sinp, 0, 1); 700 set_reuseaddr(0); 701 if (s == INVALID_SOCKET) { 702 memset((char *)&inter_list[i], 0, sizeof(struct interface)); 703 if (wildipv4 >= 0) { 704 i = wildipv4; 705 /* HACK ! -- stuff in an address */ 706 inter_list[i].bcast = addr; 707 netsyslog(LOG_ERR, 708 "...multicast address %s using wildcard socket", 709 inet_ntoa(iaddr)); 710 } else { 711 netsyslog(LOG_ERR, 712 "No wildcard socket available to use for address %s", 713 inet_ntoa(iaddr)); 714 return; 715 } 716 } else { 717 inter_list[i].fd = s; 718 inter_list[i].bfd = INVALID_SOCKET; 719 (void) strncpy(inter_list[i].name, "multicast", 720 sizeof(inter_list[i].name)); 721 ((struct sockaddr_in*)&inter_list[i].mask)->sin_addr.s_addr = htonl(~(u_int32)0); 722 #if defined (HAVE_IO_COMPLETION_PORT) 723 io_completion_port_add_socket(inter_list[i].fd, &inter_list[i]); 724 #endif 725 } 726 727 /* 728 * enable reception of multicast packets 729 */ 730 mreq.imr_multiaddr = iaddr; 731 mreq.imr_interface.s_addr = htonl(INADDR_ANY); 732 if (setsockopt(inter_list[i].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, 733 (char *)&mreq, sizeof(mreq)) == -1) 734 netsyslog(LOG_ERR, 735 "setsockopt IP_ADD_MEMBERSHIP fails: %m for %x / %x (%s)", 736 mreq.imr_multiaddr.s_addr, 737 mreq.imr_interface.s_addr, inet_ntoa(iaddr)); 738 inter_list[i].flags |= INT_MULTICAST; 739 inter_list[i].num_mcast++; 740 if (i >= ninterfaces) 741 ninterfaces = i+1; 742 743 add_addr_to_list(&addr, i); 744 break; 745 746 #ifdef HAVE_IPV6 747 case AF_INET6 : 748 749 iaddr6 = ((struct sockaddr_in6*)&addr)->sin6_addr; 750 if (!IN6_IS_ADDR_MULTICAST(&iaddr6)) { 751 netsyslog(LOG_ERR, 752 "address %s not IPv6 multicast address", 753 stoa(&addr)); 754 return; 755 } 756 for (i = nwilds; i < ninterfaces; i++) { 757 /* Be sure it's the correct family */ 758 if(inter_list[i].sin.ss_family != AF_INET6) 759 continue; 760 /* Already have this address */ 761 if (SOCKCMP(&inter_list[i].sin, &addr)) 762 return; 763 /* found a free slot */ 764 if (SOCKNUL(&inter_list[i].sin) && 765 inter_list[i].fd <= 0 && inter_list[i].bfd <= 0 && 766 inter_list[i].flags == 0) 767 break; 768 } 769 sin6p = (struct sockaddr_in6*)&inter_list[i].sin; 770 memset((char *)&mreq6, 0, sizeof(mreq6)); 771 memset((char *)&inter_list[i], 0, sizeof(struct interface)); 772 sin6p->sin6_family = AF_INET6; 773 sin6p->sin6_addr = iaddr6; 774 sin6p->sin6_port = htons(NTP_PORT); 775 776 /* 777 * Try opening a socket for the specified class D address. This 778 * works under SunOS 4.x, but not OSF1 .. :-( 779 */ 780 set_reuseaddr(1); 781 s = open_socket((struct sockaddr_storage*)sin6p, 0, 1); 782 set_reuseaddr(0); 783 if(s == INVALID_SOCKET){ 784 memset((char *)&inter_list[i], 0, sizeof(struct interface)); 785 if (wildipv6 >= 0) { 786 i = wildipv6; 787 /* HACK ! -- stuff in an address */ 788 inter_list[i].bcast = addr; 789 netsyslog(LOG_ERR, 790 "...multicast address %s using wildcard socket", 791 stoa(&addr)); 792 } else { 793 netsyslog(LOG_ERR, 794 "No wildcard socket available to use for address %s", 795 stoa(&addr)); 796 return; 797 } 798 } else { 799 inter_list[i].fd = s; 800 inter_list[i].bfd = INVALID_SOCKET; 801 (void)strncpy(inter_list[i].name, "multicast", 802 sizeof(inter_list[i].name)); 803 memset(&(((struct sockaddr_in6*)&inter_list[i].mask)->sin6_addr), 1, sizeof(struct in6_addr)); 804 #if defined (HAVE_IO_COMPLETION_PORT) 805 io_completion_port_add_socket(inter_list[i].fd, &inter_list[i]); 806 #endif 807 } 808 809 /* 810 * enable reception of multicast packets 811 */ 812 mreq6.ipv6mr_multiaddr = iaddr6; 813 mreq6.ipv6mr_interface = 0; 814 if(setsockopt(inter_list[i].fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, 815 (char *)&mreq6, sizeof(mreq6)) == -1) 816 netsyslog(LOG_ERR, 817 "setsockopt IPV6_JOIN_GROUP fails: %m on interface %d(%s)", 818 mreq6.ipv6mr_interface, stoa(&addr)); 819 inter_list[i].flags |= INT_MULTICAST; 820 inter_list[i].num_mcast++; 821 if(i >= ninterfaces) 822 ninterfaces = i+1; 823 824 add_addr_to_list(&addr, i); 825 break; 826 #endif /* HAVE_IPV6 */ 827 } 828 829 #ifdef DEBUG 830 if (debug) 831 printf("io_multicast_add %s\n", stoa(&addr)); 832 #endif 833 #else /* MCAST */ 834 netsyslog(LOG_ERR, 835 "cannot add multicast address %s as no MCAST support", 836 stoa(&addr)); 837 #endif /* MCAST */ 838 } 839 840 /* 841 * io_unsetbclient - close the broadcast client sockets 842 */ 843 void 844 io_unsetbclient(void) 845 { 846 int i; 847 848 for (i = nwilds; i < ninterfaces; i++) 849 { 850 if (!(inter_list[i].flags & INT_BCASTOPEN)) 851 continue; 852 close_socket(inter_list[i].bfd); 853 inter_list[i].bfd = INVALID_SOCKET; 854 inter_list[i].flags &= ~INT_BCASTOPEN; 855 } 856 } 857 858 859 /* 860 * io_multicast_del() - delete multicast group address 861 */ 862 void 863 io_multicast_del( 864 struct sockaddr_storage addr 865 ) 866 { 867 #ifdef MCAST 868 int i; 869 struct ip_mreq mreq; 870 u_int32 haddr; 871 872 #ifdef HAVE_IPV6 873 struct ipv6_mreq mreq6; 874 struct in6_addr haddr6; 875 #endif /* HAVE_IPV6 */ 876 877 switch (addr.ss_family) 878 { 879 case AF_INET : 880 881 haddr = ntohl(((struct sockaddr_in*)&addr)->sin_addr.s_addr); 882 883 if (!IN_CLASSD(haddr)) 884 { 885 netsyslog(LOG_ERR, 886 "invalid multicast address %s", stoa(&addr)); 887 return; 888 } 889 890 /* 891 * Disable reception of multicast packets 892 */ 893 mreq.imr_multiaddr = ((struct sockaddr_in*)&addr)->sin_addr; 894 mreq.imr_interface.s_addr = htonl(INADDR_ANY); 895 for (i = 0; i < ninterfaces; i++) 896 { 897 /* Be sure it's the correct family */ 898 if (inter_list[i].sin.ss_family != AF_INET) 899 continue; 900 if (!(inter_list[i].flags & INT_MULTICAST)) 901 continue; 902 if (!(inter_list[i].fd < 0)) 903 continue; 904 if (!SOCKCMP(&addr, &inter_list[i].sin)) 905 continue; 906 if (i != wildipv4) 907 { 908 /* we have an explicit fd, so we can close it */ 909 close_socket(inter_list[i].fd); 910 memset((char *)&inter_list[i], 0, sizeof(struct interface)); 911 inter_list[i].fd = INVALID_SOCKET; 912 inter_list[i].bfd = INVALID_SOCKET; 913 } 914 else 915 { 916 /* We are sharing "any address" port :-( Don't close it! */ 917 if (setsockopt(inter_list[i].fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, 918 (char *)&mreq, sizeof(mreq)) == -1) 919 netsyslog(LOG_ERR, "setsockopt IP_DROP_MEMBERSHIP fails on address: %s %m", 920 stoa(&addr)); 921 inter_list[i].num_mcast--; 922 /* If there are none left negate the Multicast flag */ 923 if(inter_list[i].num_mcast == 0) 924 inter_list[i].flags &= ~INT_MULTICAST; 925 } 926 } 927 break; 928 929 #ifdef HAVE_IPV6 930 case AF_INET6 : 931 haddr6 = ((struct sockaddr_in6*)&addr)->sin6_addr; 932 933 if (!IN6_IS_ADDR_MULTICAST(&haddr6)) 934 { 935 netsyslog(LOG_ERR, 936 "invalid multicast address %s", stoa(&addr)); 937 return; 938 } 939 940 /* 941 * Disable reception of multicast packets 942 */ 943 mreq6.ipv6mr_multiaddr = ((struct sockaddr_in6*)&addr)->sin6_addr; 944 mreq6.ipv6mr_interface = 0; 945 for (i = 0; i < ninterfaces; i++) 946 { 947 /* Be sure it's the correct family */ 948 if (inter_list[i].sin.ss_family != AF_INET6) 949 continue; 950 if (!(inter_list[i].flags & INT_MULTICAST)) 951 continue; 952 if (!(inter_list[i].fd < 0)) 953 continue; 954 if (!SOCKCMP(&addr, &inter_list[i].sin)) 955 continue; 956 if (i != wildipv6) 957 { 958 /* we have an explicit fd, so we can close it */ 959 close_socket(inter_list[i].fd); 960 memset((char *)&inter_list[i], 0, sizeof(struct interface)); 961 inter_list[i].fd = INVALID_SOCKET; 962 inter_list[i].bfd = INVALID_SOCKET; 963 } 964 else 965 { 966 /* We are sharing "any address" port :-( Don't close it! */ 967 if (setsockopt(inter_list[i].fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, 968 (char *)&mreq6, sizeof(mreq6)) == -1) 969 netsyslog(LOG_ERR, "setsockopt IP_DROP_MEMBERSHIP fails on address %s: %m", 970 stoa(&addr)); 971 /* If there are none left negate the Multicast flag */ 972 if(inter_list[i].num_mcast == 0) 973 inter_list[i].flags &= ~INT_MULTICAST; 974 } 975 } 976 break; 977 #endif /* HAVE_IPV6 */ 978 }/* switch */ 979 delete_addr_from_list(&addr); 980 981 #else /* not MCAST */ 982 netsyslog(LOG_ERR, "this function requires multicast kernel"); 983 #endif /* not MCAST */ 984 } 985 986 987 /* 988 * open_socket - open a socket, returning the file descriptor 989 */ 990 991 static SOCKET 992 open_socket( 993 struct sockaddr_storage *addr, 994 int flags, 995 int turn_off_reuse 996 ) 997 { 998 int errval; 999 SOCKET fd; 1000 int on = 1, off = 0; 1001 #if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS) 1002 int tos; 1003 #endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */ 1004 1005 if ((addr->ss_family == AF_INET6) && (isc_net_probeipv6() != ISC_R_SUCCESS)) 1006 return (INVALID_SOCKET); 1007 1008 /* create a datagram (UDP) socket */ 1009 #ifndef SYS_WINNT 1010 if ( (fd = socket(addr->ss_family, SOCK_DGRAM, 0)) < 0) { 1011 errval = errno; 1012 if(addr->ss_family == AF_INET) 1013 netsyslog(LOG_ERR, "socket(AF_INET, SOCK_DGRAM, 0) failed on address %s: %m", 1014 stoa(addr)); 1015 else if(addr->ss_family == AF_INET6) 1016 netsyslog(LOG_ERR, "socket(AF_INET6, SOCK_DGRAM, 0) failed on address %s: %m", 1017 stoa(addr)); 1018 if (errval == EPROTONOSUPPORT || errval == EAFNOSUPPORT || 1019 errval == EPFNOSUPPORT) 1020 return (INVALID_SOCKET); 1021 exit(1); 1022 /*NOTREACHED*/ 1023 } 1024 #else 1025 if ( (fd = socket(addr->ss_family, SOCK_DGRAM, 0)) == INVALID_SOCKET) { 1026 errval = WSAGetLastError(); 1027 if(addr->ss_family == AF_INET) 1028 netsyslog(LOG_ERR, "socket(AF_INET, SOCK_DGRAM, 0) failed on address %s: %m", 1029 stoa(addr)); 1030 else if(addr->ss_family == AF_INET6) 1031 netsyslog(LOG_ERR, "socket(AF_INET6, SOCK_DGRAM, 0) failed on address %s: %m", 1032 stoa(addr)); 1033 if (errval == WSAEPROTONOSUPPORT || errval == WSAEAFNOSUPPORT || 1034 errval == WSAEPFNOSUPPORT) 1035 return (INVALID_SOCKET); 1036 exit(1); 1037 /*NOTREACHED*/ 1038 } 1039 if (connection_reset_fix(fd) != ISC_R_SUCCESS) { 1040 netsyslog(LOG_ERR, "connection_reset_fix(fd) failed on address %s: %m", 1041 stoa(addr)); 1042 } 1043 1044 #endif /* SYS_WINNT */ 1045 1046 /* set SO_REUSEADDR since we will be binding the same port 1047 number on each interface */ 1048 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 1049 (char *)&on, sizeof(on))) 1050 { 1051 netsyslog(LOG_ERR, "setsockopt SO_REUSEADDR on fails on address %s: %m", 1052 stoa(addr)); 1053 } 1054 1055 #if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS) 1056 /* set IP_TOS to minimize packet delay */ 1057 tos = IPTOS_LOWDELAY; 1058 if (addr->ss_family == AF_INET) 1059 if (setsockopt(fd, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(tos)) < 0) 1060 { 1061 netsyslog(LOG_ERR, "setsockopt IPTOS_LOWDELAY on fails on address %s: %m", 1062 stoa(addr)); 1063 } 1064 1065 #if defined(IPV6_V6ONLY) 1066 if (addr->ss_family == AF_INET6) 1067 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, 1068 (char*)&on, sizeof(on))) 1069 { 1070 netsyslog(LOG_ERR, "setsockopt IPV6_V6ONLY on fails on address %s: %m", 1071 stoa(addr)); 1072 } 1073 #else /* IPV6_V6ONLY */ 1074 #if defined(IPV6_BINDV6ONLY) 1075 if (addr->ss_family == AF_INET6) 1076 if (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDV6ONLY, 1077 (char*)&on, sizeof(on))) 1078 { 1079 netsyslog(LOG_ERR, 1080 "setsockopt IPV6_BINDV6ONLY on fails on address %s: %m", 1081 stoa(addr)); 1082 } 1083 #endif /* IPV6_BINDV6ONLY */ 1084 #endif /* IPV6_V6ONLY */ 1085 1086 #endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */ 1087 1088 /* 1089 * bind the local address. 1090 */ 1091 if (bind(fd, (struct sockaddr *)addr, SOCKLEN(addr)) < 0) { 1092 char buff[160]; 1093 1094 if(addr->ss_family == AF_INET) 1095 sprintf(buff, 1096 "bind() fd %d, family %d, port %d, addr %s, in_classd=%d flags=%d fails: %%m", 1097 fd, addr->ss_family, (int)ntohs(((struct sockaddr_in*)addr)->sin_port), 1098 stoa(addr), 1099 IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)), flags); 1100 else if(addr->ss_family == AF_INET6) 1101 sprintf(buff, 1102 "bind() fd %d, family %d, port %d, addr %s, in6_is_addr_multicast=%d flags=%d fails: %%m", 1103 fd, addr->ss_family, (int)ntohs(((struct sockaddr_in6*)addr)->sin6_port), 1104 stoa(addr), 1105 IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr), flags); 1106 else return INVALID_SOCKET; 1107 1108 netsyslog(LOG_ERR, buff); 1109 closesocket(fd); 1110 1111 /* 1112 * soft fail if opening a multicast address 1113 */ 1114 if(addr->ss_family == AF_INET){ 1115 if(IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr))) 1116 return (INVALID_SOCKET); 1117 } 1118 else { 1119 if(IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr)) 1120 return (INVALID_SOCKET); 1121 } 1122 #if 0 1123 exit(1); 1124 #else 1125 return INVALID_SOCKET; 1126 #endif 1127 } 1128 #ifdef DEBUG 1129 if (debug) 1130 printf("bind() fd %d, family %d, port %d, addr %s, flags=%d\n", 1131 fd, 1132 addr->ss_family, 1133 (int)ntohs(((struct sockaddr_in*)addr)->sin_port), 1134 stoa(addr), 1135 flags); 1136 #endif 1137 1138 /* 1139 * I/O Completion Ports don't care about the select and FD_SET 1140 */ 1141 #ifndef HAVE_IO_COMPLETION_PORT 1142 if (fd > maxactivefd) 1143 maxactivefd = fd; 1144 FD_SET(fd, &activefds); 1145 #endif 1146 add_socket_to_list(fd); 1147 /* 1148 * set non-blocking, 1149 */ 1150 1151 #ifdef USE_FIONBIO 1152 /* in vxWorks we use FIONBIO, but the others are defined for old systems, so 1153 * all hell breaks loose if we leave them defined 1154 */ 1155 #undef O_NONBLOCK 1156 #undef FNDELAY 1157 #undef O_NDELAY 1158 #endif 1159 1160 #if defined(O_NONBLOCK) /* POSIX */ 1161 if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) 1162 { 1163 netsyslog(LOG_ERR, "fcntl(O_NONBLOCK) fails on address %s: %m", 1164 stoa(addr)); 1165 exit(1); 1166 /*NOTREACHED*/ 1167 } 1168 #elif defined(FNDELAY) 1169 if (fcntl(fd, F_SETFL, FNDELAY) < 0) 1170 { 1171 netsyslog(LOG_ERR, "fcntl(FNDELAY) fails on address %s: %m", 1172 stoa(addr)); 1173 exit(1); 1174 /*NOTREACHED*/ 1175 } 1176 #elif defined(O_NDELAY) /* generally the same as FNDELAY */ 1177 if (fcntl(fd, F_SETFL, O_NDELAY) < 0) 1178 { 1179 netsyslog(LOG_ERR, "fcntl(O_NDELAY) fails on address %s: %m", 1180 stoa(addr)); 1181 exit(1); 1182 /*NOTREACHED*/ 1183 } 1184 #elif defined(FIONBIO) 1185 # if defined(VMS) 1186 if (ioctl(fd,FIONBIO,&on) < 0) 1187 # elif defined(SYS_WINNT) 1188 if (ioctlsocket(fd,FIONBIO,(u_long *) &on) == SOCKET_ERROR) 1189 # else 1190 if (ioctl(fd,FIONBIO,&on) < 0) 1191 # endif 1192 { 1193 netsyslog(LOG_ERR, "ioctl(FIONBIO) fails on address %s: %m", 1194 stoa(addr)); 1195 exit(1); 1196 /*NOTREACHED*/ 1197 } 1198 #elif defined(FIOSNBIO) 1199 if (ioctl(fd,FIOSNBIO,&on) < 0) 1200 { 1201 netsyslog(LOG_ERR, "ioctl(FIOSNBIO) fails on address %s: %m", 1202 stoa(addr)); 1203 exit(1); 1204 /*NOTREACHED*/ 1205 } 1206 #else 1207 # include "Bletch: Need non-blocking I/O!" 1208 #endif 1209 1210 #ifdef HAVE_SIGNALED_IO 1211 init_socket_sig(fd); 1212 #endif /* not HAVE_SIGNALED_IO */ 1213 1214 /* 1215 * Turn off the SO_REUSEADDR socket option. It apparently 1216 * causes heartburn on systems with multicast IP installed. 1217 * On normal systems it only gets looked at when the address 1218 * is being bound anyway.. 1219 */ 1220 if (turn_off_reuse) 1221 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 1222 (char *)&off, sizeof(off))) 1223 { 1224 netsyslog(LOG_ERR, "setsockopt SO_REUSEADDR off fails on address %s: %m", 1225 stoa(addr)); 1226 } 1227 1228 #ifdef SO_BROADCAST 1229 /* if this interface can support broadcast, set SO_BROADCAST */ 1230 if (flags & INT_BROADCAST) 1231 { 1232 if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, 1233 (char *)&on, sizeof(on))) 1234 { 1235 netsyslog(LOG_ERR, "setsockopt(SO_BROADCAST) on address %s: %m", 1236 stoa(addr)); 1237 } 1238 } 1239 #endif /* SO_BROADCAST */ 1240 1241 #if !defined(SYS_WINNT) && !defined(VMS) 1242 # ifdef DEBUG 1243 if (debug > 1) 1244 printf("flags for fd %d: 0%o\n", fd, 1245 fcntl(fd, F_GETFL, 0)); 1246 # endif 1247 #endif /* SYS_WINNT || VMS */ 1248 1249 return fd; 1250 } 1251 1252 1253 /* 1254 * close_socket - close a socket and remove from the activefd list 1255 */ 1256 static void 1257 close_socket( 1258 SOCKET fd 1259 ) 1260 { 1261 SOCKET i, newmax; 1262 1263 (void) closesocket(fd); 1264 1265 /* 1266 * I/O Completion Ports don't care about select and fd_set 1267 */ 1268 #ifndef HAVE_IO_COMPLETION_PORT 1269 FD_CLR( (u_int) fd, &activefds); 1270 1271 if (fd == maxactivefd) { 1272 newmax = 0; 1273 for (i = 0; i < maxactivefd; i++) 1274 if (FD_ISSET(i, &activefds)) 1275 newmax = i; 1276 maxactivefd = newmax; 1277 } 1278 #endif 1279 delete_socket_from_list(fd); 1280 1281 } 1282 1283 1284 /* 1285 * close_file - close a file and remove from the activefd list 1286 * added 1/31/1997 Greg Schueman for Windows NT portability 1287 */ 1288 #ifdef REFCLOCK 1289 static void 1290 close_file( 1291 SOCKET fd 1292 ) 1293 { 1294 int i, newmax; 1295 1296 (void) close(fd); 1297 /* 1298 * I/O Completion Ports don't care about select and fd_set 1299 */ 1300 #ifndef HAVE_IO_COMPLETION_PORT 1301 FD_CLR( (u_int) fd, &activefds); 1302 1303 if (fd == maxactivefd) { 1304 newmax = 0; 1305 for (i = 0; i < maxactivefd; i++) 1306 if (FD_ISSET(i, &activefds)) 1307 newmax = i; 1308 maxactivefd = newmax; 1309 } 1310 #endif 1311 delete_socket_from_list(fd); 1312 1313 } 1314 #endif 1315 1316 1317 /* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */ 1318 /* 1319 * sendpkt - send a packet to the specified destination. Maintain a 1320 * send error cache so that only the first consecutive error for a 1321 * destination is logged. 1322 */ 1323 void 1324 sendpkt( 1325 struct sockaddr_storage *dest, 1326 struct interface *inter, 1327 int ttl, 1328 struct pkt *pkt, 1329 int len 1330 ) 1331 { 1332 int cc, slot; 1333 #ifdef SYS_WINNT 1334 DWORD err; 1335 #endif /* SYS_WINNT */ 1336 1337 /* 1338 * Send error caches. Empty slots have port == 0 1339 * Set ERRORCACHESIZE to 0 to disable 1340 */ 1341 struct cache { 1342 u_short port; 1343 struct in_addr addr; 1344 }; 1345 1346 #ifdef HAVE_IPV6 1347 struct cache6 { 1348 u_short port; 1349 struct in6_addr addr; 1350 }; 1351 #endif /* HAVE_IPV6 */ 1352 1353 #ifndef ERRORCACHESIZE 1354 #define ERRORCACHESIZE 8 1355 #endif 1356 #if ERRORCACHESIZE > 0 1357 static struct cache badaddrs[ERRORCACHESIZE]; 1358 #ifdef HAVE_IPV6 1359 static struct cache6 badaddrs6[ERRORCACHESIZE]; 1360 #endif /* HAVE_IPV6 */ 1361 #else 1362 #define badaddrs ((struct cache *)0) /* Only used in empty loops! */ 1363 #ifdef HAVE_IPV6 1364 #define badaddrs6 ((struct cache6 *)0) /* Only used in empty loops! */ 1365 #endif /* HAVE_IPV6 */ 1366 #endif 1367 #ifdef DEBUG 1368 if (debug > 1) 1369 printf("%ssendpkt(fd=%d dst=%s, src=%s, ttl=%d, len=%d)\n", 1370 (ttl >= 0) ? "\tMCAST\t*****" : "", 1371 inter->fd, stoa(dest), 1372 stoa(&inter->sin), ttl, len); 1373 #endif 1374 1375 #ifdef MCAST 1376 1377 switch (inter->sin.ss_family) { 1378 1379 case AF_INET : 1380 1381 /* 1382 * for the moment we use the bcast option to set multicast ttl 1383 */ 1384 if (ttl > 0 && ttl != inter->last_ttl) { 1385 1386 /* 1387 * set the multicast ttl for outgoing packets 1388 */ 1389 if (setsockopt(inter->fd, IPPROTO_IP, IP_MULTICAST_TTL, 1390 (char *) &ttl, sizeof(ttl)) != 0) { 1391 netsyslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL fails on address %s: %m", 1392 stoa(&inter->sin)); 1393 } 1394 else 1395 inter->last_ttl = ttl; 1396 } 1397 break; 1398 1399 #ifdef HAVE_IPV6 1400 case AF_INET6 : 1401 1402 /* 1403 * for the moment we use the bcast option to set 1404 * multicast max hops 1405 */ 1406 if (ttl > 0 && ttl != inter->last_ttl) { 1407 1408 /* 1409 * set the multicast ttl for outgoing packets 1410 */ 1411 if (setsockopt(inter->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, 1412 &ttl, sizeof(ttl)) == -1) 1413 netsyslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL fails on address %s: %m", 1414 stoa(&inter->sin)); 1415 else 1416 inter->last_ttl = ttl; 1417 } 1418 break; 1419 #endif /* HAVE_IPV6 */ 1420 1421 default : 1422 exit(1); 1423 1424 } 1425 1426 1427 #endif /* MCAST */ 1428 1429 for (slot = ERRORCACHESIZE; --slot >= 0; ) 1430 if(dest->ss_family == AF_INET) { 1431 if (badaddrs[slot].port == ((struct sockaddr_in*)dest)->sin_port && 1432 badaddrs[slot].addr.s_addr == ((struct sockaddr_in*)dest)->sin_addr.s_addr) 1433 break; 1434 } 1435 #ifdef HAVE_IPV6 1436 else if (dest->ss_family == AF_INET6) { 1437 if (badaddrs6[slot].port == ((struct sockaddr_in6*)dest)->sin6_port && 1438 badaddrs6[slot].addr.s6_addr == ((struct sockaddr_in6*)dest)->sin6_addr.s6_addr) 1439 break; 1440 } 1441 #endif /* HAVE_IPV6 */ 1442 else exit(1); /* address family not supported yet */ 1443 1444 #if defined(HAVE_IO_COMPLETION_PORT) 1445 err = io_completion_port_sendto(inter, pkt, len, dest); 1446 if (err != ERROR_SUCCESS) 1447 #else 1448 #ifdef SIM 1449 cc = srvr_rply(&ntp_node, dest, inter, pkt); 1450 #else /* SIM */ 1451 cc = sendto(inter->fd, (char *)pkt, (unsigned int)len, 0, (struct sockaddr *)dest, 1452 SOCKLEN(dest)); 1453 #endif /* SIM */ 1454 if (cc == -1) 1455 #endif 1456 { 1457 inter->notsent++; 1458 packets_notsent++; 1459 #if defined(HAVE_IO_COMPLETION_PORT) 1460 err = WSAGetLastError(); 1461 if (err != WSAEWOULDBLOCK && err != WSAENOBUFS && slot < 0) 1462 #else 1463 if (errno != EWOULDBLOCK && errno != ENOBUFS && slot < 0) 1464 #endif 1465 { 1466 /* 1467 * Remember this, if there's an empty slot 1468 */ 1469 switch (dest->ss_family) { 1470 1471 case AF_INET : 1472 1473 for (slot = ERRORCACHESIZE; --slot >= 0; ) 1474 if (badaddrs[slot].port == 0) 1475 { 1476 badaddrs[slot].port = SRCPORT(dest); 1477 badaddrs[slot].addr = ((struct sockaddr_in*)dest)->sin_addr; 1478 break; 1479 } 1480 break; 1481 1482 #ifdef HAVE_IPV6 1483 case AF_INET6 : 1484 1485 for (slot = ERRORCACHESIZE; --slot >= 0; ) 1486 if (badaddrs6[slot].port == 0) 1487 { 1488 badaddrs6[slot].port = SRCPORT(dest); 1489 badaddrs6[slot].addr = ((struct sockaddr_in6*)dest)->sin6_addr; 1490 break; 1491 } 1492 break; 1493 #endif /* HAVE_IPV6 */ 1494 1495 default : 1496 exit(1); 1497 } 1498 1499 netsyslog(LOG_ERR, "sendto(%s): %m", stoa(dest)); 1500 } 1501 } 1502 else 1503 { 1504 inter->sent++; 1505 packets_sent++; 1506 /* 1507 * He's not bad any more 1508 */ 1509 if (slot >= 0) 1510 { 1511 netsyslog(LOG_INFO, "Connection re-established to %s", stoa(dest)); 1512 switch (dest->ss_family) { 1513 case AF_INET : 1514 badaddrs[slot].port = 0; 1515 break; 1516 #ifdef HAVE_IPV6 1517 case AF_INET6 : 1518 badaddrs6[slot].port = 0; 1519 break; 1520 #endif /* HAVE_IPV6 */ 1521 } 1522 } 1523 } 1524 } 1525 1526 #if !defined(HAVE_IO_COMPLETION_PORT) 1527 /* 1528 * fdbits - generate ascii representation of fd_set (FAU debug support) 1529 * HFDF format - highest fd first. 1530 */ 1531 static char * 1532 fdbits( 1533 int count, 1534 fd_set *set 1535 ) 1536 { 1537 static char buffer[256]; 1538 char * buf = buffer; 1539 1540 count = (count < 256) ? count : 255; 1541 1542 while (count >= 0) 1543 { 1544 *buf++ = FD_ISSET(count, set) ? '#' : '-'; 1545 count--; 1546 } 1547 *buf = '\0'; 1548 1549 return buffer; 1550 } 1551 1552 /* 1553 * input_handler - receive packets asynchronously 1554 */ 1555 void 1556 input_handler( 1557 l_fp *cts 1558 ) 1559 { 1560 register int i, n; 1561 register struct recvbuf *rb; 1562 register int doing; 1563 register SOCKET fd; 1564 struct timeval tvzero; 1565 int fromlen; 1566 l_fp ts; /* Timestamp at BOselect() gob */ 1567 l_fp ts_e; /* Timestamp at EOselect() gob */ 1568 fd_set fds; 1569 int select_count = 0; 1570 static int handler_count = 0; 1571 1572 ++handler_count; 1573 if (handler_count != 1) 1574 msyslog(LOG_ERR, "input_handler: handler_count is %d!", handler_count); 1575 handler_calls++; 1576 ts = *cts; 1577 1578 for (;;) 1579 { 1580 /* 1581 * Do a poll to see who has data 1582 */ 1583 1584 fds = activefds; 1585 tvzero.tv_sec = tvzero.tv_usec = 0; 1586 1587 /* 1588 * If we have something to do, freeze a timestamp. 1589 * See below for the other cases (nothing (left) to do or error) 1590 */ 1591 while (0 < (n = select(maxactivefd+1, &fds, (fd_set *)0, (fd_set *)0, &tvzero))) 1592 { 1593 ++select_count; 1594 ++handler_pkts; 1595 1596 #ifdef REFCLOCK 1597 /* 1598 * Check out the reference clocks first, if any 1599 */ 1600 if (refio != 0) 1601 { 1602 register struct refclockio *rp; 1603 1604 for (rp = refio; rp != 0 && n > 0; rp = rp->next) 1605 { 1606 fd = rp->fd; 1607 if (FD_ISSET(fd, &fds)) 1608 { 1609 n--; 1610 if (free_recvbuffs() == 0) 1611 { 1612 char buf[RX_BUFF_SIZE]; 1613 1614 (void) read(fd, buf, sizeof buf); 1615 packets_dropped++; 1616 goto select_again; 1617 } 1618 1619 rb = get_free_recv_buffer(); 1620 1621 i = (rp->datalen == 0 1622 || rp->datalen > sizeof(rb->recv_space)) 1623 ? sizeof(rb->recv_space) : rp->datalen; 1624 rb->recv_length = 1625 read(fd, (char *)&rb->recv_space, (unsigned)i); 1626 1627 if (rb->recv_length == -1) 1628 { 1629 netsyslog(LOG_ERR, "clock read fd %d: %m", fd); 1630 freerecvbuf(rb); 1631 goto select_again; 1632 } 1633 1634 /* 1635 * Got one. Mark how 1636 * and when it got here, 1637 * put it on the full 1638 * list and do 1639 * bookkeeping. 1640 */ 1641 rb->recv_srcclock = rp->srcclock; 1642 rb->dstadr = 0; 1643 rb->fd = fd; 1644 rb->recv_time = ts; 1645 rb->receiver = rp->clock_recv; 1646 1647 if (rp->io_input) 1648 { 1649 /* 1650 * have direct 1651 * input routine 1652 * for refclocks 1653 */ 1654 if (rp->io_input(rb) == 0) 1655 { 1656 /* 1657 * data 1658 * was 1659 * consumed 1660 * - 1661 * nothing 1662 * to 1663 * pass 1664 * up 1665 * into 1666 * block 1667 * input 1668 * machine 1669 */ 1670 freerecvbuf(rb); 1671 #if 1 1672 goto select_again; 1673 #else 1674 continue; 1675 #endif 1676 } 1677 } 1678 1679 add_full_recv_buffer(rb); 1680 1681 rp->recvcount++; 1682 packets_received++; 1683 } 1684 } 1685 } 1686 #endif /* REFCLOCK */ 1687 1688 /* 1689 * Loop through the interfaces looking for data 1690 * to read. 1691 */ 1692 for (i = ninterfaces - 1; (i >= 0) && (n > 0); i--) 1693 { 1694 for (doing = 0; (doing < 2) && (n > 0); doing++) 1695 { 1696 if (doing == 0) 1697 { 1698 fd = inter_list[i].fd; 1699 } 1700 else 1701 { 1702 if (!(inter_list[i].flags & INT_BCASTOPEN)) 1703 break; 1704 fd = inter_list[i].bfd; 1705 } 1706 if (fd < 0) continue; 1707 if (FD_ISSET(fd, &fds)) 1708 { 1709 n--; 1710 1711 /* 1712 * Get a buffer and read 1713 * the frame. If we 1714 * haven't got a buffer, 1715 * or this is received 1716 * on the wild card 1717 * socket, just dump the 1718 * packet. 1719 */ 1720 if ( 1721 #ifdef UDP_WILDCARD_DELIVERY 1722 /* 1723 * these guys manage to put properly addressed 1724 * packets into the wildcard queue 1725 */ 1726 (free_recvbuffs() == 0) 1727 #else 1728 ((i == wildipv4) || (i == wildipv6)|| 1729 (free_recvbuffs() == 0)) 1730 #endif 1731 ) 1732 { 1733 char buf[RX_BUFF_SIZE]; 1734 struct sockaddr_storage from; 1735 1736 fromlen = sizeof from; 1737 (void) recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr*)&from, &fromlen); 1738 #ifdef DEBUG 1739 if (debug) 1740 printf("%s on %d(%lu) fd=%d from %s\n", 1741 (i) ? "drop" : "ignore", 1742 i, free_recvbuffs(), fd, 1743 stoa(&from)); 1744 #endif 1745 if (i == wildipv4 || i == wildipv6) 1746 packets_ignored++; 1747 else 1748 packets_dropped++; 1749 goto select_again; 1750 } 1751 1752 rb = get_free_recv_buffer(); 1753 1754 fromlen = sizeof(struct sockaddr_storage); 1755 rb->recv_length = recvfrom(fd, 1756 (char *)&rb->recv_space, 1757 sizeof(rb->recv_space), 0, 1758 (struct sockaddr *)&rb->recv_srcadr, 1759 &fromlen); 1760 if (rb->recv_length == 0 1761 #ifdef EWOULDBLOCK 1762 || errno==EWOULDBLOCK 1763 #endif 1764 #ifdef EAGAIN 1765 || errno==EAGAIN 1766 #endif 1767 ) { 1768 freerecvbuf(rb); 1769 continue; 1770 } 1771 else if (rb->recv_length < 0) 1772 { 1773 netsyslog(LOG_ERR, "recvfrom(%s) fd=%d: %m", 1774 stoa(&rb->recv_srcadr), fd); 1775 #ifdef DEBUG 1776 if (debug) 1777 printf("input_handler: fd=%d dropped (bad recvfrom)\n", fd); 1778 #endif 1779 freerecvbuf(rb); 1780 continue; 1781 } 1782 #ifdef DEBUG 1783 if (debug > 2) { 1784 if(rb->recv_srcadr.ss_family == AF_INET) 1785 printf("input_handler: if=%d fd=%d length %d from %08lx %s\n", 1786 i, fd, rb->recv_length, 1787 (u_long)ntohl(((struct sockaddr_in*)&rb->recv_srcadr)->sin_addr.s_addr) & 1788 0x00000000ffffffff, 1789 stoa(&rb->recv_srcadr)); 1790 else 1791 printf("input_handler: if=%d fd=%d length %d from %s\n", 1792 i, fd, rb->recv_length, 1793 stoa(&rb->recv_srcadr)); 1794 } 1795 #endif 1796 1797 /* 1798 * Got one. Mark how and when it got here, 1799 * put it on the full list and do bookkeeping. 1800 */ 1801 rb->dstadr = &inter_list[i]; 1802 rb->fd = fd; 1803 rb->recv_time = ts; 1804 rb->receiver = receive; 1805 1806 add_full_recv_buffer(rb); 1807 1808 inter_list[i].received++; 1809 packets_received++; 1810 goto select_again; 1811 } 1812 /* Check more interfaces */ 1813 } 1814 } 1815 select_again:; 1816 /* 1817 * Done everything from that select. Poll again. 1818 */ 1819 } 1820 1821 /* 1822 * If nothing more to do, try again. 1823 * If nothing to do, just return. 1824 * If an error occurred, complain and return. 1825 */ 1826 if (n == 0) 1827 { 1828 if (select_count == 0) /* We really had nothing to do */ 1829 { 1830 if (debug) 1831 netsyslog(LOG_DEBUG, "input_handler: select() returned 0"); 1832 --handler_count; 1833 return; 1834 } 1835 /* We've done our work */ 1836 get_systime(&ts_e); 1837 /* 1838 * (ts_e - ts) is the amount of time we spent 1839 * processing this gob of file descriptors. Log 1840 * it. 1841 */ 1842 L_SUB(&ts_e, &ts); 1843 if (debug > 3) 1844 netsyslog(LOG_INFO, "input_handler: Processed a gob of fd's in %s msec", lfptoms(&ts_e, 6)); 1845 1846 /* just bail. */ 1847 --handler_count; 1848 return; 1849 } 1850 else if (n == -1) 1851 { 1852 int err = errno; 1853 1854 /* 1855 * extended FAU debugging output 1856 */ 1857 if (err != EINTR) 1858 netsyslog(LOG_ERR, 1859 "select(%d, %s, 0L, 0L, &0.0) error: %m", 1860 maxactivefd+1, 1861 fdbits(maxactivefd, &activefds)); 1862 if (err == EBADF) { 1863 int j, b; 1864 1865 fds = activefds; 1866 for (j = 0; j <= maxactivefd; j++) 1867 if ( 1868 (FD_ISSET(j, &fds) && (read(j, &b, 0) == -1)) 1869 ) 1870 netsyslog(LOG_ERR, "Bad file descriptor %d", j); 1871 } 1872 --handler_count; 1873 return; 1874 } 1875 } 1876 msyslog(LOG_ERR, "input_handler: fell out of infinite for(;;) loop!"); 1877 --handler_count; 1878 return; 1879 } 1880 1881 #endif 1882 /* 1883 * findinterface - find interface corresponding to address 1884 */ 1885 struct interface * 1886 findinterface( 1887 struct sockaddr_storage *addr 1888 ) 1889 { 1890 SOCKET s; 1891 int rtn, i; 1892 struct sockaddr_storage saddr; 1893 int saddrlen = SOCKLEN(addr); 1894 /* 1895 * This is considerably hoke. We open a socket, connect to it 1896 * and slap a getsockname() on it. If anything breaks, as it 1897 * probably will in some j-random knockoff, we just return the 1898 * wildcard interface. 1899 */ 1900 memset(&saddr, 0, sizeof(saddr)); 1901 saddr.ss_family = addr->ss_family; 1902 if(addr->ss_family == AF_INET) 1903 memcpy(&((struct sockaddr_in*)&saddr)->sin_addr, &((struct sockaddr_in*)addr)->sin_addr, sizeof(struct in_addr)); 1904 else if(addr->ss_family == AF_INET6) 1905 memcpy(&((struct sockaddr_in6*)&saddr)->sin6_addr, &((struct sockaddr_in6*)addr)->sin6_addr, sizeof(struct in6_addr)); 1906 ((struct sockaddr_in*)&saddr)->sin_port = htons(2000); 1907 s = socket(addr->ss_family, SOCK_DGRAM, 0); 1908 if (s == INVALID_SOCKET) 1909 return ANY_INTERFACE_CHOOSE(addr); 1910 1911 rtn = connect(s, (struct sockaddr *)&saddr, SOCKLEN(&saddr)); 1912 #ifndef SYS_WINNT 1913 if (rtn < 0) 1914 #else 1915 if (rtn == SOCKET_ERROR) 1916 #endif 1917 { 1918 closesocket(s); 1919 return ANY_INTERFACE_CHOOSE(addr); 1920 } 1921 1922 rtn = getsockname(s, (struct sockaddr *)&saddr, &saddrlen); 1923 closesocket(s); 1924 #ifndef SYS_WINNT 1925 if (rtn < 0) 1926 #else 1927 if (rtn == SOCKET_ERROR) 1928 #endif 1929 return ANY_INTERFACE_CHOOSE(addr); 1930 1931 for (i = 0; i < ninterfaces; i++) { 1932 /* 1933 * First look if is the the correct family 1934 */ 1935 if(inter_list[i].sin.ss_family != saddr.ss_family) 1936 continue; 1937 /* 1938 * We match the unicast address only. 1939 */ 1940 if (SOCKCMP(&inter_list[i].sin, &saddr)) 1941 return (&inter_list[i]); 1942 } 1943 return ANY_INTERFACE_CHOOSE(addr); 1944 } 1945 1946 /* 1947 * findbcastinter - find broadcast interface corresponding to address 1948 */ 1949 struct interface * 1950 findbcastinter( 1951 struct sockaddr_storage *addr 1952 ) 1953 { 1954 #if !defined(MPE) && (defined(SIOCGIFCONF) || defined(SYS_WINNT)) 1955 register int i; 1956 1957 i = find_addr_in_list(addr); 1958 if(i >= 0) 1959 return (&inter_list[i]); 1960 1961 for (i = 0; i < ninterfaces; i++) { 1962 /* 1963 * First look if this is the correct family 1964 */ 1965 if(inter_list[i].sin.ss_family != addr->ss_family) 1966 continue; 1967 /* 1968 * We match only those interfaces marked as 1969 * broadcastable and either the explicit broadcast 1970 * address or the network portion of the IP address. 1971 * Sloppy. 1972 */ 1973 if (!(inter_list[i].flags & INT_BROADCAST)) 1974 continue; 1975 if(addr->ss_family == AF_INET) { 1976 if (SOCKCMP(&inter_list[i].bcast, addr)) 1977 return (&inter_list[i]); 1978 if ((NSRCADR(&inter_list[i].sin) & 1979 NSRCADR(&inter_list[i].mask)) == (NSRCADR(addr) & 1980 NSRCADR(&inter_list[i].mask))) 1981 return (&inter_list[i]); 1982 } 1983 else if(addr->ss_family == AF_INET6) { 1984 if (SOCKCMP(&inter_list[i].bcast, addr)) 1985 return (&inter_list[i]); 1986 if (SOCKCMP(netof(&inter_list[i].sin), netof(addr))) 1987 return (&inter_list[i]); 1988 } 1989 } 1990 #endif /* SIOCGIFCONF */ 1991 return ANY_INTERFACE_CHOOSE(addr); 1992 } 1993 1994 1995 /* 1996 * io_clr_stats - clear I/O module statistics 1997 */ 1998 void 1999 io_clr_stats(void) 2000 { 2001 packets_dropped = 0; 2002 packets_ignored = 0; 2003 packets_received = 0; 2004 packets_sent = 0; 2005 packets_notsent = 0; 2006 2007 handler_calls = 0; 2008 handler_pkts = 0; 2009 io_timereset = current_time; 2010 } 2011 2012 2013 #ifdef REFCLOCK 2014 /* 2015 * This is a hack so that I don't have to fool with these ioctls in the 2016 * pps driver ... we are already non-blocking and turn on SIGIO thru 2017 * another mechanisim 2018 */ 2019 int 2020 io_addclock_simple( 2021 struct refclockio *rio 2022 ) 2023 { 2024 BLOCKIO(); 2025 /* 2026 * Stuff the I/O structure in the list and mark the descriptor 2027 * in use. There is a harmless (I hope) race condition here. 2028 */ 2029 rio->next = refio; 2030 refio = rio; 2031 2032 /* 2033 * I/O Completion Ports don't care about select and fd_set 2034 */ 2035 #ifndef HAVE_IO_COMPLETION_PORT 2036 if (rio->fd > maxactivefd) 2037 maxactivefd = rio->fd; 2038 FD_SET(rio->fd, &activefds); 2039 #endif 2040 UNBLOCKIO(); 2041 return 1; 2042 } 2043 2044 /* 2045 * io_addclock - add a reference clock to the list and arrange that we 2046 * get SIGIO interrupts from it. 2047 */ 2048 int 2049 io_addclock( 2050 struct refclockio *rio 2051 ) 2052 { 2053 BLOCKIO(); 2054 /* 2055 * Stuff the I/O structure in the list and mark the descriptor 2056 * in use. There is a harmless (I hope) race condition here. 2057 */ 2058 rio->next = refio; 2059 refio = rio; 2060 2061 # ifdef HAVE_SIGNALED_IO 2062 if (init_clock_sig(rio)) 2063 { 2064 refio = rio->next; 2065 UNBLOCKIO(); 2066 return 0; 2067 } 2068 # elif defined(HAVE_IO_COMPLETION_PORT) 2069 if (io_completion_port_add_clock_io(rio)) 2070 { 2071 add_socket_to_list(rio->fd); 2072 refio = rio->next; 2073 UNBLOCKIO(); 2074 return 0; 2075 } 2076 # endif 2077 2078 /* 2079 * I/O Completion Ports don't care about select and fd_set 2080 */ 2081 #ifndef HAVE_IO_COMPLETION_PORT 2082 if (rio->fd > maxactivefd) 2083 maxactivefd = rio->fd; 2084 FD_SET(rio->fd, &activefds); 2085 #endif 2086 UNBLOCKIO(); 2087 return 1; 2088 } 2089 2090 /* 2091 * io_closeclock - close the clock in the I/O structure given 2092 */ 2093 void 2094 io_closeclock( 2095 struct refclockio *rio 2096 ) 2097 { 2098 /* 2099 * Remove structure from the list 2100 */ 2101 if (refio == rio) 2102 { 2103 refio = rio->next; 2104 } 2105 else 2106 { 2107 register struct refclockio *rp; 2108 2109 for (rp = refio; rp != 0; rp = rp->next) 2110 if (rp->next == rio) 2111 { 2112 rp->next = rio->next; 2113 break; 2114 } 2115 2116 if (rp == 0) 2117 { 2118 /* 2119 * Internal error. Report it. 2120 */ 2121 msyslog(LOG_ERR, 2122 "internal error: refclockio structure not found"); 2123 return; 2124 } 2125 } 2126 2127 /* 2128 * Close the descriptor. 2129 */ 2130 close_file(rio->fd); 2131 } 2132 #endif /* REFCLOCK */ 2133 2134 /* 2135 * I/O Completion Ports don't care about select and fd_set 2136 */ 2137 #ifndef HAVE_IO_COMPLETION_PORT 2138 void 2139 kill_asyncio( 2140 int startfd 2141 ) 2142 { 2143 SOCKET i; 2144 2145 BLOCKIO(); 2146 for (i = startfd; i <= maxactivefd; i++) 2147 (void)close_socket(i); 2148 } 2149 #else 2150 /* 2151 * On NT a SOCKET is an unsigned int so we cannot possibly keep it in 2152 * an array. So we use one of the ISC_LIST functions to hold the 2153 * socket value and use that when we want to enumerate it. 2154 */ 2155 void 2156 kill_asyncio(int startfd) 2157 { 2158 vsock_t *lsock; 2159 vsock_t *next; 2160 2161 BLOCKIO(); 2162 2163 lsock = ISC_LIST_HEAD(sockets_list); 2164 while (lsock != NULL) { 2165 next = ISC_LIST_NEXT(lsock, link); 2166 close_socket(lsock->fd); 2167 lsock = next; 2168 } 2169 2170 } 2171 #endif 2172 /* 2173 * Add and delete functions for the list of open sockets 2174 */ 2175 void 2176 add_socket_to_list(SOCKET fd){ 2177 vsock_t *lsock = malloc(sizeof(vsock_t)); 2178 lsock->fd = fd; 2179 2180 ISC_LIST_APPEND(sockets_list, lsock, link); 2181 } 2182 void 2183 delete_socket_from_list(SOCKET fd) { 2184 2185 vsock_t *next; 2186 vsock_t *lsock = ISC_LIST_HEAD(sockets_list); 2187 2188 while(lsock != NULL) { 2189 next = ISC_LIST_NEXT(lsock, link); 2190 if(lsock->fd == fd) { 2191 ISC_LIST_DEQUEUE(sockets_list, lsock, link); 2192 free(lsock); 2193 break; 2194 } 2195 else 2196 lsock = next; 2197 } 2198 } 2199 void 2200 add_addr_to_list(struct sockaddr_storage *addr, int if_index){ 2201 remaddr_t *laddr = malloc(sizeof(remaddr_t)); 2202 memcpy(&laddr->addr, addr, sizeof(addr)); 2203 laddr->if_index = if_index; 2204 2205 ISC_LIST_APPEND(remoteaddr_list, laddr, link); 2206 #ifdef DEBUG 2207 if (debug) 2208 printf("Added addr %s to list of addresses\n", 2209 stoa(addr)); 2210 #endif 2211 2212 2213 } 2214 void 2215 delete_addr_from_list(struct sockaddr_storage *addr) { 2216 2217 remaddr_t *next; 2218 remaddr_t *laddr = ISC_LIST_HEAD(remoteaddr_list); 2219 2220 while(laddr != NULL) { 2221 next = ISC_LIST_NEXT(laddr, link); 2222 if(SOCKCMP(&laddr->addr, addr)) { 2223 ISC_LIST_DEQUEUE(remoteaddr_list, laddr, link); 2224 free(laddr); 2225 break; 2226 } 2227 else 2228 laddr = next; 2229 } 2230 #ifdef DEBUG 2231 if (debug) 2232 printf("Deleted addr %s from list of addresses\n", 2233 stoa(addr)); 2234 #endif 2235 } 2236 int 2237 find_addr_in_list(struct sockaddr_storage *addr) { 2238 2239 remaddr_t *next; 2240 remaddr_t *laddr = ISC_LIST_HEAD(remoteaddr_list); 2241 #ifdef DEBUG 2242 if (debug) 2243 printf("Finding addr %s in list of addresses\n", 2244 stoa(addr)); 2245 #endif 2246 2247 while(laddr != NULL) { 2248 next = ISC_LIST_NEXT(laddr, link); 2249 if(SOCKCMP(&laddr->addr, addr)) { 2250 return (laddr->if_index); 2251 break; 2252 } 2253 else 2254 laddr = next; 2255 } 2256 return (-1); /* Not found */ 2257 } 2258