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