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