aboutsummaryrefslogtreecommitdiff
path: root/contrib/ntp/ntpd/ntp_peer.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ntp/ntpd/ntp_peer.c')
-rw-r--r--contrib/ntp/ntpd/ntp_peer.c566
1 files changed, 291 insertions, 275 deletions
diff --git a/contrib/ntp/ntpd/ntp_peer.c b/contrib/ntp/ntpd/ntp_peer.c
index 90646abcfac7..b1641817f165 100644
--- a/contrib/ntp/ntpd/ntp_peer.c
+++ b/contrib/ntp/ntpd/ntp_peer.c
@@ -10,6 +10,9 @@
#include "ntpd.h"
#include "ntp_stdlib.h"
+#ifdef AUTOKEY
+#include "ntp_crypto.h"
+#endif /* AUTOKEY */
/*
* Table of valid association combinations
@@ -27,15 +30,13 @@
* CONTROL | e 0 0 0 0 0
* PRIVATE | e 0 0 0 0 0
* BCLIENT | e 0 0 0 e 1
- * MCLIENT | e 0 0 0 0 0
*
- * One point to note here:
- * a packet in BCAST mode can potentially match a peer in CLIENT
- * mode, but we that is a special case and we check for that early
- * in the decision process. This avoids having to keep track of
- * what kind of associations are possible etc... We actually
- * circumvent that problem by requiring that the first b(m)roadcast
- * received after the change back to BCLIENT mode sets the clock.
+ * One point to note here: a packet in BCAST mode can potentially match
+ * a peer in CLIENT mode, but we that is a special case and we check for
+ * that early in the decision process. This avoids having to keep track
+ * of what kind of associations are possible etc... We actually
+ * circumvent that problem by requiring that the first b(m)roadcast
+ * received after the change back to BCLIENT mode sets the clock.
*/
int AM[AM_MODES][AM_MODES] = {
@@ -58,82 +59,59 @@ int AM[AM_MODES][AM_MODES] = {
/*PRIV*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
/*BCL*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_ERR, AM_PROCPKT},
-
-/*MCL*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH}
};
#define MATCH_ASSOC(x,y) AM[(x)][(y)]
/*
* These routines manage the allocation of memory to peer structures
- * and the maintenance of the peer hash table. The two main entry
- * points are findpeer(), which looks for corresponding peer data
- * in the peer list, newpeer(), which allocates a new peer structure
- * and adds it to the list, and unpeer(), which demobilizes the association
+ * and the maintenance of the peer hash table. The two main entry
+ * points are findpeer(), which looks for matching peer sturctures in
+ * the peer list, newpeer(), which allocates a new peer structure and
+ * adds it to the list, and unpeer(), which demobilizes the association
* and deallocates the structure.
*/
-
-/*
- * The peer hash table (imported by the protocol module).
- */
-struct peer *peer_hash[HASH_SIZE];
-int peer_hash_count[HASH_SIZE]; /* count of peers in each bucket */
-
/*
- * The association ID hash table. Used for lookups by association ID
+ * Peer hash tables
*/
-struct peer *assoc_hash[HASH_SIZE];
-int assoc_hash_count[HASH_SIZE];
+struct peer *peer_hash[HASH_SIZE]; /* peer hash table */
+int peer_hash_count[HASH_SIZE]; /* peers in each bucket */
+struct peer *assoc_hash[HASH_SIZE]; /* association ID hash table */
+int assoc_hash_count[HASH_SIZE]; /* peers in each bucket */
+static struct peer *peer_free; /* peer structures free list */
+int peer_free_count; /* count of free structures */
/*
- * The free list. Clean structures only, please.
- */
-static struct peer *peer_free;
-int peer_free_count;
-
-/*
- * Association ID. We initialize this value randomly, the assign a new
+ * Association ID. We initialize this value randomly, then assign a new
* value every time the peer structure is incremented.
*/
-static u_short current_association_ID;
+static associd_t current_association_ID; /* association ID */
/*
* Memory allocation watermarks.
*/
-#define INIT_PEER_ALLOC 15 /* initialize space for 15 peers */
-#define INC_PEER_ALLOC 5 /* when we run out, add 5 more */
+#define INIT_PEER_ALLOC 15 /* initialize for 15 peers */
+#define INC_PEER_ALLOC 5 /* when run out, add 5 more */
/*
* Miscellaneous statistic counters which may be queried.
*/
-u_long peer_timereset; /* time stat counters were zeroed */
-u_long findpeer_calls; /* number of calls to findpeer */
-u_long assocpeer_calls; /* number of calls to findpeerbyassoc */
-u_long peer_allocations; /* number of allocations from the free list */
-u_long peer_demobilizations; /* number of structs freed to free list */
-int total_peer_structs; /* number of peer structs in circulation */
-int peer_associations; /* number of active associations */
-
-/*
- * Our initial allocation of peer space
- */
-static struct peer init_peer_alloc[INIT_PEER_ALLOC];
-
-/*
- * Initialization data. When configuring peers at initialization time,
- * we try to get their poll update timers initialized to different values
- * to prevent us from sending big clumps of data all at once.
- */
-/* static u_long init_peer_starttime; */
+u_long peer_timereset; /* time stat counters zeroed */
+u_long findpeer_calls; /* calls to findpeer */
+u_long assocpeer_calls; /* calls to findpeerbyassoc */
+u_long peer_allocations; /* allocations from free list */
+u_long peer_demobilizations; /* structs freed to free list */
+int total_peer_structs; /* peer structs */
+int peer_associations; /* active associations */
+static struct peer init_peer_alloc[INIT_PEER_ALLOC]; /* init alloc */
static void getmorepeermem P((void));
-static void key_expire P((struct peer *));
/*
* init_peer - initialize peer data structures and counters
*
- * N.B. We use the random number routine in here. It had better be
- * initialized prior to getting here.
+ * N.B. We use the random number routine in here. It had better be
+ * initialized prior to getting here.
*/
void
init_peer(void)
@@ -157,11 +135,6 @@ init_peer(void)
assocpeer_calls = peer_demobilizations = 0;
/*
- * Initialization counter.
- */
- /* init_peer_starttime = 0; */
-
- /*
* Initialize peer memory.
*/
peer_free = 0;
@@ -175,7 +148,7 @@ init_peer(void)
/*
* Initialize our first association ID
*/
- current_association_ID = (u_short)ranp2(16);
+ current_association_ID = (associd_t)ranp2(16);
if (current_association_ID == 0)
current_association_ID = 1;
}
@@ -190,7 +163,8 @@ getmorepeermem(void)
register int i;
register struct peer *peer;
- peer = (struct peer *)emalloc(INC_PEER_ALLOC*sizeof(struct peer));
+ peer = (struct peer *)emalloc(INC_PEER_ALLOC *
+ sizeof(struct peer));
for (i = 0; i < INC_PEER_ALLOC; i++) {
peer->next = peer_free;
peer_free = peer;
@@ -202,7 +176,6 @@ getmorepeermem(void)
}
-
/*
* findexistingpeer - return a pointer to a peer in the hash table
*/
@@ -220,22 +193,21 @@ findexistingpeer(
* same peer through different interfaces in the hash table.
*/
if (start_peer == 0)
- peer = peer_hash[HASH_ADDR(addr)];
+ peer = peer_hash[HASH_ADDR(addr)];
else
- peer = start_peer->next;
+ peer = start_peer->next;
while (peer != 0) {
if (NSRCADR(addr) == NSRCADR(&peer->srcadr)
&& NSRCPORT(addr) == NSRCPORT(&peer->srcadr)) {
if (mode == -1)
- return peer;
+ return (peer);
else if (peer->hmode == mode)
break;
}
peer = peer->next;
}
-
- return peer;
+ return (peer);
}
@@ -259,50 +231,46 @@ findpeer(
for (peer = peer_hash[hash]; peer != 0; peer = peer->next) {
if (NSRCADR(srcadr) == NSRCADR(&peer->srcadr)
&& NSRCPORT(srcadr) == NSRCPORT(&peer->srcadr)) {
+
/*
- * if the association matching rules determine that
- * this is not a valid combination, then look for
- * the next valid peer association.
+ * if the association matching rules determine
+ * that this is not a valid combination, then
+ * look for the next valid peer association.
*/
*action = MATCH_ASSOC(peer->hmode, pkt_mode);
/*
* Sigh! Check if BCLIENT peer in client
- * server mode, else return error
+ * server mode, else return error.
*/
- if ((*action == AM_POSSBCL) &&
- !(peer->cast_flags & FLAG_MCAST1)) {
+ if ((*action == AM_POSSBCL) && !(peer->flags &
+ FLAG_MCAST))
*action = AM_ERR;
- }
- /* if an error was returned, exit back right here */
+ /*
+ * if an error was returned, exit back right
+ * here.
+ */
if (*action == AM_ERR)
- return (struct peer *)0;
+ return ((struct peer *)0);
- /* if a match is found, we stop our search */
+ /*
+ * if a match is found, we stop our search.
+ */
if (*action != AM_NOMATCH)
break;
}
}
-#ifdef DEBUG
- if (debug > 1)
- printf("pkt_mode %d action %d\n", pkt_mode, *action);
-#endif
- /* if no matching association is found */
+ /*
+ * If no matching association is found
+ */
if (peer == 0) {
*action = MATCH_ASSOC(NO_PEER, pkt_mode);
-#ifdef DEBUG
- if (debug > 1)
- printf("pkt_mode %d action %d\n", pkt_mode, *action);
-#endif
- return (struct peer *)0;
+ return ((struct peer *)0);
}
-
- /* reset the default interface to something more meaningful */
- if ((peer->dstadr == any_interface))
- peer->dstadr = dstadr;
- return peer;
+ peer->dstadr = dstadr;
+ return (peer);
}
/*
@@ -310,7 +278,7 @@ findpeer(
*/
struct peer *
findpeerbyassoc(
- int assoc
+ u_int assoc
)
{
register struct peer *peer;
@@ -319,101 +287,41 @@ findpeerbyassoc(
assocpeer_calls++;
hash = assoc & HASH_MASK;
- for (peer = assoc_hash[hash]; peer != 0; peer = peer->ass_next) {
- if ((u_short)assoc == peer->associd)
- return peer; /* got it! */
+ for (peer = assoc_hash[hash]; peer != 0; peer =
+ peer->ass_next) {
+ if (assoc == peer->associd)
+ return (peer);
}
-
- /*
- * Out of luck. Return 0.
- */
- return (struct peer *)0;
+ return (NULL);
}
-/*
- * findmanycastpeer - find and return an manycast peer if it exists
- *
- *
- * the current implementation loops across all hash-buckets
- *
- * *** THERE IS AN URGENT NEED TO CHANGE THIS ***
- */
-struct peer *
-findmanycastpeer(
- l_fp *p_org
- )
-{
- register struct peer *peer;
- register struct peer *manycast_peer = 0;
- int i = 0;
-
- for (i = 0; i < HASH_SIZE; i++) {
- if (peer_hash_count[i] == 0)
- continue;
-
- for (peer = peer_hash[i]; peer != 0; peer = peer->next) {
- if (peer->cast_flags & MDF_ACAST &&
- peer->flags & FLAG_CONFIG) {
- if (L_ISEQU(&peer->xmt, p_org))
- return peer; /* got it */
- else
- manycast_peer = peer;
- }
- }
- }
-
- /*
- * Out of luck. Return the manycastpeer for what it is worth.
- */
- return manycast_peer;
-}
-
-/*
- * key_expire - garbage collect keys
- */
-static void
-key_expire(
- struct peer *peer
- )
-{
- int i;
-
- if (peer->keylist != 0) {
- for (i = 0; i <= peer->keynumber; i++)
- authtrust(peer->keylist[i], 0);
- free(peer->keylist);
- peer->keylist = 0;
- }
- if (peer->keyid > NTP_MAXKEY) {
- authtrust(peer->keyid, 0);
- peer->keyid = 0;
- }
-}
/*
- * key_rekey - expire all keys and roll a new private value. Note the
- * 32-bit mask is necessary for 64-bit u_longs.
+ * clear_all - flush all time values for all associations
*/
void
-key_expire_all(
- )
+clear_all(void)
{
struct peer *peer, *next_peer;
int n;
+ /*
+ * This routine is called when the clock is stepped, and so all
+ * previously saved time values are untrusted.
+ */
for (n = 0; n < HASH_SIZE; n++) {
for (peer = peer_hash[n]; peer != 0; peer = next_peer) {
next_peer = peer->next;
- key_expire(peer);
+ peer_clear(peer);
}
}
- sys_private = (u_long)RANDOM & 0xffffffff;
#ifdef DEBUG
if (debug)
- printf("key_expire_all: at %lu private %08lx\n",
- current_time, sys_private);
+ printf("clear_all: at %lu\n", current_time);
#endif
}
+
+
/*
* unpeer - remove peer structure from hash table and free structure
*/
@@ -424,16 +332,16 @@ unpeer(
{
int hash;
+ peer_associations--;
#ifdef DEBUG
- if (debug > 1)
- printf("demobilize %u\n", peer_to_remove->associd);
+ if (debug)
+ printf("demobilize %u %d\n", peer_to_remove->associd,
+ peer_associations);
#endif
- key_expire(peer_to_remove);
+ peer_clear(peer_to_remove);
hash = HASH_ADDR(&peer_to_remove->srcadr);
peer_hash_count[hash]--;
peer_demobilizations++;
- peer_associations--;
-
#ifdef REFCLOCK
/*
* If this peer is actually a clock, shut it down first
@@ -490,7 +398,7 @@ unpeer(
/*
- * peer_config - configure a new peer
+ * peer_config - configure a new association
*/
struct peer *
peer_config(
@@ -500,63 +408,83 @@ peer_config(
int version,
int minpoll,
int maxpoll,
- int flags,
+ u_int flags,
int ttl,
- u_long key
+ keyid_t key,
+ u_char *keystr
)
{
register struct peer *peer;
+ u_int cast_flags;
/*
- * See if we have this guy in the tables already. If
- * so just mark him configured.
+ * First search from the beginning for an association with given
+ * remote address and mode. If an interface is given, search
+ * from there to find the association which matches that
+ * destination.
*/
peer = findexistingpeer(srcadr, (struct peer *)0, hmode);
if (dstadr != 0) {
while (peer != 0) {
if (peer->dstadr == dstadr)
- break;
+ break;
peer = findexistingpeer(srcadr, peer, hmode);
}
}
/*
- * If we found one, just change his mode and mark him configured.
+ * We do a dirty little jig to figure the cast flags. This is
+ * probably not the best place to do this, at least until the
+ * configure code is rebuilt. Note only one flag can be set.
+ */
+ switch (hmode) {
+
+ case MODE_BROADCAST:
+ if (IN_CLASSD(ntohl(srcadr->sin_addr.s_addr)))
+ cast_flags = MDF_MCAST;
+ else
+ cast_flags = MDF_BCAST;
+ break;
+
+ case MODE_CLIENT:
+ if (IN_CLASSD(ntohl(srcadr->sin_addr.s_addr)))
+ cast_flags = MDF_ACAST;
+ else
+ cast_flags = MDF_UCAST;
+ break;
+
+ default:
+ cast_flags = MDF_UCAST;
+ break;
+ }
+
+ /*
+ * If the peer is already configured, some dope has a duplicate
+ * configureation entry or another dope is wiggling from afar.
*/
if (peer != 0) {
peer->hmode = (u_char)hmode;
peer->version = (u_char)version;
peer->minpoll = (u_char)minpoll;
peer->maxpoll = (u_char)maxpoll;
- peer->hpoll = peer->minpoll;
- peer->ppoll = peer->minpoll;
+ peer->hpoll = peer->kpoll = peer->minpoll;
+ peer->ppoll = peer->maxpoll;
peer->flags = flags | FLAG_CONFIG |
(peer->flags & FLAG_REFCLOCK);
- peer->cast_flags = (hmode == MODE_BROADCAST) ?
- IN_CLASSD(ntohl(srcadr->sin_addr.s_addr)) ? MDF_MCAST : MDF_BCAST : MDF_UCAST;
- peer->ttl = (u_char)ttl;
+ peer->cast_flags = cast_flags;
+ peer->ttlmax = ttl;
peer->keyid = key;
- peer->keynumber = 0;
- return peer;
+ return (peer);
}
/*
- * If we're here this guy is unknown to us. Make a new peer
- * structure for him.
+ * Here no match has been found, so presumably this is a new
+ * persistent association. Mobilize the thing and initialize its
+ * variables.
*/
peer = newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll,
- ttl, key);
- if (peer != 0) {
- peer->flags |= flags | FLAG_CONFIG;
-#ifdef DEBUG
- if (debug)
- printf("peer_config: %s mode %d vers %d min %d max %d flags 0x%04x ttl %d key %lu\n",
- ntoa(&peer->srcadr), peer->hmode, peer->version,
- peer->minpoll, peer->maxpoll, peer->flags,
- peer->ttl, peer->keyid);
-#endif
- }
- return peer;
+ flags | FLAG_CONFIG, cast_flags, ttl, key);
+ return (peer);
}
@@ -571,74 +499,63 @@ newpeer(
int version,
int minpoll,
int maxpoll,
+ u_int flags,
+ u_int cast_flags,
int ttl,
- u_long key
+ keyid_t key
)
{
register struct peer *peer;
register int i;
/*
- * Some dirt here. Some of the initialization requires
- * knowlege of our system state.
+ * Allocate a new peer structure. Some dirt here, since some of
+ * the initialization requires knowlege of our system state.
*/
if (peer_free_count == 0)
- getmorepeermem();
-
+ getmorepeermem();
peer = peer_free;
peer_free = peer->next;
peer_free_count--;
peer_associations++;
+ memset((char *)peer, 0, sizeof(struct peer));
/*
- * Initialize the structure. This stuff is sort of part of
- * the receive procedure and part of the clear procedure rolled
- * into one.
- *
- * Zero the whole thing for now. We might be pickier later.
+ * Initialize the peer structure and dance the interface jig.
+ * Reference clocks step the loopback waltz, the others
+ * squaredance around the interface list looking for a buddy. If
+ * the dance peters out, there is always the wildcard interface.
+ * This might happen in some systems and would preclude proper
+ * operation with public key cryptography.
*/
- memset((char *)peer, 0, sizeof(struct peer));
-
- peer->srcadr = *srcadr;
- if (dstadr != 0)
- peer->dstadr = dstadr;
- else if (hmode == MODE_BROADCAST)
+ if (ISREFCLOCKADR(srcadr))
+ peer->dstadr = loopback_interface;
+ else if (cast_flags & MDF_BCLNT)
peer->dstadr = findbcastinter(srcadr);
+ else if (dstadr != any_interface)
+ peer->dstadr = dstadr;
else
- peer->dstadr = any_interface;
- peer->cast_flags = (hmode == MODE_BROADCAST) ?
- (IN_CLASSD(ntohl(srcadr->sin_addr.s_addr))) ? MDF_MCAST :
- MDF_BCAST : (hmode == MODE_BCLIENT || hmode == MODE_MCLIENT) ?
- (peer->dstadr->flags & INT_MULTICAST) ? MDF_MCAST : MDF_BCAST :
- MDF_UCAST;
- /* Set manycast flags if appropriate */
- if (IN_CLASSD(ntohl(srcadr->sin_addr.s_addr)) && hmode == MODE_CLIENT)
- peer->cast_flags = MDF_ACAST;
+ peer->dstadr = findinterface(srcadr);
+ peer->srcadr = *srcadr;
peer->hmode = (u_char)hmode;
- peer->keyid = key;
peer->version = (u_char)version;
- peer->minpoll = (u_char)minpoll;
- peer->maxpoll = (u_char)maxpoll;
- peer->hpoll = peer->minpoll;
- peer->ppoll = peer->minpoll;
- peer->ttl = ttl;
- peer->leap = LEAP_NOTINSYNC;
+ peer->minpoll = (u_char)max(NTP_MINPOLL, minpoll);
+ peer->maxpoll = (u_char)min(NTP_MAXPOLL, maxpoll);
+ peer->flags = flags | (key > NTP_MAXKEY ? FLAG_SKEY : 0);
+ peer->cast_flags = cast_flags;
+ peer->ttlmax = ttl;
+ peer->keyid = key;
peer->precision = sys_precision;
- peer->variance = MAXDISPERSE;
- peer->epoch = current_time;
- peer->stratum = STRATUM_UNSPEC;
peer_clear(peer);
- peer->update = peer->outdate = current_time;
- peer->nextdate = peer->outdate + RANDPOLL(NTP_MINPOLL);
- if (peer->flags & FLAG_BURST)
- peer->burst = NTP_SHIFT;
+ if (mode_ntpdate)
+ peer_ntpdate++;
/*
- * Assign him an association ID and increment the system variable
+ * Assign an association ID and increment the system variable.
*/
peer->associd = current_association_ID;
if (++current_association_ID == 0)
- ++current_association_ID;
+ ++current_association_ID;
/*
* Note time on statistics timers.
@@ -646,7 +563,6 @@ newpeer(
peer->timereset = current_time;
peer->timereachable = current_time;
peer->timereceived = current_time;
-
#ifdef REFCLOCK
if (ISREFCLOCKADR(&peer->srcadr)) {
/*
@@ -662,29 +578,32 @@ newpeer(
peer->next = peer_free;
peer_free = peer;
peer_free_count++;
- return 0;
+ return (NULL);
}
}
#endif
/*
- * Put him in the hash tables.
+ * Put the new peer in the hash tables.
*/
i = HASH_ADDR(&peer->srcadr);
peer->next = peer_hash[i];
peer_hash[i] = peer;
peer_hash_count[i]++;
-
i = peer->associd & HASH_MASK;
peer->ass_next = assoc_hash[i];
assoc_hash[i] = peer;
assoc_hash_count[i]++;
#ifdef DEBUG
- if (debug > 1)
- printf("mobilize %u next %lu\n", peer->associd,
- peer->nextdate - peer->outdate);
+ if (debug)
+ printf(
+ "newpeer: %s->%s mode %d vers %d poll %d %d flags %x %x ttl %d key %08x\n",
+ ntoa(&peer->dstadr->sin), ntoa(&peer->srcadr),
+ peer->hmode, peer->version, peer->minpoll,
+ peer->maxpoll, peer->flags, peer->cast_flags,
+ peer->ttlmax, peer->keyid);
#endif
- return peer;
+ return (peer);
}
@@ -707,14 +626,15 @@ peer_unconfig(
if (peer->flags & FLAG_CONFIG
&& (dstadr == 0 || peer->dstadr == dstadr)) {
num_found++;
+
/*
- * Tricky stuff here. If the peer is polling us
- * in active mode, turn off the configuration bit
- * and make the mode passive. This allows us to
- * avoid dumping a lot of history for peers we
- * might choose to keep track of in passive mode.
- * The protocol will eventually terminate undesirables
- * on its own.
+ * Tricky stuff here. If the peer is polling us
+ * in active mode, turn off the configuration
+ * bit and make the mode passive. This allows us
+ * to avoid dumping a lot of history for peers
+ * we might choose to keep track of in passive
+ * mode. The protocol will eventually terminate
+ * undesirables on its own.
*/
if (peer->hmode == MODE_ACTIVE
&& peer->pmode == MODE_ACTIVE) {
@@ -727,21 +647,7 @@ peer_unconfig(
}
peer = findexistingpeer(srcadr, peer, mode);
}
- return num_found;
-}
-
-/*
- * peer_copy_manycast - copy manycast peer variables to new association
- * (right now it simply copies the transmit timestamp)
- */
-void
-peer_config_manycast(
- struct peer *peer1,
- struct peer *peer2
- )
-{
- peer2->cast_flags = MDF_ACAST;
- peer2->xmt = peer1->xmt;
+ return (num_found);
}
/*
@@ -775,7 +681,6 @@ peer_reset(
peer->oldpkt = 0;
peer->seldisptoolarge = 0;
peer->selbroken = 0;
- peer->seltooold = 0;
peer->timereset = current_time;
}
@@ -793,3 +698,114 @@ peer_all_reset(void)
for (peer = peer_hash[hash]; peer != 0; peer = peer->next)
peer_reset(peer);
}
+
+
+#ifdef AUTOKEY
+/*
+ * expire_all - flush all crypto data and update timestamps.
+ */
+void
+expire_all(void)
+{
+ struct peer *peer, *next_peer;
+ int n;
+
+ /*
+ * This routine is called about once per day from the timer
+ * routine and when the client is first synchronized. Search the
+ * peer list for all associations and flush only the key list
+ * and cookie. If a manycast client association, flush
+ * everything. Then, recompute and sign the agreement public
+ * value, if present.
+ */
+ for (n = 0; n < HASH_SIZE; n++) {
+ for (peer = peer_hash[n]; peer != 0; peer = next_peer) {
+ next_peer = peer->next;
+ if (peer->cast_flags & MDF_ACAST) {
+ peer_clear(peer);
+#ifdef AUTOKEY
+ } else {
+ key_expire(peer);
+ peer->pcookie.tstamp = 0;
+#endif /* AUTOKEY */
+ }
+
+ }
+ }
+ sys_private = (u_int32)RANDOM & 0xffffffff;
+#ifdef PUBKEY
+ crypto_agree();
+#endif /* PUBKEY */
+#ifdef DEBUG
+ if (debug)
+ printf("expire_all: at %lu\n", current_time);
+#endif
+}
+#endif /* AUTOKEY */
+
+
+/*
+ * findmanycastpeer - find and return a manycast peer
+ */
+struct peer *
+findmanycastpeer(
+ struct recvbuf *rbufp
+ )
+{
+ register struct peer *peer;
+ struct pkt *pkt;
+ l_fp p_org;
+ int i;
+
+ /*
+ * This routine is called upon arrival of a client-mode message
+ * from a manycast server. Search the peer list for a manycast
+ * client association where the last transmit timestamp matches
+ * the originate timestamp. This assumes the transmit timestamps
+ * for possibly more than one manycast association are unique.
+ */
+ pkt = &rbufp->recv_pkt;
+ for (i = 0; i < HASH_SIZE; i++) {
+ if (peer_hash_count[i] == 0)
+ continue;
+
+ for (peer = peer_hash[i]; peer != 0; peer =
+ peer->next) {
+ if (peer->cast_flags & MDF_ACAST) {
+ NTOHL_FP(&pkt->org, &p_org);
+ if (L_ISEQU(&peer->xmt, &p_org))
+ return (peer);
+ }
+ }
+ }
+ return (NULL);
+}
+
+
+/*
+ * resetmanycast - reset all manycast clients
+ */
+void
+resetmanycast(void)
+{
+ register struct peer *peer;
+ int i;
+
+ /*
+ * This routine is called when the number of client associations
+ * falls below the minimum. Search the peer list for manycast
+ * client associations and reset the ttl and poll interval.
+ */
+ for (i = 0; i < HASH_SIZE; i++) {
+ if (peer_hash_count[i] == 0)
+ continue;
+
+ for (peer = peer_hash[i]; peer != 0; peer =
+ peer->next) {
+ if (peer->cast_flags & MDF_ACAST) {
+ peer->ttl = 0;
+ poll_update(peer, peer->hpoll);
+ }
+ }
+ }
+}