VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp@ 53517

Last change on this file since 53517 was 53122, checked in by vboxsync, 10 years ago

Main/HostDnsService: revert r96327 and follow-up r96329 and r96331 to
revert conversion of HostDnsInformation to Unicode.

HostDnsServiceWin.cpp behavioral changes will be redone as a separate
commit against old definition of HostDnsInformation.

Intervening SafeArray cleanup in r96372 is preserved, hopefully
without errors. Please review.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.7 KB
Line 
1/* $Id: HostDnsServiceDarwin.cpp 53122 2014-10-22 20:43:04Z vboxsync $ */
2/** @file
3 * Darwin specific DNS information fetching.
4 */
5
6/*
7 * Copyright (C) 2004-2013 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include <VBox/com/string.h>
19#include <VBox/com/ptr.h>
20
21
22#include <iprt/err.h>
23#include <iprt/thread.h>
24#include <iprt/semaphore.h>
25
26#include <CoreFoundation/CoreFoundation.h>
27#include <SystemConfiguration/SCDynamicStore.h>
28
29#include <string>
30#include <vector>
31#include "../HostDnsService.h"
32
33
34struct HostDnsServiceDarwin::Data
35{
36 SCDynamicStoreRef m_store;
37 CFRunLoopSourceRef m_DnsWatcher;
38 CFRunLoopRef m_RunLoopRef;
39 CFRunLoopSourceRef m_Stopper;
40 bool m_fStop;
41 RTSEMEVENT m_evtStop;
42 static void performShutdownCallback(void *);
43};
44
45
46static const CFStringRef kStateNetworkGlobalDNSKey = CFSTR("State:/Network/Global/DNS");
47
48
49HostDnsServiceDarwin::HostDnsServiceDarwin():HostDnsMonitor(true),m(NULL)
50{
51 m = new HostDnsServiceDarwin::Data();
52}
53
54
55HostDnsServiceDarwin::~HostDnsServiceDarwin()
56{
57 if (!m)
58 return;
59
60 monitorThreadShutdown();
61
62 CFRelease(m->m_RunLoopRef);
63
64 CFRelease(m->m_DnsWatcher);
65
66 CFRelease(m->m_store);
67
68 RTSemEventDestroy(m->m_evtStop);
69
70 delete m;
71 m = NULL;
72}
73
74
75void HostDnsServiceDarwin::hostDnsServiceStoreCallback(void *, void *, void *info)
76{
77 HostDnsServiceDarwin *pThis = (HostDnsServiceDarwin *)info;
78
79 ALock l(pThis);
80 pThis->updateInfo();
81 pThis->notifyAll();
82}
83
84
85HRESULT HostDnsServiceDarwin::init()
86{
87 SCDynamicStoreContext ctx;
88 RT_ZERO(ctx);
89
90 ctx.info = this;
91
92 m->m_store = SCDynamicStoreCreate(NULL, CFSTR("org.virtualbox.VBoxSVC"),
93 (SCDynamicStoreCallBack)HostDnsServiceDarwin::hostDnsServiceStoreCallback,
94 &ctx);
95 AssertReturn(m->m_store, E_FAIL);
96
97 m->m_DnsWatcher = SCDynamicStoreCreateRunLoopSource(NULL, m->m_store, 0);
98 if (!m->m_DnsWatcher)
99 return E_OUTOFMEMORY;
100
101 int rc = RTSemEventCreate(&m->m_evtStop);
102 AssertRCReturn(rc, E_FAIL);
103
104 CFRunLoopSourceContext sctx;
105 RT_ZERO(sctx);
106 sctx.perform = HostDnsServiceDarwin::Data::performShutdownCallback;
107 m->m_Stopper = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &sctx);
108 AssertReturn(m->m_Stopper, E_FAIL);
109
110 HRESULT hrc = HostDnsMonitor::init();
111 AssertComRCReturn(hrc, hrc);
112
113 return updateInfo();
114}
115
116
117void HostDnsServiceDarwin::monitorThreadShutdown()
118{
119 ALock l(this);
120 if (!m->m_fStop)
121 {
122 CFRunLoopSourceSignal(m->m_Stopper);
123 CFRunLoopWakeUp(m->m_RunLoopRef);
124
125 RTSemEventWait(m->m_evtStop, RT_INDEFINITE_WAIT);
126 }
127}
128
129
130int HostDnsServiceDarwin::monitorWorker()
131{
132 m->m_RunLoopRef = CFRunLoopGetCurrent();
133 AssertReturn(m->m_RunLoopRef, VERR_INTERNAL_ERROR);
134
135 CFRetain(m->m_RunLoopRef);
136
137 CFArrayRef watchingArrayRef = CFArrayCreate(NULL,
138 (const void **)&kStateNetworkGlobalDNSKey,
139 1, &kCFTypeArrayCallBacks);
140 if (!watchingArrayRef)
141 {
142 CFRelease(m->m_DnsWatcher);
143 return E_OUTOFMEMORY;
144 }
145
146 if(SCDynamicStoreSetNotificationKeys(m->m_store, watchingArrayRef, NULL))
147 CFRunLoopAddSource(CFRunLoopGetCurrent(), m->m_DnsWatcher, kCFRunLoopCommonModes);
148
149 CFRelease(watchingArrayRef);
150
151 monitorThreadInitializationDone();
152
153 while (!m->m_fStop)
154 {
155 CFRunLoopRun();
156 }
157
158 CFRelease(m->m_RunLoopRef);
159
160 /* We're notifying stopper thread. */
161 RTSemEventSignal(m->m_evtStop);
162
163 return VINF_SUCCESS;
164}
165
166
167HRESULT HostDnsServiceDarwin::updateInfo()
168{
169 CFPropertyListRef propertyRef = SCDynamicStoreCopyValue(m->m_store,
170 kStateNetworkGlobalDNSKey);
171 /**
172 * 0:vvl@nb-mbp-i7-2(0)# scutil
173 * > get State:/Network/Global/DNS
174 * > d.show
175 * <dictionary> {
176 * DomainName : vvl-domain
177 * SearchDomains : <array> {
178 * 0 : vvl-domain
179 * 1 : de.vvl-domain.com
180 * }
181 * ServerAddresses : <array> {
182 * 0 : 192.168.1.4
183 * 1 : 192.168.1.1
184 * 2 : 8.8.4.4
185 * }
186 * }
187 */
188
189 if (!propertyRef)
190 return S_OK;
191
192 HostDnsInformation info;
193 CFStringRef domainNameRef = (CFStringRef)CFDictionaryGetValue(
194 static_cast<CFDictionaryRef>(propertyRef), CFSTR("DomainName"));
195 if (domainNameRef)
196 {
197 const char *pszDomainName = CFStringGetCStringPtr(domainNameRef,
198 CFStringGetSystemEncoding());
199 if (pszDomainName)
200 info.domain = pszDomainName;
201 }
202
203 int i, arrayCount;
204 CFArrayRef serverArrayRef = (CFArrayRef)CFDictionaryGetValue(
205 static_cast<CFDictionaryRef>(propertyRef), CFSTR("ServerAddresses"));
206 if (serverArrayRef)
207 {
208 arrayCount = CFArrayGetCount(serverArrayRef);
209 for (i = 0; i < arrayCount; ++i)
210 {
211 CFStringRef serverAddressRef = (CFStringRef)CFArrayGetValueAtIndex(serverArrayRef, i);
212 if (!serverArrayRef)
213 continue;
214
215 const char *pszServerAddress = CFStringGetCStringPtr(serverAddressRef,
216 CFStringGetSystemEncoding());
217 if (!pszServerAddress)
218 continue;
219
220 info.servers.push_back(std::string(pszServerAddress));
221 }
222 }
223
224 CFArrayRef searchArrayRef = (CFArrayRef)CFDictionaryGetValue(
225 static_cast<CFDictionaryRef>(propertyRef), CFSTR("SearchDomains"));
226 if (searchArrayRef)
227 {
228 arrayCount = CFArrayGetCount(searchArrayRef);
229
230 for (i = 0; i < arrayCount; ++i)
231 {
232 CFStringRef searchStringRef = (CFStringRef)CFArrayGetValueAtIndex(searchArrayRef, i);
233 if (!searchArrayRef)
234 continue;
235
236 const char *pszSearchString = CFStringGetCStringPtr(searchStringRef,
237 CFStringGetSystemEncoding());
238 if (!pszSearchString)
239 continue;
240
241 info.searchList.push_back(std::string(pszSearchString));
242 }
243 }
244
245 CFRelease(propertyRef);
246
247 setInfo(info);
248
249 return S_OK;
250}
251
252void HostDnsServiceDarwin::Data::performShutdownCallback(void *info)
253{
254 HostDnsServiceDarwin::Data *pThis = static_cast<HostDnsServiceDarwin::Data *>(info);
255 pThis->m_fStop = true;
256}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette