1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef NET_DNS_MDNS_CACHE_H_ 6*6777b538SAndroid Build Coastguard Worker #define NET_DNS_MDNS_CACHE_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <map> 9*6777b538SAndroid Build Coastguard Worker #include <memory> 10*6777b538SAndroid Build Coastguard Worker #include <string> 11*6777b538SAndroid Build Coastguard Worker #include <vector> 12*6777b538SAndroid Build Coastguard Worker 13*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h" 14*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h" 15*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h" 16*6777b538SAndroid Build Coastguard Worker 17*6777b538SAndroid Build Coastguard Worker namespace net { 18*6777b538SAndroid Build Coastguard Worker 19*6777b538SAndroid Build Coastguard Worker class RecordParsed; 20*6777b538SAndroid Build Coastguard Worker 21*6777b538SAndroid Build Coastguard Worker // mDNS Cache 22*6777b538SAndroid Build Coastguard Worker // This is a cache of mDNS records. It keeps track of expiration times and is 23*6777b538SAndroid Build Coastguard Worker // guaranteed not to return expired records. It also has facilities for timely 24*6777b538SAndroid Build Coastguard Worker // record expiration. 25*6777b538SAndroid Build Coastguard Worker class NET_EXPORT_PRIVATE MDnsCache { 26*6777b538SAndroid Build Coastguard Worker public: 27*6777b538SAndroid Build Coastguard Worker // Key type for the record map. It is a 3-tuple of type, name and optional 28*6777b538SAndroid Build Coastguard Worker // value ordered by type, then name, then optional value. This allows us to 29*6777b538SAndroid Build Coastguard Worker // query for all records of a certain type and name, while also allowing us 30*6777b538SAndroid Build Coastguard Worker // to set records of a certain type, name and optionally value as unique. 31*6777b538SAndroid Build Coastguard Worker class Key { 32*6777b538SAndroid Build Coastguard Worker public: 33*6777b538SAndroid Build Coastguard Worker Key(unsigned type, const std::string& name, const std::string& optional); 34*6777b538SAndroid Build Coastguard Worker Key(const Key&); 35*6777b538SAndroid Build Coastguard Worker Key& operator=(const Key&); 36*6777b538SAndroid Build Coastguard Worker ~Key(); 37*6777b538SAndroid Build Coastguard Worker bool operator<(const Key& key) const; 38*6777b538SAndroid Build Coastguard Worker bool operator==(const Key& key) const; 39*6777b538SAndroid Build Coastguard Worker type()40*6777b538SAndroid Build Coastguard Worker unsigned type() const { return type_; } name_lowercase()41*6777b538SAndroid Build Coastguard Worker const std::string& name_lowercase() const { return name_lowercase_; } optional()42*6777b538SAndroid Build Coastguard Worker const std::string& optional() const { return optional_; } 43*6777b538SAndroid Build Coastguard Worker 44*6777b538SAndroid Build Coastguard Worker // Create the cache key corresponding to |record|. 45*6777b538SAndroid Build Coastguard Worker static Key CreateFor(const RecordParsed* record); 46*6777b538SAndroid Build Coastguard Worker private: 47*6777b538SAndroid Build Coastguard Worker unsigned type_; 48*6777b538SAndroid Build Coastguard Worker std::string name_lowercase_; 49*6777b538SAndroid Build Coastguard Worker std::string optional_; 50*6777b538SAndroid Build Coastguard Worker }; 51*6777b538SAndroid Build Coastguard Worker 52*6777b538SAndroid Build Coastguard Worker typedef base::RepeatingCallback<void(const RecordParsed*)> 53*6777b538SAndroid Build Coastguard Worker RecordRemovedCallback; 54*6777b538SAndroid Build Coastguard Worker 55*6777b538SAndroid Build Coastguard Worker enum UpdateType { 56*6777b538SAndroid Build Coastguard Worker RecordAdded, 57*6777b538SAndroid Build Coastguard Worker RecordChanged, 58*6777b538SAndroid Build Coastguard Worker RecordRemoved, 59*6777b538SAndroid Build Coastguard Worker NoChange 60*6777b538SAndroid Build Coastguard Worker }; 61*6777b538SAndroid Build Coastguard Worker 62*6777b538SAndroid Build Coastguard Worker MDnsCache(); 63*6777b538SAndroid Build Coastguard Worker 64*6777b538SAndroid Build Coastguard Worker MDnsCache(const MDnsCache&) = delete; 65*6777b538SAndroid Build Coastguard Worker MDnsCache& operator=(const MDnsCache&) = delete; 66*6777b538SAndroid Build Coastguard Worker 67*6777b538SAndroid Build Coastguard Worker ~MDnsCache(); 68*6777b538SAndroid Build Coastguard Worker 69*6777b538SAndroid Build Coastguard Worker // Return value indicates whether the record was added, changed 70*6777b538SAndroid Build Coastguard Worker // (existed previously with different value) or not changed (existed 71*6777b538SAndroid Build Coastguard Worker // previously with same value). 72*6777b538SAndroid Build Coastguard Worker UpdateType UpdateDnsRecord(std::unique_ptr<const RecordParsed> record); 73*6777b538SAndroid Build Coastguard Worker 74*6777b538SAndroid Build Coastguard Worker // Check cache for record with key |key|. Return the record if it exists, or 75*6777b538SAndroid Build Coastguard Worker // NULL if it doesn't. 76*6777b538SAndroid Build Coastguard Worker const RecordParsed* LookupKey(const Key& key); 77*6777b538SAndroid Build Coastguard Worker 78*6777b538SAndroid Build Coastguard Worker // Return records with type |type| and name |name|. Expired records will not 79*6777b538SAndroid Build Coastguard Worker // be returned. If |type| is zero, return all records with name |name|. 80*6777b538SAndroid Build Coastguard Worker void FindDnsRecords(unsigned type, 81*6777b538SAndroid Build Coastguard Worker const std::string& name, 82*6777b538SAndroid Build Coastguard Worker std::vector<const RecordParsed*>* records, 83*6777b538SAndroid Build Coastguard Worker base::Time now) const; 84*6777b538SAndroid Build Coastguard Worker 85*6777b538SAndroid Build Coastguard Worker // Remove expired records, call |record_removed_callback| for every removed 86*6777b538SAndroid Build Coastguard Worker // record. 87*6777b538SAndroid Build Coastguard Worker void CleanupRecords(base::Time now, 88*6777b538SAndroid Build Coastguard Worker const RecordRemovedCallback& record_removed_callback); 89*6777b538SAndroid Build Coastguard Worker 90*6777b538SAndroid Build Coastguard Worker // Returns a time less than or equal to the next time a record will expire. 91*6777b538SAndroid Build Coastguard Worker // Is updated when CleanupRecords or UpdateDnsRecord are called. Returns 92*6777b538SAndroid Build Coastguard Worker // base::Time when the cache is empty. next_expiration()93*6777b538SAndroid Build Coastguard Worker base::Time next_expiration() const { return next_expiration_; } 94*6777b538SAndroid Build Coastguard Worker 95*6777b538SAndroid Build Coastguard Worker // Remove a record from the cache. Returns a scoped version of the pointer 96*6777b538SAndroid Build Coastguard Worker // passed in if it was removed, scoped null otherwise. 97*6777b538SAndroid Build Coastguard Worker std::unique_ptr<const RecordParsed> RemoveRecord(const RecordParsed* record); 98*6777b538SAndroid Build Coastguard Worker 99*6777b538SAndroid Build Coastguard Worker bool IsCacheOverfilled() const; 100*6777b538SAndroid Build Coastguard Worker set_entry_limit_for_testing(size_t entry_limit)101*6777b538SAndroid Build Coastguard Worker void set_entry_limit_for_testing(size_t entry_limit) { 102*6777b538SAndroid Build Coastguard Worker entry_limit_ = entry_limit; 103*6777b538SAndroid Build Coastguard Worker } 104*6777b538SAndroid Build Coastguard Worker 105*6777b538SAndroid Build Coastguard Worker private: 106*6777b538SAndroid Build Coastguard Worker typedef std::map<Key, std::unique_ptr<const RecordParsed>> RecordMap; 107*6777b538SAndroid Build Coastguard Worker 108*6777b538SAndroid Build Coastguard Worker // Get the effective expiration of a cache entry, based on its creation time 109*6777b538SAndroid Build Coastguard Worker // and TTL. Does adjustments so entries with a TTL of zero will have a 110*6777b538SAndroid Build Coastguard Worker // nonzero TTL, as explained in RFC 6762 Section 10.1. 111*6777b538SAndroid Build Coastguard Worker static base::Time GetEffectiveExpiration(const RecordParsed* entry); 112*6777b538SAndroid Build Coastguard Worker 113*6777b538SAndroid Build Coastguard Worker // Get optional part of the DNS key for shared records. For example, in PTR 114*6777b538SAndroid Build Coastguard Worker // records this is the pointed domain, since multiple PTR records may exist 115*6777b538SAndroid Build Coastguard Worker // for the same name. 116*6777b538SAndroid Build Coastguard Worker static std::string GetOptionalFieldForRecord(const RecordParsed* record); 117*6777b538SAndroid Build Coastguard Worker 118*6777b538SAndroid Build Coastguard Worker RecordMap mdns_cache_; 119*6777b538SAndroid Build Coastguard Worker 120*6777b538SAndroid Build Coastguard Worker base::Time next_expiration_; 121*6777b538SAndroid Build Coastguard Worker size_t entry_limit_; 122*6777b538SAndroid Build Coastguard Worker }; 123*6777b538SAndroid Build Coastguard Worker 124*6777b538SAndroid Build Coastguard Worker } // namespace net 125*6777b538SAndroid Build Coastguard Worker 126*6777b538SAndroid Build Coastguard Worker #endif // NET_DNS_MDNS_CACHE_H_ 127