1 /*
2   chronyd/chronyc - Programs for keeping computer clocks accurate.
3 
4  **********************************************************************
5  * Copyright (C) Richard P. Curnow  1997-2003
6  * Copyright (C) Miroslav Lichvar  2011-2012, 2014, 2016, 2020-2021
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of version 2 of the GNU General Public License as
10  * published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20  *
21  **********************************************************************
22 
23   =======================================================================
24 
25   Functions which manage the pool of NTP sources that we are currently
26   a client of or peering with.
27 
28   */
29 
30 #include "config.h"
31 
32 #include "sysincl.h"
33 
34 #include "array.h"
35 #include "ntp_sources.h"
36 #include "ntp_core.h"
37 #include "ntp_io.h"
38 #include "util.h"
39 #include "logging.h"
40 #include "local.h"
41 #include "memory.h"
42 #include "nameserv_async.h"
43 #include "privops.h"
44 #include "sched.h"
45 
46 /* ================================================== */
47 
48 /* Maximum number of sources */
49 #define MAX_SOURCES 65536
50 
51 /* Record type private to this file, used to store information about
52    particular sources */
53 typedef struct {
54   NTP_Remote_Address *remote_addr; /* The address of this source, non-NULL
55                                       means this slot in table is in use
56                                       (an IPADDR_ID address means the address
57                                       is not resolved yet) */
58   NCR_Instance data;            /* Data for the protocol engine for this source */
59   char *name;                   /* Name of the source as it was specified
60                                    (may be an IP address) */
61   int pool_id;                  /* ID of the pool from which was this source
62                                    added or INVALID_POOL */
63   int tentative;                /* Flag indicating there was no valid response
64                                    received from the source yet */
65   uint32_t conf_id;             /* Configuration ID, which can be shared with
66                                    different sources in case of a pool */
67 } SourceRecord;
68 
69 /* Hash table of SourceRecord, its size is a power of two and it's never
70    more than half full */
71 static ARR_Instance records;
72 
73 /* Number of sources in the hash table */
74 static int n_sources;
75 
76 /* Flag indicating new sources will be started automatically when added */
77 static int auto_start_sources = 0;
78 
79 /* Flag indicating a record is currently being modified */
80 static int record_lock;
81 
82 /* Last assigned address ID */
83 static uint32_t last_address_id = 0;
84 
85 /* Last assigned configuration ID */
86 static uint32_t last_conf_id = 0;
87 
88 /* Source scheduled for name resolving (first resolving or replacement) */
89 struct UnresolvedSource {
90   /* Current address of the source (IPADDR_ID is used for a single source
91      with unknown address and IPADDR_UNSPEC for a pool of sources) */
92   NTP_Remote_Address address;
93   /* ID of the pool if not a single source */
94   int pool_id;
95   /* Name to be resolved */
96   char *name;
97   /* Flag indicating addresses should be used in a random order */
98   int random_order;
99   /* Next unresolved source in the list */
100   struct UnresolvedSource *next;
101 };
102 
103 #define RESOLVE_INTERVAL_UNIT 7
104 #define MIN_RESOLVE_INTERVAL 2
105 #define MAX_RESOLVE_INTERVAL 9
106 #define MIN_REPLACEMENT_INTERVAL 8
107 
108 static struct UnresolvedSource *unresolved_sources = NULL;
109 static int resolving_interval = 0;
110 static int resolving_restart = 0;
111 static SCH_TimeoutID resolving_id;
112 static struct UnresolvedSource *resolving_source = NULL;
113 static NSR_SourceResolvingEndHandler resolving_end_handler = NULL;
114 
115 #define MAX_POOL_SOURCES 16
116 #define INVALID_POOL (-1)
117 
118 /* Pool of sources with the same name */
119 struct SourcePool {
120   /* Number of all sources from the pool */
121   int sources;
122   /* Number of sources with unresolved address */
123   int unresolved_sources;
124   /* Number of non-tentative sources */
125   int confirmed_sources;
126   /* Maximum number of confirmed sources */
127   int max_sources;
128 };
129 
130 /* Array of SourcePool (indexed by their ID) */
131 static ARR_Instance pools;
132 
133 /* Requested update of a source's address */
134 struct AddressUpdate {
135   NTP_Remote_Address old_address;
136   NTP_Remote_Address new_address;
137 };
138 
139 /* Update saved when record_lock is true */
140 static struct AddressUpdate saved_address_update;
141 
142 /* ================================================== */
143 /* Forward prototypes */
144 
145 static void resolve_sources(void);
146 static void rehash_records(void);
147 static void handle_saved_address_update(void);
148 static void clean_source_record(SourceRecord *record);
149 static void remove_pool_sources(int pool_id, int tentative, int unresolved);
150 static void remove_unresolved_source(struct UnresolvedSource *us);
151 
152 static void
153 slew_sources(struct timespec *raw,
154              struct timespec *cooked,
155              double dfreq,
156              double doffset,
157              LCL_ChangeType change_type,
158              void *anything);
159 
160 /* ================================================== */
161 
162 /* Flag indicating whether module is initialised */
163 static int initialised = 0;
164 
165 /* ================================================== */
166 
167 static SourceRecord *
get_record(unsigned index)168 get_record(unsigned index)
169 {
170   return (SourceRecord *)ARR_GetElement(records, index);
171 }
172 
173 /* ================================================== */
174 
175 static struct SourcePool *
get_pool(unsigned index)176 get_pool(unsigned index)
177 {
178   return (struct SourcePool *)ARR_GetElement(pools, index);
179 }
180 
181 /* ================================================== */
182 
183 void
NSR_Initialise(void)184 NSR_Initialise(void)
185 {
186   n_sources = 0;
187   initialised = 1;
188 
189   records = ARR_CreateInstance(sizeof (SourceRecord));
190   rehash_records();
191 
192   pools = ARR_CreateInstance(sizeof (struct SourcePool));
193 
194   LCL_AddParameterChangeHandler(slew_sources, NULL);
195 }
196 
197 /* ================================================== */
198 
199 void
NSR_Finalise(void)200 NSR_Finalise(void)
201 {
202   NSR_RemoveAllSources();
203 
204   LCL_RemoveParameterChangeHandler(slew_sources, NULL);
205 
206   ARR_DestroyInstance(records);
207   ARR_DestroyInstance(pools);
208 
209   while (unresolved_sources)
210     remove_unresolved_source(unresolved_sources);
211 
212   initialised = 0;
213 }
214 
215 /* ================================================== */
216 /* Find a slot matching an IP address.  It is assumed that there can
217    only ever be one record for a particular IP address. */
218 
219 static int
find_slot(IPAddr * ip_addr,int * slot)220 find_slot(IPAddr *ip_addr, int *slot)
221 {
222   SourceRecord *record;
223   uint32_t hash;
224   unsigned int i, size;
225 
226   size = ARR_GetSize(records);
227 
228   *slot = 0;
229 
230   switch (ip_addr->family) {
231     case IPADDR_INET4:
232     case IPADDR_INET6:
233     case IPADDR_ID:
234       break;
235     default:
236       return 0;
237   }
238 
239   hash = UTI_IPToHash(ip_addr);
240 
241   for (i = 0; i < size / 2; i++) {
242     /* Use quadratic probing */
243     *slot = (hash + (i + i * i) / 2) % size;
244     record = get_record(*slot);
245 
246     if (!record->remote_addr)
247       break;
248 
249     if (UTI_CompareIPs(&record->remote_addr->ip_addr, ip_addr, NULL) == 0)
250       return 1;
251   }
252 
253   return 0;
254 }
255 
256 /* ================================================== */
257 /* Find a slot matching an IP address and port. The function returns:
258    0 => IP not matched, empty slot returned if a valid address was provided
259    1 => Only IP matched, port doesn't match
260    2 => Both IP and port matched. */
261 
262 static int
find_slot2(NTP_Remote_Address * remote_addr,int * slot)263 find_slot2(NTP_Remote_Address *remote_addr, int *slot)
264 {
265   if (!find_slot(&remote_addr->ip_addr, slot))
266     return 0;
267 
268   return get_record(*slot)->remote_addr->port == remote_addr->port ? 2 : 1;
269 }
270 
271 /* ================================================== */
272 /* Check if hash table of given size is sufficient to contain sources */
273 
274 static int
check_hashtable_size(unsigned int sources,unsigned int size)275 check_hashtable_size(unsigned int sources, unsigned int size)
276 {
277   return sources * 2 <= size;
278 }
279 
280 /* ================================================== */
281 
282 static void
rehash_records(void)283 rehash_records(void)
284 {
285   SourceRecord *temp_records;
286   unsigned int i, old_size, new_size;
287   int slot;
288 
289   assert(!record_lock);
290 
291   old_size = ARR_GetSize(records);
292 
293   temp_records = MallocArray(SourceRecord, old_size);
294   memcpy(temp_records, ARR_GetElements(records), old_size * sizeof (SourceRecord));
295 
296   /* The size of the hash table is always a power of two */
297   for (new_size = 1; !check_hashtable_size(n_sources, new_size); new_size *= 2)
298     ;
299 
300   ARR_SetSize(records, new_size);
301 
302   for (i = 0; i < new_size; i++)
303     get_record(i)->remote_addr = NULL;
304 
305   for (i = 0; i < old_size; i++) {
306     if (!temp_records[i].remote_addr)
307       continue;
308 
309     if (find_slot2(temp_records[i].remote_addr, &slot) != 0)
310       assert(0);
311 
312     *get_record(slot) = temp_records[i];
313   }
314 
315   Free(temp_records);
316 }
317 
318 /* ================================================== */
319 
320 /* Procedure to add a new source */
321 static NSR_Status
add_source(NTP_Remote_Address * remote_addr,char * name,NTP_Source_Type type,SourceParameters * params,int pool_id,uint32_t conf_id)322 add_source(NTP_Remote_Address *remote_addr, char *name, NTP_Source_Type type,
323            SourceParameters *params, int pool_id, uint32_t conf_id)
324 {
325   SourceRecord *record;
326   int slot;
327 
328   assert(initialised);
329 
330   /* Find empty bin & check that we don't have the address already */
331   if (find_slot2(remote_addr, &slot) != 0) {
332     return NSR_AlreadyInUse;
333   } else if (!name && !UTI_IsIPReal(&remote_addr->ip_addr)) {
334     /* Name is required for non-real addresses */
335     return NSR_InvalidName;
336   } else if (n_sources >= MAX_SOURCES) {
337     return NSR_TooManySources;
338   } else {
339     if (remote_addr->ip_addr.family != IPADDR_INET4 &&
340         remote_addr->ip_addr.family != IPADDR_INET6 &&
341         remote_addr->ip_addr.family != IPADDR_ID) {
342       return NSR_InvalidAF;
343     } else {
344       n_sources++;
345 
346       if (!check_hashtable_size(n_sources, ARR_GetSize(records))) {
347         rehash_records();
348         if (find_slot2(remote_addr, &slot) != 0)
349           assert(0);
350       }
351 
352       assert(!record_lock);
353       record_lock = 1;
354 
355       record = get_record(slot);
356       assert(!name || !UTI_IsStringIP(name));
357       record->name = Strdup(name ? name : UTI_IPToString(&remote_addr->ip_addr));
358       record->data = NCR_CreateInstance(remote_addr, type, params, record->name);
359       record->remote_addr = NCR_GetRemoteAddress(record->data);
360       record->pool_id = pool_id;
361       record->tentative = 1;
362       record->conf_id = conf_id;
363 
364       record_lock = 0;
365 
366       if (record->pool_id != INVALID_POOL) {
367         get_pool(record->pool_id)->sources++;
368         if (!UTI_IsIPReal(&remote_addr->ip_addr))
369           get_pool(record->pool_id)->unresolved_sources++;
370       }
371 
372       if (auto_start_sources && UTI_IsIPReal(&remote_addr->ip_addr))
373         NCR_StartInstance(record->data);
374 
375       /* The new instance is allowed to change its address immediately */
376       handle_saved_address_update();
377 
378       return NSR_Success;
379     }
380   }
381 }
382 
383 /* ================================================== */
384 
385 static NSR_Status
change_source_address(NTP_Remote_Address * old_addr,NTP_Remote_Address * new_addr,int replacement)386 change_source_address(NTP_Remote_Address *old_addr, NTP_Remote_Address *new_addr,
387                       int replacement)
388 {
389   int slot1, slot2, found;
390   SourceRecord *record;
391   LOG_Severity severity;
392   char *name;
393 
394   found = find_slot2(old_addr, &slot1);
395   if (found != 2)
396     return NSR_NoSuchSource;
397 
398   /* Make sure there is no other source using the new address (with the same
399      or different port), but allow a source to have its port changed */
400   found = find_slot2(new_addr, &slot2);
401   if (found == 2 || (found != 0 && slot1 != slot2))
402     return NSR_AlreadyInUse;
403 
404   assert(!record_lock);
405   record_lock = 1;
406 
407   record = get_record(slot1);
408   NCR_ChangeRemoteAddress(record->data, new_addr, !replacement);
409 
410   if (record->remote_addr != NCR_GetRemoteAddress(record->data) ||
411       UTI_CompareIPs(&record->remote_addr->ip_addr, &new_addr->ip_addr, NULL) != 0)
412     assert(0);
413 
414   if (!UTI_IsIPReal(&old_addr->ip_addr) && UTI_IsIPReal(&new_addr->ip_addr)) {
415     if (auto_start_sources)
416       NCR_StartInstance(record->data);
417     if (record->pool_id != INVALID_POOL)
418       get_pool(record->pool_id)->unresolved_sources--;
419   }
420 
421   if (!record->tentative) {
422     record->tentative = 1;
423 
424     if (record->pool_id != INVALID_POOL)
425       get_pool(record->pool_id)->confirmed_sources--;
426   }
427 
428   record_lock = 0;
429 
430   name = record->name;
431   severity = UTI_IsIPReal(&old_addr->ip_addr) ? LOGS_INFO : LOGS_DEBUG;
432 
433   if (found == 0) {
434     /* The hash table must be rebuilt for the changed address */
435     rehash_records();
436 
437     LOG(severity, "Source %s %s %s (%s)", UTI_IPToString(&old_addr->ip_addr),
438         replacement ? "replaced with" : "changed to",
439         UTI_IPToString(&new_addr->ip_addr), name);
440   } else {
441     LOG(severity, "Source %s (%s) changed port to %d",
442         UTI_IPToString(&new_addr->ip_addr), name, new_addr->port);
443   }
444 
445   return NSR_Success;
446 }
447 
448 /* ================================================== */
449 
450 static void
handle_saved_address_update(void)451 handle_saved_address_update(void)
452 {
453   if (!UTI_IsIPReal(&saved_address_update.old_address.ip_addr))
454     return;
455 
456   if (change_source_address(&saved_address_update.old_address,
457                             &saved_address_update.new_address, 0) != NSR_Success)
458     /* This is expected to happen only if the old address is wrong */
459     LOG(LOGS_ERR, "Could not change %s to %s",
460         UTI_IPSockAddrToString(&saved_address_update.old_address),
461         UTI_IPSockAddrToString(&saved_address_update.new_address));
462 
463   saved_address_update.old_address.ip_addr.family = IPADDR_UNSPEC;
464 }
465 
466 /* ================================================== */
467 
468 static int
replace_source_connectable(NTP_Remote_Address * old_addr,NTP_Remote_Address * new_addr)469 replace_source_connectable(NTP_Remote_Address *old_addr, NTP_Remote_Address *new_addr)
470 {
471   if (!NIO_IsServerConnectable(new_addr)) {
472     DEBUG_LOG("%s not connectable", UTI_IPToString(&new_addr->ip_addr));
473     return 0;
474   }
475 
476   if (change_source_address(old_addr, new_addr, 1) == NSR_AlreadyInUse)
477     return 0;
478 
479   handle_saved_address_update();
480 
481   return 1;
482 }
483 
484 /* ================================================== */
485 
486 static void
process_resolved_name(struct UnresolvedSource * us,IPAddr * ip_addrs,int n_addrs)487 process_resolved_name(struct UnresolvedSource *us, IPAddr *ip_addrs, int n_addrs)
488 {
489   NTP_Remote_Address old_addr, new_addr;
490   SourceRecord *record;
491   unsigned short first = 0;
492   int i, j;
493 
494   if (us->random_order)
495     UTI_GetRandomBytes(&first, sizeof (first));
496 
497   for (i = 0; i < n_addrs; i++) {
498     new_addr.ip_addr = ip_addrs[((unsigned int)i + first) % n_addrs];
499 
500     DEBUG_LOG("(%d) %s", i + 1, UTI_IPToString(&new_addr.ip_addr));
501 
502     if (us->pool_id != INVALID_POOL) {
503       /* In the pool resolving mode, try to replace a source from
504          the pool which does not have a real address yet */
505       for (j = 0; j < ARR_GetSize(records); j++) {
506         record = get_record(j);
507         if (!record->remote_addr || record->pool_id != us->pool_id ||
508             UTI_IsIPReal(&record->remote_addr->ip_addr))
509           continue;
510         old_addr = *record->remote_addr;
511         new_addr.port = old_addr.port;
512         if (replace_source_connectable(&old_addr, &new_addr))
513           ;
514         break;
515       }
516     } else {
517       new_addr.port = us->address.port;
518       if (replace_source_connectable(&us->address, &new_addr))
519         break;
520     }
521   }
522 }
523 
524 /* ================================================== */
525 
526 static int
is_resolved(struct UnresolvedSource * us)527 is_resolved(struct UnresolvedSource *us)
528 {
529   int slot;
530 
531   if (us->pool_id != INVALID_POOL) {
532     return get_pool(us->pool_id)->unresolved_sources <= 0;
533   } else {
534     /* If the address is no longer present, it was removed or replaced
535        (i.e. resolved) */
536     return find_slot2(&us->address, &slot) == 0;
537   }
538 }
539 
540 /* ================================================== */
541 
542 static void
resolve_sources_timeout(void * arg)543 resolve_sources_timeout(void *arg)
544 {
545   resolving_id = 0;
546   resolve_sources();
547 }
548 
549 /* ================================================== */
550 
551 static void
name_resolve_handler(DNS_Status status,int n_addrs,IPAddr * ip_addrs,void * anything)552 name_resolve_handler(DNS_Status status, int n_addrs, IPAddr *ip_addrs, void *anything)
553 {
554   struct UnresolvedSource *us, *next;
555 
556   us = (struct UnresolvedSource *)anything;
557 
558   assert(us == resolving_source);
559   assert(resolving_id == 0);
560 
561   DEBUG_LOG("%s resolved to %d addrs", us->name, n_addrs);
562 
563   switch (status) {
564     case DNS_TryAgain:
565       break;
566     case DNS_Success:
567       process_resolved_name(us, ip_addrs, n_addrs);
568       break;
569     case DNS_Failure:
570       LOG(LOGS_WARN, "Invalid host %s", us->name);
571       break;
572     default:
573       assert(0);
574   }
575 
576   next = us->next;
577 
578   /* Don't repeat the resolving if it (permanently) failed, it was a
579      replacement of a real address, or all addresses are already resolved */
580   if (status == DNS_Failure || UTI_IsIPReal(&us->address.ip_addr) || is_resolved(us))
581     remove_unresolved_source(us);
582 
583   /* If a restart was requested and this was the last source in the list,
584      start with the first source again (if there still is one) */
585   if (!next && resolving_restart) {
586     next = unresolved_sources;
587     resolving_restart = 0;
588   }
589 
590   resolving_source = next;
591 
592   if (next) {
593     /* Continue with the next source in the list */
594     DEBUG_LOG("resolving %s", next->name);
595     DNS_Name2IPAddressAsync(next->name, name_resolve_handler, next);
596   } else {
597     /* This was the last source in the list. If some sources couldn't
598        be resolved, try again in exponentially increasing interval. */
599     if (unresolved_sources) {
600       resolving_interval = CLAMP(MIN_RESOLVE_INTERVAL, resolving_interval + 1,
601                                  MAX_RESOLVE_INTERVAL);
602       resolving_id = SCH_AddTimeoutByDelay(RESOLVE_INTERVAL_UNIT * (1 << resolving_interval),
603                                            resolve_sources_timeout, NULL);
604     } else {
605       resolving_interval = 0;
606     }
607 
608     /* This round of resolving is done */
609     if (resolving_end_handler)
610       (resolving_end_handler)();
611   }
612 }
613 
614 /* ================================================== */
615 
616 static void
resolve_sources(void)617 resolve_sources(void)
618 {
619   struct UnresolvedSource *us, *next, *i;
620 
621   assert(!resolving_source);
622 
623   /* Remove sources that don't need to be resolved anymore */
624   for (i = unresolved_sources; i; i = next) {
625     next = i->next;
626     if (is_resolved(i))
627       remove_unresolved_source(i);
628   }
629 
630   if (!unresolved_sources)
631     return;
632 
633   PRV_ReloadDNS();
634 
635   /* Start with the first source in the list, name_resolve_handler
636      will iterate over the rest */
637   us = unresolved_sources;
638 
639   resolving_source = us;
640   DEBUG_LOG("resolving %s", us->name);
641   DNS_Name2IPAddressAsync(us->name, name_resolve_handler, us);
642 }
643 
644 /* ================================================== */
645 
646 static void
append_unresolved_source(struct UnresolvedSource * us)647 append_unresolved_source(struct UnresolvedSource *us)
648 {
649   struct UnresolvedSource **i;
650 
651   for (i = &unresolved_sources; *i; i = &(*i)->next)
652     ;
653   *i = us;
654   us->next = NULL;
655 }
656 
657 /* ================================================== */
658 
659 static void
remove_unresolved_source(struct UnresolvedSource * us)660 remove_unresolved_source(struct UnresolvedSource *us)
661 {
662   struct UnresolvedSource **i;
663 
664   for (i = &unresolved_sources; *i; i = &(*i)->next) {
665     if (*i == us) {
666       *i = us->next;
667       Free(us->name);
668       Free(us);
669       break;
670     }
671   }
672 }
673 
674 /* ================================================== */
675 
get_unused_pool_id(void)676 static int get_unused_pool_id(void)
677 {
678   struct UnresolvedSource *us;
679   int i;
680 
681   for (i = 0; i < ARR_GetSize(pools); i++) {
682     if (get_pool(i)->sources > 0)
683       continue;
684 
685     /* Make sure there is no name waiting to be resolved using this pool */
686     for (us = unresolved_sources; us; us = us->next) {
687       if (us->pool_id == i)
688         break;
689     }
690     if (us)
691       continue;
692 
693     return i;
694   }
695 
696   return INVALID_POOL;
697 }
698 
699 /* ================================================== */
700 
701 NSR_Status
NSR_AddSource(NTP_Remote_Address * remote_addr,NTP_Source_Type type,SourceParameters * params,uint32_t * conf_id)702 NSR_AddSource(NTP_Remote_Address *remote_addr, NTP_Source_Type type,
703               SourceParameters *params, uint32_t *conf_id)
704 {
705   NSR_Status s;
706 
707   s = add_source(remote_addr, NULL, type, params, INVALID_POOL, last_conf_id + 1);
708   if (s != NSR_Success)
709     return s;
710 
711   last_conf_id++;
712   if (conf_id)
713     *conf_id = last_conf_id;
714 
715   return s;
716 }
717 
718 /* ================================================== */
719 
720 NSR_Status
NSR_AddSourceByName(char * name,int port,int pool,NTP_Source_Type type,SourceParameters * params,uint32_t * conf_id)721 NSR_AddSourceByName(char *name, int port, int pool, NTP_Source_Type type,
722                     SourceParameters *params, uint32_t *conf_id)
723 {
724   struct UnresolvedSource *us;
725   struct SourcePool *sp;
726   NTP_Remote_Address remote_addr;
727   int i, new_sources, pool_id;
728 
729   /* If the name is an IP address, add the source with the address directly */
730   if (UTI_StringToIP(name, &remote_addr.ip_addr)) {
731     remote_addr.port = port;
732     return NSR_AddSource(&remote_addr, type, params, conf_id);
733   }
734 
735   /* Make sure the name is at least printable and has no spaces */
736   for (i = 0; name[i] != '\0'; i++) {
737     if (!isgraph((unsigned char)name[i]))
738       return NSR_InvalidName;
739   }
740 
741   us = MallocNew(struct UnresolvedSource);
742   us->name = Strdup(name);
743   us->random_order = 0;
744 
745   remote_addr.ip_addr.family = IPADDR_ID;
746   remote_addr.ip_addr.addr.id = ++last_address_id;
747   remote_addr.port = port;
748 
749   if (!pool) {
750     us->pool_id = INVALID_POOL;
751     us->address = remote_addr;
752     new_sources = 1;
753   } else {
754     pool_id = get_unused_pool_id();
755     if (pool_id != INVALID_POOL) {
756       sp = get_pool(pool_id);
757     } else {
758       sp = ARR_GetNewElement(pools);
759       pool_id = ARR_GetSize(pools) - 1;
760     }
761 
762     sp->sources = 0;
763     sp->unresolved_sources = 0;
764     sp->confirmed_sources = 0;
765     sp->max_sources = CLAMP(1, params->max_sources, MAX_POOL_SOURCES);
766     us->pool_id = pool_id;
767     us->address.ip_addr.family = IPADDR_UNSPEC;
768     new_sources = MIN(2 * sp->max_sources, MAX_POOL_SOURCES);
769   }
770 
771   append_unresolved_source(us);
772 
773   last_conf_id++;
774   if (conf_id)
775     *conf_id = last_conf_id;
776 
777   for (i = 0; i < new_sources; i++) {
778     if (i > 0)
779       remote_addr.ip_addr.addr.id = ++last_address_id;
780     if (add_source(&remote_addr, name, type, params, us->pool_id, last_conf_id) != NSR_Success)
781       return NSR_TooManySources;
782   }
783 
784   return NSR_UnresolvedName;
785 }
786 
787 /* ================================================== */
788 
789 void
NSR_SetSourceResolvingEndHandler(NSR_SourceResolvingEndHandler handler)790 NSR_SetSourceResolvingEndHandler(NSR_SourceResolvingEndHandler handler)
791 {
792   resolving_end_handler = handler;
793 }
794 
795 /* ================================================== */
796 
797 void
NSR_ResolveSources(void)798 NSR_ResolveSources(void)
799 {
800   /* Try to resolve unresolved sources now */
801   if (unresolved_sources) {
802     /* Allow only one resolving to be running at a time */
803     if (!resolving_source) {
804       if (resolving_id != 0) {
805         SCH_RemoveTimeout(resolving_id);
806         resolving_id = 0;
807         resolving_interval--;
808       }
809       resolve_sources();
810     } else {
811       /* Try again as soon as the current resolving ends */
812       resolving_restart = 1;
813     }
814   } else {
815     /* No unresolved sources, we are done */
816     if (resolving_end_handler)
817       (resolving_end_handler)();
818   }
819 }
820 
821 /* ================================================== */
822 
NSR_StartSources(void)823 void NSR_StartSources(void)
824 {
825   NTP_Remote_Address *addr;
826   unsigned int i;
827 
828   for (i = 0; i < ARR_GetSize(records); i++) {
829     addr = get_record(i)->remote_addr;
830     if (!addr || !UTI_IsIPReal(&addr->ip_addr))
831       continue;
832     NCR_StartInstance(get_record(i)->data);
833   }
834 }
835 
836 /* ================================================== */
837 
NSR_AutoStartSources(void)838 void NSR_AutoStartSources(void)
839 {
840   auto_start_sources = 1;
841 }
842 
843 /* ================================================== */
844 
845 static void
clean_source_record(SourceRecord * record)846 clean_source_record(SourceRecord *record)
847 {
848   assert(record->remote_addr);
849 
850   if (record->pool_id != INVALID_POOL) {
851     struct SourcePool *pool = get_pool(record->pool_id);
852 
853     pool->sources--;
854     if (!UTI_IsIPReal(&record->remote_addr->ip_addr))
855       pool->unresolved_sources--;
856     if (!record->tentative)
857       pool->confirmed_sources--;
858     if (pool->max_sources > pool->sources)
859       pool->max_sources = pool->sources;
860   }
861 
862   record->remote_addr = NULL;
863   NCR_DestroyInstance(record->data);
864   Free(record->name);
865 
866   n_sources--;
867 }
868 
869 /* ================================================== */
870 
871 /* Procedure to remove a source.  We don't bother whether the port
872    address is matched - we're only interested in removing a record for
873    the right IP address. */
874 NSR_Status
NSR_RemoveSource(IPAddr * address)875 NSR_RemoveSource(IPAddr *address)
876 {
877   int slot;
878 
879   assert(initialised);
880 
881   if (find_slot(address, &slot) == 0)
882     return NSR_NoSuchSource;
883 
884   clean_source_record(get_record(slot));
885 
886   /* Rehash the table to make sure there are no broken probe sequences.
887      This is costly, but it's not expected to happen frequently. */
888 
889   rehash_records();
890 
891   return NSR_Success;
892 }
893 
894 /* ================================================== */
895 
896 void
NSR_RemoveSourcesById(uint32_t conf_id)897 NSR_RemoveSourcesById(uint32_t conf_id)
898 {
899   SourceRecord *record;
900   unsigned int i;
901 
902   for (i = 0; i < ARR_GetSize(records); i++) {
903     record = get_record(i);
904     if (!record->remote_addr || record->conf_id != conf_id)
905       continue;
906     clean_source_record(record);
907   }
908 
909   rehash_records();
910 }
911 
912 /* ================================================== */
913 
914 void
NSR_RemoveAllSources(void)915 NSR_RemoveAllSources(void)
916 {
917   SourceRecord *record;
918   unsigned int i;
919 
920   for (i = 0; i < ARR_GetSize(records); i++) {
921     record = get_record(i);
922     if (!record->remote_addr)
923       continue;
924     clean_source_record(record);
925   }
926 
927   rehash_records();
928 }
929 
930 /* ================================================== */
931 
932 static void
resolve_source_replacement(SourceRecord * record)933 resolve_source_replacement(SourceRecord *record)
934 {
935   struct UnresolvedSource *us;
936 
937   DEBUG_LOG("trying to replace %s (%s)",
938             UTI_IPToString(&record->remote_addr->ip_addr), record->name);
939 
940   us = MallocNew(struct UnresolvedSource);
941   us->name = Strdup(record->name);
942   /* If there never was a valid reply from this source (e.g. it was a bad
943      replacement), ignore the order of addresses from the resolver to not get
944      stuck to a pair of addresses if the order doesn't change, or a group of
945      IPv4/IPv6 addresses if the resolver prefers inaccessible IP family */
946   us->random_order = record->tentative;
947   us->pool_id = INVALID_POOL;
948   us->address = *record->remote_addr;
949 
950   append_unresolved_source(us);
951   NSR_ResolveSources();
952 }
953 
954 /* ================================================== */
955 
956 void
NSR_HandleBadSource(IPAddr * address)957 NSR_HandleBadSource(IPAddr *address)
958 {
959   static struct timespec last_replacement;
960   struct timespec now;
961   SourceRecord *record;
962   IPAddr ip_addr;
963   double diff;
964   int slot;
965 
966   if (!find_slot(address, &slot))
967     return;
968 
969   record = get_record(slot);
970 
971   /* Don't try to replace a source specified by an IP address unless the
972      address changed since the source was added (e.g. by NTS-KE) */
973   if (UTI_StringToIP(record->name, &ip_addr) &&
974       UTI_CompareIPs(&record->remote_addr->ip_addr, &ip_addr, NULL) == 0)
975     return;
976 
977   /* Don't resolve names too frequently */
978   SCH_GetLastEventTime(NULL, NULL, &now);
979   diff = UTI_DiffTimespecsToDouble(&now, &last_replacement);
980   if (fabs(diff) < RESOLVE_INTERVAL_UNIT * (1 << MIN_REPLACEMENT_INTERVAL)) {
981     DEBUG_LOG("replacement postponed");
982     return;
983   }
984   last_replacement = now;
985 
986   resolve_source_replacement(record);
987 }
988 
989 /* ================================================== */
990 
991 void
NSR_RefreshAddresses(void)992 NSR_RefreshAddresses(void)
993 {
994   SourceRecord *record;
995   unsigned int i;
996 
997   for (i = 0; i < ARR_GetSize(records); i++) {
998     record = get_record(i);
999     if (!record->remote_addr)
1000       continue;
1001 
1002     resolve_source_replacement(record);
1003   }
1004 }
1005 
1006 /* ================================================== */
1007 
1008 NSR_Status
NSR_UpdateSourceNtpAddress(NTP_Remote_Address * old_addr,NTP_Remote_Address * new_addr)1009 NSR_UpdateSourceNtpAddress(NTP_Remote_Address *old_addr, NTP_Remote_Address *new_addr)
1010 {
1011   int slot;
1012 
1013   if (!UTI_IsIPReal(&old_addr->ip_addr) || !UTI_IsIPReal(&new_addr->ip_addr))
1014     return NSR_InvalidAF;
1015 
1016   if (UTI_CompareIPs(&old_addr->ip_addr, &new_addr->ip_addr, NULL) != 0 &&
1017       find_slot(&new_addr->ip_addr, &slot))
1018     return NSR_AlreadyInUse;
1019 
1020   /* If a record is being modified (e.g. by change_source_address(), or the
1021      source is just being created), postpone the change to avoid corruption */
1022 
1023   if (!record_lock)
1024     return change_source_address(old_addr, new_addr, 0);
1025 
1026   if (UTI_IsIPReal(&saved_address_update.old_address.ip_addr))
1027     return NSR_TooManySources;
1028 
1029   saved_address_update.old_address = *old_addr;
1030   saved_address_update.new_address = *new_addr;
1031 
1032   return NSR_Success;
1033 }
1034 
1035 /* ================================================== */
1036 
remove_pool_sources(int pool_id,int tentative,int unresolved)1037 static void remove_pool_sources(int pool_id, int tentative, int unresolved)
1038 {
1039   SourceRecord *record;
1040   unsigned int i, removed;
1041 
1042   for (i = removed = 0; i < ARR_GetSize(records); i++) {
1043     record = get_record(i);
1044 
1045     if (!record->remote_addr || record->pool_id != pool_id)
1046       continue;
1047 
1048     if ((tentative && !record->tentative) ||
1049         (unresolved && UTI_IsIPReal(&record->remote_addr->ip_addr)))
1050       continue;
1051 
1052     DEBUG_LOG("removing %ssource %s", tentative ? "tentative " : "",
1053               UTI_IPToString(&record->remote_addr->ip_addr));
1054 
1055     clean_source_record(record);
1056     removed++;
1057   }
1058 
1059   if (removed)
1060     rehash_records();
1061 }
1062 
1063 /* ================================================== */
1064 
1065 uint32_t
NSR_GetLocalRefid(IPAddr * address)1066 NSR_GetLocalRefid(IPAddr *address)
1067 {
1068   int slot;
1069 
1070   if (!find_slot(address, &slot))
1071     return 0;
1072 
1073   return NCR_GetLocalRefid(get_record(slot)->data);
1074 }
1075 
1076 /* ================================================== */
1077 
1078 char *
NSR_GetName(IPAddr * address)1079 NSR_GetName(IPAddr *address)
1080 {
1081   int slot;
1082 
1083   if (!find_slot(address, &slot))
1084     return NULL;
1085 
1086   return get_record(slot)->name;
1087 }
1088 
1089 /* ================================================== */
1090 
1091 /* This routine is called by ntp_io when a new packet arrives off the network,
1092    possibly with an authentication tail */
1093 void
NSR_ProcessRx(NTP_Remote_Address * remote_addr,NTP_Local_Address * local_addr,NTP_Local_Timestamp * rx_ts,NTP_Packet * message,int length)1094 NSR_ProcessRx(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr,
1095               NTP_Local_Timestamp *rx_ts, NTP_Packet *message, int length)
1096 {
1097   SourceRecord *record;
1098   struct SourcePool *pool;
1099   int slot;
1100 
1101   assert(initialised);
1102 
1103   /* Avoid unnecessary lookup if the packet cannot be a response from our
1104      source.  Otherwise, it must match both IP address and port number. */
1105   if (NTP_LVM_TO_MODE(message->lvm) != MODE_CLIENT &&
1106       find_slot2(remote_addr, &slot) == 2) {
1107     record = get_record(slot);
1108 
1109     if (!NCR_ProcessRxKnown(record->data, local_addr, rx_ts, message, length))
1110       return;
1111 
1112     if (record->tentative) {
1113       /* This was the first good reply from the source */
1114       record->tentative = 0;
1115 
1116       if (record->pool_id != INVALID_POOL) {
1117         pool = get_pool(record->pool_id);
1118         pool->confirmed_sources++;
1119 
1120         DEBUG_LOG("pool %s has %d confirmed sources", record->name, pool->confirmed_sources);
1121 
1122         /* If the number of sources from the pool reached the configured
1123            maximum, remove the remaining tentative sources */
1124         if (pool->confirmed_sources >= pool->max_sources)
1125           remove_pool_sources(record->pool_id, 1, 0);
1126       }
1127     }
1128   } else {
1129     NCR_ProcessRxUnknown(remote_addr, local_addr, rx_ts, message, length);
1130   }
1131 }
1132 
1133 /* ================================================== */
1134 
1135 void
NSR_ProcessTx(NTP_Remote_Address * remote_addr,NTP_Local_Address * local_addr,NTP_Local_Timestamp * tx_ts,NTP_Packet * message,int length)1136 NSR_ProcessTx(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr,
1137               NTP_Local_Timestamp *tx_ts, NTP_Packet *message, int length)
1138 {
1139   SourceRecord *record;
1140   int slot;
1141 
1142   /* Avoid unnecessary lookup if the packet cannot be a request to our
1143      source.  Otherwise, it must match both IP address and port number. */
1144   if (NTP_LVM_TO_MODE(message->lvm) != MODE_SERVER &&
1145       find_slot2(remote_addr, &slot) == 2) {
1146     record = get_record(slot);
1147     NCR_ProcessTxKnown(record->data, local_addr, tx_ts, message, length);
1148   } else {
1149     NCR_ProcessTxUnknown(remote_addr, local_addr, tx_ts, message, length);
1150   }
1151 }
1152 
1153 /* ================================================== */
1154 
1155 static void
slew_sources(struct timespec * raw,struct timespec * cooked,double dfreq,double doffset,LCL_ChangeType change_type,void * anything)1156 slew_sources(struct timespec *raw,
1157              struct timespec *cooked,
1158              double dfreq,
1159              double doffset,
1160              LCL_ChangeType change_type,
1161              void *anything)
1162 {
1163   SourceRecord *record;
1164   unsigned int i;
1165 
1166   for (i = 0; i < ARR_GetSize(records); i++) {
1167     record = get_record(i);
1168     if (record->remote_addr) {
1169       if (change_type == LCL_ChangeUnknownStep) {
1170         NCR_ResetInstance(record->data);
1171         NCR_ResetPoll(record->data);
1172       } else {
1173         NCR_SlewTimes(record->data, cooked, dfreq, doffset);
1174       }
1175     }
1176   }
1177 }
1178 
1179 /* ================================================== */
1180 
1181 int
NSR_SetConnectivity(IPAddr * mask,IPAddr * address,SRC_Connectivity connectivity)1182 NSR_SetConnectivity(IPAddr *mask, IPAddr *address, SRC_Connectivity connectivity)
1183 {
1184   SourceRecord *record, *syncpeer;
1185   unsigned int i, any;
1186 
1187   if (connectivity != SRC_OFFLINE)
1188     NSR_ResolveSources();
1189 
1190   any = 0;
1191   syncpeer = NULL;
1192   for (i = 0; i < ARR_GetSize(records); i++) {
1193     record = get_record(i);
1194     if (record->remote_addr) {
1195       /* Ignore SRC_MAYBE_ONLINE connectivity change for unspecified unresolved
1196          sources as they would always end up in the offline state */
1197       if ((address->family == IPADDR_UNSPEC &&
1198            (connectivity != SRC_MAYBE_ONLINE || UTI_IsIPReal(&record->remote_addr->ip_addr))) ||
1199           !UTI_CompareIPs(&record->remote_addr->ip_addr, address, mask)) {
1200         any = 1;
1201         if (NCR_IsSyncPeer(record->data)) {
1202           syncpeer = record;
1203           continue;
1204         }
1205         NCR_SetConnectivity(record->data, connectivity);
1206       }
1207     }
1208   }
1209 
1210   /* Set the sync peer last to avoid unnecessary reference switching */
1211   if (syncpeer)
1212     NCR_SetConnectivity(syncpeer->data, connectivity);
1213 
1214   return any;
1215 }
1216 
1217 /* ================================================== */
1218 
1219 int
NSR_ModifyMinpoll(IPAddr * address,int new_minpoll)1220 NSR_ModifyMinpoll(IPAddr *address, int new_minpoll)
1221 {
1222   int slot;
1223 
1224   if (!find_slot(address, &slot))
1225     return 0;
1226 
1227   NCR_ModifyMinpoll(get_record(slot)->data, new_minpoll);
1228   return 1;
1229 }
1230 
1231 /* ================================================== */
1232 
1233 int
NSR_ModifyMaxpoll(IPAddr * address,int new_maxpoll)1234 NSR_ModifyMaxpoll(IPAddr *address, int new_maxpoll)
1235 {
1236   int slot;
1237 
1238   if (!find_slot(address, &slot))
1239     return 0;
1240 
1241   NCR_ModifyMaxpoll(get_record(slot)->data, new_maxpoll);
1242   return 1;
1243 }
1244 
1245 /* ================================================== */
1246 
1247 int
NSR_ModifyMaxdelay(IPAddr * address,double new_max_delay)1248 NSR_ModifyMaxdelay(IPAddr *address, double new_max_delay)
1249 {
1250   int slot;
1251 
1252   if (!find_slot(address, &slot))
1253     return 0;
1254 
1255   NCR_ModifyMaxdelay(get_record(slot)->data, new_max_delay);
1256   return 1;
1257 }
1258 
1259 /* ================================================== */
1260 
1261 int
NSR_ModifyMaxdelayratio(IPAddr * address,double new_max_delay_ratio)1262 NSR_ModifyMaxdelayratio(IPAddr *address, double new_max_delay_ratio)
1263 {
1264   int slot;
1265 
1266   if (!find_slot(address, &slot))
1267     return 0;
1268 
1269   NCR_ModifyMaxdelayratio(get_record(slot)->data, new_max_delay_ratio);
1270   return 1;
1271 }
1272 
1273 /* ================================================== */
1274 
1275 int
NSR_ModifyMaxdelaydevratio(IPAddr * address,double new_max_delay_dev_ratio)1276 NSR_ModifyMaxdelaydevratio(IPAddr *address, double new_max_delay_dev_ratio)
1277 {
1278   int slot;
1279 
1280   if (!find_slot(address, &slot))
1281     return 0;
1282 
1283   NCR_ModifyMaxdelaydevratio(get_record(slot)->data, new_max_delay_dev_ratio);
1284   return 1;
1285 }
1286 
1287 /* ================================================== */
1288 
1289 int
NSR_ModifyMinstratum(IPAddr * address,int new_min_stratum)1290 NSR_ModifyMinstratum(IPAddr *address, int new_min_stratum)
1291 {
1292   int slot;
1293 
1294   if (!find_slot(address, &slot))
1295     return 0;
1296 
1297   NCR_ModifyMinstratum(get_record(slot)->data, new_min_stratum);
1298   return 1;
1299 }
1300 
1301 /* ================================================== */
1302 
1303 int
NSR_ModifyPolltarget(IPAddr * address,int new_poll_target)1304 NSR_ModifyPolltarget(IPAddr *address, int new_poll_target)
1305 {
1306   int slot;
1307 
1308   if (!find_slot(address, &slot))
1309     return 0;
1310 
1311   NCR_ModifyPolltarget(get_record(slot)->data, new_poll_target);
1312   return 1;
1313 }
1314 
1315 /* ================================================== */
1316 
1317 int
NSR_InitiateSampleBurst(int n_good_samples,int n_total_samples,IPAddr * mask,IPAddr * address)1318 NSR_InitiateSampleBurst(int n_good_samples, int n_total_samples,
1319                         IPAddr *mask, IPAddr *address)
1320 {
1321   SourceRecord *record;
1322   unsigned int i;
1323   int any;
1324 
1325   any = 0;
1326   for (i = 0; i < ARR_GetSize(records); i++) {
1327     record = get_record(i);
1328     if (record->remote_addr) {
1329       if (address->family == IPADDR_UNSPEC ||
1330           !UTI_CompareIPs(&record->remote_addr->ip_addr, address, mask)) {
1331         any = 1;
1332         NCR_InitiateSampleBurst(record->data, n_good_samples, n_total_samples);
1333       }
1334     }
1335   }
1336 
1337   return any;
1338 
1339 }
1340 
1341 /* ================================================== */
1342 /* The ip address is assumed to be completed on input, that is how we
1343    identify the source record. */
1344 
1345 void
NSR_ReportSource(RPT_SourceReport * report,struct timespec * now)1346 NSR_ReportSource(RPT_SourceReport *report, struct timespec *now)
1347 {
1348   int slot;
1349 
1350   if (find_slot(&report->ip_addr, &slot)) {
1351     NCR_ReportSource(get_record(slot)->data, report, now);
1352   } else {
1353     report->poll = 0;
1354     report->latest_meas_ago = 0;
1355   }
1356 }
1357 
1358 /* ================================================== */
1359 
1360 int
NSR_GetAuthReport(IPAddr * address,RPT_AuthReport * report)1361 NSR_GetAuthReport(IPAddr *address, RPT_AuthReport *report)
1362 {
1363   int slot;
1364 
1365   if (!find_slot(address, &slot))
1366     return 0;
1367 
1368   NCR_GetAuthReport(get_record(slot)->data, report);
1369   return 1;
1370 }
1371 
1372 /* ================================================== */
1373 /* The ip address is assumed to be completed on input, that is how we
1374    identify the source record. */
1375 
1376 int
NSR_GetNTPReport(RPT_NTPReport * report)1377 NSR_GetNTPReport(RPT_NTPReport *report)
1378 {
1379   int slot;
1380 
1381   if (!find_slot(&report->remote_addr, &slot))
1382     return 0;
1383 
1384   NCR_GetNTPReport(get_record(slot)->data, report);
1385   return 1;
1386 }
1387 
1388 /* ================================================== */
1389 
1390 void
NSR_GetActivityReport(RPT_ActivityReport * report)1391 NSR_GetActivityReport(RPT_ActivityReport *report)
1392 {
1393   SourceRecord *record;
1394   unsigned int i;
1395 
1396   report->online = 0;
1397   report->offline = 0;
1398   report->burst_online = 0;
1399   report->burst_offline = 0;
1400   report->unresolved = 0;
1401 
1402   for (i = 0; i < ARR_GetSize(records); i++) {
1403     record = get_record(i);
1404     if (!record->remote_addr)
1405       continue;
1406 
1407     if (!UTI_IsIPReal(&record->remote_addr->ip_addr)) {
1408       report->unresolved++;
1409     } else {
1410       NCR_IncrementActivityCounters(record->data, &report->online, &report->offline,
1411                                     &report->burst_online, &report->burst_offline);
1412     }
1413   }
1414 }
1415 
1416 /* ================================================== */
1417 
1418 void
NSR_DumpAuthData(void)1419 NSR_DumpAuthData(void)
1420 {
1421   SourceRecord *record;
1422   int i;
1423 
1424   for (i = 0; i < ARR_GetSize(records); i++) {
1425     record = get_record(i);
1426     if (!record->remote_addr)
1427       continue;
1428     NCR_DumpAuthData(record->data);
1429   }
1430 }
1431