ntp: add configuration ID to sources

Provide an ID for each configured NTP source to enable tracking and
removing of its corresponding sources, even after they change their
address.
This commit is contained in:
Miroslav Lichvar 2020-06-09 11:59:25 +02:00
parent 428f9e4228
commit 951f14ae06
6 changed files with 66 additions and 14 deletions

View file

@ -750,7 +750,7 @@ handle_add_source(CMD_Request *rx_message, CMD_Reply *tx_message)
(ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_TRUST ? SRC_SELECT_TRUST : 0) |
(ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_REQUIRE ? SRC_SELECT_REQUIRE : 0);
status = NSR_AddSourceByName(name, port, pool, type, &params);
status = NSR_AddSourceByName(name, port, pool, type, &params, NULL);
switch (status) {
case NSR_Success:
break;

4
conf.c
View file

@ -1577,7 +1577,7 @@ CNF_AddInitSources(void)
cps_source.params.iburst = 1;
cps_source.params.connectivity = SRC_OFFLINE;
NSR_AddSource(&ntp_addr, NTP_SERVER, &cps_source.params);
NSR_AddSource(&ntp_addr, NTP_SERVER, &cps_source.params, NULL);
}
ARR_SetSize(init_sources, 0);
@ -1594,7 +1594,7 @@ CNF_AddSources(void)
for (i = 0; i < ARR_GetSize(ntp_sources); i++) {
source = (NTP_Source *)ARR_GetElement(ntp_sources, i);
NSR_AddSourceByName(source->params.name, source->params.port,
source->pool, source->type, &source->params.params);
source->pool, source->type, &source->params.params, NULL);
Free(source->params.name);
}

View file

