VirtualBox

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

Last change on this file since 78030 was 78030, checked in by vboxsync, 6 years ago

Main/HostDnsServiceDarwin: Preliminary fix to make VBoxSVC start on MacOS again; more work needed in that area, code still is too convoluted.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.1 KB
Line 
1/* $Id: HostDnsServiceDarwin.cpp 78030 2019-04-05 19:08:10Z vboxsync $ */
2/** @file
3 * Darwin specific DNS information fetching.
4 */
5
6/*
7 * Copyright (C) 2004-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. 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/asm.h>
23#include <iprt/errcore.h>
24#include <iprt/thread.h>
25#include <iprt/semaphore.h>
26
27#include <CoreFoundation/CoreFoundation.h>
28#include <SystemConfiguration/SCDynamicStore.h>
29
30#include <string>
31#include <vector>
32#include "../HostDnsService.h"
33
34
35struct HostDnsServiceDarwin::Data
36{
37 Data()
38 : m_fStop(false) { }
39
40 SCDynamicStoreRef m_store;
41 CFRunLoopSourceRef m_DnsWatcher;
42 CFRunLoopRef m_RunLoopRef;
43 CFRunLoopSourceRef m_SourceStop;
44 volatile bool m_fStop;
45 RTSEMEVENT m_evtStop;
46 static void performShutdownCallback(void *);
47};
48
49
50static const CFStringRef kStateNetworkGlobalDNSKey = CFSTR("State:/Network/Global/DNS");
51
52
53HostDnsServiceDarwin::HostDnsServiceDarwin()
54 : HostDnsServiceBase(true /* fThreaded */)
55 , m(NULL)
56{
57 m = new HostDnsServiceDarwin::Data();
58}
59
60HostDnsServiceDarwin::~HostDnsServiceDarwin()
61{
62 if (m != NULL)
63 delete m;
64}
65
66HRESULT HostDnsServiceDarwin::init(HostDnsMonitorProxy *pProxy)
67{
68 SCDynamicStoreContext ctx;
69 RT_ZERO(ctx);
70
71 ctx.info = this;
72
73 m->m_store = SCDynamicStoreCreate(NULL, CFSTR("org.virtualbox.VBoxSVC.HostDNS"),
74 (SCDynamicStoreCallBack)HostDnsServiceDarwin::hostDnsServiceStoreCallback,
75 &ctx);
76 AssertReturn(m->m_store, E_FAIL);
77
78 m->m_DnsWatcher = SCDynamicStoreCreateRunLoopSource(NULL, m->m_store, 0);
79 if (!m->m_DnsWatcher)
80 return E_OUTOFMEMORY;
81
82 int rc = RTSemEventCreate(&m->m_evtStop);
83 AssertRCReturn(rc, E_FAIL);
84
85 CFRunLoopSourceContext sctx;
86 RT_ZERO(sctx);
87 sctx.info = this;
88 sctx.perform = HostDnsServiceDarwin::Data::performShutdownCallback;
89
90 m->m_SourceStop = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &sctx);
91 AssertReturn(m->m_SourceStop, E_FAIL);
92
93 CFRunLoopAddSource(m->m_RunLoopRef, m->m_SourceStop, kCFRunLoopCommonModes);
94
95 HRESULT hrc = HostDnsServiceBase::init(pProxy);
96 return hrc;
97}
98
99void HostDnsServiceDarwin::uninit(void)
100{
101 HostDnsServiceBase::uninit();
102
103 CFRunLoopRemoveSource(m->m_RunLoopRef, m->m_SourceStop, kCFRunLoopCommonModes);
104 CFRelease(m->m_SourceStop);
105
106 CFRelease(m->m_RunLoopRef);
107
108 CFRelease(m->m_DnsWatcher);
109
110 CFRelease(m->m_store);
111
112 RTSemEventDestroy(m->m_evtStop);
113}
114
115int HostDnsServiceDarwin::monitorThreadShutdown(RTMSINTERVAL uTimeoutMs)
116{
117 RTCLock grab(m_LockMtx);
118 if (!m->m_fStop)
119 {
120 ASMAtomicXchgBool(&m->m_fStop, true);
121 CFRunLoopSourceSignal(m->m_SourceStop);
122 CFRunLoopStop(m->m_RunLoopRef);
123
124 RTSemEventWait(m->m_evtStop, uTimeoutMs);
125 }
126
127 return VINF_SUCCESS;
128}
129
130int HostDnsServiceDarwin::monitorThreadProc(void)
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 VERR_NO_MEMORY;
144 }
145
146 if(SCDynamicStoreSetNotificationKeys(m->m_store, watchingArrayRef, NULL))
147 CFRunLoopAddSource(CFRunLoopGetCurrent(), m->m_DnsWatcher, kCFRunLoopCommonModes);
148
149 CFRelease(watchingArrayRef);
150
151 onMonitorThreadInitDone();
152
153 /* Trigger initial update. */
154 int rc = updateInfo();
155 AssertRC(rc); /* Not fatal in release builds. */
156
157 while (!ASMAtomicReadBool(&m->m_fStop))
158 {
159 CFRunLoopRun();
160 }
161
162 /* We're notifying stopper thread. */
163 RTSemEventSignal(m->m_evtStop);
164
165 return VINF_SUCCESS;
166}
167
168int HostDnsServiceDarwin::updateInfo(void)
169{
170 CFPropertyListRef propertyRef = SCDynamicStoreCopyValue(m->m_store, kStateNetworkGlobalDNSKey);
171 /**
172 * # 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 VINF_SUCCESS;
191
192 HostDnsInformation info;
193 CFStringRef domainNameRef = (CFStringRef)CFDictionaryGetValue(
194 static_cast<CFDictionaryRef>(propertyRef), CFSTR("DomainName"));
195
196 if (domainNameRef)
197 {
198 const char *pszDomainName = CFStringGetCStringPtr(domainNameRef, CFStringGetSystemEncoding());
199 if (pszDomainName)
200 info.domain = pszDomainName;
201 }
202
203 int i, arrayCount;
204
205 CFArrayRef serverArrayRef = (CFArrayRef)CFDictionaryGetValue(
206 static_cast<CFDictionaryRef>(propertyRef), CFSTR("ServerAddresses"));
207 if (serverArrayRef)
208 {
209 arrayCount = CFArrayGetCount(serverArrayRef);
210 for (i = 0; i < arrayCount; ++i)
211 {
212 CFStringRef serverAddressRef = (CFStringRef)CFArrayGetValueAtIndex(serverArrayRef, i);
213 if (!serverArrayRef)
214 continue;
215
216 const char *pszServerAddress = CFStringGetCStringPtr(serverAddressRef, 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
227 if (searchArrayRef)
228 {
229 arrayCount = CFArrayGetCount(searchArrayRef);
230
231 for (i = 0; i < arrayCount; ++i)
232 {
233 CFStringRef searchStringRef = (CFStringRef)CFArrayGetValueAtIndex(searchArrayRef, i);
234 if (!searchArrayRef)
235 continue;
236
237 const char *pszSearchString = CFStringGetCStringPtr(searchStringRef, 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 VINF_SUCCESS;
250}
251
252void HostDnsServiceDarwin::hostDnsServiceStoreCallback(void *, void *, void *pInfo)
253{
254 HostDnsServiceDarwin *pThis = (HostDnsServiceDarwin *)pInfo;
255 AssertPtrReturnVoid(pThis);
256
257 RTCLock grab(pThis->m_LockMtx);
258 pThis->updateInfo();
259}
260
261void HostDnsServiceDarwin::Data::performShutdownCallback(void *pInfo)
262{
263 HostDnsServiceDarwin *pThis = (HostDnsServiceDarwin *)pInfo;
264 AssertPtrReturnVoid(pThis);
265
266 AssertPtrReturnVoid(pThis->m);
267 ASMAtomicXchgBool(&pThis->m->m_fStop, true);
268}
269
Note: See TracBrowser for help on using the repository browser.

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