dns_config_service_win.h revision 5e3f23d412006dc4db4e659864679f29341e113f
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NET_DNS_DNS_CONFIG_SERVICE_WIN_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_DNS_DNS_CONFIG_SERVICE_WIN_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The sole purpose of dns_config_service_win.h is for unittests so we just
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// include these headers here.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <winsock2.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <iphlpapi.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
185e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string16.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_export.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/dns/dns_config_service.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The general effort of DnsConfigServiceWin is to configure |nameservers| and
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |search| in DnsConfig. The settings are stored in the Windows registry, but
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to simplify the task we use the IP Helper API wherever possible. That API
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// yields the complete and ordered |nameservers|, but to determine |search| we
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// need to use the registry. On Windows 7, WMI does return the correct |search|
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// but on earlier versions it is insufficient.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Experimental evaluation of Windows behavior suggests that domain parsing is
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// naive. Domain suffixes in |search| are not validated until they are appended
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to the resolved name. We attempt to replicate this behavior.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Registry key paths.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t* const kTcpipPath =
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters";
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t* const kTcpip6Path =
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters";
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t* const kDnscachePath =
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"SYSTEM\\CurrentControlSet\\Services\\Dnscache\\Parameters";
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t* const kPolicyPath =
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"SOFTWARE\\Policies\\Microsoft\\Windows NT\\DNSClient";
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the path to the HOSTS file.
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetHostsPath();
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Parses |value| as search list (comma-delimited list of domain names) from
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a registry key and stores it in |out|. Returns true on success. Empty
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// entries (e.g., "chromium.org,,org") terminate the list. Non-ascii hostnames
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are converted to punycode.
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool NET_EXPORT_PRIVATE ParseSearchList(const base::string16& value,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        std::vector<std::string>* out);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All relevant settings read from registry and IP Helper. This isolates our
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// logic from system calls and is exposed for unit tests. Keep it an aggregate
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// struct for easy initialization.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct NET_EXPORT_PRIVATE DnsSystemSettings {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The |set| flag distinguishes between empty and unset values.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct RegString {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool set;
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::string16 value;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct RegDword {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool set;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD value;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct DevolutionSetting {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // UseDomainNameDevolution
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RegDword enabled;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // DomainNameDevolutionLevel
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RegDword level;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Filled in by GetAdapterAddresses. Note that the alternative
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GetNetworkParams does not include IPv6 addresses.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr_malloc<IP_ADAPTER_ADDRESSES> addresses;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SOFTWARE\Policies\Microsoft\Windows NT\DNSClient\SearchList
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegString policy_search_list;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SYSTEM\CurrentControlSet\Tcpip\Parameters\SearchList
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegString tcpip_search_list;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SYSTEM\CurrentControlSet\Tcpip\Parameters\Domain
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegString tcpip_domain;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SOFTWARE\Policies\Microsoft\System\DNSClient\PrimaryDnsSuffix
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegString primary_dns_suffix;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SOFTWARE\Policies\Microsoft\Windows NT\DNSClient
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DevolutionSetting policy_devolution;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SYSTEM\CurrentControlSet\Dnscache\Parameters
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DevolutionSetting dnscache_devolution;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SYSTEM\CurrentControlSet\Tcpip\Parameters
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DevolutionSetting tcpip_devolution;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SOFTWARE\Policies\Microsoft\Windows NT\DNSClient\AppendToMultiLabelName
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegDword append_to_multi_label_name;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum ConfigParseWinResult {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CONFIG_PARSE_WIN_OK = 0,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CONFIG_PARSE_WIN_READ_IPHELPER,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CONFIG_PARSE_WIN_READ_POLICY_SEARCHLIST,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CONFIG_PARSE_WIN_READ_TCPIP_SEARCHLIST,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CONFIG_PARSE_WIN_READ_DOMAIN,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CONFIG_PARSE_WIN_READ_POLICY_DEVOLUTION,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CONFIG_PARSE_WIN_READ_DNSCACHE_DEVOLUTION,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CONFIG_PARSE_WIN_READ_TCPIP_DEVOLUTION,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CONFIG_PARSE_WIN_READ_APPEND_MULTILABEL,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CONFIG_PARSE_WIN_READ_PRIMARY_SUFFIX,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CONFIG_PARSE_WIN_BAD_ADDRESS,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CONFIG_PARSE_WIN_NO_NAMESERVERS,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CONFIG_PARSE_WIN_MAX  // Bounding values for enumeration.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fills in |dns_config| from |settings|. Exposed for tests.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ConfigParseWinResult NET_EXPORT_PRIVATE ConvertSettingsToDnsConfig(
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const DnsSystemSettings& settings,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DnsConfig* dns_config);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use DnsConfigService::CreateSystemService to use it outside of tests.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE DnsConfigServiceWin : public DnsConfigService {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DnsConfigServiceWin();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~DnsConfigServiceWin();
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Watcher;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class ConfigReader;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class HostsReader;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DnsConfigService:
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ReadNow() OVERRIDE;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool StartWatching() OVERRIDE;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnConfigChanged(bool succeeded);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnHostsChanged(bool succeeded);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Watcher> watcher_;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<ConfigReader> config_reader_;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HostsReader> hosts_reader_;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DnsConfigServiceWin);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // NET_DNS_DNS_CONFIG_SERVICE_WIN_H_
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155