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)// Parses |value| as search list (comma-delimited list of domain names) from 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a registry key and stores it in |out|. Returns true on success. Empty 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// entries (e.g., "chromium.org,,org") terminate the list. Non-ascii hostnames 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are converted to punycode. 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool NET_EXPORT_PRIVATE ParseSearchList(const base::string16& value, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string>* out); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All relevant settings read from registry and IP Helper. This isolates our 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// logic from system calls and is exposed for unit tests. Keep it an aggregate 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// struct for easy initialization. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct NET_EXPORT_PRIVATE DnsSystemSettings { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The |set| flag distinguishes between empty and unset values. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct RegString { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool set; 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16 value; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct RegDword { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool set; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD value; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct DevolutionSetting { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UseDomainNameDevolution 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RegDword enabled; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DomainNameDevolutionLevel 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RegDword level; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Filled in by GetAdapterAddresses. Note that the alternative 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GetNetworkParams does not include IPv6 addresses. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr_malloc<IP_ADAPTER_ADDRESSES> addresses; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SOFTWARE\Policies\Microsoft\Windows NT\DNSClient\SearchList 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RegString policy_search_list; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SYSTEM\CurrentControlSet\Tcpip\Parameters\SearchList 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RegString tcpip_search_list; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SYSTEM\CurrentControlSet\Tcpip\Parameters\Domain 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RegString tcpip_domain; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SOFTWARE\Policies\Microsoft\System\DNSClient\PrimaryDnsSuffix 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RegString primary_dns_suffix; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SOFTWARE\Policies\Microsoft\Windows NT\DNSClient 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DevolutionSetting policy_devolution; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SYSTEM\CurrentControlSet\Dnscache\Parameters 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DevolutionSetting dnscache_devolution; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SYSTEM\CurrentControlSet\Tcpip\Parameters 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DevolutionSetting tcpip_devolution; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SOFTWARE\Policies\Microsoft\Windows NT\DNSClient\AppendToMultiLabelName 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RegDword append_to_multi_label_name; 88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // True when the Name Resolution Policy Table (NRPT) has at least one rule: 90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // SOFTWARE\Policies\Microsoft\Windows NT\DNSClient\DnsPolicyConfig\Rule* 91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool have_name_resolution_policy; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum ConfigParseWinResult { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONFIG_PARSE_WIN_OK = 0, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONFIG_PARSE_WIN_READ_IPHELPER, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONFIG_PARSE_WIN_READ_POLICY_SEARCHLIST, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONFIG_PARSE_WIN_READ_TCPIP_SEARCHLIST, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONFIG_PARSE_WIN_READ_DOMAIN, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONFIG_PARSE_WIN_READ_POLICY_DEVOLUTION, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONFIG_PARSE_WIN_READ_DNSCACHE_DEVOLUTION, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONFIG_PARSE_WIN_READ_TCPIP_DEVOLUTION, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONFIG_PARSE_WIN_READ_APPEND_MULTILABEL, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONFIG_PARSE_WIN_READ_PRIMARY_SUFFIX, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONFIG_PARSE_WIN_BAD_ADDRESS, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONFIG_PARSE_WIN_NO_NAMESERVERS, 107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) CONFIG_PARSE_WIN_UNHANDLED_OPTIONS, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONFIG_PARSE_WIN_MAX // Bounding values for enumeration. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fills in |dns_config| from |settings|. Exposed for tests. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ConfigParseWinResult NET_EXPORT_PRIVATE ConvertSettingsToDnsConfig( 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DnsSystemSettings& settings, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DnsConfig* dns_config); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use DnsConfigService::CreateSystemService to use it outside of tests. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE DnsConfigServiceWin : public DnsConfigService { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DnsConfigServiceWin(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~DnsConfigServiceWin(); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Watcher; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class ConfigReader; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class HostsReader; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DnsConfigService: 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ReadNow() OVERRIDE; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool StartWatching() OVERRIDE; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnConfigChanged(bool succeeded); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnHostsChanged(bool succeeded); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Watcher> watcher_; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ConfigReader> config_reader_; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<HostsReader> hosts_reader_; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DnsConfigServiceWin); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace internal 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // NET_DNS_DNS_CONFIG_SERVICE_WIN_H_ 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 147