VirtualBox

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

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

Main/HostDnsService: Renaming and cleanup (no functional changes).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.9 KB
Line 
1/* $Id: HostDnsServiceDarwin.cpp 77984 2019-04-02 14:06:13Z 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_Stopper;
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)
55 , m(NULL)
56{
57 m = new HostDnsServiceDarwin::Data();
58}
59
60
61HostDnsServiceDarwin::~HostDnsServiceDarwin()
62{
63 if (!m)
64 return;
65
66 monitorThreadShutdown();
67
68 CFRelease(m->m_RunLoopRef);
69
70 CFRelease(m->m_DnsWatcher);
71
72 CFRelease(m->m_store);
73
74 RTSemEventDestroy(m->m_evtStop);
75
76 delete m;
77 m = NULL;
78}
79
80
81void HostDnsServiceDarwin::hostDnsServiceStoreCallback(void *, void *, void *info)
82{
83 HostDnsServiceDarwin *pThis = (HostDnsServiceDarwin *)info;
84
85 RTCLock grab(pThis->m_LockMtx);
86 pThis->updateInfo();
87}
88
89
90HRESULT HostDnsServiceDarwin::init(HostDnsMonitorProxy *pProxy)
91{
92 SCDynamicStoreContext ctx;
93 RT_ZERO(ctx);
94
95 ctx.info = this;
96
97 m->m_store = SCDynamicStoreCreate(NULL, CFSTR("org.virtualbox.VBoxSVC"),
98 (SCDynamicStoreCallBack)HostDnsServiceDarwin::hostDnsServiceStoreCallback,
99 &ctx);
100 AssertReturn(m->m_store, E_FAIL);
101
102 m->m_DnsWatcher = SCDynamicStoreCreateRunLoopSource(NULL, m->m_store, 0);
103 if (!m->m_DnsWatcher)
104 return E_OUTOFMEMORY;
105
106 int rc = RTSemEventCreate(&m->m_evtStop);
107 AssertRCReturn(rc, E_FAIL);
108
109 CFRunLoopSourceContext sctx;
110 RT_ZERO(sctx);
111 sctx.perform = HostDnsServiceDarwin::Data::performShutdownCallback;
112 m->m_Stopper = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &sctx);
113 AssertReturn(m->m_Stopper, E_FAIL);
114
115 HRESULT hrc = HostDnsServiceBase::init(pProxy);
116 AssertComRCReturn(hrc, hrc);
117
118 return updateInfo();
119}
120
121
122void HostDnsServiceDarwin::monitorThreadShutdown(void)
123{
124 RTCLock grab(m_LockMtx);
125 if (!m->m_fStop)
126 {
127 ASMAtomicXchgBool(&m->m_fStop, true);
128 CFRunLoopSourceSignal(m->m_Stopper);
129 CFRunLoopStop(m->m_RunLoopRef);
130
131 RTSemEventWait(m->m_evtStop, RT_INDEFINITE_WAIT);
132 }
133}
134
135
136int HostDnsServiceDarwin::monitorWorker(void)
137{
138 m->m_RunLoopRef = CFRunLoopGetCurrent();
139 AssertReturn(m->m_RunLoopRef, VERR_INTERNAL_ERROR);
140
141 CFRetain(m->m_RunLoopRef);
142
143 CFArrayRef watchingArrayRef = CFArrayCreate(NULL,
144 (const void **)&kStateNetworkGlobalDNSKey,
145 1, &kCFTypeArrayCallBacks);
146 if (!watchingArrayRef)
147 {
148 CFRelease(m->m_DnsWatcher);
149 return E_OUTOFMEMORY;
150 }
151
152 if(SCDynamicStoreSetNotificationKeys(m->m_store, watchingArrayRef, NULL))
153 CFRunLoopAddSource(CFRunLoopGetCurrent(), m->m_DnsWatcher, kCFRunLoopCommonModes);
154
155 CFRelease(watchingArrayRef);
156
157 monitorThreadInitializationDone();
158
159 while (!ASMAtomicReadBool(&m->m_fStop))
160 {
161 CFRunLoopRun();
162 }
163
164 CFRelease(m->m_RunLoopRef);
165
166 /* We're notifying stopper thread. */
167 RTSemEventSignal(m->m_evtStop);
168
169 return VINF_SUCCESS;
170}
171
172HRESULT HostDnsServiceDarwin::updateInfo(void)
173{
174 CFPropertyListRef propertyRef = SCDynamicStoreCopyValue(m->m_store,
175 kStateNetworkGlobalDNSKey);
176 /**
177 * # scutil
178 * \> get State:/Network/Global/DNS
179 * \> d.show
180 * \<dictionary\> {
181 * DomainName : vvl-domain
182 * SearchDomains : \<array\> {
183 * 0 : vvl-domain
184 * 1 : de.vvl-domain.com
185 * }
186 * ServerAddresses : \<array\> {
187 * 0 : 192.168.1.4
188 * 1 : 192.168.1.1
189 * 2 : 8.8.4.4
190 * }
191 * }
192 */
193
194 if (!propertyRef)
195 return S_OK;
196
197 HostDnsInformation info;
198 CFStringRef domainNameRef = (CFStringRef)CFDictionaryGetValue(
199 static_cast<CFDictionaryRef>(propertyRef), CFSTR("DomainName"));
200 if (domainNameRef)
201 {
202 const char *pszDomainName = CFStringGetCStringPtr(domainNameRef,
203 CFStringGetSystemEncoding());
204 if (pszDomainName)
205 info.domain = pszDomainName;
206 }
207
208 int i, arrayCount;
209 CFArrayRef serverArrayRef = (CFArrayRef)CFDictionaryGetValue(
210 static_cast<CFDictionaryRef>(propertyRef), CFSTR("ServerAddresses"));
211 if (serverArrayRef)
212 {
213 arrayCount = CFArrayGetCount(serverArrayRef);
214 for (i = 0; i < arrayCount; ++i)
215 {
216 CFStringRef serverAddressRef = (CFStringRef)CFArrayGetValueAtIndex(serverArrayRef, i);
217 if (!serverArrayRef)
218 continue;
219
220 const char *pszServerAddress = CFStringGetCStringPtr(serverAddressRef,
221 CFStringGetSystemEncoding());
222 if (!pszServerAddress)
223 continue;
224
225 info.servers.push_back(std::string(pszServerAddress));
226 }
227 }
228
229 CFArrayRef searchArrayRef = (CFArrayRef)CFDictionaryGetValue(
230 static_cast<CFDictionaryRef>(propertyRef), CFSTR("SearchDomains"));
231 if (searchArrayRef)
232 {
233 arrayCount = CFArrayGetCount(searchArrayRef);
234
235 for (i = 0; i < arrayCount; ++i)
236 {
237 CFStringRef searchStringRef = (CFStringRef)CFArrayGetValueAtIndex(searchArrayRef, i);
238 if (!searchArrayRef)
239 continue;
240
241 const char *pszSearchString = CFStringGetCStringPtr(searchStringRef,
242 CFStringGetSystemEncoding());
243 if (!pszSearchString)
244 continue;
245
246 info.searchList.push_back(std::string(pszSearchString));
247 }
248 }
249
250 CFRelease(propertyRef);
251
252 setInfo(info);
253
254 return S_OK;
255}
256
257void HostDnsServiceDarwin::Data::performShutdownCallback(void *pInfo)
258{
259 HostDnsServiceDarwin::Data *pThis = static_cast<HostDnsServiceDarwin::Data *>(pInfo);
260 AssertPtrReturnVoid(pThis);
261 pThis->m_fStop = true;
262}
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