#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 {
typedef struct {
int32_t on_off;
int32_t stratum;
+ Float distance;
+ int32_t orphan;
int32_t EOR;
} REQ_Local;
/* ================================================== */
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;
}
"allow all [<subnet>]\0Allow access to subnet and all children\0"
"deny [<subnet>]\0Deny access to subnet as a default\0"
"deny all [<subnet>]\0Deny access to subnet and all children\0"
- "local stratum <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"
PERMIT_AUTH, /* REFRESH */
PERMIT_AUTH, /* SERVER_STATS */
PERMIT_AUTH, /* CLIENT_ACCESSES_BY_INDEX2 */
+ PERMIT_AUTH, /* LOCAL2 */
};
/* ================================================== */
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();
}
handle_settime(&rx_message, &tx_message);
break;
- case REQ_LOCAL:
+ case REQ_LOCAL2:
handle_local(&rx_message, &tx_message);
break;
----
[[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 <<chrony.conf.adoc#local,*local*>>
-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 <<chrony.conf.adoc#local,*local*>> directive in the
+configuration file.
+
The second form disables the local reference mode.
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 */
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[] = {
/* ================================================== */
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();
}
/* ================================================== */
/* 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);