xref: /aosp_15_r20/external/cronet/net/dns/mdns_cache.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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