ntp: support per-source IP family restriction
Add a new parameter to the NSR_AddSourceByName() function to allow individual sources to be limited to IPv4 or IPv6 addresses. This doesn't change the options passed to the resolver. It's just an additional filter in the processing of resolved addresses following the -4/-6 command-line option of chronyd.
This commit is contained in:
parent
e11b518a1f
commit
d7c2b1d2f3
6 changed files with 38 additions and 17 deletions
2
cmdmon.c
2
cmdmon.c
|
@ -789,7 +789,7 @@ handle_add_source(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
NTP_EF_FLAG_EXP_NET_CORRECTION : 0);
|
||||
params.sel_options = convert_addsrc_select_options(ntohl(rx_message->data.ntp_source.flags));
|
||||
|
||||
status = NSR_AddSourceByName(name, port, pool, type, ¶ms, NULL);
|
||||
status = NSR_AddSourceByName(name, IPADDR_UNSPEC, port, pool, type, ¶ms, NULL);
|
||||
switch (status) {
|
||||
case NSR_Success:
|
||||
break;
|
||||
|
|
9
conf.c
9
conf.c
|
@ -1728,8 +1728,9 @@ reload_source_dirs(void)
|
|||
/* Add new sources */
|
||||
if (pass == 1 && d > 0) {
|
||||
source = &new_sources[j];
|
||||
s = NSR_AddSourceByName(source->params.name, source->params.port, source->pool,
|
||||
source->type, &source->params.params, &new_ids[j]);
|
||||
s = NSR_AddSourceByName(source->params.name, IPADDR_UNSPEC, source->params.port,
|
||||
source->pool, source->type, &source->params.params,
|
||||
&new_ids[j]);
|
||||
|
||||
if (s == NSR_UnresolvedName) {
|
||||
unresolved++;
|
||||
|
@ -1842,8 +1843,8 @@ CNF_AddSources(void)
|
|||
for (i = 0; i < ARR_GetSize(ntp_sources); i++) {
|
||||
source = (NTP_Source *)ARR_GetElement(ntp_sources, i);
|
||||
|
||||
s = NSR_AddSourceByName(source->params.name, source->params.port, source->pool,
|
||||
source->type, &source->params.params, NULL);
|
||||
s = NSR_AddSourceByName(source->params.name, IPADDR_UNSPEC, source->params.port,
|
||||
source->pool, source->type, &source->params.params, NULL);
|
||||
if (s != NSR_Success && s != NSR_UnresolvedName)
|
||||
LOG(LOGS_ERR, "Could not add source %s", source->params.name);
|
||||
|
||||
|
|
|
@ -61,6 +61,8 @@ typedef struct {
|
|||
(may be an IP address) */
|
||||
IPAddr resolved_addr; /* Address resolved from the name, which can be
|
||||
different from remote_addr (e.g. NTS-KE) */
|
||||
int family; /* IP family of acceptable resolved addresses
|
||||
(IPADDR_UNSPEC if any) */
|
||||
int pool_id; /* ID of the pool from which was this source
|
||||
added or INVALID_POOL */
|
||||
int tentative; /* Flag indicating there was no valid response
|
||||
|
@ -98,6 +100,8 @@ struct UnresolvedSource {
|
|||
int pool_id;
|
||||
/* Name to be resolved */
|
||||
char *name;
|
||||
/* Address family to filter resolved addresses */
|
||||
int family;
|
||||
/* Flag indicating addresses should be used in a random order */
|
||||
int random_order;
|
||||
/* Flag indicating current address should be replaced only if it is
|
||||
|
@ -353,7 +357,7 @@ log_source(SourceRecord *record, int addition, int once_per_pool)
|
|||
|
||||
/* Procedure to add a new source */
|
||||
static NSR_Status
|
||||
add_source(NTP_Remote_Address *remote_addr, char *name, NTP_Source_Type type,
|
||||
add_source(NTP_Remote_Address *remote_addr, char *name, int family, NTP_Source_Type type,
|
||||
SourceParameters *params, int pool_id, uint32_t conf_id)
|
||||
{
|
||||
SourceRecord *record;
|
||||
|
@ -391,6 +395,7 @@ add_source(NTP_Remote_Address *remote_addr, char *name, NTP_Source_Type type,
|
|||
record->data = NCR_CreateInstance(remote_addr, type, params, record->name);
|
||||
record->remote_addr = NCR_GetRemoteAddress(record->data);
|
||||
record->resolved_addr = remote_addr->ip_addr;
|
||||
record->family = family;
|
||||
record->pool_id = pool_id;
|
||||
record->tentative = 1;
|
||||
record->conf_id = conf_id;
|
||||
|
@ -552,6 +557,10 @@ process_resolved_name(struct UnresolvedSource *us, IPAddr *ip_addrs, int n_addrs
|
|||
|
||||
DEBUG_LOG("(%d) %s", i + 1, UTI_IPToString(&new_addr.ip_addr));
|
||||
|
||||
/* Skip addresses not from the requested family */
|
||||
if (us->family != IPADDR_UNSPEC && us->family != new_addr.ip_addr.family)
|
||||
continue;
|
||||
|
||||
if (us->pool_id != INVALID_POOL) {
|
||||
/* In the pool resolving mode, try to replace a source from
|
||||
the pool which does not have a real address yet */
|
||||
|
@ -768,14 +777,14 @@ NSR_Status
|
|||
NSR_AddSource(NTP_Remote_Address *remote_addr, NTP_Source_Type type,
|
||||
SourceParameters *params, uint32_t *conf_id)
|
||||
{
|
||||
return add_source(remote_addr, NULL, type, params, INVALID_POOL,
|
||||
return add_source(remote_addr, NULL, IPADDR_UNSPEC, type, params, INVALID_POOL,
|
||||
get_next_conf_id(conf_id));
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
NSR_Status
|
||||
NSR_AddSourceByName(char *name, int port, int pool, NTP_Source_Type type,
|
||||
NSR_AddSourceByName(char *name, int family, int port, int pool, NTP_Source_Type type,
|
||||
SourceParameters *params, uint32_t *conf_id)
|
||||
{
|
||||
struct UnresolvedSource *us;
|
||||
|
@ -787,7 +796,9 @@ NSR_AddSourceByName(char *name, int port, int pool, NTP_Source_Type type,
|
|||
/* If the name is an IP address, add the source with the address directly */
|
||||
if (UTI_StringToIP(name, &remote_addr.ip_addr)) {
|
||||
remote_addr.port = port;
|
||||
return add_source(&remote_addr, name, type, params, INVALID_POOL,
|
||||
if (family != IPADDR_UNSPEC && family != remote_addr.ip_addr.family)
|
||||
return NSR_InvalidAF;
|
||||
return add_source(&remote_addr, name, IPADDR_UNSPEC, type, params, INVALID_POOL,
|
||||
get_next_conf_id(conf_id));
|
||||
}
|
||||
|
||||
|
@ -799,6 +810,7 @@ NSR_AddSourceByName(char *name, int port, int pool, NTP_Source_Type type,
|
|||
|
||||
us = MallocNew(struct UnresolvedSource);
|
||||
us->name = Strdup(name);
|
||||
us->family = family;
|
||||
us->random_order = 0;
|
||||
us->refreshment = 0;
|
||||
|
||||
|
@ -835,7 +847,7 @@ NSR_AddSourceByName(char *name, int port, int pool, NTP_Source_Type type,
|
|||
for (i = 0; i < new_sources; i++) {
|
||||
if (i > 0)
|
||||
remote_addr.ip_addr.addr.id = ++last_address_id;
|
||||
if (add_source(&remote_addr, name, type, params, us->pool_id, cid) != NSR_Success)
|
||||
if (add_source(&remote_addr, name, family, type, params, us->pool_id, cid) != NSR_Success)
|
||||
return NSR_TooManySources;
|
||||
}
|
||||
|
||||
|
@ -1026,6 +1038,7 @@ resolve_source_replacement(SourceRecord *record, int refreshment)
|
|||
|
||||
us = MallocNew(struct UnresolvedSource);
|
||||
us->name = Strdup(record->name);
|
||||
us->family = record->family;
|
||||
/* Ignore the order of addresses from the resolver to not get
|
||||
stuck with a pair of unreachable or otherwise unusable servers
|
||||
(e.g. falsetickers) in case the order doesn't change, or a group
|
||||
|
|
|
@ -55,9 +55,12 @@ extern NSR_Status NSR_AddSource(NTP_Remote_Address *remote_addr, NTP_Source_Type
|
|||
|
||||
/* Procedure to add a new server, peer source, or pool of servers specified by
|
||||
name instead of address. The name is resolved in exponentially increasing
|
||||
intervals until it succeeds or fails with a non-temporary error. If the
|
||||
name is an address, it is equivalent to NSR_AddSource(). */
|
||||
extern NSR_Status NSR_AddSourceByName(char *name, int port, int pool, NTP_Source_Type type,
|
||||
intervals until it succeeds or fails with a non-temporary error. The
|
||||
specified family filters resolved addresses. If the name is an address
|
||||
and its family does not conflict with the specified family, it is equivalent
|
||||
to NSR_AddSource(). */
|
||||
extern NSR_Status NSR_AddSourceByName(char *name, int family, int port, int pool,
|
||||
NTP_Source_Type type,
|
||||
SourceParameters *params, uint32_t *conf_id);
|
||||
|
||||
extern const char *NSR_StatusToString(NSR_Status status);
|
||||
|
|
2
stubs.c
2
stubs.c
|
@ -201,7 +201,7 @@ NSR_AddSource(NTP_Remote_Address *remote_addr, NTP_Source_Type type,
|
|||
}
|
||||
|
||||
NSR_Status
|
||||
NSR_AddSourceByName(char *name, int port, int pool, NTP_Source_Type type,
|
||||
NSR_AddSourceByName(char *name, int family, int port, int pool, NTP_Source_Type type,
|
||||
SourceParameters *params, uint32_t *conf_id)
|
||||
{
|
||||
return NSR_TooManySources;
|
||||
|
|
|
@ -125,7 +125,7 @@ void
|
|||
test_unit(void)
|
||||
{
|
||||
char source_line[] = "127.0.0.1 offline", conf[] = "port 0", name[64];
|
||||
int i, j, k, slot, found, pool, prev_n;
|
||||
int i, j, k, family, slot, found, pool, prev_n;
|
||||
uint32_t hash = 0, conf_id;
|
||||
NTP_Remote_Address addrs[256], addr;
|
||||
NTP_Local_Address local_addr;
|
||||
|
@ -216,7 +216,7 @@ test_unit(void)
|
|||
|
||||
TEST_CHECK(n_sources == 0);
|
||||
|
||||
status = NSR_AddSourceByName("a b", 0, 0, 0, &source.params, &conf_id);
|
||||
status = NSR_AddSourceByName("a b", IPADDR_UNSPEC, 0, 0, 0, &source.params, &conf_id);
|
||||
TEST_CHECK(status == NSR_InvalidName);
|
||||
|
||||
local_addr.ip_addr.family = IPADDR_INET4;
|
||||
|
@ -228,11 +228,13 @@ test_unit(void)
|
|||
for (i = 0; i < 500; i++) {
|
||||
for (j = 0; j < 20; j++) {
|
||||
snprintf(name, sizeof (name), "ntp%d.example.net", (int)(random() % 10));
|
||||
family = random() % 2 ? IPADDR_UNSPEC : random() % 2 ? IPADDR_INET4 : IPADDR_INET6;
|
||||
pool = random() % 2;
|
||||
prev_n = n_sources;
|
||||
|
||||
DEBUG_LOG("%d/%d adding source %s pool=%d", i, j, name, pool);
|
||||
status = NSR_AddSourceByName(name, 0, pool, random() % 2 ? NTP_SERVER : NTP_PEER,
|
||||
status = NSR_AddSourceByName(name, family, 0, pool,
|
||||
random() % 2 ? NTP_SERVER : NTP_PEER,
|
||||
&source.params, &conf_id);
|
||||
TEST_CHECK(status == NSR_UnresolvedName);
|
||||
|
||||
|
@ -242,11 +244,13 @@ test_unit(void)
|
|||
for (us = unresolved_sources; us->next; us = us->next)
|
||||
;
|
||||
TEST_CHECK(strcmp(us->name, name) == 0);
|
||||
TEST_CHECK(us->family == family);
|
||||
if (pool) {
|
||||
TEST_CHECK(us->address.ip_addr.family == IPADDR_UNSPEC && us->pool_id >= 0);
|
||||
} else {
|
||||
TEST_CHECK(strcmp(NSR_GetName(&us->address.ip_addr), name) == 0);
|
||||
TEST_CHECK(find_slot2(&us->address, &slot) == 2);
|
||||
TEST_CHECK(get_record(slot)->family == family);
|
||||
}
|
||||
|
||||
if (random() % 2) {
|
||||
|
|
Loading…
Reference in a new issue