diff --git a/cmdmon.c b/cmdmon.c index 5854bad..ee6a25d 100644 --- a/cmdmon.c +++ b/cmdmon.c @@ -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, ¶ms); + status = NSR_AddSourceByName(name, port, pool, type, ¶ms, NULL); switch (status) { case NSR_Success: break; diff --git a/conf.c b/conf.c index d41f85f..810989f 100644 --- a/conf.c +++ b/conf.c @@ -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); } diff --git a/ntp_sources.c b/ntp_sources.c index 4a54854..753ca31 100644 --- a/ntp_sources.c +++ b/ntp_sources.c @@ -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) { diff --git a/ntp_sources.h b/ntp_sources.h index 5fbbe51..81530b1 100644 --- a/ntp_sources.h +++ b/ntp_sources.h @@ -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); diff --git a/stubs.c b/stubs.c index dece36f..463a1b3 100644 --- a/stubs.c +++ b/stubs.c @@ -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) { diff --git a/test/unit/ntp_sources.c b/test/unit/ntp_sources.c index 132b962..2488831 100644 --- a/test/unit/ntp_sources.c +++ b/test/unit/ntp_sources.c @@ -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, ¶ms); + NSR_AddSource(&addrs[j], random() % 2 ? NTP_SERVER : NTP_PEER, ¶ms, NULL); for (k = 0; k < j; k++) { addr = addrs[k];