15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifndef NET_DNS_HOST_CACHE_H_ 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define NET_DNS_HOST_CACHE_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <functional> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/non_thread_safe.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/address_family.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/address_list.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/expiring_cache.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_export.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Cache used by HostResolver to map hostnames to their resolved result. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT HostCache : NON_EXPORTED_BASE(public base::NonThreadSafe) { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stores the latest address list that was looked up for a hostname. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct NET_EXPORT Entry { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Entry(int error, const AddressList& addrlist, base::TimeDelta ttl); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use when |ttl| is unknown. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Entry(int error, const AddressList& addrlist); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~Entry(); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_ttl() const { return ttl >= base::TimeDelta(); } 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The resolve results for this entry. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddressList addrlist; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TTL obtained from the nameserver. Negative if unknown. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta ttl; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct Key { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Key(const std::string& hostname, AddressFamily address_family, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostResolverFlags host_resolver_flags) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : hostname(hostname), 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address_family(address_family), 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_resolver_flags(host_resolver_flags) {} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator<(const Key& other) const { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |address_family| and |host_resolver_flags| are compared before 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |hostname| under assumption that integer comparisons are faster than 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // string comparisons. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (address_family != other.address_family) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return address_family < other.address_family; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host_resolver_flags != other.host_resolver_flags) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return host_resolver_flags < other.host_resolver_flags; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hostname < other.hostname; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string hostname; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddressFamily address_family; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostResolverFlags host_resolver_flags; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct EvictionHandler { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Handle(const Key& key, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Entry& entry, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeTicks& expiration, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeTicks& now, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool onGet) const; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef ExpiringCache<Key, Entry, base::TimeTicks, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::less<base::TimeTicks>, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EvictionHandler> EntryMap; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Constructs a HostCache that stores up to |max_entries|. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit HostCache(size_t max_entries); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~HostCache(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns a pointer to the entry for |key|, which is valid at time 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |now|. If there is no such entry, returns NULL. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Entry* Lookup(const Key& key, base::TimeTicks now); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Overwrites or creates an entry for |key|. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |entry| is the value to set, |now| is the current time 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |ttl| is the "time to live". 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Set(const Key& key, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Entry& entry, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks now, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta ttl); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Empties the cache 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void clear(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the number of entries in the cache. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size() const; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Following are used by net_internals UI. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t max_entries() const; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EntryMap& entries() const; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a default cache. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static scoped_ptr<HostCache> CreateDefaultCache(); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(HostCacheTest, NoCache); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if this HostCache can contain no entries. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool caching_is_disabled() const { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return entries_.max_entries() == 0; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Map from hostname (presumably in lowercase canonicalized format) to 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a resolved result entry. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EntryMap entries_; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(HostCache); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif // NET_DNS_HOST_CACHE_H_ 125