/* */ #ifndef D_DNS_CACHE_H #define D_DNS_CACHE_H #include "common.h" #include #include #include #include #include "a2functional.h" namespace aria2 { class DNSCache { private: struct AddrEntry { std::string addr_; bool good_; AddrEntry(const std::string& addr); AddrEntry(const AddrEntry& c); ~AddrEntry(); AddrEntry& operator=(const AddrEntry& c); }; struct CacheEntry { std::string hostname_; uint16_t port_; std::vector addrEntries_; CacheEntry(const std::string& hostname, uint16_t port); CacheEntry(const CacheEntry& c); ~CacheEntry(); CacheEntry& operator=(const CacheEntry& c); bool add(const std::string& addr); std::vector::iterator find(const std::string& addr); std::vector::const_iterator find(const std::string& addr) const; bool contains(const std::string& addr) const; const std::string& getGoodAddr() const; template void getAllGoodAddrs(OutputIterator out) const { for (auto& elem : addrEntries_) { if (elem.good_) { *out++ = elem.addr_; } } } void markBad(const std::string& addr); bool operator<(const CacheEntry& e) const; bool operator==(const CacheEntry& e) const; }; typedef std::set, DerefLess>> CacheEntrySet; CacheEntrySet entries_; public: DNSCache(); DNSCache(const DNSCache& c); ~DNSCache(); DNSCache& operator=(const DNSCache& c); const std::string& find(const std::string& hostname, uint16_t port) const; template void findAll(OutputIterator out, const std::string& hostname, uint16_t port) const { std::shared_ptr target(new CacheEntry(hostname, port)); auto i = entries_.find(target); if (i != entries_.end()) { (*i)->getAllGoodAddrs(out); } } void put(const std::string& hostname, const std::string& ipaddr, uint16_t port); void markBad(const std::string& hostname, const std::string& ipaddr, uint16_t port); void remove(const std::string& hostname, uint16_t port); }; } // namespace aria2 #endif // D_DNS_CACHE_H