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);
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) {
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);
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;
}
#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.
/*
* 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,
}
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),
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;
}
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;
break;
case PROTO_BROADDELAY: /* default broadcast delay (bdelay) */
- sys_bdelay = dvalue;
+ sys_bdelay = (dvalue ? dvalue : BDELAY_DEFAULT);
break;
case PROTO_CEILING: /* stratum ceiling (ceiling) */