VirtualBox

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

Last change on this file since 62890 was 62485, checked in by vboxsync, 8 years ago

(C) 2016

  • 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 62485 2016-07-22 18:36:43Z vboxsync $ */
2/** @file
3 * Darwin specific DNS information fetching.
4 */
5
6/*
7 * Copyright (C) 2004-2016 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 RTCLock grab(pThis->m_LockMtx);
80 pThis->updateInfo();
81}
82
83
84HRESULT HostDnsServiceDarwin::init(VirtualBox *virtualbox)
85{
86 SCDynamicStoreContext ctx;
87 RT_ZERO(ctx);
88
89 ctx.info = this;
90
91 m->m_store = SCDynamicStoreCreate(NULL, CFSTR("org.virtualbox.VBoxSVC"),
92 (SCDynamicStoreCallBack)HostDnsServiceDarwin::hostDnsServiceStoreCallback,
93 &ctx);
94 AssertReturn(m->m_store, E_FAIL);
95
96 m->m_DnsWatcher = SCDynamicStoreCreateRunLoopSource(NULL, m->m_store, 0);
97 if (!m->m_DnsWatcher)
98 return E_OUTOFMEMORY;
99
100 int rc = RTSemEventCreate(&m->m_evtStop);
101 AssertRCReturn(rc, E_FAIL);
102
103 CFRunLoopSourceContext sctx;
104 RT_ZERO(sctx);
105 sctx.perform = HostDnsServiceDarwin::Data::performShutdownCallback;
106 m->m_Stopper = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &sctx);
107 AssertReturn(m->m_Stopper, E_FAIL);
108
109 HRESULT hrc = HostDnsMonitor::init(virtualbox);
110 AssertComRCReturn(hrc, hrc);
111
112 return updateInfo();
113}
114
115
116void HostDnsServiceDarwin::monitorThreadShutdown()
117{
118 RTCLock grab(m_LockMtx);
119 if (!m->m_fStop)
120 {
121 CFRunLoopSourceSignal(m->m_Stopper);
122 CFRunLoopWakeUp(m->m_RunLoopRef);
123
124 RTSemEventWait(m->m_evtStop, RT_INDEFINITE_WAIT);
125 }
126}
127
128
129int HostDnsServiceDarwin::monitorWorker()
130{
131 m->m_RunLoopRef = CFRunLoopGetCurrent();
132 AssertReturn(m->m_RunLoopRef, VERR_INTERNAL_ERROR);
133
134 CFRetain(m->m_RunLoopRef);
135
136 CFArrayRef watchingArrayRef = CFArrayCreate(NULL,
137 (const void **)&kStateNetworkGlobalDNSKey,
138 1, &kCFTypeArrayCallBacks);
139 if (!watchingArrayRef)
140 {
141 CFRelease(m->m_DnsWatcher);
142 return E_OUTOFMEMORY;
143 }
144
145 if(SCDynamicStoreSetNotificationKeys(m->m_store, watchingArrayRef, NULL))
146 CFRunLoopAddSource(CFRunLoopGetCurrent(), m->m_DnsWatcher, kCFRunLoopCommonModes);
147
148 CFRelease(watchingArrayRef);
149
150 monitorThreadInitializationDone();
151
152 while (!m->m_fStop)
153 {
154 CFRunLoopRun();
155 }
156
157 CFRelease(m->m_RunLoopRef);
158
159 /* We're notifying stopper thread. */
160 RTSemEventSignal(m->m_evtStop);
161
162 return VINF_SUCCESS;
163}
164
165
166HRESULT HostDnsServiceDarwin::updateInfo()
167{
168 CFPropertyListRef propertyRef = SCDynamicStoreCopyValue(m->m_store,
169 kStateNetworkGlobalDNSKey);
170 /**
171 * 0:vvl@nb-mbp-i7-2(0)# scutil
172 * > get State:/Network/Global/DNS
173 * > d.show
174 * <dictionary> {
175 * DomainName : vvl-domain
176 * SearchDomains : <array> {
177 * 0 : vvl-domain
178 * 1 : de.vvl-domain.com
179 * }
180 * ServerAddresses : <array> {
181 * 0 : 192.168.1.4
182 * 1 : 192.168.1.1
183 * 2 : 8.8.4.4
184 * }
185 * }
186 */
187
188 if (!propertyRef)
189 return S_OK;
190
191 HostDnsInformation info;
192 CFStringRef domainNameRef = (CFStringRef)CFDictionaryGetValue(
193 static_cast<CFDictionaryRef>(propertyRef), CFSTR("DomainName"));
194 if (domainNameRef)
195 {
196 const char *pszDomainName = CFStringGetCStringPtr(domainNameRef,
197 CFStringGetSystemEncoding());
198 if (pszDomainName)
199 info.domain = pszDomainName;
200 }
201
202 int i, arrayCount;
203 CFArrayRef serverArrayRef = (CFArrayRef)CFDictionaryGetValue(
204 static_cast<CFDictionaryRef>(propertyRef), CFSTR("ServerAddresses"));
205 if (serverArrayRef)
206 {
207 arrayCount = CFArrayGetCount(serverArrayRef);
208 for (i = 0; i < arrayCount; ++i)
209 {
210 CFStringRef serverAddressRef = (CFStringRef)CFArrayGetValueAtIndex(serverArrayRef, i);
211 if (!serverArrayRef)
212 continue;
213
214 const char *pszServerAddress = CFStringGetCStringPtr(serverAddressRef,
215 CFStringGetSystemEncoding());
216 if (!pszServerAddress)
217 continue;
218
219 info.servers.push_back(std::string(pszServerAddress));
220 }
221 }
222
223 CFArrayRef searchArrayRef = (CFArrayRef)CFDictionaryGetValue(
224 static_cast<CFDictionaryRef>(propertyRef), CFSTR("SearchDomains"));
225 if (searchArrayRef)
226 {
227 arrayCount = CFArrayGetCount(searchArrayRef);
228
229 for (i = 0; i < arrayCount; ++i)
230 {
231 CFStringRef searchStringRef = (CFStringRef)CFArrayGetValueAtIndex(searchArrayRef, i);
232 if (!searchArrayRef)
233 continue;
234
235 const char *pszSearchString = CFStringGetCStringPtr(searchStringRef,
236 CFStringGetSystemEncoding());
237 if (!pszSearchString)
238 continue;
239
240 info.searchList.push_back(std::string(pszSearchString));
241 }
242 }
243
244 CFRelease(propertyRef);
245
246 setInfo(info);
247
248 return S_OK;
249}
250
251void HostDnsServiceDarwin::Data::performShutdownCallback(void *info)
252{
253 HostDnsServiceDarwin::Data *pThis = static_cast<HostDnsServiceDarwin::Data *>(info);
254 pThis->m_fStop = true;
255}
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