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