diff --git a/candm.h b/candm.h index 353cc77..05daaeb 100644 --- a/candm.h +++ b/candm.h @@ -93,7 +93,8 @@ #define REQ_REFRESH 53 #define REQ_SERVER_STATS 54 #define REQ_CLIENT_ACCESSES_BY_INDEX2 55 -#define N_REQUEST_TYPES 56 +#define REQ_LOCAL2 56 +#define N_REQUEST_TYPES 57 /* Structure used to exchange timevals independent on size of time_t */ typedef struct { @@ -211,6 +212,8 @@ typedef struct { typedef struct { int32_t on_off; int32_t stratum; + Float distance; + int32_t orphan; int32_t EOR; } REQ_Local; diff --git a/client.c b/client.c index e560344..bd8c153 100644 --- a/client.c +++ b/client.c @@ -717,25 +717,26 @@ process_cmd_burst(CMD_Request *msg, char *line) /* ================================================== */ static int -process_cmd_local(CMD_Request *msg, const char *line) +process_cmd_local(CMD_Request *msg, char *line) { - const char *p; - int stratum; + int on_off, stratum, orphan; + double distance; - p = line; - - if (!strcmp(p, "off")) { - msg->data.local.on_off = htonl(0); - msg->data.local.stratum = htonl(0); - } else if (sscanf(p, "stratum%d", &stratum) == 1) { - msg->data.local.on_off = htonl(1); - msg->data.local.stratum = htonl(stratum); + if (!strcmp(line, "off")) { + on_off = 0; + } else if (CPS_ParseLocal(line, &stratum, &orphan, &distance)) { + on_off = 1; } else { LOG(LOGS_ERR, LOGF_Client, "Invalid syntax for local command"); return 0; } - msg->command = htons(REQ_LOCAL); + msg->command = htons(REQ_LOCAL2); + msg->data.local.on_off = htonl(on_off); + msg->data.local.stratum = htonl(stratum); + msg->data.local.distance = UTI_FloatHostToNetwork(distance); + msg->data.local.orphan = htonl(orphan); + return 1; } @@ -1233,7 +1234,7 @@ give_help(void) "allow all []\0Allow access to subnet and all children\0" "deny []\0Deny access to subnet as a default\0" "deny all []\0Deny access to subnet and all children\0" - "local stratum \0Serve time at stratum when not synchronised\0" + "local [options]\0Serve time even when not synchronised\0" "local off\0Don't serve time when not synchronised\0" "smoothtime reset|activate\0Reset/activate time smoothing\0" "smoothing\0Display current time smoothing state\0" diff --git a/cmdmon.c b/cmdmon.c index aafa292..26622d2 100644 --- a/cmdmon.c +++ b/cmdmon.c @@ -132,6 +132,7 @@ static const char permissions[] = { PERMIT_AUTH, /* REFRESH */ PERMIT_AUTH, /* SERVER_STATS */ PERMIT_AUTH, /* CLIENT_ACCESSES_BY_INDEX2 */ + PERMIT_AUTH, /* LOCAL2 */ }; /* ================================================== */ @@ -584,11 +585,10 @@ handle_settime(CMD_Request *rx_message, CMD_Reply *tx_message) static void handle_local(CMD_Request *rx_message, CMD_Reply *tx_message) { - int on_off, stratum; - on_off = ntohl(rx_message->data.local.on_off); - if (on_off) { - stratum = ntohl(rx_message->data.local.stratum); - REF_EnableLocal(stratum); + if (ntohl(rx_message->data.local.on_off)) { + REF_EnableLocal(ntohl(rx_message->data.local.stratum), + UTI_FloatNetworkToHost(rx_message->data.local.distance), + ntohl(rx_message->data.local.orphan)); } else { REF_DisableLocal(); } @@ -1417,7 +1417,7 @@ read_from_cmd_socket(void *anything) handle_settime(&rx_message, &tx_message); break; - case REQ_LOCAL: + case REQ_LOCAL2: handle_local(&rx_message, &tx_message); break; diff --git a/doc/chronyc.adoc b/doc/chronyc.adoc index ccf3098..2dd35d5 100644 --- a/doc/chronyc.adoc +++ b/doc/chronyc.adoc @@ -845,17 +845,16 @@ deny all ---- [[local]] -*local* *stratum* _stratum_:: +*local* [_option_]...:: *local* *off*:: The *local* command allows *chronyd* to be told that it is to appear as a reference source, even if it is not itself properly synchronised to an external source. (This can be used on isolated networks, to allow one computer to be a -master time server with the other computers slaving to it.) The *local* -command is somewhat equivalent to the <> -directive in the configuration file. +master time server with the other computers slaving to it.) + -The first form enables the local reference mode on the host, and sets the -stratum at which it should claim to be synchronised. +The first form enables the local reference mode on the host. The syntax is +identical to the <> directive in the +configuration file. + The second form disables the local reference mode. diff --git a/pktlength.c b/pktlength.c index 0774565..7366e51 100644 --- a/pktlength.c +++ b/pktlength.c @@ -67,7 +67,7 @@ static const struct request_length request_lengths[] = { REQ_LENGTH_ENTRY(modify_maxupdateskew, null), /* MODIFY_MAXUPDATESKEW */ REQ_LENGTH_ENTRY(logon, null), /* LOGON */ REQ_LENGTH_ENTRY(settime, manual_timestamp), /* SETTIME */ - REQ_LENGTH_ENTRY(local, null), /* LOCAL */ + { 0, 0 }, /* LOCAL */ REQ_LENGTH_ENTRY(manual, null), /* MANUAL */ REQ_LENGTH_ENTRY(null, n_sources), /* N_SOURCES */ REQ_LENGTH_ENTRY(source_data, source_data), /* SOURCE_DATA */ @@ -112,6 +112,7 @@ static const struct request_length request_lengths[] = { REQ_LENGTH_ENTRY(null, server_stats), /* SERVER_STATS */ REQ_LENGTH_ENTRY(client_accesses_by_index, client_accesses_by_index), /* CLIENT_ACCESSES_BY_INDEX2 */ + REQ_LENGTH_ENTRY(local, null), /* LOCAL2 */ }; static const uint16_t reply_lengths[] = { diff --git a/reference.c b/reference.c index 61a356b..2c956f5 100644 --- a/reference.c +++ b/reference.c @@ -1311,10 +1311,14 @@ REF_ModifyMakestep(int limit, double threshold) /* ================================================== */ void -REF_EnableLocal(int stratum) +REF_EnableLocal(int stratum, double distance, int orphan) { enable_local_stratum = 1; local_stratum = CLAMP(1, stratum, NTP_MAX_STRATUM - 1); + local_distance = distance; + local_orphan = !!orphan; + + update_local_timeout(); } /* ================================================== */ diff --git a/reference.h b/reference.h index abd205f..d146ec5 100644 --- a/reference.h +++ b/reference.h @@ -177,7 +177,7 @@ extern void REF_ModifyMaxupdateskew(double new_max_update_skew); /* Modify makestep settings */ extern void REF_ModifyMakestep(int limit, double threshold); -extern void REF_EnableLocal(int stratum); +extern void REF_EnableLocal(int stratum, double distance, int orphan); extern void REF_DisableLocal(void); extern int REF_IsLocalActive(void);