]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/ntp/ntpd/ntp_peer.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / ntp / ntpd / ntp_peer.c
1 /*
2  * ntp_peer.c - management of data maintained for peer associations
3  */
4 #ifdef HAVE_CONFIG_H
5 #include <config.h>
6 #endif
7
8 #include <stdio.h>
9 #include <sys/types.h>
10
11 #include "ntpd.h"
12 #include "ntp_stdlib.h"
13 #include <ntp_random.h>
14 #ifdef OPENSSL
15 #include "openssl/rand.h"
16 #endif /* OPENSSL */
17
18 #ifdef SYS_WINNT
19 extern int accept_wildcard_if_for_winnt;
20 #endif
21
22 /*
23  *                  Table of valid association combinations
24  *                  ---------------------------------------
25  *
26  *                             packet->mode
27  * peer->mode      | UNSPEC  ACTIVE PASSIVE  CLIENT  SERVER  BCAST
28  * ----------      | ---------------------------------------------
29  * NO_PEER         |   e       1       0       1       1       1
30  * ACTIVE          |   e       1       1       0       0       0
31  * PASSIVE         |   e       1       e       0       0       0
32  * CLIENT          |   e       0       0       0       1       1
33  * SERVER          |   e       0       0       0       0       0
34  * BCAST           |   e       0       0       0       0       0
35  * BCLIENT         |   e       0       0       0       e       1
36  *
37  * One point to note here: a packet in BCAST mode can potentially match
38  * a peer in CLIENT mode, but we that is a special case and we check for
39  * that early in the decision process.  This avoids having to keep track
40  * of what kind of associations are possible etc...  We actually
41  * circumvent that problem by requiring that the first b(m)roadcast
42  * received after the change back to BCLIENT mode sets the clock.
43  */
44 #define AM_MODES        7       /* number of rows and columns */
45 #define NO_PEER         0       /* action when no peer is found */
46
47 int AM[AM_MODES][AM_MODES] = {
48 /*      { UNSPEC,   ACTIVE,     PASSIVE,    CLIENT,     SERVER,     BCAST } */
49
50 /*NONE*/{ AM_ERR, AM_NEWPASS, AM_NOMATCH, AM_FXMIT,   AM_MANYCAST, AM_NEWBCL},
51
52 /*A*/   { AM_ERR, AM_PROCPKT, AM_PROCPKT, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
53
54 /*P*/   { AM_ERR, AM_PROCPKT, AM_ERR,     AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
55
56 /*C*/   { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_PROCPKT,  AM_POSSBCL},
57
58 /*S*/   { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
59
60 /*BCST*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
61
62 /*BCL*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_PROCPKT},
63 };
64
65 #define MATCH_ASSOC(x,y)        AM[(x)][(y)]
66
67 /*
68  * These routines manage the allocation of memory to peer structures
69  * and the maintenance of the peer hash table. The two main entry
70  * points are findpeer(), which looks for matching peer sturctures in
71  * the peer list, newpeer(), which allocates a new peer structure and
72  * adds it to the list, and unpeer(), which demobilizes the association
73  * and deallocates the structure.
74  */
75 /*
76  * Peer hash tables
77  */
78 struct peer *peer_hash[NTP_HASH_SIZE];  /* peer hash table */
79 int peer_hash_count[NTP_HASH_SIZE];     /* peers in each bucket */
80 struct peer *assoc_hash[NTP_HASH_SIZE]; /* association ID hash table */
81 int assoc_hash_count[NTP_HASH_SIZE];    /* peers in each bucket */
82 static struct peer *peer_free;          /* peer structures free list */
83 int peer_free_count;                    /* count of free structures */
84
85 /*
86  * Association ID.  We initialize this value randomly, then assign a new
87  * value every time the peer structure is incremented.
88  */
89 static associd_t current_association_ID; /* association ID */
90
91 /*
92  * Memory allocation watermarks.
93  */
94 #define INIT_PEER_ALLOC         15      /* initialize for 15 peers */
95 #define INC_PEER_ALLOC          5       /* when run out, add 5 more */
96
97 /*
98  * Miscellaneous statistic counters which may be queried.
99  */
100 u_long peer_timereset;                  /* time stat counters zeroed */
101 u_long findpeer_calls;                  /* calls to findpeer */
102 u_long assocpeer_calls;                 /* calls to findpeerbyassoc */
103 u_long peer_allocations;                /* allocations from free list */
104 u_long peer_demobilizations;            /* structs freed to free list */
105 int total_peer_structs;                 /* peer structs */
106 int peer_associations;                  /* mobilized associations */
107 int peer_preempt;                       /* preemptable associations */
108 static struct peer init_peer_alloc[INIT_PEER_ALLOC]; /* init alloc */
109
110 static void         getmorepeermem       P((void));
111 static struct interface *select_peerinterface P((struct peer *, struct sockaddr_storage *, struct interface *, u_char));
112
113 /*
114  * init_peer - initialize peer data structures and counters
115  *
116  * N.B. We use the random number routine in here. It had better be
117  * initialized prior to getting here.
118  */
119 void
120 init_peer(void)
121 {
122         register int i;
123
124         /*
125          * Clear hash table and counters.
126          */
127         for (i = 0; i < NTP_HASH_SIZE; i++) {
128                 peer_hash[i] = 0;
129                 peer_hash_count[i] = 0;
130                 assoc_hash[i] = 0;
131                 assoc_hash_count[i] = 0;
132         }
133
134         /*
135          * Clear stat counters
136          */
137         findpeer_calls = peer_allocations = 0;
138         assocpeer_calls = peer_demobilizations = 0;
139
140         /*
141          * Initialize peer memory.
142          */
143         peer_free = 0;
144         for (i = 0; i < INIT_PEER_ALLOC; i++) {
145                 init_peer_alloc[i].next = peer_free;
146                 peer_free = &init_peer_alloc[i];
147         }
148         total_peer_structs = INIT_PEER_ALLOC;
149         peer_free_count = INIT_PEER_ALLOC;
150
151         /*
152          * Initialize our first association ID
153          */
154         while ((current_association_ID = ntp_random() & 0xffff) == 0);
155 }
156
157
158 /*
159  * getmorepeermem - add more peer structures to the free list
160  */
161 static void
162 getmorepeermem(void)
163 {
164         register int i;
165         register struct peer *peer;
166
167         peer = (struct peer *)emalloc(INC_PEER_ALLOC *
168             sizeof(struct peer));
169         for (i = 0; i < INC_PEER_ALLOC; i++) {
170                 peer->next = peer_free;
171                 peer_free = peer;
172                 peer++;
173         }
174
175         total_peer_structs += INC_PEER_ALLOC;
176         peer_free_count += INC_PEER_ALLOC;
177 }
178
179
180 /*
181  * findexistingpeer - return a pointer to a peer in the hash table
182  */
183 struct peer *
184 findexistingpeer(
185         struct sockaddr_storage *addr,
186         struct peer *start_peer,
187         int mode
188         )
189 {
190         register struct peer *peer;
191
192         /*
193          * start_peer is included so we can locate instances of the
194          * same peer through different interfaces in the hash table.
195          */
196         if (start_peer == 0)
197                 peer = peer_hash[NTP_HASH_ADDR(addr)];
198         else
199                 peer = start_peer->next;
200         
201         while (peer != 0) {
202                 if (SOCKCMP(addr, &peer->srcadr)
203                     && NSRCPORT(addr) == NSRCPORT(&peer->srcadr)) {
204                         if (mode == -1)
205                                 return (peer);
206                         else if (peer->hmode == mode)
207                                 break;
208                 }
209                 peer = peer->next;
210         }
211         return (peer);
212 }
213
214
215 /*
216  * findpeer - find and return a peer in the hash table.
217  */
218 struct peer *
219 findpeer(
220         struct sockaddr_storage *srcadr,
221         struct interface *dstadr,
222         int     pkt_mode,
223         int     *action
224         )
225 {
226         register struct peer *peer;
227         int hash;
228
229         findpeer_calls++;
230         hash = NTP_HASH_ADDR(srcadr);
231         for (peer = peer_hash[hash]; peer != NULL; peer = peer->next) {
232                 if (SOCKCMP(srcadr, &peer->srcadr) &&
233                     NSRCPORT(srcadr) == NSRCPORT(&peer->srcadr)) {
234
235                         /*
236                          * if the association matching rules determine
237                          * that this is not a valid combination, then
238                          * look for the next valid peer association.
239                          */
240                         *action = MATCH_ASSOC(peer->hmode, pkt_mode);
241
242                         /*
243                          * if an error was returned, exit back right
244                          * here.
245                          */
246                         if (*action == AM_ERR)
247                                 return ((struct peer *)0);
248
249                         /*
250                          * if a match is found, we stop our search.
251                          */
252                         if (*action != AM_NOMATCH)
253                                 break;
254                 }
255         }
256
257         /*
258          * If no matching association is found
259          */
260         if (peer == 0) {
261                 *action = MATCH_ASSOC(NO_PEER, pkt_mode);
262                 return ((struct peer *)0);
263         }
264
265         set_peerdstadr(peer, dstadr);
266
267         return (peer);
268 }
269
270 /*
271  * findpeerbyassocid - find and return a peer using his association ID
272  */
273 struct peer *
274 findpeerbyassoc(
275         u_int assoc
276         )
277 {
278         register struct peer *peer;
279         int hash;
280
281         assocpeer_calls++;
282
283         hash = assoc & NTP_HASH_MASK;
284         for (peer = assoc_hash[hash]; peer != 0; peer =
285             peer->ass_next) {
286                 if (assoc == peer->associd)
287                     return (peer);
288         }
289         return (NULL);
290 }
291
292
293 /*
294  * clear_all - flush all time values for all associations
295  */
296 void
297 clear_all(void)
298 {
299         struct peer *peer, *next_peer;
300         int n;
301
302         /*
303          * This routine is called when the clock is stepped, and so all
304          * previously saved time values are untrusted.
305          */
306         for (n = 0; n < NTP_HASH_SIZE; n++) {
307                 for (peer = peer_hash[n]; peer != 0; peer = next_peer) {
308                         next_peer = peer->next;
309                         if (!(peer->cast_flags & (MDF_ACAST | MDF_MCAST |
310                             MDF_BCAST))) {
311                                 peer->hpoll = peer->minpoll;
312                                 peer_clear(peer, "STEP");
313                         }
314                 }
315         }
316 #ifdef DEBUG
317         if (debug)
318                 printf("clear_all: at %lu\n", current_time);
319 #endif
320 }
321
322
323 /*
324  * unpeer - remove peer structure from hash table and free structure
325  */
326 void
327 unpeer(
328         struct peer *peer_to_remove
329         )
330 {
331         int hash;
332 #ifdef OPENSSL
333         char    statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
334
335         if (peer_to_remove->flags & FLAG_SKEY) {
336                 sprintf(statstr, "unpeer %d flash %x reach %03o flags %04x",
337                     peer_to_remove->associd, peer_to_remove->flash,
338                     peer_to_remove->reach, peer_to_remove->flags);
339                 record_crypto_stats(&peer_to_remove->srcadr, statstr);
340 #ifdef DEBUG
341                 if (debug)
342                         printf("peer: %s\n", statstr);
343 #endif
344         }
345 #endif /* OPENSSL */
346 #ifdef DEBUG
347         if (debug)
348                 printf("demobilize %u %d %d\n", peer_to_remove->associd,
349                     peer_associations, peer_preempt);
350 #endif
351         set_peerdstadr(peer_to_remove, NULL);
352
353         /* XXXMEMLEAK? peer_clear->crypto allocation */
354
355         hash = NTP_HASH_ADDR(&peer_to_remove->srcadr);
356         peer_hash_count[hash]--;
357         peer_demobilizations++;
358         peer_associations--;
359         if (peer_to_remove->flags & FLAG_PREEMPT)
360                 peer_preempt--;
361 #ifdef REFCLOCK
362         /*
363          * If this peer is actually a clock, shut it down first
364          */
365         if (peer_to_remove->flags & FLAG_REFCLOCK)
366                 refclock_unpeer(peer_to_remove);
367 #endif
368         peer_to_remove->action = 0;     /* disable timeout actions */
369         if (peer_hash[hash] == peer_to_remove)
370                 peer_hash[hash] = peer_to_remove->next;
371         else {
372                 register struct peer *peer;
373
374                 peer = peer_hash[hash];
375                 while (peer != 0 && peer->next != peer_to_remove)
376                     peer = peer->next;
377                 
378                 if (peer == 0) {
379                         peer_hash_count[hash]++;
380                         msyslog(LOG_ERR, "peer struct for %s not in table!",
381                                 stoa(&peer->srcadr));
382                 } else {
383                         peer->next = peer_to_remove->next;
384                 }
385         }
386
387         /*
388          * Remove him from the association hash as well.
389          */
390         hash = peer_to_remove->associd & NTP_HASH_MASK;
391         assoc_hash_count[hash]--;
392         if (assoc_hash[hash] == peer_to_remove)
393                 assoc_hash[hash] = peer_to_remove->ass_next;
394         else {
395                 register struct peer *peer;
396
397                 peer = assoc_hash[hash];
398                 while (peer != 0 && peer->ass_next != peer_to_remove)
399                     peer = peer->ass_next;
400                 
401                 if (peer == 0) {
402                         assoc_hash_count[hash]++;
403                         msyslog(LOG_ERR,
404                                 "peer struct for %s not in association table!",
405                                 stoa(&peer->srcadr));
406                 } else {
407                         peer->ass_next = peer_to_remove->ass_next;
408                 }
409         }
410         peer_to_remove->next = peer_free;
411         peer_free = peer_to_remove;
412         peer_free_count++;
413 }
414
415
416 /*
417  * peer_config - configure a new association
418  */
419 struct peer *
420 peer_config(
421         struct sockaddr_storage *srcadr,
422         struct interface *dstadr,
423         int hmode,
424         int version,
425         int minpoll,
426         int maxpoll,
427         u_int flags,
428         int ttl,
429         keyid_t key,
430         u_char *keystr
431         )
432 {
433         register struct peer *peer;
434         u_char cast_flags;
435
436         /*
437          * First search from the beginning for an association with given
438          * remote address and mode. If an interface is given, search
439          * from there to find the association which matches that
440          * destination.  If the given interface is "any", track down
441          * the actual interface, because that's what gets put into the
442          * peer structure.
443          */
444         peer = findexistingpeer(srcadr, (struct peer *)0, hmode);
445         if (dstadr != 0) {
446                 while (peer != 0) {
447                         if (peer->dstadr == dstadr)
448                                 break;
449                         if (dstadr == ANY_INTERFACE_CHOOSE(srcadr) &&
450                             peer->dstadr == findinterface(srcadr))
451                              break;
452                         peer = findexistingpeer(srcadr, peer, hmode);
453                 }
454         }
455
456         /*
457          * We do a dirty little jig to figure the cast flags. This is
458          * probably not the best place to do this, at least until the
459          * configure code is rebuilt. Note only one flag can be set.
460          */
461         switch (hmode) {
462
463         case MODE_BROADCAST:
464                 if(srcadr->ss_family == AF_INET) {
465                         if (IN_CLASSD(ntohl(((struct sockaddr_in*)srcadr)->sin_addr.s_addr)))
466                                 cast_flags = MDF_MCAST;
467                         else
468                                 cast_flags = MDF_BCAST;
469                         break;
470                 }
471                 else {
472                         if (IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)srcadr)->sin6_addr))
473                                 cast_flags = MDF_MCAST;
474                         else
475                                 cast_flags = MDF_BCAST;
476                         break;
477                 }
478
479         case MODE_CLIENT:
480                 if(srcadr->ss_family == AF_INET) {
481                         if (IN_CLASSD(ntohl(((struct sockaddr_in*)srcadr)->sin_addr.s_addr)))
482                                 cast_flags = MDF_ACAST;
483                         else
484                                 cast_flags = MDF_UCAST;
485                         break;
486                 }
487                 else {
488                         if (IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)srcadr)->sin6_addr))
489                                 cast_flags = MDF_ACAST;
490                         else
491                                 cast_flags = MDF_UCAST;
492                         break;
493                 }
494
495         default:
496                 cast_flags = MDF_UCAST;
497         }
498
499         /*
500          * If the peer is already configured, some dope has a duplicate
501          * configureation entry or another dope is wiggling from afar.
502          */
503         if (peer != 0) {
504                 peer->hmode = (u_char)hmode;
505                 peer->version = (u_char) version;
506                 peer->minpoll = (u_char) minpoll;
507                 peer->maxpoll = (u_char) maxpoll;
508                 peer->flags = flags | FLAG_CONFIG |
509                         (peer->flags & FLAG_REFCLOCK);
510                 peer->cast_flags = cast_flags;
511                 peer->ttl = (u_char) ttl;
512                 peer->keyid = key;
513                 peer->precision = sys_precision;
514                 peer_clear(peer, "RMOT");
515                 return (peer);
516         }
517
518         /*
519          * Here no match has been found, so presumably this is a new
520          * persistent association. Mobilize the thing and initialize its
521          * variables. If emulating ntpdate, force iburst.
522          */
523         if (mode_ntpdate)
524                 flags |= FLAG_IBURST;
525         peer = newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll,
526             flags | FLAG_CONFIG, cast_flags, ttl, key);
527         return (peer);
528 }
529
530 /*
531  * setup peer dstadr field keeping it in sync with the interface structures
532  */
533 void
534 set_peerdstadr(struct peer *peer, struct interface *interface)
535 {
536         if (peer->dstadr != interface) {
537                 if (interface != NULL &&
538                     (peer->cast_flags & MDF_BCLNT) &&
539                     (interface->flags & INT_MCASTIF) &&
540                     peer->burst) {
541                         /*
542                          * don't accept updates to a true multicast reception
543                          * interface while a BCLNT peer is running it's
544                          * unicast protocol
545                          */
546                         return;
547                 }
548
549                 if (peer->dstadr != NULL)
550                 {
551                         peer->dstadr->peercnt--;
552                         ISC_LIST_UNLINK_TYPE(peer->dstadr->peers, peer, ilink, struct peer);
553                 }
554
555                 DPRINTF(4, ("set_peerdstadr(%s): change interface from %s to %s\n",
556                             stoa(&peer->srcadr),
557                             (peer->dstadr != NULL) ? stoa(&peer->dstadr->sin) : "<null>",
558                             (interface != NULL) ? stoa(&interface->sin) : "<null>"));
559
560                 peer->dstadr = interface;
561
562                 if (peer->dstadr != NULL)
563                 {
564                         ISC_LIST_APPEND(peer->dstadr->peers, peer, ilink);
565                         peer->dstadr->peercnt++;
566                 }
567         }
568 }
569
570 /*
571  * attempt to re-rebind interface if necessary
572  */
573 static void
574 peer_refresh_interface(struct peer *peer)
575 {
576         struct interface *niface, *piface;
577
578         niface = select_peerinterface(peer, &peer->srcadr, NULL, peer->cast_flags);
579
580 #ifdef DEBUG
581         if (debug > 3)
582         {
583                 printf(
584                         "peer_refresh_interface: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %d key %08x: new interface: ",
585                         peer->dstadr == NULL ? "<null>" : stoa(&peer->dstadr->sin),
586                         stoa(&peer->srcadr),
587                         peer->hmode, peer->version, peer->minpoll,
588                         peer->maxpoll, peer->flags, peer->cast_flags,
589                         peer->ttl, peer->keyid);
590                 if (niface != NULL) 
591                 {
592                         printf("fd=%d, bfd=%d, name=%.16s, flags=0x%x, scope=%d, ",
593                                niface->fd,
594                                niface->bfd,
595                                niface->name,
596                                niface->flags,
597                                niface->scopeid);
598                         /* Leave these as three printf calls. */
599                         printf(", sin=%s",
600                                stoa((&niface->sin)));
601                         if (niface->flags & INT_BROADCAST)
602                                 printf(", bcast=%s,",
603                                        stoa((&niface->bcast)));
604                         printf(", mask=%s\n",
605                                stoa((&niface->mask)));
606                 }
607                 else
608                 {
609                         printf("<NONE>\n");
610                 }
611         }
612 #endif
613
614         piface = peer->dstadr;
615
616         set_peerdstadr(peer, niface);
617
618         if (peer->dstadr) {
619                 /*
620                  * clear crypto if we change the local address
621                  */
622                 if (peer->dstadr != piface && !(peer->cast_flags & MDF_BCLNT)) {
623                         peer_crypto_clear(peer);
624                 }
625
626                 /*
627                  * Broadcast needs the socket enabled for broadcast
628                  */
629                 if (peer->cast_flags & MDF_BCAST) {
630                         enable_broadcast(peer->dstadr, &peer->srcadr);
631                 }
632
633                 /*
634                  * Multicast needs the socket interface enabled for multicast
635                  */
636                 if (peer->cast_flags & MDF_MCAST) {
637                         enable_multicast_if(peer->dstadr, &peer->srcadr);
638                 }
639         }
640 }
641
642 /*
643  * refresh_all_peerinterfaces - see that all interface bindings are up to date
644  */
645 void
646 refresh_all_peerinterfaces(void)
647 {
648         struct peer *peer, *next_peer;
649         int n;
650
651         /*
652          * this is called when the interface list has changed
653          * give all peers a chance to find a better interface
654          */
655         for (n = 0; n < NTP_HASH_SIZE; n++) {
656                 for (peer = peer_hash[n]; peer != 0; peer = next_peer) {
657                         next_peer = peer->next;
658                         peer_refresh_interface(peer);
659                 }
660         }
661 }
662
663         
664 /*
665  * find an interface suitable for the src address
666  */
667 static struct interface *
668 select_peerinterface(struct peer *peer, struct sockaddr_storage *srcadr, struct interface *dstadr, u_char cast_flags)
669 {
670         struct interface *interface;
671   
672         /*
673          * Initialize the peer structure and dance the interface jig.
674          * Reference clocks step the loopback waltz, the others
675          * squaredance around the interface list looking for a buddy. If
676          * the dance peters out, there is always the wildcard interface.
677          * This might happen in some systems and would preclude proper
678          * operation with public key cryptography.
679          */
680         if (ISREFCLOCKADR(srcadr))
681                 interface = loopback_interface;
682         else
683                 if (cast_flags & (MDF_BCLNT | MDF_ACAST | MDF_MCAST | MDF_BCAST)) {
684                         interface = findbcastinter(srcadr);
685 #ifdef DEBUG
686                         if (debug > 3) {
687                                 if (interface != NULL)
688                                         printf("Found *-cast interface address %s, for address %s\n",
689                                                stoa(&(interface)->sin), stoa(srcadr));
690                                 else
691                                         printf("No *-cast local address found for address %s\n",
692                                                stoa(srcadr));
693                         }
694 #endif
695                         /*
696                          * If it was a multicast packet, findbcastinter() may not
697                          * find it, so try a little harder.
698                          */
699                         if (interface == ANY_INTERFACE_CHOOSE(srcadr))
700                                 interface = findinterface(srcadr);
701                 }
702                 else if (dstadr != NULL && dstadr != ANY_INTERFACE_CHOOSE(srcadr))
703                         interface = dstadr;
704                 else
705                         interface = findinterface(srcadr);
706
707         /*
708          * we do not bind to the wildcard interfaces for output 
709          * as our (network) source address would be undefined and
710          * crypto will not work without knowing the own transmit address
711          */
712         if (interface != NULL && interface->flags & INT_WILDCARD)
713 #ifdef SYS_WINNT
714                 if ( !accept_wildcard_if_for_winnt )  
715 #endif
716                         interface = NULL;
717
718
719         return interface;
720 }
721
722 /*
723  * newpeer - initialize a new peer association
724  */
725 struct peer *
726 newpeer(
727         struct sockaddr_storage *srcadr,
728         struct interface *dstadr,
729         int hmode,
730         int version,
731         int minpoll,
732         int maxpoll,
733         u_int flags,
734         u_char cast_flags,
735         int ttl,
736         keyid_t key
737         )
738 {
739         register struct peer *peer;
740         register int i;
741 #ifdef OPENSSL
742         char    statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
743 #endif /* OPENSSL */
744
745         /*
746          * Allocate a new peer structure. Some dirt here, since some of
747          * the initialization requires knowlege of our system state.
748          */
749         if (peer_free_count == 0)
750                 getmorepeermem();
751         peer = peer_free;
752         peer_free = peer->next;
753         peer_free_count--;
754         peer_associations++;
755         if (flags & FLAG_PREEMPT)
756                 peer_preempt++;
757         memset((char *)peer, 0, sizeof(struct peer));
758
759         /*
760          * Assign an association ID and increment the system variable.
761          */
762         peer->associd = current_association_ID;
763         if (++current_association_ID == 0)
764                 ++current_association_ID;
765
766         DPRINTF(3, ("newpeer: cast flags: 0x%x for address: %s\n",
767                     cast_flags, stoa(srcadr)));
768
769         ISC_LINK_INIT(peer, ilink);  /* set up interface link chain */
770         peer->srcadr = *srcadr;
771         set_peerdstadr(peer, select_peerinterface(peer, srcadr, dstadr,
772             cast_flags));
773         peer->hmode = (u_char)hmode;
774         peer->version = (u_char)version;
775         peer->minpoll = (u_char)max(NTP_MINPOLL, minpoll);
776         peer->maxpoll = (u_char)min(NTP_MAXPOLL, maxpoll);
777         peer->flags = flags;
778 #ifdef DEBUG
779         if (debug > 2) {
780                 if (peer->dstadr)
781                         printf("newpeer: using fd %d and our addr %s\n",
782                                     peer->dstadr->fd,
783                                     stoa(&peer->dstadr->sin));
784                 else
785                         printf("newpeer: local interface currently not bound\n");
786         }
787 #endif
788
789         /*
790          * Broadcast needs the socket enabled for broadcast
791          */
792         if (cast_flags & MDF_BCAST && peer->dstadr) {
793                 enable_broadcast(peer->dstadr, srcadr);
794         }
795         /*
796          * Multicast needs the socket interface enabled for multicast
797          */
798         if (cast_flags & MDF_MCAST && peer->dstadr) {
799                 enable_multicast_if(peer->dstadr, srcadr);
800         }
801         if (key != 0)
802                 peer->flags |= FLAG_AUTHENABLE;
803         if (key > NTP_MAXKEY)
804                 peer->flags |= FLAG_SKEY;
805         peer->cast_flags = cast_flags;
806         peer->ttl = (u_char)ttl;
807         peer->keyid = key;
808         peer->precision = sys_precision;
809         peer->hpoll = peer->minpoll;
810         if (cast_flags & MDF_ACAST)
811                 peer_clear(peer, "ACST");
812         else if (cast_flags & MDF_MCAST)
813                 peer_clear(peer, "MCST");
814         else if (cast_flags & MDF_BCAST)
815                 peer_clear(peer, "BCST");
816         else
817                 peer_clear(peer, "INIT");
818         if (mode_ntpdate)
819                 peer_ntpdate++;
820
821         /*
822          * Note time on statistics timers.
823          */
824         peer->timereset = current_time;
825         peer->timereachable = current_time;
826         peer->timereceived = current_time;
827
828 #ifdef REFCLOCK
829         if (ISREFCLOCKADR(&peer->srcadr)) {
830
831                 /*
832                  * We let the reference clock support do clock
833                  * dependent initialization.  This includes setting
834                  * the peer timer, since the clock may have requirements
835                  * for this.
836                  */
837                 if (!refclock_newpeer(peer)) {
838                         /*
839                          * Dump it, something screwed up
840                          */
841                         set_peerdstadr(peer, NULL);
842         
843                         peer->next = peer_free;
844                         peer_free = peer;
845                         peer_free_count++;
846                         return (NULL);
847                 }
848         }
849 #endif
850
851         /*
852          * Put the new peer in the hash tables.
853          */
854         i = NTP_HASH_ADDR(&peer->srcadr);
855         peer->next = peer_hash[i];
856         peer_hash[i] = peer;
857         peer_hash_count[i]++;
858         i = peer->associd & NTP_HASH_MASK;
859         peer->ass_next = assoc_hash[i];
860         assoc_hash[i] = peer;
861         assoc_hash_count[i]++;
862
863 #ifdef OPENSSL
864         if (peer->flags & FLAG_SKEY) {
865                 sprintf(statstr, "newpeer %d", peer->associd);
866                 record_crypto_stats(&peer->srcadr, statstr);
867                 DPRINTF(1, ("peer: %s\n", statstr));
868         }
869 #endif /* OPENSSL */
870
871         DPRINTF(1, ("newpeer: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %d key %08x\n",
872                     peer->dstadr == NULL ? "<null>" : stoa(&peer->dstadr->sin),
873                     stoa(&peer->srcadr),
874                     peer->hmode, peer->version, peer->minpoll,
875                     peer->maxpoll, peer->flags, peer->cast_flags,
876                     peer->ttl, peer->keyid));
877
878         return (peer);
879 }
880
881
882 /*
883  * peer_unconfig - remove the configuration bit from a peer
884  */
885 int
886 peer_unconfig(
887         struct sockaddr_storage *srcadr,
888         struct interface *dstadr,
889         int mode
890         )
891 {
892         register struct peer *peer;
893         int num_found;
894
895         num_found = 0;
896         peer = findexistingpeer(srcadr, (struct peer *)0, mode);
897         while (peer != 0) {
898                 if (peer->flags & FLAG_CONFIG
899                     && (dstadr == 0 || peer->dstadr == dstadr)) {
900                         num_found++;
901
902                         /*
903                          * Tricky stuff here. If the peer is polling us
904                          * in active mode, turn off the configuration
905                          * bit and make the mode passive. This allows us
906                          * to avoid dumping a lot of history for peers
907                          * we might choose to keep track of in passive
908                          * mode. The protocol will eventually terminate
909                          * undesirables on its own.
910                          */
911                         if (peer->hmode == MODE_ACTIVE
912                             && peer->pmode == MODE_ACTIVE) {
913                                 peer->hmode = MODE_PASSIVE;
914                                 peer->flags &= ~FLAG_CONFIG;
915                         } else {
916                                 unpeer(peer);
917                                 peer = 0;
918                         }
919                 }
920                 peer = findexistingpeer(srcadr, peer, mode);
921         }
922         return (num_found);
923 }
924
925 /*
926  * peer_clr_stats - clear peer module stat counters
927  */
928 void
929 peer_clr_stats(void)
930 {
931         findpeer_calls = 0;
932         assocpeer_calls = 0;
933         peer_allocations = 0;
934         peer_demobilizations = 0;
935         peer_timereset = current_time;
936 }
937
938 /*
939  * peer_reset - reset stat counters in a peer structure
940  */
941 void
942 peer_reset(
943         struct peer *peer
944         )
945 {
946         if (peer == 0)
947             return;
948         peer->sent = 0;
949         peer->received = 0;
950         peer->processed = 0;
951         peer->badauth = 0;
952         peer->bogusorg = 0;
953         peer->oldpkt = 0;
954         peer->seldisptoolarge = 0;
955         peer->timereset = current_time;
956 }
957
958
959 /*
960  * peer_all_reset - reset all peer stat counters
961  */
962 void
963 peer_all_reset(void)
964 {
965         struct peer *peer;
966         int hash;
967
968         for (hash = 0; hash < NTP_HASH_SIZE; hash++)
969             for (peer = peer_hash[hash]; peer != 0; peer = peer->next)
970                 peer_reset(peer);
971 }
972
973
974 #ifdef OPENSSL
975 /*
976  * expire_all - flush all crypto data and update timestamps.
977  */
978 void
979 expire_all(void)
980 {
981         struct peer *peer, *next_peer;
982         int n;
983
984         /*
985          * This routine is called about once per day from the timer
986          * routine and when the client is first synchronized. Search the
987          * peer list for all associations and flush only the key list
988          * and cookie. If a manycast client association, flush
989          * everything. Then, recompute and sign the agreement public
990          * value, if present.
991          */
992         if (!crypto_flags)
993                 return;
994
995         for (n = 0; n < NTP_HASH_SIZE; n++) {
996                 for (peer = peer_hash[n]; peer != 0; peer = next_peer) {
997                         next_peer = peer->next;
998                         if (!(peer->flags & FLAG_SKEY)) {
999                                 continue;
1000
1001                         } else if (peer->hmode == MODE_ACTIVE ||
1002                             peer->hmode == MODE_PASSIVE) {
1003                                 key_expire(peer);
1004                                 peer->crypto &= ~(CRYPTO_FLAG_AUTO |
1005                                     CRYPTO_FLAG_AGREE);
1006                         }
1007                                 
1008                 }
1009         }
1010         RAND_bytes((u_char *)&sys_private, 4);
1011         crypto_update();
1012 }
1013 #endif /* OPENSSL */
1014
1015
1016 /*
1017  * findmanycastpeer - find and return a manycast peer
1018  */
1019 struct peer *
1020 findmanycastpeer(
1021         struct recvbuf *rbufp
1022         )
1023 {
1024         register struct peer *peer;
1025         struct pkt *pkt;
1026         l_fp p_org;
1027         int i;
1028
1029         /*
1030          * This routine is called upon arrival of a server-mode message
1031          * from a manycast client. Search the peer list for a manycast
1032          * client association where the last transmit timestamp matches
1033          * the originate timestamp. This assumes the transmit timestamps
1034          * for possibly more than one manycast association are unique.
1035          */
1036         pkt = &rbufp->recv_pkt;
1037         for (i = 0; i < NTP_HASH_SIZE; i++) {
1038                 if (peer_hash_count[i] == 0)
1039                         continue;
1040
1041                 for (peer = peer_hash[i]; peer != 0; peer =
1042                     peer->next) {
1043                         if (peer->cast_flags & MDF_ACAST) {
1044                                 NTOHL_FP(&pkt->org, &p_org);
1045                                 if (L_ISEQU(&peer->xmt, &p_org))
1046                                         return (peer);
1047                         }
1048                 }
1049         }
1050         return (NULL);
1051 }