Coverage Report

Created: 2026-02-26 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ntp-dev/ntpd/ntp_peer.c
Line
Count
Source
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_lists.h"
13
#include "ntp_stdlib.h"
14
#include "ntp_control.h"
15
#include <ntp_random.h>
16
17
/*
18
 *        Table of valid association combinations
19
 *        ---------------------------------------
20
 *
21
 *                             packet->mode
22
 * peer->mode      | UNSPEC  ACTIVE PASSIVE  CLIENT  SERVER  BCAST
23
 * ----------      | ---------------------------------------------
24
 * NO_PEER         |   e       1       0       1       1       1
25
 * ACTIVE          |   e       1       1       0       0       0
26
 * PASSIVE         |   e       1       e       0       0       0
27
 * CLIENT          |   e       0       0       0       1       0
28
 * SERVER          |   e       0       0       0       0       0
29
 * BCAST           |   e       0       0       0       0       0
30
 * BCLIENT         |   e       0       0       0       e       1
31
 *
32
 * One point to note here: a packet in BCAST mode can potentially match
33
 * a peer in CLIENT mode, but we that is a special case and we check for
34
 * that early in the decision process.  This avoids having to keep track
35
 * of what kind of associations are possible etc...  We actually
36
 * circumvent that problem by requiring that the first b(m)roadcast
37
 * received after the change back to BCLIENT mode sets the clock.
38
 */
