]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 2263] broadcast server doesn't work for host with OS_MISSES_SPECIFIC_ROUTE_UPDATES
authorHarlan Stenn <stenn@ntp.org>
Fri, 14 Sep 2012 22:44:39 +0000 (18:44 -0400)
committerHarlan Stenn <stenn@ntp.org>
Fri, 14 Sep 2012 22:44:39 +0000 (18:44 -0400)
bk: 5053b357ixSabcMDezjSxUarhp8l1g

ChangeLog
include/ntp.h
ntpd/keyword-gen.c
ntpd/ntp_io.c
ntpd/ntp_parser.y

index fccaa475763365de834a0ab7481ec98e8b63d3a1..438cadcbea9767f45d3589c19275b5fa15da23e3 100644 (file)
--- 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 <stenn@ntp.org>
 * [Bug 2264] Cleanup SEL240X Refclock.
index 5f6c275f668b66ffd32e8115626f034809789371..aa45e1604380c6cb78622e7939ae51e037869a16 100644 (file)
@@ -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)
index ea548237d87a1fbb973d23bdc5d93a8efe35e134..53d916fc0c424ceea726c26624a19252ce8b3084 100644 (file)
@@ -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 },
index edf3961ad93b311f6d13eee7aece6cc76aa418fe..3d77864ecf1ce30a73f86469b998a5fff654d94b 100644 (file)
@@ -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;
 }
 
 /*
index b7b28db5a050ae65b5063531a42d76a5ce3edae9..435fe9b6b61ba73ad5a9961e61b2a6fe1ea1a5cd 100644 (file)
@@ -66,6 +66,7 @@
 }
 
 /* TERMINALS (do not appear left of colon) */
+%token <Integer>       T_Abbrev
 %token <Integer>       T_Age
 %token <Integer>       T_All
 %token <Integer>       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); }
        ;