]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
ntp: randomize replacement interval
authorMiroslav Lichvar <mlichvar@redhat.com>
Tue, 6 Jun 2023 10:02:53 +0000 (12:02 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 8 Jun 2023 14:14:48 +0000 (16:14 +0200)
Replacement attempts are globally rate limited to one per 7*2^8 seconds
to limit the rate of DNS requests for public servers like pool.ntp.org.
If multiple sources are repeatedly attempting replacement (at their
polling intervals), one source can be getting all attempts for periods
of time.

Use a randomly generated interval to randomize the order of source
replacements without changing the average rate.

ntp_sources.c
test/simulation/139-nts

index 2f20299eab517447b1a702dec1ef37cab7c69093..152c41829d64812640fee31d32cd8169fdd5e0b4 100644 (file)
@@ -106,7 +106,7 @@ struct UnresolvedSource {
 #define RESOLVE_INTERVAL_UNIT 7
 #define MIN_RESOLVE_INTERVAL 2
 #define MAX_RESOLVE_INTERVAL 9
-#define MIN_REPLACEMENT_INTERVAL 8
+#define MAX_REPLACEMENT_INTERVAL 9
 
 static struct UnresolvedSource *unresolved_sources = NULL;
 static int resolving_interval = 0;
@@ -1006,9 +1006,10 @@ resolve_source_replacement(SourceRecord *record, int refreshment)
 void
 NSR_HandleBadSource(IPAddr *address)
 {
-  static double last_replacement = -1e6;
+  static double next_replacement = 0.0;
   SourceRecord *record;
   IPAddr ip_addr;
+  uint32_t rnd;
   double now;
   int slot;
 
@@ -1025,12 +1026,14 @@ NSR_HandleBadSource(IPAddr *address)
 
   /* Don't resolve names too frequently */
   now = SCH_GetLastEventMonoTime();
-  if (now - last_replacement <
-      RESOLVE_INTERVAL_UNIT * (1 << MIN_REPLACEMENT_INTERVAL)) {
+  if (now < next_replacement) {
     DEBUG_LOG("replacement postponed");
     return;
   }
-  last_replacement = now;
+
+  UTI_GetRandomBytes(&rnd, sizeof (rnd));
+  next_replacement = now + ((double)rnd / (uint32_t)-1) *
+                     (RESOLVE_INTERVAL_UNIT * (1 << MAX_REPLACEMENT_INTERVAL));
 
   resolve_source_replacement(record, 0);
 }
index 6a2112d9204dab860857c03cb20c677bfe2b7a70..0cfb874cf2a9fa2e7059cca2d07e951419830bf9 100755 (executable)
@@ -160,8 +160,8 @@ for dns in 1 0; do
 
        check_file_messages "   2       1       .*      4460    " 50 100 log.packets || test_fail
        check_file_messages "   2       2       .*      4460    " 0 0 log.packets || test_fail
-       check_log_messages "Source 192.168.123.1 changed to 192.168.123.2" 6 8 || test_fail
-       check_log_messages "Source 192.168.123.2 replaced with 192.168.123.1" 6 8 || test_fail
+       check_log_messages "Source 192.168.123.1 changed to 192.168.123.2" 4 10 || test_fail
+       check_log_messages "Source 192.168.123.2 replaced with 192.168.123.1" 4 10 || test_fail
 
        servers=2