blob: 18381ebba5ace3508bc8ccb5c3528c6bbafd6fbb [file] [log] [blame]
Garrick Evans066dc2c2020-12-10 10:43:55 +09001// Copyright 2021 The Chromium OS Authors. All rights reserved.
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 DNS_PROXY_PROXY_H_
6#define DNS_PROXY_PROXY_H_
7
8#include <iostream>
9#include <memory>
10#include <optional>
11#include <string>
12
13#include <base/memory/weak_ptr.h>
14#include <base/files/scoped_file.h>
15#include <brillo/daemons/dbus_daemon.h>
16#include <chromeos/patchpanel/dbus/client.h>
Garrick Evans5fe2a4f2021-02-03 17:04:48 +090017#include <gtest/gtest_prod.h> // for FRIEND_TEST
Garrick Evans066dc2c2020-12-10 10:43:55 +090018#include <shill/dbus/client/client.h>
19
Garrick Evans34650b32021-02-03 09:24:35 +090020#include "dns-proxy/resolver.h"
21
Garrick Evans066dc2c2020-12-10 10:43:55 +090022namespace dns_proxy {
23
24// The process that runs the actual proxying code.
25class Proxy : public brillo::DBusDaemon {
26 public:
27 enum class Type { kSystem, kDefault, kARC };
28
29 struct Options {
30 Type type;
31 // Required for ARC proxies as it specifies which physical interface
32 // should (always) be tracked. This field is ignored (but should be empty)
33 // for the system and default network proxies.
34 std::string ifname;
35 };
36
37 explicit Proxy(const Options& opts);
Garrick Evans5fe2a4f2021-02-03 17:04:48 +090038 // For testing.
39 Proxy(const Options& opts,
40 std::unique_ptr<patchpanel::Client> patchpanel,
41 std::unique_ptr<shill::Client> shill);
Garrick Evans066dc2c2020-12-10 10:43:55 +090042 Proxy(const Proxy&) = delete;
43 Proxy& operator=(const Proxy&) = delete;
44 ~Proxy() = default;
45
46 static const char* TypeToString(Type t);
47 static std::optional<Type> StringToType(const std::string& s);
48
49 protected:
50 int OnInit() override;
51 void OnShutdown(int*) override;
52
Garrick Evans2ca050d2021-02-09 18:21:36 +090053 // Added for testing.
Jason Jeremy Iman845f2932021-01-31 16:12:13 +090054 virtual std::unique_ptr<Resolver> NewResolver(base::TimeDelta timeout,
55 base::TimeDelta retry_delay,
56 int max_num_retries);
Garrick Evans2ca050d2021-02-09 18:21:36 +090057
Garrick Evans066dc2c2020-12-10 10:43:55 +090058 private:
Garrick Evans9c7afb82021-01-29 22:38:03 +090059 static const uint8_t kMaxShillPropertyRetries = 10;
60
Garrick Evans066dc2c2020-12-10 10:43:55 +090061 void Setup();
62 void OnPatchpanelReady(bool success);
Garrick Evansfe99aaa2021-02-12 14:32:50 +090063 void OnShillReady(bool success);
Garrick Evans9c7afb82021-01-29 22:38:03 +090064 void OnShillReset(bool reset);
Garrick Evans066dc2c2020-12-10 10:43:55 +090065
Garrick Evans34650b32021-02-03 09:24:35 +090066 // Triggered whenever the device attached to the default network changes.
67 // |device| can be null and indicates the default service is disconnected.
68 void OnDefaultDeviceChanged(const shill::Client::Device* const device);
69 void OnDeviceChanged(const shill::Client::Device* const device);
Garrick Evans066dc2c2020-12-10 10:43:55 +090070
Garrick Evans48c84ef2021-01-28 11:29:42 +090071 // Helper func for setting the dns-proxy address in shill.
72 // Only valid for the system proxy.
Garrick Evans9c7afb82021-01-29 22:38:03 +090073 // Will retry on failure up to |num_retries| before possibly crashing the
74 // proxy.
75 void SetShillProperty(const std::string& addr,
76 bool die_on_failure = false,
77 uint8_t num_retries = kMaxShillPropertyRetries);
Garrick Evans48c84ef2021-01-28 11:29:42 +090078
Garrick Evans5fe2a4f2021-02-03 17:04:48 +090079 FRIEND_TEST(ProxyTest, SystemProxy_OnShutdownClearsAddressPropertyOnShill);
80 FRIEND_TEST(ProxyTest, NonSystemProxy_OnShutdownDoesNotCallShill);
81 FRIEND_TEST(ProxyTest, SystemProxy_SetShillPropertyWithNoRetriesCrashes);
82 FRIEND_TEST(ProxyTest, SystemProxy_SetShillPropertyDoesntCrashIfDieFalse);
83 FRIEND_TEST(ProxyTest, SetupInitializesShill);
84 FRIEND_TEST(ProxyTest, SystemProxy_ConnectedNamedspace);
85 FRIEND_TEST(ProxyTest, DefaultProxy_ConnectedNamedspace);
86 FRIEND_TEST(ProxyTest, ArcProxy_ConnectedNamedspace);
87 FRIEND_TEST(ProxyTest, CrashOnConnectNamespaceFailure);
88 FRIEND_TEST(ProxyTest, CrashOnPatchpanelNotReady);
89 FRIEND_TEST(ProxyTest, ShillResetRestoresAddressProperty);
Garrick Evans2ca050d2021-02-09 18:21:36 +090090 FRIEND_TEST(ProxyTest, StateClearedIfDefaultServiceDrops);
91 FRIEND_TEST(ProxyTest, ArcProxy_IgnoredIfDefaultServiceDrops);
92 FRIEND_TEST(ProxyTest, StateClearedIfDefaultServiceIsNotOnline);
93 FRIEND_TEST(ProxyTest, NewResolverStartsListeningOnDefaultServiceComesOnline);
94 FRIEND_TEST(ProxyTest, CrashOnListenFailure);
95 FRIEND_TEST(ProxyTest, NameServersUpdatedOnDefaultServiceComesOnline);
96 FRIEND_TEST(ProxyTest,
97 SystemProxy_ShillPropertyUpdatedOnDefaultServiceComesOnline);
Garrick Evans5fe2a4f2021-02-03 17:04:48 +090098
Garrick Evans066dc2c2020-12-10 10:43:55 +090099 const Options opts_;
100 std::unique_ptr<patchpanel::Client> patchpanel_;
101 std::unique_ptr<shill::Client> shill_;
102
103 base::ScopedFD ns_fd_;
Garrick Evans9c7afb82021-01-29 22:38:03 +0900104 patchpanel::ConnectNamespaceResponse ns_;
Garrick Evans34650b32021-02-03 09:24:35 +0900105 std::unique_ptr<Resolver> resolver_;
106 std::unique_ptr<shill::Client::Device> device_;
Garrick Evans066dc2c2020-12-10 10:43:55 +0900107
108 base::WeakPtrFactory<Proxy> weak_factory_{this};
109};
110
111std::ostream& operator<<(std::ostream& stream, Proxy::Type type);
112std::ostream& operator<<(std::ostream& stream, Proxy::Options opt);
113
114} // namespace dns_proxy
115
116#endif // DNS_PROXY_PROXY_H_