[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    [PATCH 4/5] ntpd: keep increasing polling interval
From:       Miroslav Lichvar <mlichvar () redhat ! com>
Date:       2014-09-18 14:19:06
Message-ID: 1411049947-6871-5-git-send-email-mlichvar () redhat ! com
[Download RAW message or body]

Unless a shorter polling interval is needed to keep the clock well
synchronized, an NTP client should be normally always increasing the
polling interval up to the maximum to avoid overloading the network or
the server.

Keep increasing the polling interval in the following situations:
- no replies are received from a peer
- no source can be selected
- peer claims to be unsynchronized (e.g. we are polling it too
  frequently)
- recv() returns with an error (e.g. the host doesn't exist or is not
  running an NTP service)

Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
---
 networking/ntpd.c | 50 +++++++++++++++++++++++++++++---------------------
 1 file changed, 29 insertions(+), 21 deletions(-)

diff --git a/networking/ntpd.c b/networking/ntpd.c
index f182213..569e0b9 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -1652,17 +1652,6 @@ update_local_clock(peer_t *p)
  * (helpers first)
  */
 static unsigned
-retry_interval(void)
-{
-	/* Local problem, want to retry soon */
-	unsigned interval, r;
-	interval = RETRY_INTERVAL;
-	r = rand();
-	interval += r % (unsigned)(RETRY_INTERVAL / 4);
-	VERB4 bb_error_msg("chose retry interval:%u", interval);
-	return interval;
-}
-static unsigned
 poll_interval(int exponent)
 {
 	unsigned interval, r, mask;
@@ -1724,6 +1713,7 @@ recv_and_process_peer_pkt(peer_t *p)
 	datapoint_t *datapoint;
 	peer_t      *q;
 
+	rc = 0;
 	offset = 0;
 
 	/* We can recvfrom here and check from.IP, but some multihomed
@@ -1738,9 +1728,8 @@ recv_and_process_peer_pkt(peer_t *p)
 		 || errno == ECONNREFUSED || errno == EADDRNOTAVAIL
 		 || errno == EAGAIN
 		) {
-//TODO: always do this?
-			interval = retry_interval();
-			goto set_next_and_ret;
+			rc = 1;
+			goto pick_normal_interval;
 		}
 		xfunc_die();
 	}
@@ -1772,6 +1761,7 @@ recv_and_process_peer_pkt(peer_t *p)
 // "DENY", "RSTR" - peer does not like us at all
 // "RATE" - peer is overloaded, reduce polling freq
 		bb_error_msg("reply from %s: peer is unsynced", p->p_dotted);
+		rc = 1;
 		goto pick_normal_interval;
 	}
 
@@ -1860,9 +1850,8 @@ recv_and_process_peer_pkt(peer_t *p)
 	/* Muck with statictics and update the clock */
 	filter_datapoints(p);
 	q = select_and_cluster();
-	rc = -1;
+	rc = 1;
 	if (q) {
-		rc = 0;
 		if (!(option_mask32 & OPT_w)) {
 			rc = update_local_clock(q);
 			/* If drift is dangerously large, immediately
@@ -1874,10 +1863,15 @@ recv_and_process_peer_pkt(peer_t *p)
 				rc = 0;
 			}
 		}
+	} else {
+		/* Keep increasing the polling interval when no source can be
+		 * selected, but wait until the initial burst is complete.
+		 */
+		if (!G.initial_poll_complete)
+			rc = 0;
 	}
-	/* else: no peer selected, rc = -1: we want to poll more often */
 
-	if (rc != 0) {
+	if (q && rc != 0) {
 		/* Adjust the poll interval by comparing the current offset
 		 * with the clock jitter. If the offset is less than
 		 * the clock jitter times a constant, then the averaging interval
@@ -1891,10 +1885,18 @@ recv_and_process_peer_pkt(peer_t *p)
 		} else {
 			adjust_poll(-G.poll_exp * 2);
 		}
+		rc = 0;
 	}
 
-	/* Decide when to send new query for this peer */
+	/* Decide when to send new query for this peer. Unless a shorter
+	 * polling interval is needed to keep the clock well synchronized, an
+	 * NTP client should be normally always increasing the polling interval
+	 * up to the maximum to avoid overloading the network or the server.
+	 */
  pick_normal_interval:
+	if (rc > 0)
+		adjust_poll(POLLADJ_LIMIT / 8);
+
 	interval = poll_interval(0);
 	if (fabs(offset) >= STEP_THRESHOLD * 8 && interval > BIGOFF_INTERVAL) {
 		/* If we are synced, offsets are less than STEP_THRESHOLD,
@@ -1911,7 +1913,6 @@ recv_and_process_peer_pkt(peer_t *p)
 		interval = BIGOFF_INTERVAL;
 	}
 
- set_next_and_ret:
 	set_next(p, interval);
 }
 
@@ -2246,7 +2247,14 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
 					/* Timed out waiting for reply */
 					close(p->p_fd);
 					p->p_fd = -1;
-					timeout = poll_interval(-2); /* -2: try a bit sooner */
+
+					/* Slowly increase the polling interval in case the network
+					 * or the peer is overloaded and the requests or replies
+					 * are getting dropped.
+					 */
+					adjust_poll(POLLADJ_LIMIT / 8);
+
+					timeout = poll_interval(0);
 					bb_error_msg("timed out waiting for %s, reach 0x%02x, next query in %us",
 							p->p_dotted, p->reachable_bits, timeout);
 					set_next(p, timeout);
-- 
1.9.3

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic