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