summaryrefslogtreecommitdiff
path: root/chromium/net/dns/system_dns_config_change_notifier.h
blob: 447a8d8c244fff92dace351f6859a3a913d8d206 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_DNS_SYSTEM_DNS_CONFIG_CHANGE_NOTIFIER_H_
#define NET_DNS_SYSTEM_DNS_CONFIG_CHANGE_NOTIFIER_H_

#include <memory>

#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/optional.h"
#include "base/sequenced_task_runner.h"
#include "net/base/net_export.h"
#include "net/dns/dns_config.h"

namespace net {

class DnsConfigService;

// Notifier that can be subscribed to to listen for changes to system DNS
// configuration. Expected to only be used internally to HostResolverManager and
// NetworkChangeNotifier. Other classes are expected to subscribe to
// NetworkChangeNotifier::AddDNSObserver() to subscribe to listen to both system
// config changes and configuration applied on top by Chrome.
//
// This class is thread and sequence safe except that RemoveObserver() must be
// called on the same sequence as the matched AddObserver() call.
//
// TODO(crbug.com/971411): Use this class in HostResolverManager.
class NET_EXPORT_PRIVATE SystemDnsConfigChangeNotifier {
 public:
  class Observer {
   public:
    // Called on loading new config, including the initial read once the first
    // valid config has been read. If a config read encounters errors or an
    // invalid config is read, will be invoked with |base::nullopt|. Only
    // invoked when |config| changes.
    virtual void OnSystemDnsConfigChanged(base::Optional<DnsConfig> config) = 0;
  };

  SystemDnsConfigChangeNotifier();
  // Alternate constructor allowing specifying the underlying DnsConfigService.
  // |dns_config_service| will only be interacted with and destroyed using
  // |task_runner|. As required by DnsConfigService, blocking I/O may be
  // performed on |task_runner|, so it must support blocking (i.e.
  // base::MayBlock).
  //
  // |dns_config_service| may be null if system DNS config is disabled for the
  // current platform. Calls against the created object will noop, and no
  // notifications will ever be sent.
  SystemDnsConfigChangeNotifier(
      scoped_refptr<base::SequencedTaskRunner> task_runner,
      std::unique_ptr<DnsConfigService> dns_config_service);
  ~SystemDnsConfigChangeNotifier();

  // An added Observer will receive notifications on the sequence where
  // AddObserver() was called. If the config has been successfully read before
  // calling this method, a notification will be sent for that current config
  // before any other notifications.
  void AddObserver(Observer* observer);

  // In order to ensure notifications immediately stop on calling
  // RemoveObserver(), must be called on the same sequence where the associated
  // AddObserver() was called.
  void RemoveObserver(Observer* observer);

  // Triggers invalidation and re-read of the current configuration (followed by
  // notifications to registered Observers). For use only on platforms
  // expecting network-stack-external notifications of DNS config changes.
  void RefreshConfig();

  void SetDnsConfigServiceForTesting(
      std::unique_ptr<DnsConfigService> dns_config_service);

 private:
  class Core;

  std::unique_ptr<Core, base::OnTaskRunnerDeleter> core_;

  DISALLOW_COPY_AND_ASSIGN(SystemDnsConfigChangeNotifier);
};

}  // namespace net

#endif  // NET_DNS_SYSTEM_DNS_CONFIG_CHANGE_NOTIFIER_H_