1 // Copyright 2012 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_DNS_HOSTS_H_ 6 #define NET_DNS_DNS_HOSTS_H_ 7 8 #include <stddef.h> 9 10 #include <string> 11 #include <string_view> 12 #include <unordered_map> 13 #include <utility> 14 15 #include "base/files/file_path.h" 16 #include "net/base/address_family.h" 17 #include "net/base/ip_address.h" 18 #include "net/base/net_export.h" 19 20 namespace net { 21 22 using DnsHostsKey = std::pair<std::string, AddressFamily>; 23 24 struct DnsHostsKeyHash { operatorDnsHostsKeyHash25 std::size_t operator()(const DnsHostsKey& key) const { 26 return std::hash<std::string_view>()(key.first) + key.second; 27 } 28 }; 29 30 // There are OS-specific variations in how commas in the hosts file behave. 31 enum ParseHostsCommaMode { 32 // Comma is treated as part of a hostname: 33 // "127.0.0.1 foo,bar" parses as "foo,bar" mapping to "127.0.0.1". 34 PARSE_HOSTS_COMMA_IS_TOKEN, 35 36 // Comma is treated as a hostname separator: 37 // "127.0.0.1 foo,bar" parses as "foo" and "bar" both mapping to "127.0.0.1". 38 PARSE_HOSTS_COMMA_IS_WHITESPACE, 39 }; 40 41 // Parsed results of a Hosts file. 42 // 43 // Although Hosts files map IP address to a list of domain names, for name 44 // resolution the desired mapping direction is: domain name to IP address. 45 // When parsing Hosts, we apply the "first hit" rule as Windows and glibc do. 46 // With a Hosts file of: 47 // 300.300.300.300 localhost # bad ip 48 // 127.0.0.1 localhost 49 // 10.0.0.1 localhost 50 // The expected resolution of localhost is 127.0.0.1. 51 using DnsHosts = std::unordered_map<DnsHostsKey, IPAddress, DnsHostsKeyHash>; 52 53 // Parses |contents| (as read from /etc/hosts or equivalent) and stores results 54 // in |dns_hosts|. Invalid lines are ignored (as in most implementations). 55 // Overrides the OS-specific default handling of commas, so unittests can test 56 // both modes. 57 void NET_EXPORT_PRIVATE ParseHostsWithCommaModeForTesting( 58 const std::string& contents, 59 DnsHosts* dns_hosts, 60 ParseHostsCommaMode comma_mode); 61 62 // Parses |contents| (as read from /etc/hosts or equivalent) and stores results 63 // in |dns_hosts|. Invalid lines are ignored (as in most implementations). 64 void NET_EXPORT_PRIVATE ParseHosts(const std::string& contents, 65 DnsHosts* dns_hosts); 66 67 // Test-injectable HOSTS parser. 68 class NET_EXPORT_PRIVATE DnsHostsParser { 69 public: 70 virtual ~DnsHostsParser(); 71 72 // Parses HOSTS and stores results in `dns_hosts`, with addresses in the order 73 // in which they were read. Invalid lines are ignored (as in most 74 // implementations). 75 virtual bool ParseHosts(DnsHosts* hosts) const = 0; 76 }; 77 78 // Implementation of `DnsHostsParser` that reads HOSTS from a given file. 79 class NET_EXPORT_PRIVATE DnsHostsFileParser : public DnsHostsParser { 80 public: 81 explicit DnsHostsFileParser(base::FilePath hosts_file_path); 82 ~DnsHostsFileParser() override; 83 84 DnsHostsFileParser(const DnsHostsFileParser&) = delete; 85 DnsHostsFileParser& operator=(const DnsHostsFileParser&) = delete; 86 87 // DnsHostsParser: 88 bool ParseHosts(DnsHosts* dns_hosts) const override; 89 90 private: 91 const base::FilePath hosts_file_path_; 92 }; 93 94 } // namespace net 95 96 #endif // NET_DNS_DNS_HOSTS_H_ 97