From: Harlan Stenn Date: Sat, 17 Jun 2006 18:13:36 +0000 (-0400) Subject: Merge whimsy.udel.edu:/deacon/backroom/ntp-stable X-Git-Tag: NTP_4_2_3P4~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9d7368e02b9d3ccab91a056ff0211e91c771d5f4;p=thirdparty%2Fntp.git Merge whimsy.udel.edu:/deacon/backroom/ntp-stable into whimsy.udel.edu:/deacon/backroom/ntp-dev bk: 44944650VbDYh6m4zQnD6CSUx1wNJg --- 9d7368e02b9d3ccab91a056ff0211e91c771d5f4 diff --cc ntpd/ntp_io.c index c8f482843,462f42f6f..ec00fb40e --- a/ntpd/ntp_io.c +++ b/ntpd/ntp_io.c @@@ -1013,161 -671,66 +1013,174 @@@ update_interfaces if (scan_ipv6 == ISC_FALSE && family == AF_INET6) continue; - /* - * Check to see if we are going to use the interface - * If we don't use it we mark it to drop any packet - * received but we still must create the socket and - * bind to it. This prevents other apps binding to it - * and potentially causing problems with more than one - * process fiddling with the clock + /* + * create prototype */ - if (address_okay(&isc_if) == ISC_TRUE) { - inter_list[idx].ignore_packets = ISC_FALSE; - } - else { - inter_list[idx].ignore_packets = ISC_TRUE; + init_interface(&interface); + + DPRINT_INTERFACE(1, (&interface, "examining", "\n")); + + convert_isc_if(&isc_if, &interface, port); + + if (!(interface.flags & INT_UP)) { /* interfaces must be UP to be usable */ + DPRINTF(1, ("skipping interface %s (%s) - DOWN\n", interface.name, stoa(&interface.sin))); + continue; } - - convert_isc_if(&isc_if, &inter_list[idx], port); + + /* + * skip any interfaces UP and bound to a wildcard + * address - some dhcp clients produce that in the + * wild + */ + if (family == AF_INET && + ((struct sockaddr_in*)&inter_list[idx].sin)->sin_addr.s_addr == htonl(INADDR_ANY)) + continue; + + if (family == AF_INET6 && + memcmp(&((struct sockaddr_in6*)&inter_list[idx].sin)->sin6_addr, &in6addr_any, + sizeof(in6addr_any) == 0)) + continue; - inter_list[idx].fd = INVALID_SOCKET; - inter_list[idx].bfd = INVALID_SOCKET; - inter_list[idx].num_mcast = 0; - inter_list[idx].received = 0; - inter_list[idx].sent = 0; - inter_list[idx].notsent = 0; - idx++; + /* + * map to local *address* in order + * to map all duplicate interfaces to an interface structure + * with the appropriate socket (our name space is + * (ip-address) - NOT (interface name, ip-address)) + */ + iface = findlocalinterface(&interface.sin); + + if (iface && refresh_interface(iface)) + { + /* + * found existing and up to date interface - mark present + */ + + iface->phase = sys_interphase; + DPRINT_INTERFACE(2, (iface, "updating ", " present\n")); + ifi.action = IFS_EXISTS; + ifi.interface = iface; + if (receiver) + receiver(data, &ifi); + } + else + { + /* + * this is new or refreshing failed - add to our interface list + * if refreshing failed we will delete the interface structure in + * phase 2 as the interface was not marked current. We can bind to + * the address as the refresh code already closed the offending socket + */ + + iface = create_interface(port, &interface); + + if (iface) + { + ifi.action = IFS_CREATED; + ifi.interface = iface; + if (receiver && iface) + receiver(data, &ifi); + DPRINT_INTERFACE(2, (iface ? iface : &interface, "updating ", iface ? " new - created\n" : " new - creation FAILED")); + } + else + { + msyslog(LOG_INFO, "failed to initialize interface for address %s", stoa(&interface.sin)); + } + } + /* + * Check to see if we are going to use the interface + * If we don't use it we mark it to drop any packet + * received but we still must create the socket and + * bind to it. This prevents other apps binding to it + * and potentially causing problems with more than one + * process fiddling with the clock + */ + if (address_okay(&isc_if) == ISC_TRUE) { + iface->ignore_packets = ISC_FALSE; + } + else { + iface->ignore_packets = ISC_TRUE; + } } + isc_interfaceiter_destroy(&iter); - ninterfaces = idx; /* - * Create the sockets + * phase 2 - delete gone interfaces - reassigning peers to other interfaces */ - for (i = 0; i < ninterfaces; i++) { - inter_list[i].fd = open_socket(&inter_list[i].sin, - inter_list[i].flags, 0, &inter_list[i], i); - if (inter_list[i].fd != INVALID_SOCKET) - msyslog(LOG_INFO, "Listening on interface %s, %s#%d %s", - inter_list[i].name, - stoa((&inter_list[i].sin)), - NTP_PORT, - (inter_list[i].ignore_packets == ISC_FALSE) ? - "Enabled": "Disabled"); + { + struct interface *interf = ISC_LIST_HEAD(inter_list); + + while (interf != NULL) + { + struct interface *next = ISC_LIST_NEXT(interf, link); + + if (!(interf->flags & (INT_WILDCARD|INT_MCASTIF))) { + /* + * if phase does not match sys_phase this interface was not + * enumerated during interface scan - so it is gone and + * will be deleted here unless it is solely an MCAST interface + */ + if (interf->phase != sys_interphase) { + struct peer *peer; + DPRINT_INTERFACE(2, (interf, "updating ", "GONE - deleting\n")); + remove_interface(interf); + + ifi.action = IFS_DELETED; + ifi.interface = interf; + if (receiver) + receiver(data, &ifi); + + peer = ISC_LIST_HEAD(interf->peers); + /* + * disconnect peer from deleted interface + */ + while (peer != NULL) { + struct peer *npeer = ISC_LIST_NEXT(peer, ilink); + + /* + * this one just lost it's interface + */ + set_peerdstadr(peer, NULL); + + peer = npeer; + } + delete_interface(interf); + } + } + interf = next; + } + } + /* - * Calculate the address hash for each interface address. + * phase3 - re-configure as the world has changed if necessary */ - inter_list[i].addr_refid = addr2refid(&inter_list[i].sin); - } + refresh_all_peerinterfaces(); +} + + +/* + * create_sockets - create a socket for each interface plus a default + * socket for when we don't know where to send + */ +static int +create_sockets( + u_short port + ) +{ +#ifndef HAVE_IO_COMPLETION_PORT + /* + * I/O Completion Ports don't care about the select and FD_SET + */ + maxactivefd = 0; + FD_ZERO(&activefds); +#endif + + DPRINTF(2, ("create_sockets(%d)\n", ntohs( (u_short) port))); + create_wildcards(port); + + update_interfaces(port, NULL, NULL); + /* * Now that we have opened all the sockets, turn off the reuse * flag for security.