39
#define AM_MODES  7 /* number of rows and columns */
40
#define NO_PEER   0 /* action when no peer is found */
41
42
const s_char AM[AM_MODES][AM_MODES] = {
43
/*      packet->mode              */
44
/* peer { UNSPEC,   ACTIVE,     PASSIVE,    CLIENT,     SERVER,     BCAST } */
45
/* mode */
46
/*NONE*/{ AM_ERR, AM_NEWPASS, AM_NOMATCH, AM_FXMIT,   AM_MANYCAST, AM_NEWBCL},
47
48
/*A*/ { AM_ERR, AM_PROCPKT, AM_PROCPKT, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
49
50
/*P*/ { AM_ERR, AM_PROCPKT, AM_ERR,     AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
51
52
/*C*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_PROCPKT,  AM_NOMATCH},
53
54
/*S*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
55
56
/*BCST*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
57
58
/*BCL*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_PROCPKT},
59
};
60
61
0
#define MATCH_ASSOC(x, y) (AM[CLAMP((x), 0, AM_MODES)][CLAMP((y), 0, AM_MODES)])
62
63
/*
64
 * These routines manage the allocation of memory to peer structures
65
 * and the maintenance of three data structures involving all peers:
66
 *
67
 * - peer_list is a single list with all peers, suitable for scanning
68
 *   operations over all peers.
69
 * - peer_adr_hash is an array of lists indexed by hashed peer address.
70
 * - peer_aid_hash is an array of lists indexed by hashed associd.
71
 *
72
 * They also maintain a free list of peer structures, peer_free.
73
 *
74
 * The three main entry points are findpeer(), which looks for matching
75
 * peer structures in the peer list, newpeer(), which allocates a new
76
 * peer structure and adds it to the list, and unpeer(), which
77
 * demobilizes the association and deallocates the structure.
78
 */
79
/*
80
 * Peer hash tables
81
 */
82
struct peer *peer_hash[NTP_HASH_SIZE];  /* peer hash table */
83
int peer_hash_count[NTP_HASH_SIZE]; /* peers in each bucket */
84
struct peer *assoc_hash[NTP_HASH_SIZE]; /* association ID hash table */
85
int assoc_hash_count[NTP_HASH_SIZE];/* peers in each bucket */
86
struct peer *peer_list;     /* peer structures list */
87
static struct peer *peer_free;    /* peer structures free list */
88
int peer_free_count;    /* count of free structures */
89
90
/*
91
 * Association ID.  We initialize this value randomly, then assign a new
92
 * value every time an association is mobilized.
93
 */
94
static associd_t current_association_ID; /* actually next poss. ID */
95
static associd_t initial_association_ID;
96
97
/*
98
 * Memory allocation watermarks.
99
 */
100
#define INIT_PEER_ALLOC   8 /* static preallocation */
101
0
#define INC_PEER_ALLOC    4  /* add N more when empty */
102
103
/*
104
 * Miscellaneous statistic counters which may be queried.
105
 */
106
u_long  peer_timereset;     /* time stat counters zeroed */
107
u_long  findpeer_calls;     /* calls to findpeer */
108
u_long  assocpeer_calls;    /* calls to findpeerbyassoc */
109
u_long  peer_allocations;   /* allocations from free list */
110
u_long  peer_demobilizations;   /* structs freed to free list */
111
int total_peer_structs;   /* peer structs */
112
int peer_associations;    /* mobilized associations */
113
int peer_preempt;     /* preemptable associations */
114
static struct peer init_peer_alloc[INIT_PEER_ALLOC]; /* init alloc */
115
116
static struct peer *  findexistingpeer_name(const char *, u_short,
117
                struct peer *, int);
118
static struct peer *  findexistingpeer_addr(sockaddr_u *,
119
                struct peer *, int,
120
                u_char, int *);
121
static void   free_peer(struct peer *, int);
122
static void   getmorepeermem(void);
123
static int    score(struct peer *);
124
125
126
/*
127
 * init_peer - initialize peer data structures and counters
128
 *
129
 * N.B. We use the random number routine in here. It had better be
130
 * initialized prior to getting here.
131
 */
132
void
133
init_peer(void)
134
1
{
135
1
  int i;
136
137
  /*
138
   * Initialize peer free list from static allocation.
139
   */
140
9
  for (i = COUNTOF(init_peer_alloc) - 1; i >= 0; i--)
141
8
    LINK_SLIST(peer_free, &init_peer_alloc[i], p_link);
142
1
  total_peer_structs = COUNTOF(init_peer_alloc);
143
1
  peer_free_count = COUNTOF(init_peer_alloc);
144
145
  /*
146
   * Initialize our first association ID
147
   */
148
1
  do
149
1
    current_association_ID = ntp_random() & ASSOCID_MAX;
150
1
  while (!current_association_ID);
151
1
  initial_association_ID = current_association_ID;
152
1
}
153
154
155
/*
156
 * getmorepeermem - add more peer structures to the free list
157
 */
158
static void
159
getmorepeermem(void)
160
0
{
161
0
  int i;
162
0
  struct peer *peers;
163
164
0
  peers = eallocarray(INC_PEER_ALLOC, sizeof(*peers));
165
166
0
  for (i = INC_PEER_ALLOC - 1; i >= 0; i--)
167
0
    LINK_SLIST(peer_free, &peers[i], p_link);
168
169
0
  total_peer_structs += INC_PEER_ALLOC;
170
0
  peer_free_count += INC_PEER_ALLOC;
171
0
}
172
173
174
static struct peer *
175
findexistingpeer_name(
176
  const char *  hostname,
177
  u_short   hname_fam,
178
  struct peer * start_peer,
179
  int   mode
180
  )
181
0
{
182
0
  struct peer *p;
183
184
0
  if (NULL == start_peer)
185
0
    p = peer_list;
186
0
  else
187
0
    p = start_peer->p_link;
188
0
  for (; p != NULL; p = p->p_link)
189
0
    if (p->hostname != NULL
190
0
        && (-1 == mode || p->hmode == mode)
191
0
        && (AF_UNSPEC == hname_fam
192
0
      || AF_UNSPEC == AF(&p->srcadr)
193
0
      || hname_fam == AF(&p->srcadr))
194
0
        && !strcasecmp(p->hostname, hostname))
195
0
      break;
196
0
  return p;
197
0
}
198
199
200
static
201
struct peer *   
202
findexistingpeer_addr(
203
  sockaddr_u *  addr,
204
  struct peer * start_peer,
205
  int   mode,
206
  u_char    cast_flags,
207
  int *   ip_count
208
  )
209
0
{
210
0
  struct peer *peer;
211
212
0
  DPRINTF(2, ("findexistingpeer_addr(%s, %s, %d, 0x%x, %p)\n",
213
0
    sptoa(addr),
214
0
    (start_peer)
215
0
        ? sptoa(&start_peer->srcadr)
216
0
        : "NULL",
217
0
    mode, (u_int)cast_flags, ip_count));
218
219
  /*
220
   * start_peer is included so we can locate instances of the
221
   * same peer through different interfaces in the hash table.
222
   * Without MDF_BCLNT, a match requires the same mode and remote
223
   * address.  MDF_BCLNT associations start out as MODE_CLIENT
224
   * if broadcastdelay is not specified, and switch to
225
   * MODE_BCLIENT after estimating the one-way delay.  Duplicate
226
   * associations are expanded in definition to match any other
227
   * MDF_BCLNT with the same srcadr (remote, unicast address).
228
   */
229
0
  if (NULL == start_peer)
230
0
    peer = peer_hash[NTP_HASH_ADDR(addr)];
231
0
  else
232
0
    peer = start_peer->adr_link;
233
  
234
0
  while (peer != NULL) {
235
0
    DPRINTF(3, ("%s %s %d %d 0x%x 0x%x ", sptoa(addr),
236
0
      sptoa(&peer->srcadr), mode, peer->hmode,
237
0
      (u_int)cast_flags, (u_int)peer->cast_flags));
238
0
    if (ip_count) {
239
0
      if (SOCK_EQ(addr, &peer->srcadr)) {
240
0
        (*ip_count)++;
241
0
      }
242
0
    }
243
0
    if ((-1 == mode || peer->hmode == mode ||
244
0
         ((MDF_BCLNT & peer->cast_flags) &&
245
0
          (MDF_BCLNT & cast_flags))) &&
246
0
        ADDR_PORT_EQ(addr, &peer->srcadr)) {
247
0
      DPRINTF(3, ("found.\n"));
248
0
      break;
249
0
    }
250
0
    DPRINTF(3, ("\n"));
251
0
    peer = peer->adr_link;
252
0
  }
253
254
0
  return peer;
255
0
}
256
257
258
/*
259
 * findexistingpeer - search by name+family or address.
260
 */
261
struct peer *
262
findexistingpeer(
263
  sockaddr_u *  addr,
264
  const char *  hostname,
265
  struct peer * start_peer,
266
  int   mode,
267
  u_char    cast_flags,
268
  int *   ip_count
269
  )
270
0
{
271
0
  if (hostname != NULL)
272
0
    return findexistingpeer_name(hostname, AF(addr),
273
0
               start_peer, mode);
274
0
  else
275
0
    return findexistingpeer_addr(addr, start_peer, mode,
276
0
               cast_flags, ip_count);
277
0
}
278
279
280
/*
281
 * findpeer - find and return a peer match for a received datagram in
282
 *        the peer_hash table.
283
 *
284
 * [Bug 3072] To faciliate a faster reorganisation after routing changes
285
 * the original code re-assigned the peer address to be the destination
286
 * of the received packet and initiated another round on a mismatch.
287
 * Unfortunately this leaves us wide open for a DoS attack where the
288
 * attacker directs a packet with forged destination address to us --
289
 * this results in a wrong interface assignment, actually creating a DoS
290
 * situation.
291
 *
292
 * This condition would persist until the next update of the interface
293
 * list, but a continued attack would put us out of business again soon
294
 * enough. Authentication alone does not help here, since it does not
295
 * protect the UDP layer and leaves us open for a replay attack.
296
 *
297
 * So we do not update the addresses and wait until the next interface
298
 * list update does the right thing for us.
299
 */
300
struct peer *
301
findpeer(
302
  struct recvbuf *rbufp,
303
  int   pkt_mode,
304
  int *   action
305
  )
306
0
{
307
0
  struct peer * p;
308
0
  sockaddr_u *  srcadr;
309
0
  u_int   hash;
310
0
  struct pkt *  pkt;
311
0
  l_fp    pkt_org;
312
313
0
  findpeer_calls++;
314
0
  srcadr = &rbufp->recv_srcadr;
315
0
  hash = NTP_HASH_ADDR(srcadr);
316
0
  for (p = peer_hash[hash]; p != NULL; p = p->adr_link) {
317
318
    /* [Bug 3072] ensure interface of peer matches */
319
    /* [Bug 3356] ... if NOT a broadcast peer!     */
320
0
    if (p->hmode != MODE_BCLIENT && p->dstadr != rbufp->dstadr)
321
0
      continue;
322
323
    /* ensure peer source address matches */
324
0
    if ( ! ADDR_PORT_EQ(srcadr, &p->srcadr))
325
0
      continue;
326
    
327
    /* If the association matching rules determine that this
328
     * is not a valid combination, then look for the next
329
     * valid peer association.
330
     */
331
0
    *action = MATCH_ASSOC(p->hmode, pkt_mode);
332
333
    /* A response to our manycastclient solicitation might
334
     * be misassociated with an ephemeral peer already spun
335
     * for the server.  If the packet's org timestamp
336
     * doesn't match the peer's, check if it matches the
337
     * ACST prototype peer's.  If so it is a redundant
338
     * solicitation response, return AM_ERR to discard it.
339
     * [Bug 1762]
340
     */
341
0
    if (MODE_SERVER == pkt_mode && AM_PROCPKT == *action) {
342
0
      pkt = &rbufp->recv_pkt;
343
0
      NTOHL_FP(&pkt->org, &pkt_org);
344
0
      if (!L_ISEQU(&p->aorg, &pkt_org) &&
345
0
          findmanycastpeer(rbufp))
346
0
        *action = AM_ERR;
347
0
    }
348
349
    /* if an error was returned, exit back right here. */
350
0
    if (*action == AM_ERR) {
351
0
      return NULL;
352
0
    }
353
354
    /* if a match is found, we stop our search. */
355
0
    if (*action != AM_NOMATCH) {
356
0
      break;
357
0
    }
358
0
  }
359
360
  /* If no matching association is found... */
361
0
  if (NULL == p) {
362
0
    *action = MATCH_ASSOC(NO_PEER, pkt_mode);
363
0
  }
364
0
  return p;
365
0
}
366
367
/*
368
 * findpeerbyassoc - find and return a peer using his association ID
369
 */
370
struct peer *
371
findpeerbyassoc(
372
  associd_t assoc
373
  )
374
0
{
375
0
  struct peer *p;
376
0
  u_int hash;
377
378
0
  assocpeer_calls++;
379
0
  hash = assoc & NTP_HASH_MASK;
380
0
  for (p = assoc_hash[hash]; p != NULL; p = p->aid_link)
381
0
    if (assoc == p->associd)
382
0
      break;
383
0
  return p;
384
0
}
385
386
387
/*
388
 * clear_all - flush all time values for all associations
389
 */
390
void
391
clear_all(void)
392
0
{
393
0
  struct peer *p;
394
395
  /*
396
   * This routine is called when the clock is stepped, and so all
397
   * previously saved time values are untrusted.
398
   */
399
0
  for (p = peer_list; p != NULL; p = p->p_link)
400
0
    if (!(MDF_TXONLY_MASK & p->cast_flags))
401
0
      peer_clear(p, "STEP");
402
403
0
  DPRINTF(1, ("clear_all: at %lu\n", current_time));
404
0
}
405
406
407
/*
408
 * score_all() - determine if an association can be demobilized
409
 */
410
int
411
score_all(
412
  struct peer *peer /* peer structure pointer */
413
  )
414
0
{
415
0
  struct peer *speer;
416
0
  int temp, tamp;
417
0
  int x;
418
419
  /*
420
   * This routine finds the minimum score for all preemptible
421
   * associations and returns > 0 if the association can be
422
   * demobilized.
423
   */
424
0
  tamp = score(peer);
425
0
  temp = 100;
426
0
  for (speer = peer_list; speer != NULL; speer = speer->p_link)
427
0
    if (speer->flags & FLAG_PREEMPT) {
428
0
      x = score(speer);
429
0
      if (x < temp)
430
0
        temp = x;
431
0
    }
432
0
  DPRINTF(1, ("score_all: at %lu score %d min %d\n",
433
0
        current_time, tamp, temp));
434
435
0
  if (tamp != temp)
436
0
    temp = 0;
437
438
0
  return temp;
439
0
}
440
441
442
/*
443
 * score() - calculate preemption score
444
 */
445
static int
446
score(
447
  struct peer *peer /* peer structure pointer */
448
  )
449
0
{
450
0
  int temp;
451
452
  /*
453
   * This routine calculates the premption score from the peer
454
   * error bits and status. Increasing values are more cherished.
455
   */
456
0
  temp = 0;
457
0
  if (!(peer->flash & TEST10))
458
0
    temp++;     /* 1 good synch and stratum */
459
0
  if (!(peer->flash & TEST13))
460
0
    temp++;     /* 2 reachable */
461
0
  if (!(peer->flash & TEST12))
462
0
    temp++;     /* 3 no loop */
463
0
  if (!(peer->flash & TEST11))
464
0
    temp++;     /* 4 good distance */
465
0
  if (peer->status >= CTL_PST_SEL_SELCAND)
466
0
    temp++;     /* 5 in the hunt */
467
0
  if (peer->status != CTL_PST_SEL_EXCESS)
468
0
    temp++;     /* 6 not spare tire */
469
0
  return (temp);      /* selection status */
470
0
}
471
472
473
/*
474
 * free_peer - internal routine to free memory referred to by a struct
475
 *         peer and return it to the peer free list.  If unlink is
476
 *         nonzero, unlink from the various lists.
477
 */
478
static void
479
free_peer(
480
  struct peer * p,
481
  int   unlink_peer
482
  )
483
0
{
484
0
  struct peer * unlinked;
485
0
  int   hash;
486
487
0
  if (unlink_peer) {
488
0
    hash = NTP_HASH_ADDR(&p->srcadr);
489
0
    peer_hash_count[hash]--;
490
491
0
    UNLINK_SLIST(unlinked, peer_hash[hash], p, adr_link,
492
0
           struct peer);
493
0
    if (NULL == unlinked) {
494
0
      peer_hash_count[hash]++;
495
0
      msyslog(LOG_ERR, "peer %s not in address table!",
496
0
        stoa(&p->srcadr));
497
0
    }
498
499
    /*
500
     * Remove him from the association hash as well.
501
     */
502
0
    hash = p->associd & NTP_HASH_MASK;
503
0
    assoc_hash_count[hash]--;
504
505
0
    UNLINK_SLIST(unlinked, assoc_hash[hash], p, aid_link,
506
0
           struct peer);
507
0
    if (NULL == unlinked) {
508
0
      assoc_hash_count[hash]++;
509
0
      msyslog(LOG_ERR,
510
0
        "peer %s not in association ID table!",
511
0
        stoa(&p->srcadr));
512
0
    }
513
514
    /* Remove him from the overall list. */
515
0
    UNLINK_SLIST(unlinked, peer_list, p, p_link,
516
0
           struct peer);
517
0
    if (NULL == unlinked)
518
0
      msyslog(LOG_ERR, "%s not in peer list!",
519
0
        stoa(&p->srcadr));
520
0
  }
521
522
0
  if (p->hostname != NULL)
523
0
    free(p->hostname);
524
525
0
  if (p->ident != NULL)
526
0
    free(p->ident);
527
528
0
  if (p->addrs != NULL)
529
0
    free(p->addrs);   /* from copy_addrinfo_list() */
530
531
  /* Add his corporeal form to peer free list */
532
0
  ZERO(*p);
533
0
  LINK_SLIST(peer_free, p, p_link);
534
0
  peer_free_count++;
535
0
}
536
537
538
/*
539
 * unpeer - remove peer structure from hash table and free structure
540
 */
541
void
542
unpeer(
543
  struct peer *peer
544
  )
545
0
{
546
0
  mprintf_event(PEVNT_DEMOBIL, peer, "assoc %u", peer->associd);
547
0
  restrict_source(&peer->srcadr, TRUE, 0);
548
0
  peer->flags |= FLAG_DISABLED;
549
0
  set_peerdstadr(peer, NULL);
550
0
  peer_demobilizations++;
551
0
  peer_associations--;
552
0
  if (FLAG_PREEMPT & peer->flags)
553
0
    peer_preempt--;
554
0
#ifdef REFCLOCK
555
  /*
556
   * If this peer is actually a clock, shut it down first
557
   */
558
0
  if (FLAG_REFCLOCK & peer->flags)
559
0
    refclock_unpeer(peer);
560
0
#endif
561
562
0
  free_peer(peer, TRUE);
563
0
}
564
565
566
/*
567
 * peer_config - configure a new association
568
 */
569
struct peer *
570
peer_config(
571
  sockaddr_u *  srcadr,
572
  const char *  hostname,
573
  endpt *   dstadr,
574
  int   ippeerlimit,
575
  u_char    hmode,
576
  u_char    version,
577
  u_char    minpoll,
578
  u_char    maxpoll,
579
  u_int   flags,
580
  u_int32   ttl,
581
  keyid_t   key,
582
  const char *  ident   /* autokey group */
583
  )
584
0
{
585
0
  u_char cast_flags;
586
587
  /*
588
   * We do a dirty little jig to figure the cast flags. This is
589
   * probably not the best place to do this, at least until the
590
   * configure code is rebuilt. Note only one flag can be set.
591
   */
592
0
  switch (hmode) {
593
0
  case MODE_BROADCAST:
594
0
    if (IS_MCAST(srcadr))
595
0
      cast_flags = MDF_MCAST;
596
0
    else
597
0
      cast_flags = MDF_BCAST;
598
0
    break;
599
600
0
  case MODE_CLIENT:
601
0
    if (hostname != NULL && SOCK_UNSPEC(srcadr))
602
0
      cast_flags = MDF_POOL;
603
0
    else if (IS_MCAST(srcadr))
604
0
      cast_flags = MDF_ACAST;
605
0
    else
606
0
      cast_flags = MDF_UCAST;
607
0
    break;
608
609
0
  default:
610
0
    cast_flags = MDF_UCAST;
611
0
  }
612
613
  /*
614
   * Mobilize the association and initialize its variables. If
615
   * emulating ntpdate, force iburst.  For pool and manycastclient
616
   * strip FLAG_PREEMPT as the prototype associations are not
617
   * themselves preemptible, though the resulting associations
618
   * are.
619
   */
620
0
  flags |= FLAG_CONFIG;
621
0
  if (mode_ntpdate)
622
0
    flags |= FLAG_IBURST;
623
0
  if ((MDF_ACAST | MDF_POOL) & cast_flags)
624
0
    flags &= ~FLAG_PREEMPT;
625
0
  return newpeer(srcadr, hostname, dstadr, ippeerlimit, hmode, version,
626
0
      minpoll, maxpoll, flags, cast_flags, ttl, key, ident);
627
0
}
628
629
/*
630
 * setup peer dstadr field keeping it in sync with the interface
631
 * structures
632
 */
633
void
634
set_peerdstadr(
635
  struct peer * p,
636
  endpt *   dstadr
637
  )
638
0
{
639
0
  struct peer * unlinked;
640
641
0
  DEBUG_INSIST(p != NULL);
642
643
0
  if (p == NULL)
644
0
    return;
645
646
  /* check for impossible or identical assignment */
647
0
  if (p->dstadr == dstadr)
648
0
    return;
649
650
  /*
651
   * Do not change the local address of a link-local
652
   * peer address.
653
   */
654
0
  if (   p->dstadr != NULL && is_linklocal(&p->dstadr->sin)
655
0
      && dstadr != NULL) {
656
0
    return;
657
0
  }
658
659
  /*
660
   * Do not set the local address for a link-local IPv6 peer
661
   * to one with a different scope ID.
662
   */
663
0
  if (   dstadr != NULL && IS_IPV6(&p->srcadr)
664
0
      && SCOPE(&dstadr->sin) != SCOPE(&p->srcadr)) {
665
0
    return;
666
0
  }
667
668
  /*
669
   * Don't accept updates to a separate multicast receive-only
670
   * endpt while a BCLNT peer is running its unicast protocol.
671
   */
672
0
  if (dstadr != NULL && (FLAG_BC_VOL & p->flags) &&
673
0
      (INT_MCASTIF & dstadr->flags) && MODE_CLIENT == p->hmode) {
674
0
    return;
675
0
  }
676
677
  /* unlink from list if we have an address prior to assignment */
678
0
  if (p->dstadr != NULL) {
679
0
    p->dstadr->peercnt--;
680
0
    UNLINK_SLIST(unlinked, p->dstadr->peers, p, ilink,
681
0
           struct peer);
682
0
  }
683
0
  if (   !IS_MCAST(&p->srcadr) && !(FLAG_DISABLED & p->flags)
684
0
      && !initializing) {
685
0
    msyslog(LOG_INFO, "%s local addr %s -> %s",
686
0
      stoa(&p->srcadr), eptoa(p->dstadr),
687
0
      eptoa(dstadr));
688
0
  }
689
690
0
  p->dstadr = dstadr;
691
692
  /* link to list if we have an address after assignment */
693
0
  if (p->dstadr != NULL) {
694
0
    LINK_SLIST(dstadr->peers, p, ilink);
695
0
    dstadr->peercnt++;
696
0
  }
697
0
}
698
699
/*
700
 * attempt to re-rebind interface if necessary
701
 */
702
static void
703
peer_refresh_interface(
704
  struct peer *p
705
  )
706
0
{
707
0
  endpt * niface;
708
0
  endpt * piface;
709
710
0
  niface = select_peerinterface(p, &p->srcadr, NULL);
711
712
0
  DPRINTF(4, (
713
0
      "peer_refresh_interface: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %u key %08x: new interface: ",
714
0
      p->dstadr == NULL ? "<null>" :
715
0
      stoa(&p->dstadr->sin), stoa(&p->srcadr), p->hmode,
716
0
      p->version, p->minpoll, p->maxpoll, p->flags, p->cast_flags,
717
0
      p->ttl, p->keyid));
718
0
  if (niface != NULL) {
719
0
    DPRINTF(4, (
720
0
        "fd=%d, bfd=%d, name=%.16s, flags=0x%x, ifindex=%u, sin=%s",
721
0
        niface->fd,  niface->bfd, niface->name,
722
0
        niface->flags, niface->ifindex,
723
0
        stoa(&niface->sin)));
724
0
    if (niface->flags & INT_BROADCAST)
725
0
      DPRINTF(4, (", bcast=%s",
726
0
        stoa(&niface->bcast)));
727
0
    DPRINTF(4, (", mask=%s\n", stoa(&niface->mask)));
728
0
  } else {
729
0
    DPRINTF(4, ("<NONE>\n"));
730
0
  }
731
732
0
  piface = p->dstadr;
733
0
  set_peerdstadr(p, niface);
734
0
  if (p->dstadr != NULL) {
735
    /*
736
     * clear crypto if we change the local address
737
     */
738
0
    if (p->dstadr != piface && !(MDF_ACAST & p->cast_flags)
739
0
        && MODE_BROADCAST != p->pmode)
740
0
      peer_clear(p, "XFAC");
741
742
    /*
743
     * Broadcast needs the socket enabled for broadcast
744
     */
745
0
    if (MDF_BCAST & p->cast_flags)
746
0
      enable_broadcast(p->dstadr, &p->srcadr);
747
748
    /*
749
     * Multicast needs the socket interface enabled for
750
     * multicast
751
     */
752
0
    if (MDF_MCAST & p->cast_flags)
753
0
      enable_multicast_if(p->dstadr, &p->srcadr);
754
0
  }
755
0
}
756
757
758
/*
759
 * refresh_all_peerinterfaces - see that all interface bindings are up
760
 * to date
761
 */
762
void
763
refresh_all_peerinterfaces(void)
764
1
{
765
1
  struct peer *p;
766
767
  /*
768
   * This is called when the interface list has changed.
769
   * Give peers a chance to find a better interface.
770
   */
771
1
  for (p = peer_list; p != NULL; p = p->p_link) {
772
    /* 
773
     * Bug 2849 XOR 2043
774
     * Change local address only if the peer doesn't
775
     * have a local address already or if the one
776
     * they have hasn't worked for a while.
777
     */
778
0
    if (p->dstadr != NULL && (p->reach & 0x3)) {
779
0
      continue;
780
0
    }
781
0
    peer_refresh_interface(p);
782
0
  }
783
1
}
784
785
786
/*
787
 * newpeer - initialize a new peer association
788
 */
789
struct peer *
790
newpeer(
791
  sockaddr_u *  srcadr,
792
  const char *  hostname,
793
  endpt *   dstadr,
794
  int   ippeerlimit,
795
  u_char    hmode,
796
  u_char    version,
797
  u_char    minpoll,
798
  u_char    maxpoll,
799
  u_int   flags,
800
  u_char    cast_flags,
801
  u_int32   ttl,
802
  keyid_t   key,
803
  const char *  ident
804
  )
805
0
{
806
0
  struct peer * peer;
807
0
  u_int   hash;
808
0
  int   ip_count = 0;
809
810
0
  DEBUG_REQUIRE(srcadr);
811
812
0
#ifdef AUTOKEY
813
  /*
814
   * If Autokey is requested but not configured, complain loudly.
815
   */
816
0
  if (!crypto_flags) {
817
0
    if (key > NTP_MAXKEY) {
818
0
      return (NULL);
819
820
0
    } else if (flags & FLAG_SKEY) {
821
0
      msyslog(LOG_ERR, "Rejecting Autokey with %s,"
822
0
           " built without support.",
823
0
           stoa(srcadr));
824
0
      return (NULL);
825
0
    } 
826
0
  }
827
0
#endif  /* AUTOKEY */
828
829
  /*
830
   * For now only pool associations have a hostname.
831
   */
832
0
  INSIST(NULL == hostname || (MDF_POOL & cast_flags));
833
834
  /*
835
   * First search from the beginning for an association with given
836
   * remote address and mode. If an interface is given, search
837
   * from there to find the association which matches that
838
   * destination. If the given interface is "any", track down the
839
   * actual interface, because that's what gets put into the peer
840
   * structure.
841
   */
842
0
  if (dstadr != NULL) {
843
0
    peer = findexistingpeer(srcadr, hostname, NULL, hmode,
844
0
          cast_flags, &ip_count);
845
0
    while (peer != NULL) {
846
0
      if (   peer->dstadr == dstadr
847
0
          || (   (MDF_BCLNT & cast_flags)
848
0
        && (MDF_BCLNT & peer->cast_flags)))
849
0
        break;
850
851
0
      if (dstadr == ANY_INTERFACE_CHOOSE(srcadr) &&
852
0
          peer->dstadr == findinterface(srcadr))
853
0
        break;
854
855
0
      peer = findexistingpeer(srcadr, hostname, peer,
856
0
            hmode, cast_flags, &ip_count);
857
0
    }
858
0
  } else {
859
    /* no endpt address given */
860
0
    peer = findexistingpeer(srcadr, hostname, NULL, hmode,
861
0
          cast_flags, &ip_count);
862
0
  }
863
864
  /*
865
   * In any case, do not create an association with a duplicate
866
   * remote address (srcadr) except for undefined (zero) address.
867
   * Arguably this should be part of the logic above but
868
   * [Bug 3888] exposed a situation with manycastclient where
869
   * duplicate associations happened.
870
   */
871
0
  if (NULL == peer) {
872
0
    for (peer = peer_list;
873
0
         peer != NULL;
874
0
         peer = peer->p_link) {
875
0
      if (   SOCK_EQ(srcadr, &peer->srcadr)
876
0
          && !SOCK_UNSPEC(srcadr)
877
0
          && !SOCK_UNSPEC(&peer->srcadr)) {
878
        /* leave peer non-NULL */
879
0
        break;
880
0
      }
881
0
    }
882
0
  }
883
884
  /*
885
   * If a peer is found, this would be a duplicate and we don't
886
   * allow that. This avoids duplicate ephemeral (broadcast/
887
   * multicast) and preemptible (manycast and pool) client
888
   * associations.
889
   */
890
0
  if (peer != NULL) {
891
0
    DPRINTF(2, ("%s(%s) found existing association\n",
892
0
      __func__,
893
0
      (hostname)
894
0
          ? hostname
895
0
          : stoa(srcadr)));
896
0
    return NULL;
897
0
  }
898
899
#if 0
900
  DPRINTF(1, ("newpeer(%s) found no existing and %d other associations\n",
901
    (hostname)
902
        ? hostname
903
        : stoa(srcadr),
904
    ip_count));
905
#endif
906
907
  /* Check ippeerlimit wrt ip_count */
908
0
  if (ippeerlimit > -1) {
909
0
    if (ip_count + 1 > ippeerlimit) {
910
0
      DPRINTF(2, ("newpeer(%s) denied - ippeerlimit %d\n",
911
0
        (hostname)
912
0
            ? hostname
913
0
            : stoa(srcadr),
914
0
        ippeerlimit));
915
0
      return NULL;
916
0
    }
917
0
  } else {
918
0
    DPRINTF(1, ("newpeer(%s) - ippeerlimit %d ignored\n",
919
0
      (hostname)
920
0
          ? hostname
921
0
          : stoa(srcadr),
922
0
      ippeerlimit));
923
0
  }
924
925
  /*
926
   * Allocate a new peer structure. Some dirt here, since some of
927
   * the initialization requires knowlege of our system state.
928
   */
929
0
  if (peer_free_count == 0)
930
0
    getmorepeermem();
931
0
  UNLINK_HEAD_SLIST(peer, peer_free, p_link);
932
0
  INSIST(peer != NULL);
933
0
  peer_free_count--;
934
0
  peer_associations++;
935
0
  if (FLAG_PREEMPT & flags)
936
0
    peer_preempt++;
937
938
  /*
939
   * Assign an available association ID.  Zero is reserved.
940
   */
941
0
  do {
942
0
    while (0 == ++current_association_ID) {
943
      /* EMPTY */
944
0
    }
945
0
  } while (NULL != findpeerbyassoc(current_association_ID));
946
0
  peer->associd = current_association_ID;
947
948
0
  peer->srcadr = *srcadr;
949
0
  if (hostname != NULL) {
950
0
    peer->hostname = estrdup(hostname);
951
0
  }
952
0
  peer->hmode = hmode;
953
0
  peer->version = version;
954
0
  peer->flags = flags;
955
0
  peer->cast_flags = cast_flags;
956
0
  set_peerdstadr(peer, 
957
0
           select_peerinterface(peer, srcadr, dstadr));
958
959
  /*
960
   * Zero for minpoll or maxpoll means use defaults.
961
   */
962
0
  peer->maxpoll = (0 == maxpoll)
963
0
          ? NTP_MAXDPOLL
964
0
          : maxpoll;
965
0
  peer->minpoll = (0 == minpoll)
966
0
          ? NTP_MINDPOLL
967
0
          : minpoll;
968
969
  /*
970
   * Clamp maxpoll and minpoll within NTP_MINPOLL and NTP_MAXPOLL,
971
   * and further clamp minpoll less than or equal maxpoll.
972
   */
973
0
  peer->maxpoll = CLAMP(peer->maxpoll, NTP_MINPOLL, NTP_MAXPOLL);
974
0
  peer->minpoll = CLAMP(peer->minpoll, NTP_MINPOLL, peer->maxpoll);
975
976
0
  if (peer->dstadr != NULL) {
977
0
    DPRINTF(3, ("newpeer(%s): using fd %d and our addr %s\n",
978
0
      stoa(srcadr), peer->dstadr->fd,
979
0
      stoa(&peer->dstadr->sin)));
980
0
  } else {
981
0
    DPRINTF(3, ("newpeer(%s): local addr unavailable\n",
982
0
      stoa(srcadr))); 
983
0
  }
984
  /*
985
   * Broadcast needs the socket enabled for broadcast
986
   */
987
0
  if ((MDF_BCAST & cast_flags) && peer->dstadr != NULL) {
988
0
    enable_broadcast(peer->dstadr, srcadr);
989
0
  }
990
  /*
991
   * Multicast needs the socket interface enabled for multicast
992
   */
993
0
  if ((MDF_MCAST & cast_flags) && peer->dstadr != NULL) {
994
0
    enable_multicast_if(peer->dstadr, srcadr);
995
0
  }
996
0
#ifdef AUTOKEY
997
0
  if (key > NTP_MAXKEY)
998
0
    peer->flags |= FLAG_SKEY;
999
0
#endif  /* AUTOKEY */
1000
0
  peer->ttl = ttl;
1001
0
  peer->keyid = key;
1002
0
  if (ident != NULL) {
1003
0
    peer->ident = estrdup(ident);
1004
0
  }
1005
0
  peer->precision = sys_precision;
1006
0
  peer->hpoll = peer->minpoll;
1007
0
  if (cast_flags & MDF_ACAST) {
1008
0
    peer_clear(peer, "ACST");
1009
0
  } else if (cast_flags & MDF_POOL) {
1010
0
    peer_clear(peer, "POOL");
1011
0
  } else if (cast_flags & MDF_MCAST) {
1012
0
    peer_clear(peer, "MCST");
1013
0
  } else if (cast_flags & MDF_BCAST) {
1014
0
    peer_clear(peer, "BCST");
1015
0
  } else {
1016
0
    peer_clear(peer, "INIT");
1017
0
  }
1018
0
  if (mode_ntpdate) {
1019
0
    peer_ntpdate++;
1020
0
  }
1021
  /*
1022
   * Note time on statistics timers.
1023
   */
1024
0
  peer->timereset = current_time;
1025
0
  peer->timereachable = current_time;
1026
0
  peer->timereceived = current_time;
1027
1028
0
  if (ISREFCLOCKADR(&peer->srcadr)) {
1029
0
#ifdef REFCLOCK
1030
    /*
1031
     * We let the reference clock support do clock
1032
     * dependent initialization.  This includes setting
1033
     * the peer timer, since the clock may have requirements
1034
     * for this.
1035
     */
1036
0
    if (!refclock_newpeer(peer)) {
1037
      /*
1038
       * Dump it, something screwed up
1039
       */
1040
0
      set_peerdstadr(peer, NULL);
1041
0
      free_peer(peer, 0);
1042
0
      return NULL;
1043
0
    }
1044
#else /* REFCLOCK */
1045
    msyslog(LOG_ERR, "refclock %s isn't supported. ntpd was compiled without refclock support.",
1046
      stoa(&peer->srcadr));
1047
    set_peerdstadr(peer, NULL);
1048
    free_peer(peer, 0);
1049
    return NULL;
1050
#endif /* REFCLOCK */
1051
0
  }
1052
1053
  /*
1054
   * Put the new peer in the hash tables.
1055
   */
1056
0
  hash = NTP_HASH_ADDR(&peer->srcadr);
1057
0
  LINK_SLIST(peer_hash[hash], peer, adr_link);
1058
0
  peer_hash_count[hash]++;
1059
0
  hash = peer->associd & NTP_HASH_MASK;
1060
0
  LINK_SLIST(assoc_hash[hash], peer, aid_link);
1061
0
  assoc_hash_count[hash]++;
1062
0
  LINK_SLIST(peer_list, peer, p_link);
1063
1064
0
  restrict_source(&peer->srcadr, FALSE, 0);
1065
0
  mprintf_event(PEVNT_MOBIL, peer, "assoc %d", peer->associd);
1066
0
  DPRINTF(1, ("newpeer: %s->%s mode %u vers %u poll %u %u flags 0x%x 0x%x ttl %u key %08x\n",
1067
0
      latoa(peer->dstadr), stoa(&peer->srcadr), peer->hmode,
1068
0
      peer->version, peer->minpoll, peer->maxpoll, peer->flags,
1069
0
      peer->cast_flags, peer->ttl, peer->keyid));
1070
0
  return peer;
1071
0
}
1072
1073
1074
/*
1075
 * peer_clr_stats - clear peer module statistics counters
1076
 */
1077
void
1078
peer_clr_stats(void)
1079
0
{
1080
0
  findpeer_calls = 0;
1081
0
  assocpeer_calls = 0;
1082
0
  peer_allocations = 0;
1083
0
  peer_demobilizations = 0;
1084
0
  peer_timereset = current_time;
1085
0
}
1086
1087
1088
/*
1089
 * peer_reset - reset statistics counters
1090
 */
1091
void
1092
peer_reset(
1093
  struct peer *peer
1094
  )
1095
0
{
1096
0
  if (peer == NULL)
1097
0
    return;
1098
1099
0
  peer->timereset = current_time;
1100
0
  peer->sent = 0;
1101
0
  peer->received = 0;
1102
0
  peer->processed = 0;
1103
0
  peer->badauth = 0;
1104
0
  peer->bogusorg = 0;
1105
0
  peer->oldpkt = 0;
1106
0
  peer->seldisptoolarge = 0;
1107
0
  peer->selbroken = 0;
1108
0
}
1109
1110
1111
/*
1112
 * peer_all_reset - reset all peer statistics counters
1113
 */
1114
void
1115
peer_all_reset(void)
1116
0
{
1117
0
  struct peer *peer;
1118
1119
0
  for (peer = peer_list; peer != NULL; peer = peer->p_link)
1120
0
    peer_reset(peer);
1121
0
}
1122
1123
1124
/*
1125
 * findmanycastpeer - find and return a manycastclient or pool
1126
 *          association matching a received response.
1127
 */
1128
struct peer *
1129
findmanycastpeer(
1130
  struct recvbuf *rbufp /* receive buffer pointer */
1131
  )
1132
0
{
1133
0
  struct peer *peer;
1134
0
  struct pkt *pkt;
1135
0
  l_fp p_org;
1136
1137
  /*
1138
   * This routine is called upon arrival of a server-mode response
1139
   * to a manycastclient multicast solicitation, or to a pool
1140
   * server unicast solicitation.  Search the peer list for a
1141
   * manycastclient association where the last transmit timestamp
1142
   * matches the response packet's originate timestamp.  There can
1143
   * be multiple manycastclient associations, or multiple pool
1144
   * solicitation assocations, so this assumes the transmit
1145
   * timestamps are unique for such.
1146
   */
1147
0
  pkt = &rbufp->recv_pkt;
1148
0
  for (peer = peer_list; peer != NULL; peer = peer->p_link)
1149
0
    if (MDF_SOLICIT_MASK & peer->cast_flags) {
1150
0
      NTOHL_FP(&pkt->org, &p_org);
1151
0
      if (L_ISEQU(&p_org, &peer->aorg)) {
1152
0
        break;
1153
0
      }
1154
0
    }
1155
1156
0
  return peer;
1157
0
}
1158
1159
/* peer_cleanup - clean peer list prior to shutdown */
1160
void peer_cleanup(void)
1161
0
{
1162
0
  struct peer *peer;
1163
0
  struct peer *nextpeer;
1164
1165
0
  for (peer = peer_list; peer != NULL; peer = nextpeer) {
1166
0
    nextpeer = peer->p_link;
1167
0
    unpeer(peer);
1168
0
  }
1169
0
}