extern struct peer *findpeer P((struct sockaddr_storage *, struct interface *, int, int *));
extern struct peer *findpeerbyassoc P((u_int));
extern void set_peerdstadr P((struct peer *peer, struct interface *interface));
-extern struct interface *select_peerinterface P((struct peer *, struct sockaddr_storage *, struct interface *, u_char));
extern struct peer *newpeer P((struct sockaddr_storage *, struct interface *, int, int, int, int, u_int, u_char, int, keyid_t));
extern void peer_all_reset P((void));
extern void peer_clr_stats P((void));
*/
init_interface(&interface);
- DPRINT_INTERFACE(1, (&interface, "examining", "\n"));
-
convert_isc_if(&isc_if, &interface, port);
+ DPRINT_INTERFACE(1, (&interface, "examining ", "\n"));
+
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;
#ifdef RTM_DELETE
case RTM_DELETE:
#endif
+#ifdef RTM_REDIRECT
+ case RTM_REDIRECT:
+#endif
+#ifdef RTM_CHANGE
+ case RTM_CHANGE:
+#endif
#ifdef RTM_LOSING
case RTM_LOSING:
#endif
* we are keen on new and deleted addresses and if an interface goes up and down or routing changes
*/
DPRINTF(1, ("routing message op = %d: scheduling interface update\n", rtm->rtm_type));
- timer_interfacetimeout(current_time + 2);
+ timer_interfacetimeout(current_time);
break;
default:
/*
static struct peer init_peer_alloc[INIT_PEER_ALLOC]; /* init alloc */
static void getmorepeermem P((void));
+static struct interface *select_peerinterface P((struct peer *, struct sockaddr_storage *, struct interface *, u_char));
/*
* init_peer - initialize peer data structures and counters
set_peerdstadr(struct peer *peer, struct interface *interface)
{
if (peer->dstadr != interface) {
+ struct interface *prev_dstadr = peer->dstadr;
+
if (peer->dstadr != NULL)
{
peer->dstadr->peercnt--;
ISC_LIST_UNLINK_TYPE(peer->dstadr->peers, peer, ilink, struct peer);
}
- if (interface == NULL)
- {
+ DPRINTF(1, ("set_peerdstadr(%s): change interface from %s to %s\n",
+ stoa(&peer->srcadr),
+ (peer->dstadr != NULL) ? stoa(&peer->dstadr->sin) : "<null>",
+ (interface != NULL) ? stoa(&interface->sin) : "<null>"));
+
+ peer->dstadr = interface;
+
+ if (prev_dstadr != NULL) {
/*
- * reset crypto information if we disconnect from
- * an interface - other crypto updates are handled
- * by the crypto machinery
+ * reset crypto information if we change from an
+ * active interface
+ * all other crypto updates are handled by the crypto
+ * machinery
*/
-#ifdef DEBUG
- msyslog(LOG_INFO, "set_peerdstadr: disconnecting peer from interface - clearing crypto");
-#endif
peer_crypto_clear(peer);
}
- DPRINTF(1, ("set_peerdstadr: at %ld next %ld assoc ID %d\n",
- current_time, peer->nextdate, peer->associd));
-
-
- peer->dstadr = interface;
-
if (peer->dstadr != NULL)
{
ISC_LIST_APPEND(peer->dstadr->peers, peer, ilink);
int n;
/*
- * this is called when te interfac list has changed
+ * this is called when the interface list has changed
* give all peers a chance to find a better interface
*/
for (n = 0; n < NTP_HASH_SIZE; n++) {
/*
* find an interface suitable for the src address
*/
-struct interface *
+static struct interface *
select_peerinterface(struct peer *peer, struct sockaddr_storage *srcadr, struct interface *dstadr, u_char cast_flags)
{
struct interface *interface;
interface = dstadr;
else
interface = findinterface(srcadr);
+
+ /*
+ * we do not bind to the wildcard interfaces for output
+ * as our (network) source address would be undefined and
+ * crypto will not work without knowing the own transmit address
+ */
+ if (interface != NULL && interface->flags & INT_WILDCARD)
+ interface = NULL;
+
return interface;
}
return (NULL);
}
+ peer->srcadr = *srcadr;
+ peer->hmode = (u_char)hmode;
+ peer->version = (u_char)version;
+ peer->minpoll = (u_char)max(NTP_MINPOLL, minpoll);
+ peer->maxpoll = (u_char)min(NTP_MAXPOLL, maxpoll);
+ peer->flags = flags;
+
set_peerdstadr(peer, dstadr);
+
+#ifdef DEBUG
+ if (debug>2) {
+ if (peer->dstadr)
+ printf("newpeer: using fd %d and our addr %s\n",
+ peer->dstadr->fd, stoa(&peer->dstadr->sin));
+ else
+ printf("newpeer: local interface currently not bound\n");
+ }
+#endif
/*
* Broadcast needs the socket enabled for broadcast
if (cast_flags & MDF_MCAST && peer->dstadr) {
enable_multicast_if(peer->dstadr, srcadr);
}
-#ifdef DEBUG
- if (debug>2) {
- if (peer->dstadr)
- printf("newpeer: using fd %d and our addr %s\n",
- peer->dstadr->fd, stoa(&peer->dstadr->sin));
- else
- printf("newpeer: local interface currently not bound\n");
- }
-#endif
- peer->srcadr = *srcadr;
- peer->hmode = (u_char)hmode;
- peer->version = (u_char)version;
- peer->minpoll = (u_char)max(NTP_MINPOLL, minpoll);
- peer->maxpoll = (u_char)min(NTP_MAXPOLL, maxpoll);
- peer->flags = flags;
if (key != 0)
peer->flags |= FLAG_AUTHENABLE;
if (key > NTP_MAXKEY)