From 50eba0ae125e7090913de57b28045df40ca22106 Mon Sep 17 00:00:00 2001 From: lihuiba Date: Fri, 7 Feb 2025 10:36:13 +0800 Subject: [PATCH] fix potential race condition in DefaultResolver when discard_cache() --- net/utils.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/net/utils.cpp b/net/utils.cpp index d6c4ed7f..75e0a596 100644 --- a/net/utils.cpp +++ b/net/utils.cpp @@ -263,8 +263,9 @@ class DefaultResolver : public Resolver { IPAddr addr; IPAddrNode(IPAddr addr) : addr(addr) {} }; - using IPAddrList = intrusive_list; - + struct IPAddrList : public intrusive_list, rwlock { + ~IPAddrList() { delete_all(); } + }; IPAddr do_resolve(std::string_view host, Delegate filter) { auto ctr = [&]() -> IPAddrList* { auto addrs = new IPAddrList(); @@ -295,6 +296,7 @@ class DefaultResolver : public Resolver { }; auto ips = dnscache_.borrow(host, ctr); if (ips->empty()) LOG_ERRNO_RETURN(0, IPAddr(), "Domain resolution for '`' failed", host); + scoped_rwlock _(*ips, RLOCK); auto ret = ips->front(); ips->node = ret->next(); // access in round robin order return ret->addr; @@ -303,13 +305,6 @@ class DefaultResolver : public Resolver { public: DefaultResolver(uint64_t cache_ttl, uint64_t resolve_timeout) : dnscache_(cache_ttl), resolve_timeout_(resolve_timeout) {} - ~DefaultResolver() { - for (auto it : dnscache_) { - ((IPAddrList*)it->_obj)->delete_all(); - } - dnscache_.clear(); - } - IPAddr resolve(std::string_view host) override { return do_resolve(host, nullptr); } @@ -321,9 +316,9 @@ class DefaultResolver : public Resolver { void discard_cache(std::string_view host, IPAddr ip) override { auto ipaddr = dnscache_.borrow(host); if (ip.undefined() || ipaddr->empty()) { - ipaddr->delete_all(); ipaddr.recycle(true); } else { + scoped_rwlock _(*ipaddr, WLOCK); for (auto itr = ipaddr->rbegin(); itr != ipaddr->rend(); itr++) { if ((*itr)->addr == ip) { ipaddr->erase(*itr);