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;
/* 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++;
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);
(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
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
/* 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;
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;
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 */
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;
/* 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));
}
us = MallocNew(struct UnresolvedSource);
us->name = Strdup(name);
+ us->family = family;
us->random_order = 0;
us->refreshment = 0;
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;
}
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
/* 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);
}
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;
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;
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;
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);
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) {