mirror of
https://gitlab.com/chrony/chrony.git
synced 2025-12-04 10:55:06 -05:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16519ee2cc | ||
|
|
50022e9286 | ||
|
|
5059019535 | ||
|
|
c6a38f5069 | ||
|
|
11ed197663 | ||
|
|
5634e6b963 | ||
|
|
db312a5ff6 | ||
|
|
88c31b3785 | ||
|
|
967f3e4f77 | ||
|
|
2e311d1766 | ||
|
|
11f7cc0507 | ||
|
|
a4f28892a5 | ||
|
|
5bc53741be | ||
|
|
95a4f33265 | ||
|
|
fac1093ebf | ||
|
|
1b1384ccaa | ||
|
|
0c9a19ded5 | ||
|
|
b7bd7469b7 |
7
NEWS
7
NEWS
@@ -16,14 +16,21 @@ Enhancements
|
|||||||
* Add -t option to chronyd to exit after specified time
|
* Add -t option to chronyd to exit after specified time
|
||||||
* Add partial protection against replay attacks on symmetric mode
|
* Add partial protection against replay attacks on symmetric mode
|
||||||
* Don't reset polling interval when switching sources to online state
|
* Don't reset polling interval when switching sources to online state
|
||||||
|
* Enable NTP response rate limiting by default
|
||||||
|
(1024 packets per second per IP address and 25% leak)
|
||||||
* Improve maximum server throughput on Linux and NetBSD
|
* Improve maximum server throughput on Linux and NetBSD
|
||||||
* Remove dump files after start
|
* Remove dump files after start
|
||||||
* Add tab-completion to chronyc with libedit/readline
|
* Add tab-completion to chronyc with libedit/readline
|
||||||
* Add ntpdata command to print details about NTP measurements
|
* Add ntpdata command to print details about NTP measurements
|
||||||
|
* Allow all source options to be set in add server/peer command
|
||||||
* Indicate truncated addresses/hostnames in chronyc output
|
* Indicate truncated addresses/hostnames in chronyc output
|
||||||
* Print reference IDs as hexadecimal numbers to avoid confusion with
|
* Print reference IDs as hexadecimal numbers to avoid confusion with
|
||||||
IPv4 addresses
|
IPv4 addresses
|
||||||
|
|
||||||
|
Bug fixes
|
||||||
|
---------
|
||||||
|
* Fix crash with disabled asynchronous name resolving
|
||||||
|
|
||||||
New in version 2.4.1
|
New in version 2.4.1
|
||||||
====================
|
====================
|
||||||
|
|
||||||
|
|||||||
5
candm.h
5
candm.h
@@ -362,8 +362,8 @@ typedef struct {
|
|||||||
domain socket.
|
domain socket.
|
||||||
|
|
||||||
Version 6 (no authentication) : changed format of client accesses by index
|
Version 6 (no authentication) : changed format of client accesses by index
|
||||||
(using new request/reply types), new flags in NTP source request and report,
|
(using new request/reply types), new fields and flags in NTP source request
|
||||||
new commands: refresh, serverstats
|
and report, new commands: ntpdata, refresh, serverstats
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PROTO_VERSION_NUMBER 6
|
#define PROTO_VERSION_NUMBER 6
|
||||||
@@ -672,6 +672,7 @@ typedef struct {
|
|||||||
uint32_t total_tx_count;
|
uint32_t total_tx_count;
|
||||||
uint32_t total_rx_count;
|
uint32_t total_rx_count;
|
||||||
uint32_t total_valid_count;
|
uint32_t total_valid_count;
|
||||||
|
uint32_t reserved[4];
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} RPY_NTPData;
|
} RPY_NTPData;
|
||||||
|
|
||||||
|
|||||||
155
client.c
155
client.c
@@ -1191,7 +1191,7 @@ give_help(void)
|
|||||||
"\0\0"
|
"\0\0"
|
||||||
"NTP sources:\0\0"
|
"NTP sources:\0\0"
|
||||||
"activity\0Check how many NTP sources are online/offline\0"
|
"activity\0Check how many NTP sources are online/offline\0"
|
||||||
"ntpdata <address>\0Display information about last valid measurement\0"
|
"ntpdata [<address>]\0Display information about last valid measurement\0"
|
||||||
"add server <address> [options]\0Add new NTP server\0"
|
"add server <address> [options]\0Add new NTP server\0"
|
||||||
"add peer <address> [options]\0Add new NTP peer\0"
|
"add peer <address> [options]\0Add new NTP peer\0"
|
||||||
"delete <address>\0Remove server or peer\0"
|
"delete <address>\0Remove server or peer\0"
|
||||||
@@ -2244,71 +2244,104 @@ process_cmd_ntpdata(char *line)
|
|||||||
CMD_Reply reply;
|
CMD_Reply reply;
|
||||||
IPAddr remote_addr, local_addr;
|
IPAddr remote_addr, local_addr;
|
||||||
struct timespec ref_time;
|
struct timespec ref_time;
|
||||||
|
uint32_t i, n_sources;
|
||||||
|
uint16_t mode;
|
||||||
|
int specified_addr;
|
||||||
|
|
||||||
if (DNS_Name2IPAddress(line, &remote_addr, 1) != DNS_Success) {
|
if (*line) {
|
||||||
LOG(LOGS_ERR, LOGF_Client, "Could not get address for hostname");
|
specified_addr = 1;
|
||||||
return 0;
|
n_sources = 1;
|
||||||
|
} else {
|
||||||
|
specified_addr = 0;
|
||||||
|
request.command = htons(REQ_N_SOURCES);
|
||||||
|
if (!request_reply(&request, &reply, RPY_N_SOURCES, 0))
|
||||||
|
return 0;
|
||||||
|
n_sources = ntohl(reply.data.n_sources.n_sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
request.command = htons(REQ_NTP_DATA);
|
for (i = 0; i < n_sources; i++) {
|
||||||
UTI_IPHostToNetwork(&remote_addr, &request.data.ntp_data.ip_addr);
|
if (specified_addr) {
|
||||||
if (!request_reply(&request, &reply, RPY_NTP_DATA, 0))
|
if (DNS_Name2IPAddress(line, &remote_addr, 1) != DNS_Success) {
|
||||||
return 0;
|
LOG(LOGS_ERR, LOGF_Client, "Could not get address for hostname");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
request.command = htons(REQ_SOURCE_DATA);
|
||||||
|
request.data.source_data.index = htonl(i);
|
||||||
|
if (!request_reply(&request, &reply, RPY_SOURCE_DATA, 0))
|
||||||
|
return 0;
|
||||||
|
|
||||||
UTI_IPNetworkToHost(&reply.data.ntp_data.remote_addr, &remote_addr);
|
mode = ntohs(reply.data.source_data.mode);
|
||||||
UTI_IPNetworkToHost(&reply.data.ntp_data.local_addr, &local_addr);
|
if (mode != RPY_SD_MD_CLIENT && mode != RPY_SD_MD_PEER)
|
||||||
UTI_TimespecNetworkToHost(&reply.data.ntp_data.ref_time, &ref_time);
|
continue;
|
||||||
|
|
||||||
print_report("Remote address : %s (%R)\n"
|
UTI_IPNetworkToHost(&reply.data.source_data.ip_addr, &remote_addr);
|
||||||
"Remote port : %u\n"
|
}
|
||||||
"Local address : %s (%R)\n"
|
|
||||||
"Leap status : %L\n"
|
request.command = htons(REQ_NTP_DATA);
|
||||||
"Version : %u\n"
|
UTI_IPHostToNetwork(&remote_addr, &request.data.ntp_data.ip_addr);
|
||||||
"Mode : %M\n"
|
if (!request_reply(&request, &reply, RPY_NTP_DATA, 0))
|
||||||
"Stratum : %u\n"
|
return 0;
|
||||||
"Poll : %d\n"
|
|
||||||
"Precision : %.9f seconds\n"
|
UTI_IPNetworkToHost(&reply.data.ntp_data.remote_addr, &remote_addr);
|
||||||
"Root delay : %.6f seconds\n"
|
UTI_IPNetworkToHost(&reply.data.ntp_data.local_addr, &local_addr);
|
||||||
"Root dispersion : %.6f seconds\n"
|
UTI_TimespecNetworkToHost(&reply.data.ntp_data.ref_time, &ref_time);
|
||||||
"Reference ID : %R\n"
|
|
||||||
"Reference time : %T\n"
|
if (!specified_addr && !csv_mode)
|
||||||
"Offset : %+.9f seconds\n"
|
printf("\n");
|
||||||
"Peer delay : %.9f seconds\n"
|
|
||||||
"Peer dispersion : %.9f seconds\n"
|
print_report("Remote address : %s (%R)\n"
|
||||||
"Response time : %.9f seconds\n"
|
"Remote port : %u\n"
|
||||||
"Jitter asymmetry: %+.2f\n"
|
"Local address : %s (%R)\n"
|
||||||
"NTP tests : %.3b %.3b %.4b\n"
|
"Leap status : %L\n"
|
||||||
"Interleaved : %B\n"
|
"Version : %u\n"
|
||||||
"Authenticated : %B\n"
|
"Mode : %M\n"
|
||||||
"TX timestamping : %N\n"
|
"Stratum : %u\n"
|
||||||
"RX timestamping : %N\n"
|
"Poll interval : %d (%.0f seconds)\n"
|
||||||
"Total TX : %U\n"
|
"Precision : %d (%.9f seconds)\n"
|
||||||
"Total RX : %U\n"
|
"Root delay : %.6f seconds\n"
|
||||||
"Total valid RX : %U\n",
|
"Root dispersion : %.6f seconds\n"
|
||||||
UTI_IPToString(&remote_addr), (unsigned long)UTI_IPToRefid(&remote_addr),
|
"Reference ID : %R\n"
|
||||||
ntohs(reply.data.ntp_data.remote_port),
|
"Reference time : %T\n"
|
||||||
UTI_IPToString(&local_addr), (unsigned long)UTI_IPToRefid(&local_addr),
|
"Offset : %+.9f seconds\n"
|
||||||
reply.data.ntp_data.leap, reply.data.ntp_data.version,
|
"Peer delay : %.9f seconds\n"
|
||||||
reply.data.ntp_data.mode, reply.data.ntp_data.stratum,
|
"Peer dispersion : %.9f seconds\n"
|
||||||
reply.data.ntp_data.poll, UTI_Log2ToDouble(reply.data.ntp_data.precision),
|
"Response time : %.9f seconds\n"
|
||||||
UTI_FloatNetworkToHost(reply.data.ntp_data.root_delay),
|
"Jitter asymmetry: %+.2f\n"
|
||||||
UTI_FloatNetworkToHost(reply.data.ntp_data.root_dispersion),
|
"NTP tests : %.3b %.3b %.4b\n"
|
||||||
(unsigned long)ntohl(reply.data.ntp_data.ref_id), &ref_time,
|
"Interleaved : %B\n"
|
||||||
UTI_FloatNetworkToHost(reply.data.ntp_data.offset),
|
"Authenticated : %B\n"
|
||||||
UTI_FloatNetworkToHost(reply.data.ntp_data.peer_delay),
|
"TX timestamping : %N\n"
|
||||||
UTI_FloatNetworkToHost(reply.data.ntp_data.peer_dispersion),
|
"RX timestamping : %N\n"
|
||||||
UTI_FloatNetworkToHost(reply.data.ntp_data.response_time),
|
"Total TX : %U\n"
|
||||||
UTI_FloatNetworkToHost(reply.data.ntp_data.jitter_asymmetry),
|
"Total RX : %U\n"
|
||||||
ntohs(reply.data.ntp_data.flags) >> 7,
|
"Total valid RX : %U\n",
|
||||||
ntohs(reply.data.ntp_data.flags) >> 4,
|
UTI_IPToString(&remote_addr), (unsigned long)UTI_IPToRefid(&remote_addr),
|
||||||
ntohs(reply.data.ntp_data.flags),
|
ntohs(reply.data.ntp_data.remote_port),
|
||||||
ntohs(reply.data.ntp_data.flags) & RPY_NTP_FLAG_INTERLEAVED,
|
UTI_IPToString(&local_addr), (unsigned long)UTI_IPToRefid(&local_addr),
|
||||||
ntohs(reply.data.ntp_data.flags) & RPY_NTP_FLAG_AUTHENTICATED,
|
reply.data.ntp_data.leap, reply.data.ntp_data.version,
|
||||||
reply.data.ntp_data.tx_tss_char, reply.data.ntp_data.rx_tss_char,
|
reply.data.ntp_data.mode, reply.data.ntp_data.stratum,
|
||||||
(unsigned long)ntohl(reply.data.ntp_data.total_tx_count),
|
reply.data.ntp_data.poll, UTI_Log2ToDouble(reply.data.ntp_data.poll),
|
||||||
(unsigned long)ntohl(reply.data.ntp_data.total_rx_count),
|
reply.data.ntp_data.precision, UTI_Log2ToDouble(reply.data.ntp_data.precision),
|
||||||
(unsigned long)ntohl(reply.data.ntp_data.total_valid_count),
|
UTI_FloatNetworkToHost(reply.data.ntp_data.root_delay),
|
||||||
REPORT_END);
|
UTI_FloatNetworkToHost(reply.data.ntp_data.root_dispersion),
|
||||||
|
(unsigned long)ntohl(reply.data.ntp_data.ref_id), &ref_time,
|
||||||
|
UTI_FloatNetworkToHost(reply.data.ntp_data.offset),
|
||||||
|
UTI_FloatNetworkToHost(reply.data.ntp_data.peer_delay),
|
||||||
|
UTI_FloatNetworkToHost(reply.data.ntp_data.peer_dispersion),
|
||||||
|
UTI_FloatNetworkToHost(reply.data.ntp_data.response_time),
|
||||||
|
UTI_FloatNetworkToHost(reply.data.ntp_data.jitter_asymmetry),
|
||||||
|
ntohs(reply.data.ntp_data.flags) >> 7,
|
||||||
|
ntohs(reply.data.ntp_data.flags) >> 4,
|
||||||
|
ntohs(reply.data.ntp_data.flags),
|
||||||
|
ntohs(reply.data.ntp_data.flags) & RPY_NTP_FLAG_INTERLEAVED,
|
||||||
|
ntohs(reply.data.ntp_data.flags) & RPY_NTP_FLAG_AUTHENTICATED,
|
||||||
|
reply.data.ntp_data.tx_tss_char, reply.data.ntp_data.rx_tss_char,
|
||||||
|
(unsigned long)ntohl(reply.data.ntp_data.total_tx_count),
|
||||||
|
(unsigned long)ntohl(reply.data.ntp_data.total_rx_count),
|
||||||
|
(unsigned long)ntohl(reply.data.ntp_data.total_valid_count),
|
||||||
|
REPORT_END);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
76
clientlog.c
76
clientlog.c
@@ -86,6 +86,10 @@ static unsigned int max_slots;
|
|||||||
#define TS_FRAC 4
|
#define TS_FRAC 4
|
||||||
#define INVALID_TS 0
|
#define INVALID_TS 0
|
||||||
|
|
||||||
|
/* Static offset included in conversion to the fixed-point timestamps to
|
||||||
|
randomise their alignment */
|
||||||
|
static uint32_t ts_offset;
|
||||||
|
|
||||||
/* Request rates are saved in the record as 8-bit scaled log2 values */
|
/* Request rates are saved in the record as 8-bit scaled log2 values */
|
||||||
#define RATE_SCALE 4
|
#define RATE_SCALE 4
|
||||||
#define MIN_RATE (-14 * RATE_SCALE)
|
#define MIN_RATE (-14 * RATE_SCALE)
|
||||||
@@ -95,7 +99,7 @@ static unsigned int max_slots;
|
|||||||
number of tokens spent on response are determined from configured
|
number of tokens spent on response are determined from configured
|
||||||
minimum inverval between responses (in log2) and burst length. */
|
minimum inverval between responses (in log2) and burst length. */
|
||||||
|
|
||||||
#define MIN_LIMIT_INTERVAL (-TS_FRAC)
|
#define MIN_LIMIT_INTERVAL (-15 - TS_FRAC)
|
||||||
#define MAX_LIMIT_INTERVAL 12
|
#define MAX_LIMIT_INTERVAL 12
|
||||||
#define MIN_LIMIT_BURST 1
|
#define MIN_LIMIT_BURST 1
|
||||||
#define MAX_LIMIT_BURST 255
|
#define MAX_LIMIT_BURST 255
|
||||||
@@ -105,7 +109,8 @@ static uint16_t max_cmd_tokens;
|
|||||||
static uint16_t ntp_tokens_per_packet;
|
static uint16_t ntp_tokens_per_packet;
|
||||||
static uint16_t cmd_tokens_per_packet;
|
static uint16_t cmd_tokens_per_packet;
|
||||||
|
|
||||||
/* Reduction of token rates to avoid overflow of 16-bit counters */
|
/* Reduction of token rates to avoid overflow of 16-bit counters. Negative
|
||||||
|
shift is used for coarse limiting with intervals shorter than -TS_FRAC. */
|
||||||
static int ntp_token_shift;
|
static int ntp_token_shift;
|
||||||
static int cmd_token_shift;
|
static int cmd_token_shift;
|
||||||
|
|
||||||
@@ -114,7 +119,7 @@ static int cmd_token_shift;
|
|||||||
prevent an attacker sending requests with spoofed source address
|
prevent an attacker sending requests with spoofed source address
|
||||||
from blocking responses to the address completely. */
|
from blocking responses to the address completely. */
|
||||||
|
|
||||||
#define MIN_LEAK_RATE 1
|
#define MIN_LEAK_RATE 0
|
||||||
#define MAX_LEAK_RATE 4
|
#define MAX_LEAK_RATE 4
|
||||||
|
|
||||||
static int ntp_leak_rate;
|
static int ntp_leak_rate;
|
||||||
@@ -133,6 +138,8 @@ static uint32_t total_ntp_drops;
|
|||||||
static uint32_t total_cmd_drops;
|
static uint32_t total_cmd_drops;
|
||||||
static uint32_t total_record_drops;
|
static uint32_t total_record_drops;
|
||||||
|
|
||||||
|
#define NSEC_PER_SEC 1000000000U
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static int expand_hashtable(void);
|
static int expand_hashtable(void);
|
||||||
@@ -271,10 +278,17 @@ set_bucket_params(int interval, int burst, uint16_t *max_tokens,
|
|||||||
interval = CLAMP(MIN_LIMIT_INTERVAL, interval, MAX_LIMIT_INTERVAL);
|
interval = CLAMP(MIN_LIMIT_INTERVAL, interval, MAX_LIMIT_INTERVAL);
|
||||||
burst = CLAMP(MIN_LIMIT_BURST, burst, MAX_LIMIT_BURST);
|
burst = CLAMP(MIN_LIMIT_BURST, burst, MAX_LIMIT_BURST);
|
||||||
|
|
||||||
/* Find smallest shift with which the maximum number fits in 16 bits */
|
if (interval >= -TS_FRAC) {
|
||||||
for (*token_shift = 0; *token_shift < interval + TS_FRAC; (*token_shift)++) {
|
/* Find the smallest shift with which the maximum number fits in 16 bits */
|
||||||
if (burst << (TS_FRAC + interval - *token_shift) < 1U << 16)
|
for (*token_shift = 0; *token_shift < interval + TS_FRAC; (*token_shift)++) {
|
||||||
break;
|
if (burst << (TS_FRAC + interval - *token_shift) < 1U << 16)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Coarse rate limiting */
|
||||||
|
*token_shift = interval + TS_FRAC;
|
||||||
|
*tokens_per_packet = 1;
|
||||||
|
burst = MAX(1U << -*token_shift, burst);
|
||||||
}
|
}
|
||||||
|
|
||||||
*tokens_per_packet = 1U << (TS_FRAC + interval - *token_shift);
|
*tokens_per_packet = 1U << (TS_FRAC + interval - *token_shift);
|
||||||
@@ -291,29 +305,19 @@ CLG_Initialise(void)
|
|||||||
{
|
{
|
||||||
int interval, burst, leak_rate;
|
int interval, burst, leak_rate;
|
||||||
|
|
||||||
max_ntp_tokens = max_cmd_tokens = 0;
|
CNF_GetNTPRateLimit(&interval, &burst, &leak_rate);
|
||||||
ntp_tokens_per_packet = cmd_tokens_per_packet = 0;
|
set_bucket_params(interval, burst, &max_ntp_tokens, &ntp_tokens_per_packet,
|
||||||
ntp_token_shift = cmd_token_shift = 0;
|
&ntp_token_shift);
|
||||||
ntp_leak_rate = cmd_leak_rate = 0;
|
ntp_leak_rate = CLAMP(MIN_LEAK_RATE, leak_rate, MAX_LEAK_RATE);
|
||||||
|
|
||||||
if (CNF_GetNTPRateLimit(&interval, &burst, &leak_rate)) {
|
CNF_GetCommandRateLimit(&interval, &burst, &leak_rate);
|
||||||
set_bucket_params(interval, burst, &max_ntp_tokens, &ntp_tokens_per_packet,
|
set_bucket_params(interval, burst, &max_cmd_tokens, &cmd_tokens_per_packet,
|
||||||
&ntp_token_shift);
|
&cmd_token_shift);
|
||||||
ntp_leak_rate = CLAMP(MIN_LEAK_RATE, leak_rate, MAX_LEAK_RATE);
|
cmd_leak_rate = CLAMP(MIN_LEAK_RATE, leak_rate, MAX_LEAK_RATE);
|
||||||
}
|
|
||||||
|
|
||||||
if (CNF_GetCommandRateLimit(&interval, &burst, &leak_rate)) {
|
|
||||||
set_bucket_params(interval, burst, &max_cmd_tokens, &cmd_tokens_per_packet,
|
|
||||||
&cmd_token_shift);
|
|
||||||
cmd_leak_rate = CLAMP(MIN_LEAK_RATE, leak_rate, MAX_LEAK_RATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
active = !CNF_GetNoClientLog();
|
active = !CNF_GetNoClientLog();
|
||||||
if (!active) {
|
if (!active)
|
||||||
if (ntp_leak_rate || cmd_leak_rate)
|
|
||||||
LOG_FATAL(LOGF_ClientLog, "ratelimit cannot be used with noclientlog");
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate the maximum number of slots that can be allocated in the
|
/* Calculate the maximum number of slots that can be allocated in the
|
||||||
configured memory limit. Take into account expanding of the hash
|
configured memory limit. Take into account expanding of the hash
|
||||||
@@ -325,6 +329,9 @@ CLG_Initialise(void)
|
|||||||
records = NULL;
|
records = NULL;
|
||||||
|
|
||||||
expand_hashtable();
|
expand_hashtable();
|
||||||
|
|
||||||
|
UTI_GetRandomBytes(&ts_offset, sizeof (ts_offset));
|
||||||
|
ts_offset %= NSEC_PER_SEC / (1U << TS_FRAC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -345,6 +352,12 @@ get_ts_from_timespec(struct timespec *ts)
|
|||||||
{
|
{
|
||||||
uint32_t sec = ts->tv_sec, nsec = ts->tv_nsec;
|
uint32_t sec = ts->tv_sec, nsec = ts->tv_nsec;
|
||||||
|
|
||||||
|
nsec += ts_offset;
|
||||||
|
if (nsec >= NSEC_PER_SEC) {
|
||||||
|
nsec -= NSEC_PER_SEC;
|
||||||
|
sec++;
|
||||||
|
}
|
||||||
|
|
||||||
/* This is fast and accurate enough */
|
/* This is fast and accurate enough */
|
||||||
return sec << TS_FRAC | (140740U * (nsec >> 15)) >> (32 - TS_FRAC);
|
return sec << TS_FRAC | (140740U * (nsec >> 15)) >> (32 - TS_FRAC);
|
||||||
}
|
}
|
||||||
@@ -369,7 +382,12 @@ update_record(struct timespec *now, uint32_t *last_hit, uint32_t *hits,
|
|||||||
if (prev_hit == INVALID_TS || (int32_t)interval < 0)
|
if (prev_hit == INVALID_TS || (int32_t)interval < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
new_tokens = (now_ts >> token_shift) - (prev_hit >> token_shift);
|
if (token_shift >= 0)
|
||||||
|
new_tokens = (now_ts >> token_shift) - (prev_hit >> token_shift);
|
||||||
|
else if (now_ts - prev_hit > max_tokens)
|
||||||
|
new_tokens = max_tokens;
|
||||||
|
else
|
||||||
|
new_tokens = (now_ts - prev_hit) << -token_shift;
|
||||||
*tokens = MIN(*tokens + new_tokens, max_tokens);
|
*tokens = MIN(*tokens + new_tokens, max_tokens);
|
||||||
|
|
||||||
/* Convert the interval to scaled and rounded log2 */
|
/* Convert the interval to scaled and rounded log2 */
|
||||||
@@ -502,7 +520,7 @@ CLG_LimitNTPResponseRate(int index)
|
|||||||
Record *record;
|
Record *record;
|
||||||
int drop;
|
int drop;
|
||||||
|
|
||||||
if (!ntp_tokens_per_packet)
|
if (!ntp_leak_rate)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
record = ARR_GetElement(records, index);
|
record = ARR_GetElement(records, index);
|
||||||
@@ -543,7 +561,7 @@ CLG_LimitCommandResponseRate(int index)
|
|||||||
{
|
{
|
||||||
Record *record;
|
Record *record;
|
||||||
|
|
||||||
if (!cmd_tokens_per_packet)
|
if (!cmd_leak_rate)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
record = ARR_GetElement(records, index);
|
record = ARR_GetElement(records, index);
|
||||||
|
|||||||
1
cmdmon.c
1
cmdmon.c
@@ -1232,6 +1232,7 @@ handle_ntp_data(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||||||
tx_message->data.ntp_data.total_tx_count = htonl(report.total_tx_count);
|
tx_message->data.ntp_data.total_tx_count = htonl(report.total_tx_count);
|
||||||
tx_message->data.ntp_data.total_rx_count = htonl(report.total_rx_count);
|
tx_message->data.ntp_data.total_rx_count = htonl(report.total_rx_count);
|
||||||
tx_message->data.ntp_data.total_valid_count = htonl(report.total_valid_count);
|
tx_message->data.ntp_data.total_valid_count = htonl(report.total_valid_count);
|
||||||
|
memset(tx_message->data.ntp_data.reserved, 0xff, sizeof (tx_message->data.ntp_data.reserved));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|||||||
31
conf.c
31
conf.c
@@ -66,8 +66,7 @@ static void parse_log(char *);
|
|||||||
static void parse_mailonchange(char *);
|
static void parse_mailonchange(char *);
|
||||||
static void parse_makestep(char *);
|
static void parse_makestep(char *);
|
||||||
static void parse_maxchange(char *);
|
static void parse_maxchange(char *);
|
||||||
static void parse_ratelimit(char *line, int *enabled, int *interval,
|
static void parse_ratelimit(char *line, int *interval, int *burst, int *leak);
|
||||||
int *burst, int *leak);
|
|
||||||
static void parse_refclock(char *);
|
static void parse_refclock(char *);
|
||||||
static void parse_smoothtime(char *);
|
static void parse_smoothtime(char *);
|
||||||
static void parse_source(char *line, NTP_Source_Type type, int pool);
|
static void parse_source(char *line, NTP_Source_Type type, int pool);
|
||||||
@@ -191,14 +190,12 @@ static char *ntp_signd_socket = NULL;
|
|||||||
static char *pidfile;
|
static char *pidfile;
|
||||||
|
|
||||||
/* Rate limiting parameters */
|
/* Rate limiting parameters */
|
||||||
static int ntp_ratelimit_enabled = 0;
|
static int ntp_ratelimit_interval = -10;
|
||||||
static int ntp_ratelimit_interval = 3;
|
static int ntp_ratelimit_burst = 16;
|
||||||
static int ntp_ratelimit_burst = 8;
|
static int ntp_ratelimit_leak = 2;
|
||||||
static int ntp_ratelimit_leak = 3;
|
static int cmd_ratelimit_interval = -10;
|
||||||
static int cmd_ratelimit_enabled = 0;
|
|
||||||
static int cmd_ratelimit_interval = 1;
|
|
||||||
static int cmd_ratelimit_burst = 16;
|
static int cmd_ratelimit_burst = 16;
|
||||||
static int cmd_ratelimit_leak = 2;
|
static int cmd_ratelimit_leak = 0;
|
||||||
|
|
||||||
/* Smoothing constants */
|
/* Smoothing constants */
|
||||||
static double smooth_max_freq = 0.0; /* in ppm */
|
static double smooth_max_freq = 0.0; /* in ppm */
|
||||||
@@ -455,8 +452,7 @@ CNF_ParseLine(const char *filename, int number, char *line)
|
|||||||
} else if (!strcasecmp(command, "cmdport")) {
|
} else if (!strcasecmp(command, "cmdport")) {
|
||||||
parse_int(p, &cmd_port);
|
parse_int(p, &cmd_port);
|
||||||
} else if (!strcasecmp(command, "cmdratelimit")) {
|
} else if (!strcasecmp(command, "cmdratelimit")) {
|
||||||
parse_ratelimit(p, &cmd_ratelimit_enabled, &cmd_ratelimit_interval,
|
parse_ratelimit(p, &cmd_ratelimit_interval, &cmd_ratelimit_burst, &cmd_ratelimit_leak);
|
||||||
&cmd_ratelimit_burst, &cmd_ratelimit_leak);
|
|
||||||
} else if (!strcasecmp(command, "combinelimit")) {
|
} else if (!strcasecmp(command, "combinelimit")) {
|
||||||
parse_double(p, &combine_limit);
|
parse_double(p, &combine_limit);
|
||||||
} else if (!strcasecmp(command, "corrtimeratio")) {
|
} else if (!strcasecmp(command, "corrtimeratio")) {
|
||||||
@@ -536,8 +532,7 @@ CNF_ParseLine(const char *filename, int number, char *line)
|
|||||||
} else if (!strcasecmp(command, "port")) {
|
} else if (!strcasecmp(command, "port")) {
|
||||||
parse_int(p, &ntp_port);
|
parse_int(p, &ntp_port);
|
||||||
} else if (!strcasecmp(command, "ratelimit")) {
|
} else if (!strcasecmp(command, "ratelimit")) {
|
||||||
parse_ratelimit(p, &ntp_ratelimit_enabled, &ntp_ratelimit_interval,
|
parse_ratelimit(p, &ntp_ratelimit_interval, &ntp_ratelimit_burst, &ntp_ratelimit_leak);
|
||||||
&ntp_ratelimit_burst, &ntp_ratelimit_leak);
|
|
||||||
} else if (!strcasecmp(command, "refclock")) {
|
} else if (!strcasecmp(command, "refclock")) {
|
||||||
parse_refclock(p);
|
parse_refclock(p);
|
||||||
} else if (!strcasecmp(command, "reselectdist")) {
|
} else if (!strcasecmp(command, "reselectdist")) {
|
||||||
@@ -642,13 +637,11 @@ parse_source(char *line, NTP_Source_Type type, int pool)
|
|||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_ratelimit(char *line, int *enabled, int *interval, int *burst, int *leak)
|
parse_ratelimit(char *line, int *interval, int *burst, int *leak)
|
||||||
{
|
{
|
||||||
int n, val;
|
int n, val;
|
||||||
char *opt;
|
char *opt;
|
||||||
|
|
||||||
*enabled = 1;
|
|
||||||
|
|
||||||
while (*line) {
|
while (*line) {
|
||||||
opt = line;
|
opt = line;
|
||||||
line = CPS_SplitWord(line);
|
line = CPS_SplitWord(line);
|
||||||
@@ -1830,22 +1823,20 @@ CNF_GetLockMemory(void)
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int CNF_GetNTPRateLimit(int *interval, int *burst, int *leak)
|
void CNF_GetNTPRateLimit(int *interval, int *burst, int *leak)
|
||||||
{
|
{
|
||||||
*interval = ntp_ratelimit_interval;
|
*interval = ntp_ratelimit_interval;
|
||||||
*burst = ntp_ratelimit_burst;
|
*burst = ntp_ratelimit_burst;
|
||||||
*leak = ntp_ratelimit_leak;
|
*leak = ntp_ratelimit_leak;
|
||||||
return ntp_ratelimit_enabled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int CNF_GetCommandRateLimit(int *interval, int *burst, int *leak)
|
void CNF_GetCommandRateLimit(int *interval, int *burst, int *leak)
|
||||||
{
|
{
|
||||||
*interval = cmd_ratelimit_interval;
|
*interval = cmd_ratelimit_interval;
|
||||||
*burst = cmd_ratelimit_burst;
|
*burst = cmd_ratelimit_burst;
|
||||||
*leak = cmd_ratelimit_leak;
|
*leak = cmd_ratelimit_leak;
|
||||||
return cmd_ratelimit_enabled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|||||||
4
conf.h
4
conf.h
@@ -102,8 +102,8 @@ extern void CNF_SetupAccessRestrictions(void);
|
|||||||
extern int CNF_GetSchedPriority(void);
|
extern int CNF_GetSchedPriority(void);
|
||||||
extern int CNF_GetLockMemory(void);
|
extern int CNF_GetLockMemory(void);
|
||||||
|
|
||||||
extern int CNF_GetNTPRateLimit(int *interval, int *burst, int *leak);
|
extern void CNF_GetNTPRateLimit(int *interval, int *burst, int *leak);
|
||||||
extern int CNF_GetCommandRateLimit(int *interval, int *burst, int *leak);
|
extern void CNF_GetCommandRateLimit(int *interval, int *burst, int *leak);
|
||||||
extern void CNF_GetSmooth(double *max_freq, double *max_wander, int *leap_only);
|
extern void CNF_GetSmooth(double *max_freq, double *max_wander, int *leap_only);
|
||||||
extern void CNF_GetTempComp(char **file, double *interval, char **point_file, double *T0, double *k0, double *k1, double *k2);
|
extern void CNF_GetTempComp(char **file, double *interval, char **point_file, double *T0, double *k0, double *k1, double *k2);
|
||||||
|
|
||||||
|
|||||||
20
configure
vendored
20
configure
vendored
@@ -219,6 +219,7 @@ try_lockmem=0
|
|||||||
feat_asyncdns=1
|
feat_asyncdns=1
|
||||||
feat_forcednsretry=1
|
feat_forcednsretry=1
|
||||||
try_clock_gettime=1
|
try_clock_gettime=1
|
||||||
|
try_recvmmsg=1
|
||||||
feat_timestamping=1
|
feat_timestamping=1
|
||||||
try_timestamping=0
|
try_timestamping=0
|
||||||
feat_ntp_signd=0
|
feat_ntp_signd=0
|
||||||
@@ -400,6 +401,9 @@ case $OPERATINGSYSTEM in
|
|||||||
echo "Configuring for " $SYSTEM
|
echo "Configuring for " $SYSTEM
|
||||||
;;
|
;;
|
||||||
FreeBSD)
|
FreeBSD)
|
||||||
|
# recvmmsg() seems to be broken on FreeBSD 11.0 and it's just
|
||||||
|
# a wrapper around recvmsg()
|
||||||
|
try_recvmmsg=0
|
||||||
EXTRA_OBJECTS="sys_generic.o sys_netbsd.o sys_timex.o"
|
EXTRA_OBJECTS="sys_generic.o sys_netbsd.o sys_timex.o"
|
||||||
add_def FREEBSD
|
add_def FREEBSD
|
||||||
if [ $feat_droproot = "1" ]; then
|
if [ $feat_droproot = "1" ]; then
|
||||||
@@ -629,14 +633,16 @@ fi
|
|||||||
RECVMMSG_CODE='
|
RECVMMSG_CODE='
|
||||||
struct mmsghdr hdr;
|
struct mmsghdr hdr;
|
||||||
return !recvmmsg(0, &hdr, 1, MSG_DONTWAIT, 0);'
|
return !recvmmsg(0, &hdr, 1, MSG_DONTWAIT, 0);'
|
||||||
if test_code 'recvmmsg()' 'sys/socket.h' '' "$EXTRA_LIBS" "$RECVMMSG_CODE"; then
|
if [ $try_recvmmsg = "1" ]; then
|
||||||
add_def HAVE_RECVMMSG
|
if test_code 'recvmmsg()' 'sys/socket.h' '' "$EXTRA_LIBS" "$RECVMMSG_CODE"; then
|
||||||
else
|
|
||||||
if test_code 'recvmmsg() with _GNU_SOURCE' 'sys/socket.h' '-D_GNU_SOURCE' \
|
|
||||||
"$EXTRA_LIBS" "$RECVMMSG_CODE"
|
|
||||||
then
|
|
||||||
add_def _GNU_SOURCE
|
|
||||||
add_def HAVE_RECVMMSG
|
add_def HAVE_RECVMMSG
|
||||||
|
else
|
||||||
|
if test_code 'recvmmsg() with _GNU_SOURCE' 'sys/socket.h' '-D_GNU_SOURCE' \
|
||||||
|
"$EXTRA_LIBS" "$RECVMMSG_CODE"
|
||||||
|
then
|
||||||
|
add_def _GNU_SOURCE
|
||||||
|
add_def HAVE_RECVMMSG
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,8 @@ round-trip delay of 0.3 seconds or more should be ignored. The default value is
|
|||||||
This option is similar to the maxdelay option above. *chronyd* keeps a record
|
This option is similar to the maxdelay option above. *chronyd* keeps a record
|
||||||
of the minimum round-trip delay amongst the previous measurements that it has
|
of the minimum round-trip delay amongst the previous measurements that it has
|
||||||
buffered. If a measurement has a round trip delay that is greater than the
|
buffered. If a measurement has a round trip delay that is greater than the
|
||||||
maxdelayratio times the minimum delay, it will be rejected.
|
maxdelayratio times the minimum delay, it will be rejected. This option works
|
||||||
|
only in the *server* directive when not in the interleaved mode.
|
||||||
*maxdelaydevratio* _ratio_:::
|
*maxdelaydevratio* _ratio_:::
|
||||||
If a measurement has a ratio of the increase in the round-trip delay from the
|
If a measurement has a ratio of the increase in the round-trip delay from the
|
||||||
minimum delay amongst the previous measurements to the standard deviation of
|
minimum delay amongst the previous measurements to the standard deviation of
|
||||||
@@ -1220,8 +1221,8 @@ source port used in NTP client requests can be set by the
|
|||||||
<<acquisitionport,*acquisitionport*>> directive.
|
<<acquisitionport,*acquisitionport*>> directive.
|
||||||
|
|
||||||
[[ratelimit]]*ratelimit* [_option_]...::
|
[[ratelimit]]*ratelimit* [_option_]...::
|
||||||
This directive enables response rate limiting for NTP packets. Its purpose is
|
This directive configures response rate limiting for NTP packets. Its purpose
|
||||||
to reduce network traffic with misconfigured or broken NTP clients that are
|
is to reduce network traffic with misconfigured or broken NTP clients that are
|
||||||
polling the server too frequently. The limits are applied to individual IP
|
polling the server too frequently. The limits are applied to individual IP
|
||||||
addresses. If multiple clients share one IP address (e.g. multiple hosts behind
|
addresses. If multiple clients share one IP address (e.g. multiple hosts behind
|
||||||
NAT), the sum of their traffic will be limited. If a client that increases its
|
NAT), the sum of their traffic will be limited. If a client that increases its
|
||||||
@@ -1236,33 +1237,40 @@ in any order):
|
|||||||
+
|
+
|
||||||
*interval*:::
|
*interval*:::
|
||||||
This option sets the minimum interval between responses. It is defined as a
|
This option sets the minimum interval between responses. It is defined as a
|
||||||
power of 2 in seconds. The default value is 3 (8 seconds). The minimum value
|
power of 2 in seconds. The default value is -10 (1/1024 of a second, or 1024
|
||||||
is -4 and the maximum value is 12.
|
packets per second). The minimum value is -19 (524288 packets per second) and
|
||||||
|
the maximum value is 12 (one packet per 4096 seconds). Note that with values
|
||||||
|
below -4 the rate limiting is coarse (responses are allowed in bursts, even if
|
||||||
|
the interval between them is shorter than the specified interval).
|
||||||
*burst*:::
|
*burst*:::
|
||||||
This option sets the maximum number of responses that can be sent in a burst,
|
This option sets the maximum number of responses that can be sent in a burst,
|
||||||
temporarily exceeding the limit specified by the *interval* option. This is
|
temporarily exceeding the limit specified by the *interval* option. This is
|
||||||
useful for clients that make rapid measurements on start (e.g. *chronyd* with
|
useful for clients that make rapid measurements on start (e.g. *chronyd* with
|
||||||
the *iburst* option). The default value is 8. The minimum value is 1 and the
|
the *iburst* option). The default value is 16. The minimum value is 1 and the
|
||||||
maximum value is 255.
|
maximum value is 255.
|
||||||
*leak*:::
|
*leak*:::
|
||||||
This option sets the rate at which responses are randomly allowed even if the
|
This option sets the rate at which responses are randomly allowed even if the
|
||||||
limits specified by the *interval* and *burst* options are exceeded. This is
|
limits specified by the *interval* and *burst* options are exceeded. This is
|
||||||
necessary to prevent an attacker who is sending requests with a spoofed
|
necessary to prevent an attacker who is sending requests with a spoofed
|
||||||
source address from completely blocking responses to that address. The leak
|
source address from completely blocking responses to that address. The leak
|
||||||
rate is defined as a power of 1/2 and it is 3 by default, i.e. on average at
|
rate is defined as a power of 1/2 and it is 2 by default, i.e. on average at
|
||||||
least every eighth request has a response. The minimum value is 1 and the
|
least every fourth request has a response. The minimum value is 0, which
|
||||||
maximum value is 4.
|
disables the rate limiting, and the maximum value is 4 (one response per 16
|
||||||
|
requests).
|
||||||
::
|
::
|
||||||
+
|
+
|
||||||
An example use of the directive is:
|
An example use of the directive is:
|
||||||
+
|
+
|
||||||
----
|
----
|
||||||
ratelimit interval 4 burst 4
|
ratelimit interval 1 burst 8
|
||||||
----
|
----
|
||||||
+
|
+
|
||||||
This would reduce the response rate for IP addresses that send packets on
|
This would reduce the response rate for IP addresses sending packets on average
|
||||||
average more frequently than once per 16 seconds or send packets in bursts
|
more than once per 2 seconds, or sending packets in bursts of more than 8
|
||||||
of more than 4 packets.
|
packets, by up to 75% (with default *leak* of 2).
|
||||||
|
+
|
||||||
|
Rate limiting can be disabled by setting the *leak* option to 0, or by the
|
||||||
|
<<noclientlog,*noclientlog*>> directive.
|
||||||
|
|
||||||
[[smoothtime]]*smoothtime* _max-freq_ _max-wander_ [*leaponly*]::
|
[[smoothtime]]*smoothtime* _max-freq_ _max-wander_ [*leaponly*]::
|
||||||
The *smoothtime* directive can be used to enable smoothing of the time that
|
The *smoothtime* directive can be used to enable smoothing of the time that
|
||||||
@@ -1389,16 +1397,18 @@ This would make *chronyd* use UDP 257 as its command port. (*chronyc* would
|
|||||||
need to be run with the *-p 257* switch to inter-operate correctly.)
|
need to be run with the *-p 257* switch to inter-operate correctly.)
|
||||||
|
|
||||||
[[cmdratelimit]]*cmdratelimit* [_option_]...::
|
[[cmdratelimit]]*cmdratelimit* [_option_]...::
|
||||||
This directive enables response rate limiting for command packets. It is
|
This directive is identical to the <<ratelimit,*ratelimit*>> directive, except
|
||||||
similar to the <<ratelimit,*ratelimit*>> directive, except responses to
|
it configures rate limiting for command packets and responses to localhost are
|
||||||
localhost are never limited and the default interval is 1 (2 seconds), the default
|
never limited. It is disabled by default (the default *leak* is 0).
|
||||||
burst is 16, and the default leak rate is 2.
|
|
||||||
+
|
+
|
||||||
An example of the use of the directive is:
|
An example of the use of the directive is:
|
||||||
+
|
+
|
||||||
----
|
----
|
||||||
cmdratelimit interval 2
|
cmdratelimit interval -2 burst 128 leak 2
|
||||||
----
|
----
|
||||||
|
+
|
||||||
|
This would reduce response rate for addresses that send more than 4 requests
|
||||||
|
per second, or bursts of more than 128 packets, by up to 75%.
|
||||||
|
|
||||||
=== Real-time clock (RTC)
|
=== Real-time clock (RTC)
|
||||||
|
|
||||||
@@ -1779,10 +1789,11 @@ received from the specified network interface. The network interface controller
|
|||||||
receptions, avoiding processing and queueing delays in the kernel, network
|
receptions, avoiding processing and queueing delays in the kernel, network
|
||||||
driver, and hardware. This can significantly improve the accuracy of the
|
driver, and hardware. This can significantly improve the accuracy of the
|
||||||
timestamps and the measured offset, which is used for synchronisation of the
|
timestamps and the measured offset, which is used for synchronisation of the
|
||||||
system clock. In order to get best results, it is necessary to enable HW
|
system clock. In order to get the best results, both sides receiving and
|
||||||
timestamping on both sides receiving and sending the packets (i.e. server and
|
sending NTP packets (i.e. server and client, or two peers) need to use HW
|
||||||
client, or both peers), and also enable the interleaved mode with the *xleave*
|
timestamping. If the server or peer supports the interleaved mode, it needs to
|
||||||
option in the <<server,*server*>> or the <<peer,*peer*>> directive.
|
be enabled by the *xleave* option in the <<server,*server*>> or the
|
||||||
|
<<peer,*peer*>> directive.
|
||||||
+
|
+
|
||||||
This directive is supported on Linux 3.19 and newer. The NIC must support HW
|
This directive is supported on Linux 3.19 and newer. The NIC must support HW
|
||||||
timestamping, which can be verified with the *ethtool -T* command. The list of
|
timestamping, which can be verified with the *ethtool -T* command. The list of
|
||||||
@@ -1799,6 +1810,9 @@ interfaces. The timestamping used in measurements is indicated in the
|
|||||||
_measurements.log_ file if enabled by the <<log,*log measurements*>> directive,
|
_measurements.log_ file if enabled by the <<log,*log measurements*>> directive,
|
||||||
and the <<chronyc.adoc#ntpdata,*ntpdata*>> report in *chronyc*.
|
and the <<chronyc.adoc#ntpdata,*ntpdata*>> report in *chronyc*.
|
||||||
+
|
+
|
||||||
|
If the specified interface is _*_, *chronyd* will try to enable HW timestamping
|
||||||
|
on all available interfaces.
|
||||||
|
+
|
||||||
An example of the directive is:
|
An example of the directive is:
|
||||||
+
|
+
|
||||||
----
|
----
|
||||||
@@ -2213,7 +2227,7 @@ http://www.pool.ntp.org/en/join.html[pool.ntp.org] project. The configuration
|
|||||||
is similar to the NTP client with permanent connection, except it needs to
|
is similar to the NTP client with permanent connection, except it needs to
|
||||||
allow client access from all addresses. It is recommended to handpick at least
|
allow client access from all addresses. It is recommended to handpick at least
|
||||||
few good servers, and possibly combine them with a random selection of other
|
few good servers, and possibly combine them with a random selection of other
|
||||||
servers in the pool. Rate limiting can be enabled to not waste too much
|
servers in the pool. The rate limiting interval can be increased to save more
|
||||||
bandwidth on misconfigured and broken NTP clients. The *-r* option with the
|
bandwidth on misconfigured and broken NTP clients. The *-r* option with the
|
||||||
*dumpdir* directive shortens the time for which *chronyd* will not serve time
|
*dumpdir* directive shortens the time for which *chronyd* will not serve time
|
||||||
to its clients when it needs to be restarted for any reason.
|
to its clients when it needs to be restarted for any reason.
|
||||||
@@ -2228,7 +2242,7 @@ pool pool.ntp.org iburst
|
|||||||
makestep 1.0 3
|
makestep 1.0 3
|
||||||
rtcsync
|
rtcsync
|
||||||
allow
|
allow
|
||||||
ratelimit interval 2 burst 10
|
ratelimit interval 1
|
||||||
driftfile @CHRONYVARDIR@/drift
|
driftfile @CHRONYVARDIR@/drift
|
||||||
dumpdir @CHRONYRUNDIR@
|
dumpdir @CHRONYRUNDIR@
|
||||||
dumponexit
|
dumponexit
|
||||||
|
|||||||
@@ -441,10 +441,10 @@ the offline state.
|
|||||||
the name of the server or peer was not resolved to an address yet; this source is
|
the name of the server or peer was not resolved to an address yet; this source is
|
||||||
not visible in the *sources* and *sourcestats* reports.
|
not visible in the *sources* and *sourcestats* reports.
|
||||||
|
|
||||||
[[ntpdata]]*ntpdata* _address_::
|
[[ntpdata]]*ntpdata* [_address_]::
|
||||||
The *ntpdata* command displays the last valid measurement and other
|
The *ntpdata* command displays the last valid measurement and other
|
||||||
NTP-specific information about the NTP source. An example of the output is
|
NTP-specific information about the specified NTP source, or all NTP sources if
|
||||||
shown below.
|
no address was specified. An example of the output is shown below.
|
||||||
+
|
+
|
||||||
----
|
----
|
||||||
Remote address : 203.0.113.15 (CB00710F)
|
Remote address : 203.0.113.15 (CB00710F)
|
||||||
@@ -454,8 +454,8 @@ Leap status : Normal
|
|||||||
Version : 4
|
Version : 4
|
||||||
Mode : Server
|
Mode : Server
|
||||||
Stratum : 1
|
Stratum : 1
|
||||||
Poll : 10
|
Poll interval : 10 (1024 seconds)
|
||||||
Precision : 0.000000060 seconds
|
Precision : -24 (0.000000060 seconds)
|
||||||
Root delay : 0.000015 seconds
|
Root delay : 0.000015 seconds
|
||||||
Root dispersion : 0.000015 seconds
|
Root dispersion : 0.000015 seconds
|
||||||
Reference ID : 50505331
|
Reference ID : 50505331
|
||||||
@@ -489,7 +489,7 @@ reference ID.
|
|||||||
*Version*:::
|
*Version*:::
|
||||||
*Mode*:::
|
*Mode*:::
|
||||||
*Stratum*:::
|
*Stratum*:::
|
||||||
*Poll*:::
|
*Poll interval*:::
|
||||||
*Precision*:::
|
*Precision*:::
|
||||||
*Root delay*:::
|
*Root delay*:::
|
||||||
*Root dispersion*:::
|
*Root dispersion*:::
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Wants=time-sync.target
|
|||||||
Type=oneshot
|
Type=oneshot
|
||||||
# Wait up to ~10 minutes for chronyd to synchronize and the remaining
|
# Wait up to ~10 minutes for chronyd to synchronize and the remaining
|
||||||
# clock correction to be less than 0.1 seconds
|
# clock correction to be less than 0.1 seconds
|
||||||
ExecStart=/usr/bin/chronyc waitsync 600 0.1 0.0 1
|
ExecStart=/usr/bin/chronyc -h 127.0.0.1,::1 waitsync 600 0.1 0.0 1
|
||||||
RemainAfterExit=yes
|
RemainAfterExit=yes
|
||||||
StandardOutput=null
|
StandardOutput=null
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,9 @@ DNS_Name2IPAddressAsync(const char *name, DNS_NameResolveHandler handler, void *
|
|||||||
LOG_FATAL(LOGF_Nameserv, "pipe() failed");
|
LOG_FATAL(LOGF_Nameserv, "pipe() failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UTI_FdSetCloexec(inst->pipe[0]);
|
||||||
|
UTI_FdSetCloexec(inst->pipe[1]);
|
||||||
|
|
||||||
resolving_threads++;
|
resolving_threads++;
|
||||||
assert(resolving_threads <= 1);
|
assert(resolving_threads <= 1);
|
||||||
|
|
||||||
|
|||||||
@@ -1453,11 +1453,12 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
|
|||||||
!(inst->mode == MODE_ACTIVE && interleaved_packet &&
|
!(inst->mode == MODE_ACTIVE && interleaved_packet &&
|
||||||
delay > UTI_Log2ToDouble(message->poll - 1));
|
delay > UTI_Log2ToDouble(message->poll - 1));
|
||||||
|
|
||||||
/* Test B requires that the ratio of the round trip delay to the
|
/* Test B requires in the basic client mode that the ratio of the round
|
||||||
minimum one currently in the stats data register is less than an
|
trip delay to the minimum one currently in the stats data register is
|
||||||
administrator-defined value */
|
less than an administrator-defined value */
|
||||||
testB = inst->max_delay_ratio <= 1.0 ||
|
testB = inst->max_delay_ratio <= 1.0 ||
|
||||||
(delay - dispersion) / SST_MinRoundTripDelay(stats) <= inst->max_delay_ratio;
|
!(inst->mode == MODE_CLIENT && !interleaved_packet &&
|
||||||
|
(delay - dispersion) / SST_MinRoundTripDelay(stats) > inst->max_delay_ratio);
|
||||||
|
|
||||||
/* Test C requires that the ratio of the increase in delay from the minimum
|
/* Test C requires that the ratio of the increase in delay from the minimum
|
||||||
one in the stats data register to the standard deviation of the offsets
|
one in the stats data register to the standard deviation of the offsets
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include "sysincl.h"
|
#include "sysincl.h"
|
||||||
|
|
||||||
|
#include <ifaddrs.h>
|
||||||
#include <linux/errqueue.h>
|
#include <linux/errqueue.h>
|
||||||
#include <linux/ethtool.h>
|
#include <linux/ethtool.h>
|
||||||
#include <linux/net_tstamp.h>
|
#include <linux/net_tstamp.h>
|
||||||
@@ -90,9 +91,16 @@ add_interface(const char *name)
|
|||||||
struct hwtstamp_config ts_config;
|
struct hwtstamp_config ts_config;
|
||||||
struct ifreq req;
|
struct ifreq req;
|
||||||
int sock_fd, if_index, phc_index, phc_fd;
|
int sock_fd, if_index, phc_index, phc_fd;
|
||||||
|
unsigned int i;
|
||||||
struct Interface *iface;
|
struct Interface *iface;
|
||||||
char phc_path[64];
|
char phc_path[64];
|
||||||
|
|
||||||
|
/* Check if the interface was not already added */
|
||||||
|
for (i = 0; i < ARR_GetSize(interfaces); i++) {
|
||||||
|
if (!strcmp(name, ((struct Interface *)ARR_GetElement(interfaces, i))->name))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (sock_fd < 0)
|
if (sock_fd < 0)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -160,11 +168,37 @@ add_interface(const char *name)
|
|||||||
|
|
||||||
iface->clock = HCL_CreateInstance();
|
iface->clock = HCL_CreateInstance();
|
||||||
|
|
||||||
|
DEBUG_LOG(LOGF_NtpIOLinux, "Enabled HW timestamping on %s", name);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
static int
|
||||||
|
add_all_interfaces(void)
|
||||||
|
{
|
||||||
|
struct ifaddrs *ifaddr, *ifa;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (getifaddrs(&ifaddr)) {
|
||||||
|
DEBUG_LOG(LOGF_NtpIOLinux, "getifaddrs() failed : %s", strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (r = 0, ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
|
||||||
|
if (add_interface(ifa->ifa_name))
|
||||||
|
r = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
freeifaddrs(ifaddr);
|
||||||
|
|
||||||
|
/* Return success if at least one interface was added */
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_interface_speed(struct Interface *iface)
|
update_interface_speed(struct Interface *iface)
|
||||||
{
|
{
|
||||||
@@ -202,19 +236,34 @@ NIO_Linux_Initialise(void)
|
|||||||
ARR_Instance config_hwts_ifaces;
|
ARR_Instance config_hwts_ifaces;
|
||||||
char *if_name;
|
char *if_name;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
int wildcard, hwts;
|
||||||
|
|
||||||
interfaces = ARR_CreateInstance(sizeof (struct Interface));
|
interfaces = ARR_CreateInstance(sizeof (struct Interface));
|
||||||
|
|
||||||
config_hwts_ifaces = CNF_GetHwTsInterfaces();
|
config_hwts_ifaces = CNF_GetHwTsInterfaces();
|
||||||
|
|
||||||
/* Enable HW timestamping on all specified interfaces. If no interface was
|
/* Enable HW timestamping on specified interfaces. If "*" was specified, try
|
||||||
specified, use SW timestamping. */
|
all interfaces. If no interface was specified, enable SW timestamping. */
|
||||||
if (ARR_GetSize(config_hwts_ifaces)) {
|
|
||||||
|
for (i = wildcard = 0; i < ARR_GetSize(config_hwts_ifaces); i++) {
|
||||||
|
if (!strcmp("*", *(char **)ARR_GetElement(config_hwts_ifaces, i)))
|
||||||
|
wildcard = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wildcard && ARR_GetSize(config_hwts_ifaces)) {
|
||||||
for (i = 0; i < ARR_GetSize(config_hwts_ifaces); i++) {
|
for (i = 0; i < ARR_GetSize(config_hwts_ifaces); i++) {
|
||||||
if_name = *(char **)ARR_GetElement(config_hwts_ifaces, i);
|
if_name = *(char **)ARR_GetElement(config_hwts_ifaces, i);
|
||||||
if (!add_interface(if_name))
|
if (!add_interface(if_name))
|
||||||
LOG_FATAL(LOGF_NtpIO, "Could not enable HW timestamping on %s", if_name);
|
LOG_FATAL(LOGF_NtpIO, "Could not enable HW timestamping on %s", if_name);
|
||||||
}
|
}
|
||||||
|
hwts = 1;
|
||||||
|
} else if (wildcard && add_all_interfaces()) {
|
||||||
|
hwts = 1;
|
||||||
|
} else {
|
||||||
|
hwts = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hwts) {
|
||||||
ts_flags = SOF_TIMESTAMPING_RAW_HARDWARE | SOF_TIMESTAMPING_RX_HARDWARE;
|
ts_flags = SOF_TIMESTAMPING_RAW_HARDWARE | SOF_TIMESTAMPING_RX_HARDWARE;
|
||||||
ts_tx_flags = SOF_TIMESTAMPING_TX_HARDWARE;
|
ts_tx_flags = SOF_TIMESTAMPING_TX_HARDWARE;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -47,8 +47,12 @@
|
|||||||
2000ppm, which would be pretty bad */
|
2000ppm, which would be pretty bad */
|
||||||
#define WORST_CASE_FREQ_BOUND (2000.0/1.0e6)
|
#define WORST_CASE_FREQ_BOUND (2000.0/1.0e6)
|
||||||
|
|
||||||
/* The minimum allowed skew */
|
/* The minimum and maximum assumed skew */
|
||||||
#define MIN_SKEW 1.0e-12
|
#define MIN_SKEW 1.0e-12
|
||||||
|
#define MAX_SKEW 1.0e+02
|
||||||
|
|
||||||
|
/* The minimum assumed std dev for weighting */
|
||||||
|
#define MIN_WEIGHT_SD 1.0e-9
|
||||||
|
|
||||||
/* The asymmetry of network jitter when all jitter is in one direction */
|
/* The asymmetry of network jitter when all jitter is in one direction */
|
||||||
#define MAX_ASYMMETRY 0.5
|
#define MAX_ASYMMETRY 0.5
|
||||||
@@ -507,8 +511,7 @@ SST_DoNewRegression(SST_Stats inst)
|
|||||||
/* And now, work out the weight vector */
|
/* And now, work out the weight vector */
|
||||||
|
|
||||||
sd = mean_distance - min_distance;
|
sd = mean_distance - min_distance;
|
||||||
if (sd > min_distance || sd <= 0.0)
|
sd = CLAMP(MIN_WEIGHT_SD, sd, min_distance);
|
||||||
sd = min_distance;
|
|
||||||
|
|
||||||
for (i=0; i<inst->n_samples; i++) {
|
for (i=0; i<inst->n_samples; i++) {
|
||||||
sd_weight = 1.0 + SD_TO_DIST_RATIO * (peer_distances[i] - min_distance) / sd;
|
sd_weight = 1.0 + SD_TO_DIST_RATIO * (peer_distances[i] - min_distance) / sd;
|
||||||
@@ -539,9 +542,7 @@ SST_DoNewRegression(SST_Stats inst)
|
|||||||
inst->std_dev = sqrt(est_var);
|
inst->std_dev = sqrt(est_var);
|
||||||
inst->nruns = nruns;
|
inst->nruns = nruns;
|
||||||
|
|
||||||
if (inst->skew < MIN_SKEW)
|
inst->skew = CLAMP(MIN_SKEW, inst->skew, MAX_SKEW);
|
||||||
inst->skew = MIN_SKEW;
|
|
||||||
|
|
||||||
stress = fabs(old_freq - inst->estimated_frequency) / old_skew;
|
stress = fabs(old_freq - inst->estimated_frequency) / old_skew;
|
||||||
|
|
||||||
DEBUG_LOG(LOGF_SourceStats, "off=%e freq=%e skew=%e n=%d bs=%d runs=%d asym=%f arun=%d",
|
DEBUG_LOG(LOGF_SourceStats, "off=%e freq=%e skew=%e n=%d bs=%d runs=%d asym=%f arun=%d",
|
||||||
@@ -844,6 +845,8 @@ SST_SaveToFile(SST_Stats inst, FILE *out)
|
|||||||
inst->strata[j]);
|
inst->strata[j]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fprintf(out, "%d\n", inst->asymmetry_run);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
@@ -898,6 +901,10 @@ SST_LoadFromFile(SST_Stats inst, FILE *in)
|
|||||||
UTI_NormaliseTimespec(&inst->sample_times[i]);
|
UTI_NormaliseTimespec(&inst->sample_times[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This field was not saved in older versions */
|
||||||
|
if (!fgets(line, sizeof(line), in) || sscanf(line, "%d\n", &inst->asymmetry_run) != 1)
|
||||||
|
inst->asymmetry_run = 0;
|
||||||
} else {
|
} else {
|
||||||
inst->n_samples = 0; /* Load abandoned if any sign of corruption */
|
inst->n_samples = 0; /* Load abandoned if any sign of corruption */
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
20
stubs.c
20
stubs.c
@@ -42,6 +42,7 @@
|
|||||||
#include "privops.h"
|
#include "privops.h"
|
||||||
#include "refclock.h"
|
#include "refclock.h"
|
||||||
#include "sched.h"
|
#include "sched.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#ifndef FEAT_ASYNCDNS
|
#ifndef FEAT_ASYNCDNS
|
||||||
|
|
||||||
@@ -51,10 +52,11 @@ struct DNS_Async_Instance {
|
|||||||
const char *name;
|
const char *name;
|
||||||
DNS_NameResolveHandler handler;
|
DNS_NameResolveHandler handler;
|
||||||
void *arg;
|
void *arg;
|
||||||
|
int pipe[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
resolve_name(void *anything)
|
resolve_name(int fd, int event, void *anything)
|
||||||
{
|
{
|
||||||
struct DNS_Async_Instance *inst;
|
struct DNS_Async_Instance *inst;
|
||||||
IPAddr addrs[DNS_MAX_ADDRESSES];
|
IPAddr addrs[DNS_MAX_ADDRESSES];
|
||||||
@@ -62,6 +64,11 @@ resolve_name(void *anything)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
inst = (struct DNS_Async_Instance *)anything;
|
inst = (struct DNS_Async_Instance *)anything;
|
||||||
|
|
||||||
|
SCH_RemoveFileHandler(inst->pipe[0]);
|
||||||
|
close(inst->pipe[0]);
|
||||||
|
close(inst->pipe[1]);
|
||||||
|
|
||||||
status = PRV_Name2IPAddress(inst->name, addrs, DNS_MAX_ADDRESSES);
|
status = PRV_Name2IPAddress(inst->name, addrs, DNS_MAX_ADDRESSES);
|
||||||
|
|
||||||
for (i = 0; status == DNS_Success && i < DNS_MAX_ADDRESSES &&
|
for (i = 0; status == DNS_Success && i < DNS_MAX_ADDRESSES &&
|
||||||
@@ -83,7 +90,16 @@ DNS_Name2IPAddressAsync(const char *name, DNS_NameResolveHandler handler, void *
|
|||||||
inst->handler = handler;
|
inst->handler = handler;
|
||||||
inst->arg = anything;
|
inst->arg = anything;
|
||||||
|
|
||||||
SCH_AddTimeoutByDelay(0.0, resolve_name, inst);
|
if (pipe(inst->pipe))
|
||||||
|
LOG_FATAL(LOGF_Nameserv, "pipe() failed");
|
||||||
|
|
||||||
|
UTI_FdSetCloexec(inst->pipe[0]);
|
||||||
|
UTI_FdSetCloexec(inst->pipe[1]);
|
||||||
|
|
||||||
|
SCH_AddFileHandler(inst->pipe[0], SCH_FILE_INPUT, resolve_name, inst);
|
||||||
|
|
||||||
|
if (write(inst->pipe[1], "", 1) < 0)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !FEAT_ASYNCDNS */
|
#endif /* !FEAT_ASYNCDNS */
|
||||||
|
|||||||
Reference in New Issue
Block a user