From: Aki Tuomi Date: Sun, 15 Apr 2018 18:33:44 +0000 (+0300) Subject: stubresolver: Improve locking X-Git-Tag: dnsdist-1.3.1~67^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9a987ad13bae2b985451fed0975f47bafac373ba;p=pdns stubresolver: Improve locking --- diff --git a/pdns/stubresolver.cc b/pdns/stubresolver.cc index 1006618ba..6541dbc80 100644 --- a/pdns/stubresolver.cc +++ b/pdns/stubresolver.cc @@ -23,7 +23,8 @@ // s_resolversForStub contains the ComboAddresses that are used by // stubDoResolve static vector s_resolversForStub; -static pthread_mutex_t s_resolversForStubLock = PTHREAD_MUTEX_INITIALIZER; +static pthread_rwlock_t s_resolversForStubLock = PTHREAD_RWLOCK_INITIALIZER; +static bool s_stubResolvConfigured = false; // /etc/resolv.conf last modification time static time_t s_localResolvConfMtime = 0; @@ -34,6 +35,7 @@ static time_t s_localResolvConfLastCheck = 0; */ bool resolversDefined() { + ReadLock l(&s_resolversForStubLock); if (s_resolversForStub.empty()) { g_log< now) - return ; s_localResolvConfLastCheck = now; if (stat(LOCAL_RESOLV_CONF_PATH, &st) != -1) { if (st.st_mtime != s_localResolvConfMtime) { ifstream ifs(LOCAL_RESOLV_CONF_PATH); string line; - Lock l(&s_resolversForStubLock); s_localResolvConfMtime = st.st_mtime; if(!ifs) @@ -89,6 +86,17 @@ static void parseLocalResolvConf() } } +static void parseLocalResolvConf() +{ + const time_t now = time(nullptr); + if ((s_localResolvConfLastCheck + LOCAL_RESOLV_CONF_MAX_CHECK_INTERVAL) > now) + return ; + + WriteLock wl(&s_resolversForStubLock); + parseLocalResolvConf_locked(now); +} + + /* * Fill the s_resolversForStub vector with addresses for the upstream resolvers. * First, parse the `resolver` configuration option for IP addresses to use. @@ -98,6 +106,7 @@ static void parseLocalResolvConf() void stubParseResolveConf() { if(::arg().mustDo("resolver")) { + WriteLock wl(&s_resolversForStubLock); vector parts; stringtok(parts, ::arg()["resolver"], " ,\t"); for (const auto& addr : parts) @@ -109,11 +118,16 @@ void stubParseResolveConf() } // Emit a warning if there are no stubs. resolversDefined(); + s_stubResolvConfigured = true; } // s_resolversForStub contains the ComboAddresses that are used to resolve the int stubDoResolve(const DNSName& qname, uint16_t qtype, vector& ret) { + // ensure resolver gets always configured + if (!s_stubResolvConfigured) { + stubParseResolveConf(); + } // only check if resolvers come from local resolv.conf in the first place if (s_localResolvConfMtime != 0) { parseLocalResolvConf(); @@ -121,6 +135,7 @@ int stubDoResolve(const DNSName& qname, uint16_t qtype, vector& r if (!resolversDefined()) return RCode::ServFail; + ReadLock l(&s_resolversForStubLock); vector packet; DNSPacketWriter pw(packet, qname, qtype);