From: Harlan Stenn Date: Fri, 14 Sep 2012 22:44:39 +0000 (-0400) Subject: [Bug 2263] broadcast server doesn't work for host with OS_MISSES_SPECIFIC_ROUTE_UPDATES X-Git-Tag: NTP_4_2_7P305~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c9860addc747b3dcc08e8fa1d20d77ee4dd1ba95;p=thirdparty%2Fntp.git [Bug 2263] broadcast server doesn't work for host with OS_MISSES_SPECIFIC_ROUTE_UPDATES bk: 5053b357ixSabcMDezjSxUarhp8l1g --- diff --git a/ChangeLog b/ChangeLog index fccaa4757..438cadcbe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,6 @@ * [Bug 752] Use proper ToS network packet markings for IPv4 and IPv6. +* [Bug 2263] broadcast server doesn't work for host with + OS_MISSES_SPECIFIC_ROUTE_UPDATES. * [Bug 2271] Decode refclock types when built with --disable-all-clocks. (4.2.7p304) 2012/09/06 Released by Harlan Stenn * [Bug 2264] Cleanup SEL240X Refclock. diff --git a/include/ntp.h b/include/ntp.h index 5f6c275f6..aa45e1604 100644 --- a/include/ntp.h +++ b/include/ntp.h @@ -207,11 +207,12 @@ struct interface { #define INT_LOOPBACK 0x004 /* the loopback interface */ #define INT_BROADCAST 0x008 /* can broadcast out this interface */ #define INT_MULTICAST 0x010 /* can multicast out this interface */ -#define INT_BCASTOPEN 0x020 /* broadcast socket is open */ +#define INT_BCASTOPEN 0x020 /* broadcast receive socket is open */ #define INT_MCASTOPEN 0x040 /* multicasting enabled */ #define INT_WILDCARD 0x080 /* wildcard interface - usually skipped */ #define INT_MCASTIF 0x100 /* bound directly to MCAST address */ #define INT_PRIVACY 0x200 /* RFC 4941 IPv6 privacy address */ +#define INT_BCASTXMIT 0x400 /* socket setup to allow broadcasts */ /* * Define flasher bits (tests 1 through 11 in packet procedure) diff --git a/ntpd/keyword-gen.c b/ntpd/keyword-gen.c index ea548237d..53d916fc0 100644 --- a/ntpd/keyword-gen.c +++ b/ntpd/keyword-gen.c @@ -181,6 +181,7 @@ struct key_tok ntp_keywords[] = { { "maxmem", T_Maxmem, FOLLBY_TOKEN }, { "mru", T_Mru, FOLLBY_TOKEN }, /* fudge_factor */ +{ "abbrev", T_Abbrev, FOLLBY_STRING }, { "flag1", T_Flag1, FOLLBY_TOKEN }, { "flag2", T_Flag2, FOLLBY_TOKEN }, { "flag3", T_Flag3, FOLLBY_TOKEN }, diff --git a/ntpd/ntp_io.c b/ntpd/ntp_io.c index edf3961ad..3d77864ec 100644 --- a/ntpd/ntp_io.c +++ b/ntpd/ntp_io.c @@ -1022,14 +1022,16 @@ remove_interface( ep->notsent, current_time - ep->starttime); close_and_delete_fd_from_list(ep->fd); + ep->fd = INVALID_SOCKET; } if (ep->bfd != INVALID_SOCKET) { msyslog(LOG_INFO, - "Deleting broadcast address %s#%d from interface #%d %s", - stoa(&ep->bcast), SRCPORT(&ep->bcast), - ep->ifnum, ep->name); + "stop listening for broadcasts to %s on interface #%d %s", + stoa(&ep->bcast), ep->ifnum, ep->name); close_and_delete_fd_from_list(ep->bfd); + ep->bfd = INVALID_SOCKET; + ep->flags &= ~INT_BCASTOPEN; } ninterfaces--; @@ -1475,9 +1477,18 @@ refresh_interface( { #ifdef OS_MISSES_SPECIFIC_ROUTE_UPDATES if (interface->fd != INVALID_SOCKET) { + int bcast = (interface->flags & INT_BCASTXMIT) != 0; + /* as we forcibly close() the socket remove the + broadcast permission indication */ + if (bcast) + socket_broadcast_disable(interface, &interface->sin); + close_and_delete_fd_from_list(interface->fd); + + /* create new socket picking up a new first hop binding + at connect() time */ interface->fd = open_socket(&interface->sin, - 0, 0, interface); + bcast, 0, interface); /* * reset TTL indication so TTL is is set again * next time around @@ -1918,6 +1929,10 @@ update_interfaces( /* * phase 3 - re-configure as the world has changed if necessary */ + + if (broadcast_client_enabled) + io_setbclient(); + if (refresh_peers) { refresh_all_peerinterfaces(); msyslog(LOG_INFO, "peers refreshed"); @@ -2180,8 +2195,7 @@ socket_broadcast_enable( DPRINTF(2, ("Broadcast enabled on socket %d for address %s\n", fd, stoa(baddr))); } - iface->flags |= INT_BCASTOPEN; - broadcast_client_enabled = ISC_TRUE; + iface->flags |= INT_BCASTXMIT; return ISC_TRUE; #else return ISC_FALSE; @@ -2208,8 +2222,7 @@ socket_broadcast_disable( "setsockopt(SO_BROADCAST) disable failure on address %s: %m", stoa(baddr)); - iface->flags &= ~INT_BCASTOPEN; - broadcast_client_enabled = ISC_FALSE; + iface->flags &= ~INT_BCASTXMIT; return ISC_TRUE; #else return ISC_FALSE; @@ -2484,9 +2497,6 @@ io_setbclient(void) #ifdef OPEN_BCAST_SOCKET struct interface * interf; int nif; - isc_boolean_t jstatus; - SOCKET fd; - u_int32 prev_refid; nif = 0; set_reuseaddr(1); @@ -2530,36 +2540,30 @@ io_setbclient(void) * broadcast on the interface address */ if (interf->bfd != INVALID_SOCKET) { - fd = interf->bfd; - jstatus = ISC_TRUE; - } else { - fd = interf->fd; - jstatus = socket_broadcast_enable(interf, fd, - &interf->sin); - } - - /* Enable Broadcast on socket */ - if (jstatus) { nif++; + interf->flags |= INT_BCASTOPEN; msyslog(LOG_INFO, - "io_setbclient: Opened broadcast client on interface #%d %s", - interf->ifnum, interf->name); - /* hart suspects this is unneeded, verify */ - prev_refid = interf->addr_refid; - interf->addr_refid = addr2refid(&interf->sin); - if (prev_refid != interf->addr_refid) - msyslog(LOG_NOTICE, - "io_setbclient: code is not dead, addr_refid for %s updated %8.8x -> %8.8x, please email hart@ntp.org to remove this message", - stoa(&interf->sin), prev_refid, - interf->addr_refid); + "Listen for broadcasts to %s on interface #%d %s", + stoa(&interf->bcast), interf->ifnum, interf->name); + } else { + /* silently ignore EADDRINUSE as we probably opened + the socket already for an address in the same network */ + if (errno != EADDRINUSE) + msyslog(LOG_INFO, + "failed to listen for broadcasts to %s on interface #%d %s", + stoa(&interf->bcast), interf->ifnum, interf->name); } } set_reuseaddr(0); - if (nif > 0) - DPRINTF(1, ("io_setbclient: Opened broadcast clients\n")); - else if (!nif) + if (nif > 0) { + broadcast_client_enabled = ISC_TRUE; + DPRINTF(1, ("io_setbclient: listening to %d broadcast addresses\n", nif)); + } + else if (!nif) { + broadcast_client_enabled = ISC_FALSE; msyslog(LOG_ERR, "Unable to listen for broadcasts, no broadcast interfaces available"); + } #else msyslog(LOG_ERR, "io_setbclient: Broadcast Client disabled by build"); @@ -2579,8 +2583,18 @@ io_unsetbclient(void) continue; if (!(INT_BCASTOPEN & ep->flags)) continue; - socket_broadcast_disable(ep, &ep->sin); + + if (ep->bfd != INVALID_SOCKET) { + /* destroy broadcast listening socket */ + msyslog(LOG_INFO, + "stop listening for broadcasts to %s on interface #%d %s", + stoa(&ep->bcast), ep->ifnum, ep->name); + close_and_delete_fd_from_list(ep->bfd); + ep->bfd = INVALID_SOCKET; + ep->flags &= ~INT_BCASTOPEN; + } } + broadcast_client_enabled = ISC_FALSE; } /* diff --git a/ntpd/ntp_parser.y b/ntpd/ntp_parser.y index b7b28db5a..435fe9b6b 100644 --- a/ntpd/ntp_parser.y +++ b/ntpd/ntp_parser.y @@ -66,6 +66,7 @@ } /* TERMINALS (do not appear left of colon) */ +%token T_Abbrev %token T_Age %token T_All %token T_Allan @@ -943,6 +944,8 @@ fudge_factor { $$ = create_attr_ival($1, $2); } | T_Stratum T_Integer { $$ = create_attr_ival($1, $2); } + | T_Abbrev T_String + { $$ = create_attr_sval($1, $2); } | T_Refid T_String { $$ = create_attr_sval($1, $2); } ;