In no particular order, they are manual preempt, scored auto-expiry, and start/stop-pump.
Manual preempt basically adds the preempt as a depressible button for external helper scripts. Scored auto expiry adds a score a bit like the one used by the NTP pool, and kicks the worst of the lot off the island 6 times a week and the eldest once. I also, think it needs controls and documentation, but I didn't see how at the time. start/stop pump has a couple of values for the number of pool association children to ask for more when the number drops, and more importantly to stop asking when the population burgeons. I forgot to add a way to adjust it off.
From 07e651a521f26bcad95a927d6cd1fac9ec8bd586 Mon Sep 17 00:00:00 2001 From: James Browning <jamesb.f...@gmail.com> Date: Wed, 9 Jun 2021 16:15:03 -0700 Subject: [PATCH] ntpd: add 'preempt' as under documented server option ... It is intended for external tools that emulate the pool option. --- docs/includes/assoc-options.adoc | 6 ++++++ ntpd/keyword-gen.c | 1 + ntpd/ntp_config.c | 4 ++++ ntpd/ntp_parser.y | 2 ++ 4 files changed, 13 insertions(+) diff --git a/docs/includes/assoc-options.adoc b/docs/includes/assoc-options.adoc index 3028c0b89..aace11a53 100644 --- a/docs/includes/assoc-options.adoc +++ b/docs/includes/assoc-options.adoc @@ -53,6 +53,12 @@ Marks the server as unused, except for display purposes. The server is discarded by the selection algorithm. ++preempt+:: + Marks the server as preemptable. If the server is not performing well, + it can be automatically dissociated. Intended for use by external tools + and not in config files or manual entry via +ntp+. It is automatically + added to servers from the +pool+ option. + +prefer+:: Marks the server as preferred. All other things being equal, this host will be chosen for synchronization among a set of correctly operating diff --git a/ntpd/keyword-gen.c b/ntpd/keyword-gen.c index 1b7de71ae..5482a95f4 100644 --- a/ntpd/keyword-gen.c +++ b/ntpd/keyword-gen.c @@ -87,6 +87,7 @@ struct key_tok ntp_keywords[] = { { "mode", T_Mode, FOLLBY_TOKEN }, { "noselect", T_Noselect, FOLLBY_TOKEN }, { "true", T_True, FOLLBY_TOKEN }, +{ "preempt", T_Preempt, FOLLBY_TOKEN }, { "prefer", T_Prefer, FOLLBY_TOKEN }, { "subtype", T_Subtype, FOLLBY_TOKEN }, { "version", T_Version, FOLLBY_TOKEN }, diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index b5638d7e6..3735e1b16 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -617,6 +617,10 @@ create_peer_node( break; #endif + case T_Preempt: + my_node->ctl.flags |= FLAG_PREEMPT; + break; + case T_Prefer: my_node->ctl.flags |= FLAG_PREFER; break; diff --git a/ntpd/ntp_parser.y b/ntpd/ntp_parser.y index 91a15ce2c..0ab3fe4c5 100644 --- a/ntpd/ntp_parser.y +++ b/ntpd/ntp_parser.y @@ -177,6 +177,7 @@ %token <Integer> T_Pidfile %token <Integer> T_Pool %token <Integer> T_Ppspath +%token <Integer> T_Preempt %token <Integer> T_Prefer %token <Integer> T_Protostats %token <Integer> T_Rawstats @@ -421,6 +422,7 @@ option_flag_keyword | T_Noselect | T_Noval | T_Nts + | T_Preempt | T_Prefer | T_True ; -- 2.25.1
From 63c0cd2258ae692e95e81ea5b72ee2a2fbf3de24 Mon Sep 17 00:00:00 2001 From: James Browning <jamesb.f...@gmail.com> Date: Mon, 14 Jun 2021 07:33:18 -0700 Subject: [PATCH] ntpd: Purge worst ephemeral peer daily and the oldest weekly ... Also add an undocumented variable for 'ntpq -c "rv ${peer}" to show number used to make the worst determination. --- include/ntp.h | 1 + include/ntpd.h | 2 ++ ntpd/ntp_control.c | 4 ++++ ntpd/ntp_proto.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ ntpd/ntp_timer.c | 2 ++ 5 files changed, 53 insertions(+) diff --git a/include/ntp.h b/include/ntp.h index 729e482ee..bedcd9043 100644 --- a/include/ntp.h +++ b/include/ntp.h @@ -244,6 +244,7 @@ struct peer_ctl { * It used to be called ttl which was used by multicast which we dropped. */ struct peer { + double goodness; /* how worthy the server is to survive the day */ struct peer *p_link; /* link pointer in free & peer lists */ struct peer *adr_link; /* link pointer in address hash */ struct peer *aid_link; /* link pointer in associd hash */ diff --git a/include/ntpd.h b/include/ntpd.h index a15ac00ff..89b4ac268 100644 --- a/include/ntpd.h +++ b/include/ntpd.h @@ -196,6 +196,8 @@ extern void set_sys_tick_precision(double); extern void proto_config (int, unsigned long, double); extern void proto_clr_stats (void); +extern void purge_day (bool); + /* ntp_restrict.c */ extern void init_restrict (void); extern unsigned short restrictions (sockaddr_u *); diff --git a/ntpd/ntp_control.c b/ntpd/ntp_control.c index 4b66ecd71..108811191 100644 --- a/ntpd/ntp_control.c +++ b/ntpd/ntp_control.c @@ -522,6 +522,8 @@ static const struct ctl_var peer_var[] = { /* new in NTPsec */ #define CP_NTSCOOKIES 49 { CP_NTSCOOKIES, RO|DEF, "ntscookies" }, +#define CP_GOODNESS 50 + { CP_GOODNESS, RO|DEF, "goodness" }, #define CP_MAXCODE ((sizeof(peer_var)/sizeof(peer_var[0])) - 1) { 0, EOV, "" } }; @@ -2054,6 +2056,8 @@ ctl_putpeer( CASE_INT(CP_NTSCOOKIES, p->nts_state.count); + CASE_DBL6(CP_GOODNESS, p->goodness); + default: break; } diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index 895567c83..3733303b6 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -625,6 +625,21 @@ handle_procpkt( } peer->reach |= 1; + // Nudge the peer survivability score -- badly ripped from + // lines 140-158,165 of the pools Control/Monitor.pm / + // credit is for ABH, blame for JamesB192 + if ((peer->stratum == 0)||(peer->stratum > 15)) { + // already dropped the 5 which factors below as well + } else if ((peer->stratum >= 8)||(delta > 3)) { + peer->goodness += 1; + } else if (delta > 0.75) { + peer->goodness += 3; + } else if (delta > 0.075) { + peer->goodness += 6 - (4 * theta); + } else { + peer->goodness += 6; + }; + /* Hooray! Pass our new sample off to the clock filter. */ clock_filter(peer, theta + peer->cfg.bias, delta, epsilon); } @@ -856,6 +871,8 @@ transmit( peer->outdate = current_time; peer->unreach++; peer->reach <<= 1; + peer->goodness *= 0.95; + peer->goodness -= 5; if (!peer->reach) { /* @@ -2951,3 +2968,30 @@ void maybe_log_junk(const char *tag, struct recvbuf *rbufp) { "%s: %s", tag, buf); } +void purge_day(bool eldest) { + double worstscore = 20; +// uint6_t ties = 0; + struct peer *loop, *purgable = NULL; + if (eldest) { + for (loop = peer_list; loop->p_link != NULL; loop = loop->p_link) { + if (loop->cfg.flags & FLAG_PREEMPT) { + unpeer(loop); + return; + } + } + return; + } + for (loop = peer_list; loop->p_link != NULL; loop = loop->p_link) { + if ((loop->cfg.flags & FLAG_PREEMPT)&&(loop->goodness < worstscore)) { + worstscore = loop->goodness; + purgable = loop; +// ties = 1; +// } else if (loop->goodness == worstscore) { +// ties++; + } + } + if (purgable != NULL) { + unpeer(purgable); + purgable = NULL; + } +} diff --git a/ntpd/ntp_timer.c b/ntpd/ntp_timer.c index 3dd44e859..cf4e8d53f 100644 --- a/ntpd/ntp_timer.c +++ b/ntpd/ntp_timer.c @@ -288,6 +288,8 @@ timer(void) if (leapf_timer <= current_time) { leapf_timer += SECSPERDAY; check_leap_file(true, now); + bool eldest = (6 == (current_time / SECSPERDAY) % 7); + purge_day(eldest); } else { check_leap_file(false, now); } -- 2.25.1
From 82f367b4db2d3780314b3a2bad577c73279a247e Mon Sep 17 00:00:00 2001 From: James Browning <jamesb.f...@gmail.com> Date: Wed, 16 Jun 2021 08:17:35 -0700 Subject: [PATCH] ntpd: Add startpump and stoppump options intended for pool use ... If children of a pool association have been disassociated decrement count and remove them from the array. If the number of children above is greater than or equal to stoppump (default 5 constrained 1..12) stop making requests, otherwise if the number of children above is less than or equal to startpump (default 3 constrained 0..11) start making requests. Start not making requests, and document nothing. --- docs/includes/assoc-options.adoc | 10 +++++++++ include/ntp.h | 4 ++++ ntpd/keyword-gen.c | 2 ++ ntpd/ntp_config.c | 26 ++++++++++++++++++++++ ntpd/ntp_dns.c | 38 ++++++++++++++++++++++++++++++-- ntpd/ntp_parser.y | 4 ++++ 6 files changed, 82 insertions(+), 2 deletions(-) diff --git a/docs/includes/assoc-options.adoc b/docs/includes/assoc-options.adoc index 3028c0b89..49d0e9a7a 100644 --- a/docs/includes/assoc-options.adoc +++ b/docs/includes/assoc-options.adoc @@ -59,6 +59,16 @@ hosts. See the "Mitigation Rules and the prefer Keyword" page for further information. ++starpump+ 'on_at':: ++stoppump+ 'off_at':: + When the number of associated children for a pool directive drops below + _on_at_, begin associating new pools of ntp servers until the number rises + to _off_at_. When the number of associated children from the same pool + association is above _off_at_, stop asking for new server pools until their + number goes down to _on_at_. _on_at_ can be set between 0 and 11 inclusive, + defaulting to 3, and must be below _off_at_, while _off_at_ may be between 1 + and 12 incluse, defaulting to 5, and must be greater than _on_at_. + +true+:: Mark the association to assume truechimer status; that is, always survive the selection and clustering algorithms. This option can be diff --git a/include/ntp.h b/include/ntp.h index 729e482ee..ecca2e087 100644 --- a/include/ntp.h +++ b/include/ntp.h @@ -188,6 +188,8 @@ struct peer_ctl { double bias; struct ntscfg_t nts_cfg; uint32_t mode; /* only used by refclocks */ + uint32_t startpump; /* only used by pool */ + uint32_t stoppump; /* only used by pool */ #ifdef REFCLOCK uint32_t baud; char *path; @@ -260,6 +262,8 @@ struct peer { uint8_t num_events; /* number of error events */ struct ntsclient_t nts_state; /* per-peer NTS state */ + uint16_t *children; /* count and addocids of pool children */ + /* * Variables used by reference clock support */ diff --git a/ntpd/keyword-gen.c b/ntpd/keyword-gen.c index 1b7de71ae..d1b3e1286 100644 --- a/ntpd/keyword-gen.c +++ b/ntpd/keyword-gen.c @@ -88,6 +88,8 @@ struct key_tok ntp_keywords[] = { { "noselect", T_Noselect, FOLLBY_TOKEN }, { "true", T_True, FOLLBY_TOKEN }, { "prefer", T_Prefer, FOLLBY_TOKEN }, +{ "startpump", T_Startpump, FOLLBY_TOKEN }, +{ "stoppump", T_Stoppump, FOLLBY_TOKEN }, { "subtype", T_Subtype, FOLLBY_TOKEN }, { "version", T_Version, FOLLBY_TOKEN }, /*** MONITORING COMMANDS ***/ diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index b5638d7e6..9e00bd014 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -565,6 +565,8 @@ create_peer_node( my_node->ctl.version = NTP_VERSION; my_node->ctl.minpoll = NTP_MINDPOLL; + my_node->ctl.startpump = 3; + my_node->ctl.stoppump = 5; /* can not set maxpoll default yet, it may be NTP_MAXDPOLL or minpoll */ my_node->ctl.maxpoll = NTP_MAXPOLL_UNK; my_node->ctl.bias = 0; @@ -678,6 +680,30 @@ create_peer_node( my_node->ctl.mode = option->value.u; break; + case T_Startpump: + if ((option->value.u >= 12)) { + msyslog(LOG_ERR, "CONFIG: startpump: not in range 0..11"); + errflag = true; + } else if (option->value.u <= my_node->ctl.stoppump) { + msyslog(LOG_ERR, "CONFIG: startpump: not less than stoppump value."); + errflag = true; + } else { + my_node->ctl.startpump = option->value.u; + } + break; + + case T_Stoppump: + if ((option->value.u = 0)||(option->value.u > 12)) { + msyslog(LOG_ERR, "CONFIG: stoppump: not in range 1..12"); + errflag = true; + } else if (option->value.u >= my_node->ctl.stoppump) { + msyslog(LOG_ERR, "CONFIG: stoppump: not greater than startpump value."); + errflag = true; + } else { + my_node->ctl.stoppump = option->value.u; + } + break; + case T_Key: if (option->value.u >= NTP_MAXKEY) { msyslog(LOG_ERR, "CONFIG: key: invalid argument"); diff --git a/ntpd/ntp_dns.c b/ntpd/ntp_dns.c index e87e20b99..993ee7fa0 100644 --- a/ntpd/ntp_dns.c +++ b/ntpd/ntp_dns.c @@ -66,6 +66,39 @@ bool dns_probe(struct peer* pp) hostname = socktoa(&pp->srcadr); } + if (pp->cast_flags & MDF_POOL) { + if (NULL == pp->children) { + pp->children = calloc(sizeof(uint16_t), NTP_HASH_SIZE); + if (NULL == pp->children) { + _Exit(1); + } + } + uint16_t *kids = pp->children; + uint16_t old = kids[0] & ~(1 << 15), new, iterator; + bool pull = (kids[0] & (1 << 15)); + new = iterator = 1; + while(iterator < old) { + if (findpeerbyassoc(kids[iterator])) { + new++; + } + kids[iterator] = kids[new]; + iterator++; + } + for (iterator = new + 1; iterator <= old; iterator++) { + kids[iterator] = 0; + } + if (pull && (new >= pp->cfg.stoppump)) { + kids[0] = new & ~(1 << 15); + pull = false; + } else if (!pull && (new <= pp->cfg.startpump)) { + kids[0] = (1 << 15) | new; + pull = true; + } + if (!pull) { + return true; + } + } + msyslog(LOG_INFO, "DNS: dns_probe: %s, cast_flags:%x, flags:%x%s", hostname, pp->cast_flags, pp->cfg.flags, busy); if (NULL != active) /* normally redundant */ @@ -128,10 +161,11 @@ void dns_check(void) /* Both dns_take_pool and dns_take_server log something. */ // msyslog(LOG_INFO, "DNS: Take %s=>%s", // socktoa(ai->ai_addr), socktoa(&sockaddr)); - if (active->cast_flags & MDF_POOL) + if (active->cast_flags & MDF_POOL) { dns_take_pool(active, &sockaddr); - else + } else { dns_take_server(active, &sockaddr); + } } switch (gai_rc) { diff --git a/ntpd/ntp_parser.y b/ntpd/ntp_parser.y index 91a15ce2c..b1f159f13 100644 --- a/ntpd/ntp_parser.y +++ b/ntpd/ntp_parser.y @@ -192,6 +192,7 @@ %token <Integer> T_Setvar %token <Integer> T_Source %token <Integer> T_Stacksize +%token <Integer> T_Startpump %token <Integer> T_Statistics %token <Integer> T_Stats %token <Integer> T_Statsdir @@ -199,6 +200,7 @@ %token <Integer> T_Stepback %token <Integer> T_Stepfwd %token <Integer> T_Stepout +%token <Integer> T_Stoppump %token <Integer> T_Stratum %token <Integer> T_Subtype %token <String> T_String /* Not a token */ @@ -451,6 +453,8 @@ option_int_keyword | T_Version | T_Baud | T_Holdover + | T_Startpump + | T_Stoppump ; option_double -- 2.25.1
_______________________________________________ devel mailing list devel@ntpsec.org https://lists.ntpsec.org/mailman/listinfo/devel