Compare commits

..

No commits in common. "fix-ipv6-interface" and "master" have entirely different histories.

8 changed files with 27 additions and 131 deletions

6
.gitignore vendored
View file

@ -26,9 +26,3 @@ tags
/test/unit/Makefile /test/unit/Makefile
/test/unit/*.test /test/unit/*.test
/test/unit/*.o /test/unit/*.o
# Build
/cmake-build-*/
# IDE
/.idea/

View file

@ -1,46 +0,0 @@
cmake_minimum_required(VERSION 3.10)
project(chrony)
# Directories configuration
set(SYSCONFDIR "/etc")
set(BINDIR "/usr/local/bin")
set(SBINDIR "/usr/local/sbin")
set(LOCALSTATEDIR "/var")
set(CHRONYVARDIR "/var/lib/chrony")
set(DESTDIR "")
# Compiler and flags
set(CMAKE_C_FLAGS "-g -D_FORTIFY_SOURCE=2 -fPIE -fstack-protector-strong --param=ssp-buffer-size=4 -Wmissing-prototypes -Wall -pthread")
set(CMAKE_EXE_LINKER_FLAGS "-pie -Wl,-z,relro,-z,now")
# Targets
add_executable(chronyd
sys_generic.c sys_linux.c sys_timex.c sys_posix.c cmdmon.c manual.c pktlength.c ntp_auth.c ntp_core.c ntp_ext.c ntp_io.c
ntp_sources.c addrfilt.c clientlog.c keys.c nameserv.c refclock.c refclock_phc.c refclock_pps.c refclock_shm.c
refclock_sock.c nameserv_async.c hwclock.c ntp_io_linux.c rtc_linux.c hash_intmd5.c cmac_gnutls.c
nts_ntp_client.c
array.c cmdparse.c conf.c leapdb.c local.c logging.c main.c memory.c quantiles.c reference.c regress.c rtc.c samplefilt.c
sched.c socket.c sources.c sourcestats.c stubs.c smooth.c sys.c sys_null.c tempcomp.c util.c
nts_ntp_auth.c siv_gnutls.c nts_ke_client.c nts_ke_session.c nts_ntp_server.c nts_ke_server.c
)
add_executable(chronyc
array.c client.c cmdparse.c getdate.c memory.c nameserv.c pktlength.c socket.c util.c hash_intmd5.c cmac_gnutls.c)
# Libraries
target_link_libraries(chronyd m gnutls)
target_link_libraries(chronyc m edit gnutls)
# Install commands
install(TARGETS chronyd DESTINATION ${DESTDIR}${SBINDIR})
install(TARGETS chronyc DESTINATION ${DESTDIR}${BINDIR})
# Docs
add_custom_target(docs
COMMAND ${CMAKE_MAKE_PROGRAM} -C doc docs
COMMENT "Building documentation"
)
add_custom_target(install-docs
COMMAND ${CMAKE_MAKE_PROGRAM} -C doc install-docs
COMMENT "Installing documentation"
)

View file

