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