1 // Copyright 2019 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_DNS_SYSTEM_DNS_CONFIG_CHANGE_NOTIFIER_H_ 6 #define NET_DNS_SYSTEM_DNS_CONFIG_CHANGE_NOTIFIER_H_ 7 8 #include <memory> 9 #include <optional> 10 11 #include "base/memory/scoped_refptr.h" 12 #include "base/task/sequenced_task_runner.h" 13 #include "net/base/net_export.h" 14 #include "net/dns/dns_config.h" 15 16 namespace net { 17 18 class DnsConfigService; 19 20 // Notifier that can be subscribed to to listen for changes to system DNS 21 // configuration. Expected to only be used internally to HostResolverManager and 22 // NetworkChangeNotifier. Other classes are expected to subscribe to 23 // NetworkChangeNotifier::AddDNSObserver() to subscribe to listen to both system 24 // config changes and configuration applied on top by Chrome. 25 // 26 // This class is thread and sequence safe except that RemoveObserver() must be 27 // called on the same sequence as the matched AddObserver() call. 28 // 29 // TODO(crbug.com/971411): Use this class in HostResolverManager. 30 class NET_EXPORT_PRIVATE SystemDnsConfigChangeNotifier { 31 public: 32 class Observer { 33 public: 34 // Called on loading new config, including the initial read once the first 35 // valid config has been read. If a config read encounters errors or an 36 // invalid config is read, will be invoked with |std::nullopt|. Only 37 // invoked when |config| changes. 38 virtual void OnSystemDnsConfigChanged(std::optional<DnsConfig> config) = 0; 39 }; 40 41 SystemDnsConfigChangeNotifier(); 42 // Alternate constructor allowing specifying the underlying DnsConfigService. 43 // |dns_config_service| will only be interacted with and destroyed using 44 // |task_runner|. As required by DnsConfigService, blocking I/O may be 45 // performed on |task_runner|, so it must support blocking (i.e. 46 // base::MayBlock). 47 // 48 // |dns_config_service| may be null if system DNS config is disabled for the 49 // current platform. Calls against the created object will noop, and no 50 // notifications will ever be sent. 51 SystemDnsConfigChangeNotifier( 52 scoped_refptr<base::SequencedTaskRunner> task_runner, 53 std::unique_ptr<DnsConfigService> dns_config_service); 54 55 SystemDnsConfigChangeNotifier(const SystemDnsConfigChangeNotifier&) = delete; 56 SystemDnsConfigChangeNotifier& operator=( 57 const SystemDnsConfigChangeNotifier&) = delete; 58 59 ~SystemDnsConfigChangeNotifier(); 60 61 // An added Observer will receive notifications on the sequence where 62 // AddObserver() was called. If the config has been successfully read before 63 // calling this method, a notification will be sent for that current config 64 // before any other notifications. 65 void AddObserver(Observer* observer); 66 67 // In order to ensure notifications immediately stop on calling 68 // RemoveObserver(), must be called on the same sequence where the associated 69 // AddObserver() was called. 70 void RemoveObserver(Observer* observer); 71 72 // Triggers invalidation and re-read of the current configuration (followed by 73 // notifications to registered Observers). For use only on platforms 74 // expecting network-stack-external notifications of DNS config changes. 75 void RefreshConfig(); 76 77 // Sets the DnsConfigService. If `done_cb` is non-null, this also runs 78 // dns_config_service->RefreshConfig() on the DnsConfigService sequence and 79 // then invokes `done_cb` on the current sequence. 80 void SetDnsConfigServiceForTesting( 81 std::unique_ptr<DnsConfigService> dns_config_service, 82 base::OnceClosure done_cb); 83 84 private: 85 class Core; 86 87 std::unique_ptr<Core, base::OnTaskRunnerDeleter> core_; 88 }; 89 90 } // namespace net 91 92 #endif // NET_DNS_SYSTEM_DNS_CONFIG_CHANGE_NOTIFIER_H_ 93