diff --git a/candm.h b/candm.h index 49c68f4..1c7cccf 100644 --- a/candm.h +++ b/candm.h @@ -86,7 +86,8 @@ #define REQ_MANUAL_DELETE 42 #define REQ_MAKESTEP 43 #define REQ_ACTIVITY 44 -#define N_REQUEST_TYPES 45 +#define REQ_MODIFY_MINSTRATUM 45 +#define N_REQUEST_TYPES 46 /* Special utoken value used to log on with first exchange being the password. (This time value has long since gone by) */ @@ -162,6 +163,12 @@ typedef struct { int32_t EOR; } REQ_Modify_Maxdelayratio; +typedef struct { + IPAddr address; + int32_t new_min_stratum; + int32_t EOR; +} REQ_Modify_Minstratum; + typedef struct { Float new_max_update_skew; int32_t EOR; @@ -370,6 +377,7 @@ typedef struct { REQ_Dump dump; REQ_Modify_Maxdelay modify_maxdelay; REQ_Modify_Maxdelayratio modify_maxdelayratio; + REQ_Modify_Minstratum modify_minstratum; REQ_Modify_Maxupdateskew modify_maxupdateskew; REQ_Logon logon; REQ_Settime settime; diff --git a/chrony.texi b/chrony.texi index 9996bb9..b4681ae 100644 --- a/chrony.texi +++ b/chrony.texi @@ -2821,6 +2821,7 @@ interface. * maxpoll command:: Set maximum polling interval for a source * maxupdateskew command:: Set safety threshold for clock gain/loss rate * minpoll command:: Set minimum polling interval for a source +* minstratum command:: Set minimum stratum for a source * offline command:: Warn that connectivity to a source will be lost * online command:: Warn that connectivity to a source has been restored * password command:: Provide password needed for most commands @@ -3446,6 +3447,35 @@ to 32 seconds. Note that the new minimum polling interval only takes effect after the next measurement has been made. @c }}} +@c {{{ minstratum +@node minstratum command +@subsubsection minstratum +The @code{minstratum} command is used to modify the minimum stratum +for one of the current set of sources. It is equivalent to the +@code{minstratum} option in the @code{server} directive in the +configuration file (@pxref{server directive}). + +The syntax is as follows + +@example +minstratum +@end example + +where the host can be specified as either a machine name or +IP address. + +An example is + +@example +minpoll foo.bar.com 5 +@end example + +which sets the minimum stratum for the host @code{foo.bar.com} +to 5. + +Note that the new minimum stratum only takes effect after the +next measurement has been made. +@c }}} @c {{{ offline @node offline command @subsubsection offline diff --git a/client.c b/client.c index fcc627b..cfe518d 100644 --- a/client.c +++ b/client.c @@ -458,6 +458,28 @@ process_cmd_maxdelayratio(CMD_Request *msg, char *line) /* ================================================== */ +static int +process_cmd_minstratum(CMD_Request *msg, char *line) +{ + IPAddr address; + int min_stratum; + int ok; + + if (read_address_integer(line, &address, &min_stratum)) { + UTI_IPHostToNetwork(&address, &msg->data.modify_minstratum.address); + msg->data.modify_minstratum.new_min_stratum = htonl(min_stratum); + msg->command = htons(REQ_MODIFY_MINSTRATUM); + ok = 1; + } else { + ok = 0; + } + + return ok; + +} + +/* ================================================== */ + static int process_cmd_maxupdateskew(CMD_Request *msg, char *line) { @@ -1138,9 +1160,10 @@ give_help(void) printf("manual list : Show previous settime entries\n"); printf("maxdelay
: Modify maximum round-trip valid sample delay for source\n"); printf("maxdelayratio
: Modify max round-trip delay ratio for source\n"); - printf("maxpoll
: Modify maximum polling interval of source\n"); + printf("maxpoll
: Modify maximum polling interval of source\n"); printf("maxupdateskew : Modify maximum skew for a clock frequency update to be made\n"); printf("minpoll
: Modify minimum polling interval of source\n"); + printf("minstratum
: Modify minimum stratum of source\n"); printf("offline [/] : Set sources in subnet to offline status\n"); printf("online [/] : Set sources in subnet to online status\n"); printf("password [] : Set command authentication password\n"); @@ -2349,6 +2372,8 @@ process_line(char *line, int *quit) do_normal_submit = process_cmd_maxdelay(&tx_message, p+8); } else if (!strncmp(p, "maxupdateskew", 13)) { do_normal_submit = process_cmd_maxupdateskew(&tx_message, p+13); + } else if (!strncmp(p, "minstratum", 10)) { + do_normal_submit = process_cmd_minstratum(&tx_message, p+10); } else if (!strncmp(p, "settime", 7)) { do_normal_submit = 0; ret = process_cmd_settime(p+7); diff --git a/cmdmon.c b/cmdmon.c index c39317e..e382e10 100644 --- a/cmdmon.c +++ b/cmdmon.c @@ -158,7 +158,8 @@ static int permissions[] = { PERMIT_OPEN, /* MANUAL_LIST */ PERMIT_AUTH, /* MANUAL_DELETE */ PERMIT_AUTH, /* MAKESTEP */ - PERMIT_OPEN /* ACTIVITY */ + PERMIT_OPEN, /* ACTIVITY */ + PERMIT_AUTH /* MODIFY_MINSTRATUM */ }; /* ================================================== */ @@ -902,6 +903,24 @@ handle_modify_maxdelayratio(CMD_Request *rx_message, CMD_Reply *tx_message) /* ================================================== */ +static void +handle_modify_minstratum(CMD_Request *rx_message, CMD_Reply *tx_message) +{ + int status; + IPAddr address; + UTI_IPNetworkToHost(&rx_message->data.modify_minpoll.address, &address); + status = NSR_ModifyMinstratum(&address, + ntohl(rx_message->data.modify_minstratum.new_min_stratum)); + + if (status) { + tx_message->status = htons(STT_SUCCESS); + } else { + tx_message->status = htons(STT_NOSUCHSOURCE); + } +} + +/* ================================================== */ + static void handle_modify_maxupdateskew(CMD_Request *rx_message, CMD_Reply *tx_message) { @@ -2211,6 +2230,10 @@ read_from_cmd_socket(void *anything) handle_activity(&rx_message, &tx_message); break; + case REQ_MODIFY_MINSTRATUM: + handle_modify_minstratum(&rx_message, &tx_message); + break; + default: /* Ignore message */ break; diff --git a/ntp_core.c b/ntp_core.c index e06ea41..c00c462 100644 --- a/ntp_core.c +++ b/ntp_core.c @@ -1749,6 +1749,16 @@ NCR_ModifyMaxdelayratio(NCR_Instance inst, double new_max_delay_ratio) /* ================================================== */ +void +NCR_ModifyMinstratum(NCR_Instance inst, int new_min_stratum) +{ + inst->min_stratum = new_min_stratum; + LOG(LOGS_INFO, LOGF_NtpCore, "Source %s new minstratum %d", + UTI_IPToString(&inst->remote_addr.ip_addr), new_min_stratum); +} + +/* ================================================== */ + void NCR_InitiateSampleBurst(NCR_Instance inst, int n_good_samples, int n_total_samples) { diff --git a/ntp_core.h b/ntp_core.h index 5bddc52..46e70bb 100644 --- a/ntp_core.h +++ b/ntp_core.h @@ -91,6 +91,8 @@ extern void NCR_ModifyMaxdelay(NCR_Instance inst, double new_max_delay); extern void NCR_ModifyMaxdelayratio(NCR_Instance inst, double new_max_delay_ratio); +extern void NCR_ModifyMinstratum(NCR_Instance inst, int new_min_stratum); + extern void NCR_InitiateSampleBurst(NCR_Instance inst, int n_good_samples, int n_total_samples); extern void NCR_ReportSource(NCR_Instance inst, RPT_SourceReport *report, struct timeval *now); diff --git a/ntp_sources.c b/ntp_sources.c index 3750ef2..4a75b07 100644 --- a/ntp_sources.c +++ b/ntp_sources.c @@ -555,6 +555,25 @@ NSR_ModifyMaxdelayratio(IPAddr *address, double new_max_delay_ratio) /* ================================================== */ +int +NSR_ModifyMinstratum(IPAddr *address, int new_min_stratum) +{ + int slot, found; + NTP_Remote_Address addr; + addr.ip_addr = *address; + addr.port = 0; + + find_slot(&addr, &slot, &found); + if (found == 0) { + return 0; + } else { + NCR_ModifyMinstratum(records[slot].data, new_min_stratum); + return 1; + } +} + +/* ================================================== */ + int NSR_InitiateSampleBurst(int n_good_samples, int n_total_samples, IPAddr *mask, IPAddr *address) diff --git a/ntp_sources.h b/ntp_sources.h index d69ee0d..716e387 100644 --- a/ntp_sources.h +++ b/ntp_sources.h @@ -91,6 +91,8 @@ extern int NSR_ModifyMaxdelay(IPAddr *address, double new_max_delay); extern int NSR_ModifyMaxdelayratio(IPAddr *address, double new_max_delay_ratio); +extern int NSR_ModifyMinstratum(IPAddr *address, int new_min_stratum); + extern int NSR_InitiateSampleBurst(int n_good_samples, int n_total_samples, IPAddr *mask, IPAddr *address); extern void NSR_ReportSource(RPT_SourceReport *report, struct timeval *now); diff --git a/pktlength.c b/pktlength.c index 70e16eb..1fdbeaf 100644 --- a/pktlength.c +++ b/pktlength.c @@ -147,6 +147,8 @@ PKL_CommandLength(CMD_Request *r) return offsetof(CMD_Request, data.make_step.EOR); case REQ_ACTIVITY: return offsetof(CMD_Request, data.activity.EOR); + case REQ_MODIFY_MINSTRATUM: + return offsetof(CMD_Request, data.modify_minstratum.EOR); default: /* If we fall through the switch, it most likely means we've forgotten to implement a new case */ assert(0);