#define REQ_ADDSRC_INTERLEAVED 0x80
#define REQ_ADDSRC_BURST 0x100
#define REQ_ADDSRC_NTS 0x200
+#define REQ_ADDSRC_COPY 0x400
typedef struct {
uint32_t type;
(data.params.interleaved ? REQ_ADDSRC_INTERLEAVED : 0) |
(data.params.burst ? REQ_ADDSRC_BURST : 0) |
(data.params.nts ? REQ_ADDSRC_NTS : 0) |
+ (data.params.copy ? REQ_ADDSRC_COPY : 0) |
(data.params.sel_options & SRC_SELECT_PREFER ? REQ_ADDSRC_PREFER : 0) |
(data.params.sel_options & SRC_SELECT_NOSELECT ? REQ_ADDSRC_NOSELECT : 0) |
(data.params.sel_options & SRC_SELECT_TRUST ? REQ_ADDSRC_TRUST : 0) |
params.interleaved = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_INTERLEAVED ? 1 : 0;
params.burst = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_BURST ? 1 : 0;
params.nts = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_NTS ? 1 : 0;
+ params.copy = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_COPY ? 1 : 0;
params.sel_options =
(ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_PREFER ? SRC_SELECT_PREFER : 0) |
(ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_NOSELECT ? SRC_SELECT_NOSELECT : 0) |
src->params.sel_options = 0;
src->params.nts = 0;
src->params.nts_port = SRC_DEFAULT_NTSPORT;
+ src->params.copy = 0;
src->params.authkey = INACTIVE_AUTHKEY;
src->params.cert_set = SRC_DEFAULT_CERTSET;
src->params.max_delay = SRC_DEFAULT_MAXDELAY;
src->params.auto_offline = 1;
} else if (!strcasecmp(cmd, "burst")) {
src->params.burst = 1;
+ } else if (!strcasecmp(cmd, "copy")) {
+ src->params.copy = 1;
} else if (!strcasecmp(cmd, "iburst")) {
src->params.iburst = 1;
} else if (!strcasecmp(cmd, "offline")) {
is using. If the output size of the hash function is longer than 160 bits, the
default version is 3 for compatibility with older *chronyd* servers. Otherwise,
the default version is 4.
+*copy*:::
+This option specifies that the server and client are closely related, their
+configuration does not allow a synchronisation loop to form between them, and
+the client is allowed to assume the reference ID and stratum of the server.
+This is useful when multiple instances of `chronyd` are running on one computer
+(e.g. for security or performance reasons), one primarily operating as a client
+to synchronise the system clock and other instances started with the *-x*
+option to operate as NTP servers for other computers with their NTP clocks
+synchronised to the first instance.
[[pool]]*pool* _name_ [_option_]...::
The syntax of this directive is similar to that for the <<server,*server*>>
This directive can be used multiple times to specify multiple peers.
+
The following options of the *server* directive do not work in the *peer*
-directive: *iburst*, *burst*, *nts*, *presend*.
+directive: *iburst*, *burst*, *nts*, *presend*, *copy*.
+
When using the *xleave* option, both peers must support and have enabled the
interleaved mode, otherwise the synchronisation will work in one direction
int min_stratum; /* Increase stratum in received packets to the
minimum */
+ int copy; /* Boolean suppressing own refid and stratum */
+
int poll_target; /* Target number of sourcestats samples */
int version; /* Version set in packets for server/peer */
result->auto_iburst = params->iburst;
result->auto_burst = params->burst;
result->auto_offline = params->auto_offline;
+ result->copy = params->copy && result->mode == MODE_CLIENT;
result->poll_target = params->poll_target;
if (params->nts) {
inst->tx_count = 0;
SRC_UpdateReachability(inst->source, synced_packet);
- if (synced_packet)
- SRC_UpdateStatus(inst->source, MAX(message->stratum, inst->min_stratum), pkt_leap);
+
+ if (synced_packet) {
+ if (inst->copy && inst->remote_stratum > 0) {
+ /* Assume the reference ID and stratum of the server */
+ inst->remote_stratum--;
+ SRC_SetRefid(inst->source, ntohl(message->reference_id), &inst->remote_addr.ip_addr);
+ }
+
+ SRC_UpdateStatus(inst->source, MAX(inst->remote_stratum, inst->min_stratum), pkt_leap);
+ }
if (good_packet) {
/* Adjust the polling interval, accumulate the sample, etc. */
int sel_options;
int nts;
int nts_port;
+ int copy;
uint32_t authkey;
uint32_t cert_set;
double max_delay;
--- /dev/null
+#!/usr/bin/env bash
+
+. ./test.common
+
+test_start "copy option"
+
+check_config_h 'FEAT_CMDMON 1' || test_skip
+
+client_server_options="copy"
+chronyc_conf="tracking"
+
+run_test || test_fail
+check_chronyd_exit || test_fail
+check_source_selection || test_fail
+check_sync || test_fail
+check_chronyc_output "^Reference ID *: 7F7F0101 \(192\.168\.123\.1\)
+Stratum *: 1" || test_fail
+
+test_pass