1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/dns/dns_config_watcher_mac.h"
9 #include "base/lazy_instance.h"
10 #include "third_party/apple_apsl/dnsinfo.h"
14 // dnsinfo symbols are available via libSystem.dylib, but can also be present in
15 // SystemConfiguration.framework. To avoid confusion, load them explicitly from
19 typedef const char* (*dns_configuration_notify_key_t
)();
20 typedef dns_config_t
* (*dns_configuration_copy_t
)();
21 typedef void (*dns_configuration_free_t
)(dns_config_t
*);
24 : dns_configuration_notify_key(NULL
),
25 dns_configuration_copy(NULL
),
26 dns_configuration_free(NULL
) {
27 handle_
= dlopen("/usr/lib/libSystem.dylib",
28 RTLD_LAZY
| RTLD_NOLOAD
);
31 dns_configuration_notify_key
=
32 reinterpret_cast<dns_configuration_notify_key_t
>(
33 dlsym(handle_
, "dns_configuration_notify_key"));
34 dns_configuration_copy
=
35 reinterpret_cast<dns_configuration_copy_t
>(
36 dlsym(handle_
, "dns_configuration_copy"));
37 dns_configuration_free
=
38 reinterpret_cast<dns_configuration_free_t
>(
39 dlsym(handle_
, "dns_configuration_free"));
47 dns_configuration_notify_key_t dns_configuration_notify_key
;
48 dns_configuration_copy_t dns_configuration_copy
;
49 dns_configuration_free_t dns_configuration_free
;
55 const DnsInfoApi
& GetDnsInfoApi() {
56 static base::LazyInstance
<DnsInfoApi
>::Leaky api
= LAZY_INSTANCE_INITIALIZER
;
60 struct DnsConfigTDeleter
{
61 inline void operator()(dns_config_t
* ptr
) const {
62 if (GetDnsInfoApi().dns_configuration_free
)
63 GetDnsInfoApi().dns_configuration_free(ptr
);
72 bool DnsConfigWatcher::Watch(
73 const base::Callback
<void(bool succeeded
)>& callback
) {
74 if (!GetDnsInfoApi().dns_configuration_notify_key
)
76 return watcher_
.Watch(GetDnsInfoApi().dns_configuration_notify_key(),
81 ConfigParsePosixResult
DnsConfigWatcher::CheckDnsConfig() {
82 if (!GetDnsInfoApi().dns_configuration_copy
)
83 return CONFIG_PARSE_POSIX_NO_DNSINFO
;
84 scoped_ptr
<dns_config_t
, DnsConfigTDeleter
> dns_config(
85 GetDnsInfoApi().dns_configuration_copy());
87 return CONFIG_PARSE_POSIX_NO_DNSINFO
;
89 // TODO(szym): Parse dns_config_t for resolvers rather than res_state.
90 // DnsClient can't handle domain-specific unscoped resolvers.
91 unsigned num_resolvers
= 0;
92 for (int i
= 0; i
< dns_config
->n_resolver
; ++i
) {
93 dns_resolver_t
* resolver
= dns_config
->resolver
[i
];
94 if (!resolver
->n_nameserver
)
96 if (resolver
->options
&& !strcmp(resolver
->options
, "mdns"))
100 if (num_resolvers
> 1)
101 return CONFIG_PARSE_POSIX_UNHANDLED_OPTIONS
;
102 return CONFIG_PARSE_POSIX_OK
;
105 } // namespace internal