1 /* $NetBSD: ntp_peer.c,v 1.5 2007/06/24 16:55:14 kardel Exp $ */
4 * ntp_peer.c - management of data maintained for peer associations
11 #include <sys/types.h>
14 #include "ntp_stdlib.h"
15 #include <ntp_random.h>
17 #include "openssl/rand.h"
21 extern int accept_wildcard_if_for_winnt
;
25 * Table of valid association combinations
26 * ---------------------------------------
29 * peer->mode | UNSPEC ACTIVE PASSIVE CLIENT SERVER BCAST
30 * ---------- | ---------------------------------------------
31 * NO_PEER | e 1 0 1 1 1
32 * ACTIVE | e 1 1 0 0 0
33 * PASSIVE | e 1 e 0 0 0
34 * CLIENT | e 0 0 0 1 1
35 * SERVER | e 0 0 0 0 0
37 * BCLIENT | e 0 0 0 e 1
39 * One point to note here: a packet in BCAST mode can potentially match
40 * a peer in CLIENT mode, but we that is a special case and we check for
41 * that early in the decision process. This avoids having to keep track
42 * of what kind of associations are possible etc... We actually
43 * circumvent that problem by requiring that the first b(m)roadcast
44 * received after the change back to BCLIENT mode sets the clock.
46 #define AM_MODES 7 /* number of rows and columns */
47 #define NO_PEER 0 /* action when no peer is found */
49 int AM
[AM_MODES
][AM_MODES
] = {
50 /* { UNSPEC, ACTIVE, PASSIVE, CLIENT, SERVER, BCAST } */
52 /*NONE*/{ AM_ERR
, AM_NEWPASS
, AM_NOMATCH
, AM_FXMIT
, AM_MANYCAST
, AM_NEWBCL
},
54 /*A*/ { AM_ERR
, AM_PROCPKT
, AM_PROCPKT
, AM_NOMATCH
, AM_NOMATCH
, AM_NOMATCH
},
56 /*P*/ { AM_ERR
, AM_PROCPKT
, AM_ERR
, AM_NOMATCH
, AM_NOMATCH
, AM_NOMATCH
},
58 /*C*/ { AM_ERR
, AM_NOMATCH
, AM_NOMATCH
, AM_NOMATCH
, AM_PROCPKT
, AM_POSSBCL
},
60 /*S*/ { AM_ERR
, AM_NOMATCH
, AM_NOMATCH
, AM_NOMATCH
, AM_NOMATCH
, AM_NOMATCH
},
62 /*BCST*/{ AM_ERR
, AM_NOMATCH
, AM_NOMATCH
, AM_NOMATCH
, AM_NOMATCH
, AM_NOMATCH
},
64 /*BCL*/ { AM_ERR
, AM_NOMATCH
, AM_NOMATCH
, AM_NOMATCH
, AM_NOMATCH
, AM_PROCPKT
},
67 #define MATCH_ASSOC(x,y) AM[(x)][(y)]
70 * These routines manage the allocation of memory to peer structures
71 * and the maintenance of the peer hash table. The two main entry
72 * points are findpeer(), which looks for matching peer sturctures in
73 * the peer list, newpeer(), which allocates a new peer structure and
74 * adds it to the list, and unpeer(), which demobilizes the association
75 * and deallocates the structure.
80 struct peer
*peer_hash
[NTP_HASH_SIZE
]; /* peer hash table */
81 int peer_hash_count
[NTP_HASH_SIZE
]; /* peers in each bucket */
82 struct peer
*assoc_hash
[NTP_HASH_SIZE
]; /* association ID hash table */
83 int assoc_hash_count
[NTP_HASH_SIZE
]; /* peers in each bucket */
84 static struct peer
*peer_free
; /* peer structures free list */
85 int peer_free_count
; /* count of free structures */
88 * Association ID. We initialize this value randomly, then assign a new
89 * value every time the peer structure is incremented.
91 static associd_t current_association_ID
; /* association ID */
94 * Memory allocation watermarks.
96 #define INIT_PEER_ALLOC 15 /* initialize for 15 peers */
97 #define INC_PEER_ALLOC 5 /* when run out, add 5 more */
100 * Miscellaneous statistic counters which may be queried.
102 u_long peer_timereset
; /* time stat counters zeroed */
103 u_long findpeer_calls
; /* calls to findpeer */
104 u_long assocpeer_calls
; /* calls to findpeerbyassoc */
105 u_long peer_allocations
; /* allocations from free list */
106 u_long peer_demobilizations
; /* structs freed to free list */
107 int total_peer_structs
; /* peer structs */
108 int peer_associations
; /* mobilized associations */
109 int peer_preempt
; /* preemptable associations */
110 static struct peer init_peer_alloc
[INIT_PEER_ALLOC
]; /* init alloc */
112 static void getmorepeermem
P((void));
113 static struct interface
*select_peerinterface
P((struct peer
*, struct sockaddr_storage
*, struct interface
*, u_char
));
116 * init_peer - initialize peer data structures and counters
118 * N.B. We use the random number routine in here. It had better be
119 * initialized prior to getting here.
127 * Clear hash table and counters.
129 for (i
= 0; i
< NTP_HASH_SIZE
; i
++) {
131 peer_hash_count
[i
] = 0;
133 assoc_hash_count
[i
] = 0;
137 * Clear stat counters
139 findpeer_calls
= peer_allocations
= 0;
140 assocpeer_calls
= peer_demobilizations
= 0;
143 * Initialize peer memory.
146 for (i
= 0; i
< INIT_PEER_ALLOC
; i
++) {
147 init_peer_alloc
[i
].next
= peer_free
;
148 peer_free
= &init_peer_alloc
[i
];
150 total_peer_structs
= INIT_PEER_ALLOC
;
151 peer_free_count
= INIT_PEER_ALLOC
;
154 * Initialize our first association ID
156 while ((current_association_ID
= ntp_random() & 0xffff) == 0);
161 * getmorepeermem - add more peer structures to the free list
167 register struct peer
*peer
;
169 peer
= (struct peer
*)emalloc(INC_PEER_ALLOC
*
170 sizeof(struct peer
));
171 for (i
= 0; i
< INC_PEER_ALLOC
; i
++) {
172 peer
->next
= peer_free
;
177 total_peer_structs
+= INC_PEER_ALLOC
;
178 peer_free_count
+= INC_PEER_ALLOC
;
183 * findexistingpeer - return a pointer to a peer in the hash table
187 struct sockaddr_storage
*addr
,
188 struct peer
*start_peer
,
192 register struct peer
*peer
;
195 * start_peer is included so we can locate instances of the
196 * same peer through different interfaces in the hash table.
199 peer
= peer_hash
[NTP_HASH_ADDR(addr
)];
201 peer
= start_peer
->next
;
204 if (SOCKCMP(addr
, &peer
->srcadr
)
205 && NSRCPORT(addr
) == NSRCPORT(&peer
->srcadr
)) {
208 else if (peer
->hmode
== mode
)
218 * findpeer - find and return a peer in the hash table.
222 struct sockaddr_storage
*srcadr
,
223 struct interface
*dstadr
,
228 register struct peer
*peer
;
232 hash
= NTP_HASH_ADDR(srcadr
);
233 for (peer
= peer_hash
[hash
]; peer
!= NULL
; peer
= peer
->next
) {
234 if (SOCKCMP(srcadr
, &peer
->srcadr
) &&
235 NSRCPORT(srcadr
) == NSRCPORT(&peer
->srcadr
)) {
238 * if the association matching rules determine
239 * that this is not a valid combination, then
240 * look for the next valid peer association.
242 *action
= MATCH_ASSOC(peer
->hmode
, pkt_mode
);
245 * if an error was returned, exit back right
248 if (*action
== AM_ERR
)
249 return ((struct peer
*)0);
252 * if a match is found, we stop our search.
254 if (*action
!= AM_NOMATCH
)
260 * If no matching association is found
263 *action
= MATCH_ASSOC(NO_PEER
, pkt_mode
);
264 return ((struct peer
*)0);
267 set_peerdstadr(peer
, dstadr
);
273 * findpeerbyassocid - find and return a peer using his association ID
280 register struct peer
*peer
;
285 hash
= assoc
& NTP_HASH_MASK
;
286 for (peer
= assoc_hash
[hash
]; peer
!= 0; peer
=
288 if (assoc
== peer
->associd
)
296 * clear_all - flush all time values for all associations
301 struct peer
*peer
, *next_peer
;
305 * This routine is called when the clock is stepped, and so all
306 * previously saved time values are untrusted.
308 for (n
= 0; n
< NTP_HASH_SIZE
; n
++) {
309 for (peer
= peer_hash
[n
]; peer
!= 0; peer
= next_peer
) {
310 next_peer
= peer
->next
;
311 if (!(peer
->cast_flags
& (MDF_ACAST
| MDF_MCAST
|
313 peer
->hpoll
= peer
->minpoll
;
314 peer_clear(peer
, "STEP");
320 printf("clear_all: at %lu\n", current_time
);
326 * unpeer - remove peer structure from hash table and free structure
330 struct peer
*peer_to_remove
335 char statstr
[NTP_MAXSTRLEN
]; /* statistics for filegen */
337 if (peer_to_remove
->flags
& FLAG_SKEY
) {
338 sprintf(statstr
, "unpeer %d flash %x reach %03o flags %04x",
339 peer_to_remove
->associd
, peer_to_remove
->flash
,
340 peer_to_remove
->reach
, peer_to_remove
->flags
);
341 record_crypto_stats(&peer_to_remove
->srcadr
, statstr
);
344 printf("peer: %s\n", statstr
);
350 printf("demobilize %u %d %d\n", peer_to_remove
->associd
,
351 peer_associations
, peer_preempt
);
353 set_peerdstadr(peer_to_remove
, NULL
);
355 /* XXXMEMLEAK? peer_clear->crypto allocation */
357 hash
= NTP_HASH_ADDR(&peer_to_remove
->srcadr
);
358 peer_hash_count
[hash
]--;
359 peer_demobilizations
++;
361 if (peer_to_remove
->flags
& FLAG_PREEMPT
)
365 * If this peer is actually a clock, shut it down first
367 if (peer_to_remove
->flags
& FLAG_REFCLOCK
)
368 refclock_unpeer(peer_to_remove
);
370 peer_to_remove
->action
= 0; /* disable timeout actions */
371 if (peer_hash
[hash
] == peer_to_remove
)
372 peer_hash
[hash
] = peer_to_remove
->next
;
374 register struct peer
*peer
;
376 peer
= peer_hash
[hash
];
377 while (peer
!= 0 && peer
->next
!= peer_to_remove
)
381 peer_hash_count
[hash
]++;
382 msyslog(LOG_ERR
, "peer struct for %s not in table!",
383 stoa(&peer
->srcadr
));
385 peer
->next
= peer_to_remove
->next
;
390 * Remove him from the association hash as well.
392 hash
= peer_to_remove
->associd
& NTP_HASH_MASK
;
393 assoc_hash_count
[hash
]--;
394 if (assoc_hash
[hash
] == peer_to_remove
)
395 assoc_hash
[hash
] = peer_to_remove
->ass_next
;
397 register struct peer
*peer
;
399 peer
= assoc_hash
[hash
];
400 while (peer
!= 0 && peer
->ass_next
!= peer_to_remove
)
401 peer
= peer
->ass_next
;
404 assoc_hash_count
[hash
]++;
406 "peer struct for %s not in association table!",
407 stoa(&peer
->srcadr
));
409 peer
->ass_next
= peer_to_remove
->ass_next
;
412 peer_to_remove
->next
= peer_free
;
413 peer_free
= peer_to_remove
;
419 * peer_config - configure a new association
423 struct sockaddr_storage
*srcadr
,
424 struct interface
*dstadr
,
435 register struct peer
*peer
;
439 * First search from the beginning for an association with given
440 * remote address and mode. If an interface is given, search
441 * from there to find the association which matches that
442 * destination. If the given interface is "any", track down
443 * the actual interface, because that's what gets put into the
446 peer
= findexistingpeer(srcadr
, (struct peer
*)0, hmode
);
449 if (peer
->dstadr
== dstadr
)
451 if (dstadr
== ANY_INTERFACE_CHOOSE(srcadr
) &&
452 peer
->dstadr
== findinterface(srcadr
))
454 peer
= findexistingpeer(srcadr
, peer
, hmode
);
459 * We do a dirty little jig to figure the cast flags. This is
460 * probably not the best place to do this, at least until the
461 * configure code is rebuilt. Note only one flag can be set.
466 if(srcadr
->ss_family
== AF_INET
) {
467 if (IN_CLASSD(ntohl(((struct sockaddr_in
*)srcadr
)->sin_addr
.s_addr
)))
468 cast_flags
= MDF_MCAST
;
470 cast_flags
= MDF_BCAST
;
474 if (IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6
*)srcadr
)->sin6_addr
))
475 cast_flags
= MDF_MCAST
;
477 cast_flags
= MDF_BCAST
;
482 if(srcadr
->ss_family
== AF_INET
) {
483 if (IN_CLASSD(ntohl(((struct sockaddr_in
*)srcadr
)->sin_addr
.s_addr
)))
484 cast_flags
= MDF_ACAST
;
486 cast_flags
= MDF_UCAST
;
490 if (IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6
*)srcadr
)->sin6_addr
))
491 cast_flags
= MDF_ACAST
;
493 cast_flags
= MDF_UCAST
;
498 cast_flags
= MDF_UCAST
;
502 * If the peer is already configured, some dope has a duplicate
503 * configureation entry or another dope is wiggling from afar.
506 peer
->hmode
= (u_char
)hmode
;
507 peer
->version
= (u_char
) version
;
508 peer
->minpoll
= (u_char
) minpoll
;
509 peer
->maxpoll
= (u_char
) maxpoll
;
510 peer
->flags
= flags
| FLAG_CONFIG
|
511 (peer
->flags
& FLAG_REFCLOCK
);
512 peer
->cast_flags
= cast_flags
;
513 peer
->ttl
= (u_char
) ttl
;
515 peer
->precision
= sys_precision
;
516 peer_clear(peer
, "RMOT");
521 * Here no match has been found, so presumably this is a new
522 * persistent association. Mobilize the thing and initialize its
523 * variables. If emulating ntpdate, force iburst.
526 flags
|= FLAG_IBURST
;
527 peer
= newpeer(srcadr
, dstadr
, hmode
, version
, minpoll
, maxpoll
,
528 flags
| FLAG_CONFIG
, cast_flags
, ttl
, key
);
533 * setup peer dstadr field keeping it in sync with the interface structures
536 set_peerdstadr(struct peer
*peer
, struct interface
*interface
)
538 if (peer
->dstadr
!= interface
) {
539 if (interface
!= NULL
&&
540 (peer
->cast_flags
& MDF_BCLNT
) &&
541 (interface
->flags
& INT_MCASTIF
) &&
544 * don't accept updates to a true multicast reception
545 * interface while a BCLNT peer is running it's
551 if (peer
->dstadr
!= NULL
)
553 peer
->dstadr
->peercnt
--;
554 ISC_LIST_UNLINK_TYPE(peer
->dstadr
->peers
, peer
, ilink
, struct peer
);
557 DPRINTF(4, ("set_peerdstadr(%s): change interface from %s to %s\n",
559 (peer
->dstadr
!= NULL
) ? stoa(&peer
->dstadr
->sin
) : "<null>",
560 (interface
!= NULL
) ? stoa(&interface
->sin
) : "<null>"));
562 peer
->dstadr
= interface
;
564 if (peer
->dstadr
!= NULL
)
566 ISC_LIST_APPEND(peer
->dstadr
->peers
, peer
, ilink
);
567 peer
->dstadr
->peercnt
++;
573 * attempt to re-rebind interface if necessary
576 peer_refresh_interface(struct peer
*peer
)
578 struct interface
*niface
, *piface
;
580 niface
= select_peerinterface(peer
, &peer
->srcadr
, NULL
, peer
->cast_flags
);
586 "peer_refresh_interface: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %d key %08x: new interface: ",
587 peer
->dstadr
== NULL
? "<null>" : stoa(&peer
->dstadr
->sin
),
589 peer
->hmode
, peer
->version
, peer
->minpoll
,
590 peer
->maxpoll
, peer
->flags
, peer
->cast_flags
,
591 peer
->ttl
, peer
->keyid
);
594 printf("fd=%d, bfd=%d, name=%.16s, flags=0x%x, scope=%d, ",
600 /* Leave these as three printf calls. */
602 stoa((&niface
->sin
)));
603 if (niface
->flags
& INT_BROADCAST
)
604 printf(", bcast=%s,",
605 stoa((&niface
->bcast
)));
606 printf(", mask=%s\n",
607 stoa((&niface
->mask
)));
616 piface
= peer
->dstadr
;
618 set_peerdstadr(peer
, niface
);
622 * clear crypto if we change the local address
624 if (peer
->dstadr
!= piface
&& !(peer
->cast_flags
& MDF_BCLNT
)) {
625 peer_crypto_clear(peer
);
629 * Broadcast needs the socket enabled for broadcast
631 if (peer
->cast_flags
& MDF_BCAST
) {
632 enable_broadcast(peer
->dstadr
, &peer
->srcadr
);
636 * Multicast needs the socket interface enabled for multicast
638 if (peer
->cast_flags
& MDF_MCAST
) {
639 enable_multicast_if(peer
->dstadr
, &peer
->srcadr
);
645 * refresh_all_peerinterfaces - see that all interface bindings are up to date
648 refresh_all_peerinterfaces(void)
650 struct peer
*peer
, *next_peer
;
654 * this is called when the interface list has changed
655 * give all peers a chance to find a better interface
657 for (n
= 0; n
< NTP_HASH_SIZE
; n
++) {
658 for (peer
= peer_hash
[n
]; peer
!= 0; peer
= next_peer
) {
659 next_peer
= peer
->next
;
660 peer_refresh_interface(peer
);
667 * find an interface suitable for the src address
669 static struct interface
*
670 select_peerinterface(struct peer
*peer
, struct sockaddr_storage
*srcadr
, struct interface
*dstadr
, u_char cast_flags
)
672 struct interface
*interface
;
675 * Initialize the peer structure and dance the interface jig.
676 * Reference clocks step the loopback waltz, the others
677 * squaredance around the interface list looking for a buddy. If
678 * the dance peters out, there is always the wildcard interface.
679 * This might happen in some systems and would preclude proper
680 * operation with public key cryptography.
682 if (ISREFCLOCKADR(srcadr
))
683 interface
= loopback_interface
;
685 if (cast_flags
& (MDF_BCLNT
| MDF_ACAST
| MDF_MCAST
| MDF_BCAST
)) {
686 interface
= findbcastinter(srcadr
);
689 if (interface
!= NULL
)
690 printf("Found *-cast interface address %s, for address %s\n",
691 stoa(&(interface
)->sin
), stoa(srcadr
));
693 printf("No *-cast local address found for address %s\n",
698 * If it was a multicast packet, findbcastinter() may not
699 * find it, so try a little harder.
701 if (interface
== ANY_INTERFACE_CHOOSE(srcadr
))
702 interface
= findinterface(srcadr
);
704 else if (dstadr
!= NULL
&& dstadr
!= ANY_INTERFACE_CHOOSE(srcadr
))
707 interface
= findinterface(srcadr
);
710 * we do not bind to the wildcard interfaces for output
711 * as our (network) source address would be undefined and
712 * crypto will not work without knowing the own transmit address
714 if (interface
!= NULL
&& interface
->flags
& INT_WILDCARD
)
716 if ( !accept_wildcard_if_for_winnt
)
725 * newpeer - initialize a new peer association
729 struct sockaddr_storage
*srcadr
,
730 struct interface
*dstadr
,
741 register struct peer
*peer
;
744 char statstr
[NTP_MAXSTRLEN
]; /* statistics for filegen */
748 * Allocate a new peer structure. Some dirt here, since some of
749 * the initialization requires knowlege of our system state.
751 if (peer_free_count
== 0)
754 peer_free
= peer
->next
;
757 if (flags
& FLAG_PREEMPT
)
759 memset((char *)peer
, 0, sizeof(struct peer
));
762 * Assign an association ID and increment the system variable.
764 peer
->associd
= current_association_ID
;
765 if (++current_association_ID
== 0)
766 ++current_association_ID
;
768 DPRINTF(3, ("newpeer: cast flags: 0x%x for address: %s\n",
769 cast_flags
, stoa(srcadr
)));
771 ISC_LINK_INIT(peer
, ilink
); /* set up interface link chain */
772 peer
->srcadr
= *srcadr
;
773 set_peerdstadr(peer
, select_peerinterface(peer
, srcadr
, dstadr
,
775 peer
->hmode
= (u_char
)hmode
;
776 peer
->version
= (u_char
)version
;
777 peer
->minpoll
= (u_char
)max(NTP_MINPOLL
, minpoll
);
778 peer
->maxpoll
= (u_char
)min(NTP_MAXPOLL
, maxpoll
);
783 printf("newpeer: using fd %d and our addr %s\n",
785 stoa(&peer
->dstadr
->sin
));
787 printf("newpeer: local interface currently not bound\n");
792 * Broadcast needs the socket enabled for broadcast
794 if (cast_flags
& MDF_BCAST
&& peer
->dstadr
) {
795 enable_broadcast(peer
->dstadr
, srcadr
);
798 * Multicast needs the socket interface enabled for multicast
800 if (cast_flags
& MDF_MCAST
&& peer
->dstadr
) {
801 enable_multicast_if(peer
->dstadr
, srcadr
);
804 peer
->flags
|= FLAG_AUTHENABLE
;
805 if (key
> NTP_MAXKEY
)
806 peer
->flags
|= FLAG_SKEY
;
807 peer
->cast_flags
= cast_flags
;
808 peer
->ttl
= (u_char
)ttl
;
810 peer
->precision
= sys_precision
;
811 peer
->hpoll
= peer
->minpoll
;
812 if (cast_flags
& MDF_ACAST
)
813 peer_clear(peer
, "ACST");
814 else if (cast_flags
& MDF_MCAST
)
815 peer_clear(peer
, "MCST");
816 else if (cast_flags
& MDF_BCAST
)
817 peer_clear(peer
, "BCST");
819 peer_clear(peer
, "INIT");
824 * Note time on statistics timers.
826 peer
->timereset
= current_time
;
827 peer
->timereachable
= current_time
;
828 peer
->timereceived
= current_time
;
831 if (ISREFCLOCKADR(&peer
->srcadr
)) {
834 * We let the reference clock support do clock
835 * dependent initialization. This includes setting
836 * the peer timer, since the clock may have requirements
839 if (!refclock_newpeer(peer
)) {
841 * Dump it, something screwed up
843 set_peerdstadr(peer
, NULL
);
845 peer
->next
= peer_free
;
854 * Put the new peer in the hash tables.
856 i
= NTP_HASH_ADDR(&peer
->srcadr
);
857 peer
->next
= peer_hash
[i
];
859 peer_hash_count
[i
]++;
860 i
= peer
->associd
& NTP_HASH_MASK
;
861 peer
->ass_next
= assoc_hash
[i
];
862 assoc_hash
[i
] = peer
;
863 assoc_hash_count
[i
]++;
866 if (peer
->flags
& FLAG_SKEY
) {
867 sprintf(statstr
, "newpeer %d", peer
->associd
);
868 record_crypto_stats(&peer
->srcadr
, statstr
);
869 DPRINTF(1, ("peer: %s\n", statstr
));
873 DPRINTF(1, ("newpeer: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %d key %08x\n",
874 peer
->dstadr
== NULL
? "<null>" : stoa(&peer
->dstadr
->sin
),
876 peer
->hmode
, peer
->version
, peer
->minpoll
,
877 peer
->maxpoll
, peer
->flags
, peer
->cast_flags
,
878 peer
->ttl
, peer
->keyid
));
885 * peer_unconfig - remove the configuration bit from a peer
889 struct sockaddr_storage
*srcadr
,
890 struct interface
*dstadr
,
894 register struct peer
*peer
;
898 peer
= findexistingpeer(srcadr
, (struct peer
*)0, mode
);
900 if (peer
->flags
& FLAG_CONFIG
901 && (dstadr
== 0 || peer
->dstadr
== dstadr
)) {
905 * Tricky stuff here. If the peer is polling us
906 * in active mode, turn off the configuration
907 * bit and make the mode passive. This allows us
908 * to avoid dumping a lot of history for peers
909 * we might choose to keep track of in passive
910 * mode. The protocol will eventually terminate
911 * undesirables on its own.
913 if (peer
->hmode
== MODE_ACTIVE
914 && peer
->pmode
== MODE_ACTIVE
) {
915 peer
->hmode
= MODE_PASSIVE
;
916 peer
->flags
&= ~FLAG_CONFIG
;
922 peer
= findexistingpeer(srcadr
, peer
, mode
);
928 * peer_clr_stats - clear peer module stat counters
935 peer_allocations
= 0;
936 peer_demobilizations
= 0;
937 peer_timereset
= current_time
;
941 * peer_reset - reset stat counters in a peer structure
956 peer
->seldisptoolarge
= 0;
957 peer
->timereset
= current_time
;
962 * peer_all_reset - reset all peer stat counters
970 for (hash
= 0; hash
< NTP_HASH_SIZE
; hash
++)
971 for (peer
= peer_hash
[hash
]; peer
!= 0; peer
= peer
->next
)
978 * expire_all - flush all crypto data and update timestamps.
983 struct peer
*peer
, *next_peer
;
987 * This routine is called about once per day from the timer
988 * routine and when the client is first synchronized. Search the
989 * peer list for all associations and flush only the key list
990 * and cookie. If a manycast client association, flush
991 * everything. Then, recompute and sign the agreement public
997 for (n
= 0; n
< NTP_HASH_SIZE
; n
++) {
998 for (peer
= peer_hash
[n
]; peer
!= 0; peer
= next_peer
) {
999 next_peer
= peer
->next
;
1000 if (!(peer
->flags
& FLAG_SKEY
)) {
1003 } else if (peer
->hmode
== MODE_ACTIVE
||
1004 peer
->hmode
== MODE_PASSIVE
) {
1006 peer
->crypto
&= ~(CRYPTO_FLAG_AUTO
|
1012 RAND_bytes((u_char
*)&sys_private
, 4);
1015 #endif /* OPENSSL */
1019 * findmanycastpeer - find and return a manycast peer
1023 struct recvbuf
*rbufp
1026 register struct peer
*peer
;
1032 * This routine is called upon arrival of a server-mode message
1033 * from a manycast client. Search the peer list for a manycast
1034 * client association where the last transmit timestamp matches
1035 * the originate timestamp. This assumes the transmit timestamps
1036 * for possibly more than one manycast association are unique.
1038 pkt
= &rbufp
->recv_pkt
;
1039 for (i
= 0; i
< NTP_HASH_SIZE
; i
++) {
1040 if (peer_hash_count
[i
] == 0)
1043 for (peer
= peer_hash
[i
]; peer
!= 0; peer
=
1045 if (peer
->cast_flags
& MDF_ACAST
) {
1046 NTOHL_FP(&pkt
->org
, &p_org
);
1047 if (L_ISEQU(&peer
->xmt
, &p_org
))