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