diff --git a/src/config.c b/src/config.c index 7d840524e..e118d74df 100644 --- a/src/config.c +++ b/src/config.c @@ -438,6 +438,11 @@ void read_FTLconf(void) config.refresh_hostnames = REFRESH_NONE; logg(" REFRESH_HOSTNAMES: Not periodically refreshing names"); } + else if(buffer != NULL && strcasecmp(buffer, "UNKNOWN") == 0) + { + config.refresh_hostnames = REFRESH_UNKNOWN; + logg(" REFRESH_HOSTNAMES: Only refreshing recently active clients with unknown hostnames"); + } else { config.refresh_hostnames = REFRESH_IPV4_ONLY; diff --git a/src/enums.h b/src/enums.h index 35caf92c0..447bf50a9 100644 --- a/src/enums.h +++ b/src/enums.h @@ -145,6 +145,7 @@ enum events { RELOAD_GRAVITY, RELOAD_PRIVACY_LEVEL, RERESOLVE_HOSTNAMES, + RERESOLVE_HOSTNAMES_FORCE, REIMPORT_ALIASCLIENTS, PARSE_NEIGHBOR_CACHE, EVENTS_MAX @@ -153,6 +154,7 @@ enum events { enum refresh_hostnames { REFRESH_ALL, REFRESH_IPV4_ONLY, + REFRESH_UNKNOWN, REFRESH_NONE } __attribute__ ((packed)); diff --git a/src/events.c b/src/events.c index 845837026..062807075 100644 --- a/src/events.c +++ b/src/events.c @@ -92,6 +92,8 @@ static const char *eventtext(const enum events event) return "RELOAD_PRIVACY_LEVEL"; case RERESOLVE_HOSTNAMES: return "RERESOLVE_HOSTNAMES"; + case RERESOLVE_HOSTNAMES_FORCE: + return "RERESOLVE_HOSTNAMES_FORCE"; case REIMPORT_ALIASCLIENTS: return "REIMPORT_ALIASCLIENTS"; case PARSE_NEIGHBOR_CACHE: diff --git a/src/resolve.c b/src/resolve.c index cd71996ef..7262f677b 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -350,7 +350,7 @@ static size_t resolveAndAddHostname(size_t ippos, size_t oldnamepos) } // Resolve client host names -static void resolveClients(const bool onlynew) +static void resolveClients(const bool onlynew, const bool force_refreshing) { const time_t now = time(NULL); // Lock counter access here, we use a copy in the following loop @@ -386,7 +386,7 @@ static void resolveClients(const bool onlynew) // Only try to resolve host names of clients which were recently active if we are re-resolving // Limit for a "recently active" client is two hours ago - if(onlynew == false && client->lastQuery < now - 2*60*60) + if(!force_refreshing && !onlynew && client->lastQuery < now - 2*60*60) { if(config.debug & DEBUG_RESOLVER) { @@ -401,7 +401,7 @@ static void resolveClients(const bool onlynew) // If onlynew flag is set, we will only resolve new clients // If not, we will try to re-resolve all known clients - if(onlynew && !newflag) + if(!force_refreshing && onlynew && !newflag) { if(config.debug & DEBUG_RESOLVER) { @@ -419,15 +419,27 @@ static void resolveClients(const bool onlynew) IPv6 = true; // If we're in refreshing mode (onlynew == false), we skip clients if - // either IPv4-only or none is selected + // 1. We should not refresh any hostnames + // 2. We should only refresh IPv4 client, but this client is IPv6 + // 3. We should only refresh unknown hostnames, but leave + // existing ones as they are if(onlynew == false && - (config.refresh_hostnames == REFRESH_NONE || - (config.refresh_hostnames == REFRESH_IPV4_ONLY && IPv6))) + (config.refresh_hostnames == REFRESH_NONE || + (config.refresh_hostnames == REFRESH_IPV4_ONLY && IPv6) || + (config.refresh_hostnames == REFRESH_UNKNOWN && oldnamepos != 0))) { if(config.debug & DEBUG_RESOLVER) { - logg("Skipping client %s (%s) because it should not be refreshed", - getstr(ippos), getstr(oldnamepos)); + const char *reason = "N/A"; + if(config.refresh_hostnames == REFRESH_NONE) + reason = "Not refreshing any hostnames"; + else if(config.refresh_hostnames == REFRESH_IPV4_ONLY) + reason = "Only refreshing IPv4 names"; + else if(config.refresh_hostnames == REFRESH_UNKNOWN) + reason = "Looking only for unknown hostnames"; + + logg("Skipping client %s (%s) because it should not be refreshed: %s", + getstr(ippos), getstr(oldnamepos), reason); } skipped++; continue; @@ -559,7 +571,8 @@ void *DNSclient_thread(void *val) if(resolver_ready && (time(NULL) % RESOLVE_INTERVAL == 0)) { // Try to resolve new client host names (onlynew=true) - resolveClients(true); + // We're not forcing refreshing here + resolveClients(true, false); // Try to resolve new upstream destination host names (onlynew=true) resolveUpstreams(true); // Prevent immediate re-run of this routine @@ -572,11 +585,18 @@ void *DNSclient_thread(void *val) set_event(RERESOLVE_HOSTNAMES); // done below } + bool force_refreshing = false; + if(get_and_clear_event(RERESOLVE_HOSTNAMES_FORCE)) + { + set_event(RERESOLVE_HOSTNAMES); // done below + force_refreshing = true; + } + // Process resolver related event queue elements if(get_and_clear_event(RERESOLVE_HOSTNAMES)) { // Try to resolve all client host names (onlynew=false) - resolveClients(false); + resolveClients(false, force_refreshing); // Try to resolve all upstream destination host names (onlynew=false) resolveUpstreams(false); // Prevent immediate re-run of this routine diff --git a/src/signals.c b/src/signals.c index b5ec061da..ec3705071 100644 --- a/src/signals.c +++ b/src/signals.c @@ -283,7 +283,9 @@ static void SIGRT_handler(int signum, siginfo_t *si, void *unused) else if(rtsig == 4) { // Re-resolve all clients and forward destinations - set_event(RERESOLVE_HOSTNAMES); + // Force refreshing hostnames according to + // REFRESH_HOSTNAMES config option + set_event(RERESOLVE_HOSTNAMES_FORCE); } else if(rtsig == 5) {