190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NET_DNS_MDNS_CACHE_H_ 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#define NET_DNS_MDNS_CACHE_H_ 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <map> 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <string> 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <vector> 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/callback.h" 1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/base/net_export.h" 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace net { 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class ParsedDnsRecord; 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class RecordParsed; 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// mDNS Cache 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// This is a cache of mDNS records. It keeps track of expiration times and is 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// guaranteed not to return expired records. It also has facilities for timely 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// record expiration. 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class NET_EXPORT_PRIVATE MDnsCache { 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Key type for the record map. It is a 3-tuple of type, name and optional 297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // value ordered by type, then name, then optional value. This allows us to 307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // query for all records of a certain type and name, while also allowing us 317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // to set records of a certain type, name and optionally value as unique. 327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) class Key { 337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public: 347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Key(unsigned type, const std::string& name, const std::string& optional); 357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Key(const Key&); 367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Key& operator=(const Key&); 377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ~Key(); 387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bool operator<(const Key& key) const; 397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bool operator==(const Key& key) const; 407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) unsigned type() const { return type_; } 427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& name() const { return name_; } 437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& optional() const { return optional_; } 447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Create the cache key corresponding to |record|. 467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) static Key CreateFor(const RecordParsed* record); 477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private: 487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) unsigned type_; 497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::string name_; 507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::string optional_; 517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) }; 527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) typedef base::Callback<void(const RecordParsed*)> RecordRemovedCallback; 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) enum UpdateType { 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RecordAdded, 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RecordChanged, 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RecordRemoved, 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NoChange 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) }; 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) MDnsCache(); 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ~MDnsCache(); 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Return value indicates whether the record was added, changed 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // (existed previously with different value) or not changed (existed 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // previously with same value). 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UpdateType UpdateDnsRecord(scoped_ptr<const RecordParsed> record); 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Check cache for record with key |key|. Return the record if it exists, or 717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // NULL if it doesn't. 727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const RecordParsed* LookupKey(const Key& key); 737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Return records with type |type| and name |name|. Expired records will not 75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // be returned. If |type| is zero, return all records with name |name|. 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void FindDnsRecords(unsigned type, 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& name, 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<const RecordParsed*>* records, 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Time now) const; 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Remove expired records, call |record_removed_callback| for every removed 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // record. 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void CleanupRecords(base::Time now, 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const RecordRemovedCallback& record_removed_callback); 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Returns a time less than or equal to the next time a record will expire. 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Is updated when CleanupRecords or UpdateDnsRecord are called. Returns 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // base::Time when the cache is empty. 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Time next_expiration() const { return next_expiration_; } 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Remove a record from the cache. Returns a scoped version of the pointer 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // passed in if it was removed, scoped null otherwise. 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<const RecordParsed> RemoveRecord(const RecordParsed* record); 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void Clear(); 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) typedef std::map<Key, const RecordParsed*> RecordMap; 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Get the effective expiration of a cache entry, based on its creation time 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // and TTL. Does adjustments so entries with a TTL of zero will have a 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // nonzero TTL, as explained in RFC 6762 Section 10.1. 1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) static base::Time GetEffectiveExpiration(const RecordParsed* entry); 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Get optional part of the DNS key for shared records. For example, in PTR 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // records this is the pointed domain, since multiple PTR records may exist 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // for the same name. 1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) static std::string GetOptionalFieldForRecord( 1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const RecordParsed* record); 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RecordMap mdns_cache_; 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Time next_expiration_; 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MDnsCache); 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace net 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif // NET_DNS_MDNS_CACHE_H_ 121