Compare commits
3 commits
master
...
fix-ipv6-i
Author | SHA1 | Date | |
---|---|---|---|
46919561ad | |||
b814b7cef3 | |||
|
12237bf283 |
8 changed files with 131 additions and 27 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -26,3 +26,9 @@ tags
|
||||||
/test/unit/Makefile
|
/test/unit/Makefile
|
||||||
/test/unit/*.test
|
/test/unit/*.test
|
||||||
/test/unit/*.o
|
/test/unit/*.o
|
||||||
|
|
||||||
|
# Build
|
||||||
|
/cmake-build-*/
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
/.idea/
|
||||||
|
|
46
CMakeLists.txt
Normal file
46
CMakeLists.txt
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
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"
|
||||||
|
)
|
|
@ -45,7 +45,7 @@ typedef struct {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
} addr;
|
} addr;
|
||||||
uint16_t family;
|
uint16_t family;
|
||||||
uint16_t _pad;
|
uint16_t interface;
|
||||||
} IPAddr;
|
} IPAddr;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -661,14 +661,13 @@ 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 length of the median filter which is used to reduce the
|
This option sets the maximum number of samples that can be stored in the median
|
||||||
noise in the measurements. With each poll about 40 percent of the stored
|
filter between polls of the source. The filter combines about 60 percent of the
|
||||||
samples are discarded and one final sample is calculated as an average of the
|
samples closest to the median offset into one sample. If more samples are
|
||||||
remaining samples. If the length is 4 or more, at least 4 samples have to be
|
received by the driver between polls, the oldest samples will be dropped. One
|
||||||
collected between polls. For lengths below 4, the filter has to be full. The
|
sample per poll is sufficient for the source to be selectable. The default
|
||||||
default is 64. With drivers that perform their own polling (PPS, PHC, SHM), the
|
is 64. Note that the PHC driver has additional filtering based on the reading
|
||||||
maximum value is adjusted to the number of driver polls per source poll, i.e.
|
delay.
|
||||||
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*:::
|
||||||
|
|
14
refclock.c
14
refclock.c
|
@ -233,12 +233,10 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -246,11 +244,9 @@ 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);
|
||||||
|
|
||||||
/* Require the filter to have at least 4 samples to produce a filtered
|
/* Don't require more than one sample per poll and combine 60% of the
|
||||||
sample, or be full for shorter lengths, and combine 60% of samples
|
samples closest to the median offset */
|
||||||
closest to the median */
|
inst->filter = SPF_CreateInstance(1, params->filter_length, params->max_dispersion, 0.6);
|
||||||
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,
|
||||||
|
|
1
socket.c
1
socket.c
|
@ -1785,6 +1785,7 @@ 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);
|
||||||
|
|
|
@ -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=80
|
min_sync_time=180
|
||||||
max_sync_time=180
|
max_sync_time=260
|
||||||
chronyc_start=220
|
chronyc_start=270
|
||||||
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,6 +112,30 @@ 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
44
util.c
|
@ -32,6 +32,9 @@
|
||||||
#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
|
||||||
|
@ -302,13 +305,21 @@ 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]));
|
(unsigned int)(ip6[2 * a] << 8 | ip6[2 * a + 1]));_pad
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case IPADDR_ID:
|
case IPADDR_ID:
|
||||||
|
@ -332,15 +343,35 @@ 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->_pad = 0;
|
ip->interface = 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
|
||||||
if (inet_pton(AF_INET6, addr, &in6) > 0) {
|
// split the address into an IP and an interface.
|
||||||
|
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->_pad = 0;
|
ip->interface = addr_if_index;
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -366,7 +397,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->_pad = 0;
|
ip->interface = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,6 +497,7 @@ 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);
|
||||||
|
@ -481,7 +513,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->_pad = 0;
|
dest->interface = src->interface;
|
||||||
|
|
||||||
switch (dest->family) {
|
switch (dest->family) {
|
||||||
case IPADDR_INET4:
|
case IPADDR_INET4:
|
||||||
|
|
Loading…
Reference in a new issue