]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 3031]
authorJuergen Perlinger <perlinger@ntp.org>
Wed, 30 Mar 2016 17:23:06 +0000 (19:23 +0200)
committerJuergen Perlinger <perlinger@ntp.org>
Wed, 30 Mar 2016 17:23:06 +0000 (19:23 +0200)
bk: 56fc0b7aFs-Og_w3xoHRCZlPNA1QGQ

ntpd/ntp_io.c
ntpd/ntp_proto.c

index 95229d6a7f022d0cd6b9b8939f4985434c5e4982..8050bb3afa562d1dcc64391c2effa3dddd6b6904 100644 (file)
@@ -1013,8 +1013,8 @@ remove_interface(
                        stoa(&ep->bcast), ep->ifnum, ep->name);
                close_and_delete_fd_from_list(ep->bfd);
                ep->bfd = INVALID_SOCKET;
-               ep->flags &= ~INT_BCASTOPEN;
        }
+       ep->flags &= ~INT_BCASTOPEN;
 
        ninterfaces--;
        mon_clearinterface(ep);
@@ -2565,7 +2565,7 @@ io_setbclient(void)
                        continue;
 
                /* Only IPv4 addresses are valid for broadcast */
-               REQUIRE(IS_IPV4(&interf->sin));
+               REQUIRE(IS_IPV4(&interf->bcast));
 
                /* Do we already have the broadcast address open? */
                if (interf->flags & INT_BCASTOPEN) {
@@ -2593,13 +2593,31 @@ io_setbclient(void)
                        msyslog(LOG_INFO,
                                "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);
+               } else switch (errno) {
+                       /* Silently ignore EADDRINUSE as we probably
+                        * opened the socket already for an address in
+                        * the same network */
+               case EADDRINUSE:
+                       /* Some systems cannot bind a socket to a broadcast
+                        * address, as that is not a valid host address. */
+               case EADDRNOTAVAIL:
+#                  ifdef SYS_WINNT     /*TODO: use for other systems, too? */
+                       /* avoid recurrence here -- if we already have a
+                        * regular socket, it's quite useless to try this
+                        * again.
+                        */
+                       if (interf->fd != INVALID_SOCKET) {
+                               interf->flags |= INT_BCASTOPEN;
+                               nif++;
+                       }
+#                  endif
+                       break;
+
+               default:
+                       msyslog(LOG_INFO,
+                               "failed to listen for broadcasts to %s on interface #%d %s",
+                               stoa(&interf->bcast), interf->ifnum, interf->name);
+                       break;
                }
        }
        set_reuseaddr(0);
@@ -2639,8 +2657,8 @@ io_unsetbclient(void)
                                stoa(&ep->bcast), ep->ifnum, ep->name);
                        close_and_delete_fd_from_list(ep->bfd);
                        ep->bfd = INVALID_SOCKET;
-                       ep->flags &= ~INT_BCASTOPEN;
                }
+               ep->flags &= ~INT_BCASTOPEN;
        }
        broadcast_client_enabled = ISC_FALSE;
 }
index 43f166f26fe5fc96cad5cef0c547bd3421b0f7e9..d757b5bf284922df6941498d5d0ee63ece8413ed 100644 (file)
 #include <unistd.h>
 #endif
 
+/*[Bug 3031] define automatic broadcastdelay cutoff preset */
+#ifndef BDELAY_DEFAULT
+# define BDELAY_DEFAULT (-0.050)
+#endif
+
 /*
  * This macro defines the authentication state. If x is 1 authentication
  * is required; othewise it is optional.
@@ -1144,7 +1149,7 @@ receive(
                /*
                 * Determine whether to execute the initial volley.
                 */
-               if (sys_bdelay != 0) {
+               if (sys_bdelay > 0.0) {
 #ifdef AUTOKEY
                        /*
                         * If a two-way exchange is not possible,
@@ -1339,7 +1344,7 @@ receive(
                        }
 
                        if (  (current_time - peer->timelastrec)
-                           < (1 << pkt->ppoll)) {
+                           < (1u << pkt->ppoll) - 1) {
                                msyslog(LOG_INFO, "receive: broadcast packet from %s arrived after %ld, not %d seconds!",
                                        stoa(&rbufp->recv_srcadr),
                                        (current_time - peer->timelastrec),
@@ -1993,8 +1998,11 @@ process_packet(
                if (FLAG_BC_VOL & peer->flags) {
                        peer->flags &= ~FLAG_BC_VOL;
                        peer->delay = fabs(peer->offset - p_offset) * 2;
-                       if (peer->delay > 0.05) {
-       bcc_init_volley_fail:
+                       DPRINTF(2, ("broadcast volley: initial delay=%.6f\n",
+                               peer->delay));
+                       if (peer->delay > fabs(sys_bdelay)) {
+               bcc_init_volley_fail:
+                               DPRINTF(2, ("%s", "broadcast volley: initial delay exceeds limit\n"));
                                unpeer(peer);
                                return;
                        }
@@ -4344,7 +4352,7 @@ init_proto(void)
        sys_survivors = 0;
        sys_manycastserver = 0;
        sys_bclient = 0;
-       sys_bdelay = 0;
+       sys_bdelay = BDELAY_DEFAULT;    /*[Bug 3031] delay cutoff */
        sys_authenticate = 1;
        sys_stattime = current_time;
        orphwait = current_time + sys_orphwait;
@@ -4437,7 +4445,7 @@ proto_config(
                break;
 
        case PROTO_BROADDELAY:  /* default broadcast delay (bdelay) */
-               sys_bdelay = dvalue;
+               sys_bdelay = (dvalue ? dvalue : BDELAY_DEFAULT);
                break;
 
        case PROTO_CEILING:     /* stratum ceiling (ceiling) */