• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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