@ -58,6 +58,8 @@ typedef struct {
added or INVALID_POOL */
int tentative; /* Flag indicating there was no valid response
received from the source yet */
uint32_t conf_id; /* Configuration ID, which can be shared with
different sources in case of a pool */
} SourceRecord;
/* Hash table of SourceRecord, its size is a power of two and it's never
@ -73,6 +75,9 @@ static int auto_start_sources = 0;
/* Last assigned address ID */
static uint32_t last_address_id = 0;
/* Last assigned configuration ID */
static uint32_t last_conf_id = 0;
/* Source scheduled for name resolving (first resolving or replacement) */
struct UnresolvedSource {
/* Current address of the source (IDADDR_ID is used for a single source
@ -302,7 +307,8 @@ rehash_records(void)
/* Procedure to add a new source */
static NSR_Status
add_source(NTP_Remote_Address *remote_addr, char *name, NTP_Source_Type type, SourceParameters *params, int pool)
add_source(NTP_Remote_Address *remote_addr, char *name, NTP_Source_Type type,
SourceParameters *params, int pool, uint32_t conf_id)
{
SourceRecord *record;
int slot;
@ -332,6 +338,7 @@ add_source(NTP_Remote_Address *remote_addr, char *name, NTP_Source_Type type, So
record->name = name ? Strdup(name) : NULL;
record->pool = pool;
record->tentative = 1;
record->conf_id = conf_id;
if (record->pool != INVALID_POOL) {
get_pool(record->pool)->sources++;
@ -604,15 +611,27 @@ remove_unresolved_source(struct UnresolvedSource *us)
/* ================================================== */
NSR_Status
NSR_AddSource(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourceParameters *params)
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);
NSR_Status s;
s = add_source(remote_addr, NULL, type, params, INVALID_POOL, last_conf_id + 1);
if (s != NSR_Success)
return s;
last_conf_id++;
if (conf_id)
*conf_id = last_conf_id;
return s;
}
/* ================================================== */
NSR_Status
NSR_AddSourceByName(char *name, int port, int pool, NTP_Source_Type type, SourceParameters *params)
NSR_AddSourceByName(char *name, int port, int pool, NTP_Source_Type type,
SourceParameters *params, uint32_t *conf_id)
{
struct UnresolvedSource *us;
struct SourcePool *sp;
@ -623,7 +642,7 @@ NSR_AddSourceByName(char *name, int port, int pool, NTP_Source_Type type, Source
or later when trying to replace the source */
if (UTI_StringToIP(name, &remote_addr.ip_addr)) {
remote_addr.port = port;
return NSR_AddSource(&remote_addr, type, params);
return NSR_AddSource(&remote_addr, type, params, conf_id);
}
/* Make sure the name is at least printable and has no spaces */
@ -657,10 +676,14 @@ NSR_AddSourceByName(char *name, int port, int pool, NTP_Source_Type type, Source
append_unresolved_source(us);
last_conf_id++;
if (conf_id)
*conf_id = last_conf_id;
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) != NSR_Success)
if (add_source(&remote_addr, name, type, params, us->pool, last_conf_id) != NSR_Success)
return NSR_TooManySources;
}
@ -774,6 +797,24 @@ NSR_RemoveSource(IPAddr *address)
/* ================================================== */
void
NSR_RemoveSourcesById(uint32_t conf_id)
{
SourceRecord *record;
unsigned int i;
for (i = 0; i < ARR_GetSize(records); i++) {
record = get_record(i);
if (!record->remote_addr || record->conf_id != conf_id)
continue;
clean_source_record(record);
}
rehash_records();
}
/* ================================================== */
void
NSR_RemoveAllSources(void)
{

View file

@ -50,14 +50,15 @@ typedef enum {
} NSR_Status;
/* Procedure to add a new server or peer source. */
extern NSR_Status NSR_AddSource(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourceParameters *params);
extern NSR_Status NSR_AddSource(NTP_Remote_Address *remote_addr, NTP_Source_Type type,
SourceParameters *params, uint32_t *conf_id);
/* 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,
SourceParameters *params);
SourceParameters *params, uint32_t *conf_id);
/* Function type for handlers to be called back when an attempt
* (possibly unsuccessful) to resolve unresolved sources ends */
@ -78,6 +79,9 @@ extern void NSR_AutoStartSources(void);
/* Procedure to remove a source */
extern NSR_Status NSR_RemoveSource(IPAddr *address);
/* Procedure to remove all sources matching a configuration ID */
extern void NSR_RemoveSourcesById(uint32_t conf_id);
/* Procedure to remove all sources */
extern void NSR_RemoveAllSources(void);

11
stubs.c
View file

@ -194,13 +194,15 @@ NSR_Finalise(void)
}
NSR_Status
NSR_AddSource(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourceParameters *params)
NSR_AddSource(NTP_Remote_Address *remote_addr, NTP_Source_Type type,
SourceParameters *params, uint32_t *conf_id)
{
return NSR_TooManySources;
}
NSR_Status
NSR_AddSourceByName(char *name, int port, int pool, NTP_Source_Type type, SourceParameters *params)
NSR_AddSourceByName(char *name, int port, int pool, NTP_Source_Type type,
SourceParameters *params, uint32_t *conf_id)
{
return NSR_TooManySources;
}
@ -211,6 +213,11 @@ NSR_RemoveSource(IPAddr *address)
return NSR_NoSuchSource;
}
void
NSR_RemoveSourcesById(uint32_t conf_id)
{
}
void
NSR_RemoveAllSources(void)
{

View file

@ -66,7 +66,7 @@ test_unit(void)
DEBUG_LOG("adding source %s hash %"PRIu32, UTI_IPToString(&addrs[j].ip_addr),
UTI_IPToHash(&addrs[j].ip_addr) % (1U << i));
NSR_AddSource(&addrs[j], random() % 2 ? NTP_SERVER : NTP_PEER, &params);
NSR_AddSource(&addrs[j], random() % 2 ? NTP_SERVER : NTP_PEER, &params, NULL);
for (k = 0; k < j; k++) {
addr = addrs[k];