xref: /aosp_15_r20/external/cronet/net/dns/nsswitch_reader.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2021 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_NSSWITCH_READER_H_
6*6777b538SAndroid Build Coastguard Worker #define NET_DNS_NSSWITCH_READER_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <string>
9*6777b538SAndroid Build Coastguard Worker #include <tuple>
10*6777b538SAndroid Build Coastguard Worker #include <vector>
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
13*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h"
14*6777b538SAndroid Build Coastguard Worker 
15*6777b538SAndroid Build Coastguard Worker namespace net {
16*6777b538SAndroid Build Coastguard Worker 
17*6777b538SAndroid Build Coastguard Worker // Reader to read and parse Posix nsswitch.conf files, particularly the "hosts:"
18*6777b538SAndroid Build Coastguard Worker // database entry.
19*6777b538SAndroid Build Coastguard Worker class NET_EXPORT_PRIVATE NsswitchReader {
20*6777b538SAndroid Build Coastguard Worker  public:
21*6777b538SAndroid Build Coastguard Worker   // These values are emitted in metrics. Entries should not be renumbered and
22*6777b538SAndroid Build Coastguard Worker   // numeric values should never be reused. (See NsswitchService in
23*6777b538SAndroid Build Coastguard Worker   // tools/metrics/histograms/enums.xml.)
24*6777b538SAndroid Build Coastguard Worker   enum class Service {
25*6777b538SAndroid Build Coastguard Worker     kUnknown = 0,
26*6777b538SAndroid Build Coastguard Worker     kFiles = 1,
27*6777b538SAndroid Build Coastguard Worker     kDns = 2,
28*6777b538SAndroid Build Coastguard Worker     kMdns = 3,
29*6777b538SAndroid Build Coastguard Worker     kMdns4 = 4,
30*6777b538SAndroid Build Coastguard Worker     kMdns6 = 5,
31*6777b538SAndroid Build Coastguard Worker     kMdnsMinimal = 6,
32*6777b538SAndroid Build Coastguard Worker     kMdns4Minimal = 7,
33*6777b538SAndroid Build Coastguard Worker     kMdns6Minimal = 8,
34*6777b538SAndroid Build Coastguard Worker     kMyHostname = 9,
35*6777b538SAndroid Build Coastguard Worker     kResolve = 10,
36*6777b538SAndroid Build Coastguard Worker     kNis = 11,
37*6777b538SAndroid Build Coastguard Worker     kMaxValue = kNis
38*6777b538SAndroid Build Coastguard Worker   };
39*6777b538SAndroid Build Coastguard Worker 
40*6777b538SAndroid Build Coastguard Worker   enum class Status {
41*6777b538SAndroid Build Coastguard Worker     kUnknown,
42*6777b538SAndroid Build Coastguard Worker     kSuccess,
43*6777b538SAndroid Build Coastguard Worker     kNotFound,
44*6777b538SAndroid Build Coastguard Worker     kUnavailable,
45*6777b538SAndroid Build Coastguard Worker     kTryAgain,
46*6777b538SAndroid Build Coastguard Worker   };
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker   enum class Action {
49*6777b538SAndroid Build Coastguard Worker     kUnknown,
50*6777b538SAndroid Build Coastguard Worker     kReturn,
51*6777b538SAndroid Build Coastguard Worker     kContinue,
52*6777b538SAndroid Build Coastguard Worker     kMerge,
53*6777b538SAndroid Build Coastguard Worker   };
54*6777b538SAndroid Build Coastguard Worker 
55*6777b538SAndroid Build Coastguard Worker   struct ServiceAction {
56*6777b538SAndroid Build Coastguard Worker     bool operator==(const ServiceAction& other) const {
57*6777b538SAndroid Build Coastguard Worker       return std::tie(negated, status, action) ==
58*6777b538SAndroid Build Coastguard Worker              std::tie(other.negated, other.status, other.action);
59*6777b538SAndroid Build Coastguard Worker     }
60*6777b538SAndroid Build Coastguard Worker 
61*6777b538SAndroid Build Coastguard Worker     bool negated;
62*6777b538SAndroid Build Coastguard Worker     Status status;
63*6777b538SAndroid Build Coastguard Worker     Action action;
64*6777b538SAndroid Build Coastguard Worker   };
65*6777b538SAndroid Build Coastguard Worker 
66*6777b538SAndroid Build Coastguard Worker   struct NET_EXPORT_PRIVATE ServiceSpecification {
67*6777b538SAndroid Build Coastguard Worker     explicit ServiceSpecification(Service service,
68*6777b538SAndroid Build Coastguard Worker                                   std::vector<ServiceAction> actions = {});
69*6777b538SAndroid Build Coastguard Worker     ~ServiceSpecification();
70*6777b538SAndroid Build Coastguard Worker     ServiceSpecification(const ServiceSpecification&);
71*6777b538SAndroid Build Coastguard Worker     ServiceSpecification& operator=(const ServiceSpecification&);
72*6777b538SAndroid Build Coastguard Worker     ServiceSpecification(ServiceSpecification&&);
73*6777b538SAndroid Build Coastguard Worker     ServiceSpecification& operator=(ServiceSpecification&&);
74*6777b538SAndroid Build Coastguard Worker 
75*6777b538SAndroid Build Coastguard Worker     bool operator==(const ServiceSpecification& other) const {
76*6777b538SAndroid Build Coastguard Worker       return std::tie(service, actions) ==
77*6777b538SAndroid Build Coastguard Worker              std::tie(other.service, other.actions);
78*6777b538SAndroid Build Coastguard Worker     }
79*6777b538SAndroid Build Coastguard Worker 
80*6777b538SAndroid Build Coastguard Worker     Service service;
81*6777b538SAndroid Build Coastguard Worker     std::vector<ServiceAction> actions;
82*6777b538SAndroid Build Coastguard Worker   };
83*6777b538SAndroid Build Coastguard Worker 
84*6777b538SAndroid Build Coastguard Worker   // Test-replacable call for the actual file read. Default implementation does
85*6777b538SAndroid Build Coastguard Worker   // a fresh read of the nsswitch.conf file every time it is called. Returns
86*6777b538SAndroid Build Coastguard Worker   // empty string on error reading the file.
87*6777b538SAndroid Build Coastguard Worker   using FileReadCall = base::RepeatingCallback<std::string()>;
88*6777b538SAndroid Build Coastguard Worker 
89*6777b538SAndroid Build Coastguard Worker   NsswitchReader();
90*6777b538SAndroid Build Coastguard Worker   virtual ~NsswitchReader();
91*6777b538SAndroid Build Coastguard Worker 
92*6777b538SAndroid Build Coastguard Worker   NsswitchReader(const NsswitchReader&) = delete;
93*6777b538SAndroid Build Coastguard Worker   NsswitchReader& operator=(const NsswitchReader&) = delete;
94*6777b538SAndroid Build Coastguard Worker 
95*6777b538SAndroid Build Coastguard Worker   // Reads nsswitch.conf and parses the "hosts:" database. In case of multiple
96*6777b538SAndroid Build Coastguard Worker   // matching databases, only parses the first. Assumes a basic default
97*6777b538SAndroid Build Coastguard Worker   // configuration if the file cannot be read or a "hosts:" database cannot be
98*6777b538SAndroid Build Coastguard Worker   // found.
99*6777b538SAndroid Build Coastguard Worker   virtual std::vector<ServiceSpecification> ReadAndParseHosts();
100*6777b538SAndroid Build Coastguard Worker 
set_file_read_call_for_testing(FileReadCall file_read_call)101*6777b538SAndroid Build Coastguard Worker   void set_file_read_call_for_testing(FileReadCall file_read_call) {
102*6777b538SAndroid Build Coastguard Worker     file_read_call_ = std::move(file_read_call);
103*6777b538SAndroid Build Coastguard Worker   }
104*6777b538SAndroid Build Coastguard Worker 
105*6777b538SAndroid Build Coastguard Worker  private:
106*6777b538SAndroid Build Coastguard Worker   FileReadCall file_read_call_;
107*6777b538SAndroid Build Coastguard Worker };
108*6777b538SAndroid Build Coastguard Worker 
109*6777b538SAndroid Build Coastguard Worker }  // namespace net
110*6777b538SAndroid Build Coastguard Worker 
111*6777b538SAndroid Build Coastguard Worker #endif  // NET_DNS_NSSWITCH_READER_H_
112