@ -45,7 +45,7 @@ typedef struct {
uint32_t id; uint32_t id;
} addr; } addr;
uint16_t family; uint16_t family;
uint16_t interface; uint16_t _pad;
} IPAddr; } IPAddr;
typedef struct { typedef struct {

View file

@ -661,13 +661,14 @@ value is the estimated precision of the system clock.
Maximum allowed dispersion for filtered samples (in seconds). Samples with Maximum allowed dispersion for filtered samples (in seconds). Samples with
larger estimated dispersion are ignored. By default, this limit is disabled. larger estimated dispersion are ignored. By default, this limit is disabled.
*filter* _samples_::: *filter* _samples_:::
This option sets the maximum number of samples that can be stored in the median This option sets the length of the median filter which is used to reduce the
filter between polls of the source. The filter combines about 60 percent of the noise in the measurements. With each poll about 40 percent of the stored
samples closest to the median offset into one sample. If more samples are samples are discarded and one final sample is calculated as an average of the
received by the driver between polls, the oldest samples will be dropped. One remaining samples. If the length is 4 or more, at least 4 samples have to be
sample per poll is sufficient for the source to be selectable. The default collected between polls. For lengths below 4, the filter has to be full. The
is 64. Note that the PHC driver has additional filtering based on the reading default is 64. With drivers that perform their own polling (PPS, PHC, SHM), the
delay. maximum value is adjusted to the number of driver polls per source poll, i.e.
2^(_poll_ - _dpoll_).
*prefer*::: *prefer*:::
Prefer this source over other selectable sources without the *prefer* option. Prefer this source over other selectable sources without the *prefer* option.
*noselect*::: *noselect*:::

View file

@ -233,10 +233,12 @@ RCL_AddRefclock(RefclockParameters *params)
if (inst->driver_poll > inst->poll) if (inst->driver_poll > inst->poll)
inst->driver_poll = inst->poll; inst->driver_poll = inst->poll;
/* Adjust the filter length to save memory if the expected number
of samples is smaller */
max_samples = 1 << (inst->poll - inst->driver_poll); max_samples = 1 << (inst->poll - inst->driver_poll);
if (max_samples < params->filter_length) { if (max_samples < params->filter_length) {
if (max_samples < 4) {
LOG(LOGS_WARN, "Setting filter length for %s to %d",
UTI_RefidToString(inst->ref_id), max_samples);
}
params->filter_length = max_samples; params->filter_length = max_samples;
} }
} }
@ -244,9 +246,11 @@ RCL_AddRefclock(RefclockParameters *params)
if (inst->driver->init && !inst->driver->init(inst)) if (inst->driver->init && !inst->driver->init(inst))
LOG_FATAL("refclock %s initialisation failed", params->driver_name); LOG_FATAL("refclock %s initialisation failed", params->driver_name);
/* Don't require more than one sample per poll and combine 60% of the /* Require the filter to have at least 4 samples to produce a filtered
samples closest to the median offset */ sample, or be full for shorter lengths, and combine 60% of samples
inst->filter = SPF_CreateInstance(1, params->filter_length, params->max_dispersion, 0.6); closest to the median */
inst->filter = SPF_CreateInstance(MIN(params->filter_length, 4), params->filter_length,
params->max_dispersion, 0.6);
inst->source = SRC_CreateNewInstance(inst->ref_id, SRC_REFCLOCK, 0, params->sel_options, inst->source = SRC_CreateNewInstance(inst->ref_id, SRC_REFCLOCK, 0, params->sel_options,
NULL, params->min_samples, params->max_samples, NULL, params->min_samples, params->max_samples,

View file

@ -1785,7 +1785,6 @@ SCK_IPSockAddrToSockaddr(IPSockAddr *ip_sa, struct sockaddr *sa, int sa_length)
return 0; return 0;
memset(sa, 0, sizeof (struct sockaddr_in6)); memset(sa, 0, sizeof (struct sockaddr_in6));
sa->sa_family = AF_INET6; sa->sa_family = AF_INET6;
((struct sockaddr_in6 *)sa)->sin6_scope_id = ip_sa->ip_addr.interface;
memcpy(&((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr, ip_sa->ip_addr.addr.in6, memcpy(&((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr, ip_sa->ip_addr.addr.in6,
sizeof (((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr)); sizeof (((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr));
((struct sockaddr_in6 *)sa)->sin6_port = htons(ip_sa->port); ((struct sockaddr_in6 *)sa)->sin6_port = htons(ip_sa->port);

View file

@ -89,9 +89,9 @@ Root delay : 0\.000000001 seconds
check_file_messages "20.* PPS1.*- N " 60 63 refclocks.log || test_fail check_file_messages "20.* PPS1.*- N " 60 63 refclocks.log || test_fail
rm -f tmp/refclocks.log rm -f tmp/refclocks.log
min_sync_time=180 min_sync_time=80
max_sync_time=260 max_sync_time=180
chronyc_start=270 chronyc_start=220
client_conf=" client_conf="
refclock SHM 0 refid NMEA offset 0.35 delay 0.1 refclock SHM 0 refid NMEA offset 0.35 delay 0.1
refclock PPS /dev/pps0 refclock PPS /dev/pps0
@ -112,30 +112,6 @@ Root delay : 0\.000000001 seconds
check_file_messages "20.* PPS1.*[0-9] N " 800 960 refclocks.log || test_fail check_file_messages "20.* PPS1.*[0-9] N " 800 960 refclocks.log || test_fail
check_file_messages "20.* PPS1.*- N " 50 63 refclocks.log || test_fail check_file_messages "20.* PPS1.*- N " 50 63 refclocks.log || test_fail
rm -f tmp/refclocks.log rm -f tmp/refclocks.log
min_sync_time=80
max_sync_time=180
chronyc_start=220
# Swapped order of SHM and PPS impacts first accepted sample
client_conf="
refclock PPS /dev/pps0
refclock SHM 0 refid NMEA offset 0.35 delay 0.1
logdir tmp
log refclocks
maxupdateskew 10000"
run_test || test_fail
check_chronyd_exit || test_fail
check_source_selection || test_fail
check_sync || test_fail
check_chronyc_output "^Reference ID.*50505330 \(PPS0\)
Stratum.*: 1
.*
Root delay : 0\.000000001 seconds
.*$" || test_fail
check_file_messages "20.* PPS0.*[0-9] N " 800 960 refclocks.log || test_fail
check_file_messages "20.* PPS0.*- N " 50 63 refclocks.log || test_fail
fi fi
export CLKNETSIM_PHC_JITTER_OFF=$[2 * 25 * 492] export CLKNETSIM_PHC_JITTER_OFF=$[2 * 25 * 492]

44
util.c
View file

@ -32,9 +32,6 @@
#include "logging.h" #include "logging.h"
#include "memory.h" #include "memory.h"
#include "util.h" #include "util.h"
#include <net/if.h>
#include "hash.h" #include "hash.h"
#define NSEC_PER_SEC 1000000000 #define NSEC_PER_SEC 1000000000
@ -305,21 +302,13 @@ UTI_IPToString(const IPAddr *addr)
break; break;
case IPADDR_INET6: case IPADDR_INET6:
ip6 = addr->addr.in6; ip6 = addr->addr.in6;
uint16_t interface = addr->interface;
#ifdef FEAT_IPV6 #ifdef FEAT_IPV6
// compose the IPv6
inet_ntop(AF_INET6, ip6, result, BUFFER_LENGTH); inet_ntop(AF_INET6, ip6, result, BUFFER_LENGTH);
// if used, append the interface name
if (interface != 0) {
char* result_if_delimiter = result + strlen(result);
*result_if_delimiter = '%';
if_indextoname(interface, result_if_delimiter + 1);
}
#else #else
assert(BUFFER_LENGTH >= 40); assert(BUFFER_LENGTH >= 40);
for (a = 0; a < 8; a++) for (a = 0; a < 8; a++)
snprintf(result + a * 5, 40 - a * 5, "%04x:", snprintf(result + a * 5, 40 - a * 5, "%04x:",
(unsigned int)(ip6[2 * a] << 8 | ip6[2 * a + 1]));_pad (unsigned int)(ip6[2 * a] << 8 | ip6[2 * a + 1]));
#endif #endif
break; break;
case IPADDR_ID: case IPADDR_ID:
@ -343,35 +332,15 @@ UTI_StringToIP(const char *addr, IPAddr *ip)
if (inet_pton(AF_INET, addr, &in4) > 0) { if (inet_pton(AF_INET, addr, &in4) > 0) {
ip->family = IPADDR_INET4; ip->family = IPADDR_INET4;
ip->interface = 0; ip->_pad = 0;
ip->addr.in4 = ntohl(in4.s_addr); ip->addr.in4 = ntohl(in4.s_addr);
return 1; return 1;
} }
#ifdef FEAT_IPV6 #ifdef FEAT_IPV6
// split the address into an IP and an interface. if (inet_pton(AF_INET6, addr, &in6) > 0) {
char addr_ip[INET6_ADDRSTRLEN];
strncpy(addr_ip, addr, sizeof(addr_ip));
char *addr_if = strchr(addr_ip, '%');
// prepare the interface index
unsigned int addr_if_index = 0;
// check if an interface is specified
if (addr_if != NULL) {
// split the string into two string, by replacing the "%" into an end-of-string
*addr_if = '\0';
// the interface will now start on the next character
addr_if++;
// get the index of the interface
addr_if_index = if_nametoindex(addr_if);
if (addr_if_index == 0)
return 0;
}
if (inet_pton(AF_INET6, addr_ip, &in6) > 0) {
ip->family = IPADDR_INET6; ip->family = IPADDR_INET6;
ip->interface = addr_if_index; ip->_pad = 0;
memcpy(ip->addr.in6, in6.s6_addr, sizeof (ip->addr.in6)); memcpy(ip->addr.in6, in6.s6_addr, sizeof (ip->addr.in6));
return 1; return 1;
} }
@ -397,7 +366,7 @@ UTI_StringToIdIP(const char *addr, IPAddr *ip)
{ {
if (sscanf(addr, "ID#%"SCNu32, &ip->addr.id) == 1) { if (sscanf(addr, "ID#%"SCNu32, &ip->addr.id) == 1) {
ip->family = IPADDR_ID; ip->family = IPADDR_ID;
ip->interface = 0; ip->_pad = 0;
return 1; return 1;
} }
@ -497,7 +466,6 @@ UTI_IPHostToNetwork(const IPAddr *src, IPAddr *dest)
break; break;
case IPADDR_INET6: case IPADDR_INET6:
memcpy(dest->addr.in6, src->addr.in6, sizeof (dest->addr.in6)); memcpy(dest->addr.in6, src->addr.in6, sizeof (dest->addr.in6));
dest->interface = src->interface;
break; break;
case IPADDR_ID: case IPADDR_ID:
dest->addr.id = htonl(src->addr.id); dest->addr.id = htonl(src->addr.id);
@ -513,7 +481,7 @@ void
UTI_IPNetworkToHost(const IPAddr *src, IPAddr *dest) UTI_IPNetworkToHost(const IPAddr *src, IPAddr *dest)
{ {
dest->family = ntohs(src->family); dest->family = ntohs(src->family);
dest->interface = src->interface; dest->_pad = 0;
switch (dest->family) { switch (dest->family) {
case IPADDR_INET4: case IPADDR_INET4: