VirtualBox

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

最後變更 在這個檔案是 108012,由 vboxsync 提交於 6 週 前

Main: Replaced std::string with com::Utf8Str in the HostDnsService code, santizing all the strings.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 8.1 KB
 
1/* $Id: HostDnsServiceDarwin.cpp 108012 2025-02-01 02:19:11Z vboxsync $ */
2/** @file
3 * Darwin specific DNS information fetching.
4 */
5
6/*
7 * Copyright (C) 2004-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.alldomusa.eu.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#include <VBox/com/string.h>
29#include <VBox/com/ptr.h>
30
31
32#include <iprt/asm.h>
33#include <iprt/errcore.h>
34#include <iprt/thread.h>
35#include <iprt/semaphore.h>
36
37#include <CoreFoundation/CoreFoundation.h>
38#include <SystemConfiguration/SCDynamicStore.h>
39
40#include <vector>
41#include "../HostDnsService.h"
42
43
44struct HostDnsServiceDarwin::Data
45{
46 Data()
47 : m_store(NULL)
48 , m_DnsWatcher(NULL)
49 , m_RunLoopRef(NULL)
50 , m_SourceStop(NULL)
51 , m_fStop(false)
52 , m_evtStop(NIL_RTSEMEVENT) { }
53
54 SCDynamicStoreRef m_store;
55 CFRunLoopSourceRef m_DnsWatcher;
56 CFRunLoopRef m_RunLoopRef;
57 CFRunLoopSourceRef m_SourceStop;
58 volatile bool m_fStop;
59 RTSEMEVENT m_evtStop;
60 static void performShutdownCallback(void *);
61};
62
63
64static const CFStringRef kStateNetworkGlobalDNSKey = CFSTR("State:/Network/Global/DNS");
65
66
67HostDnsServiceDarwin::HostDnsServiceDarwin()
68 : HostDnsServiceBase(true /* fThreaded */)
69 , m(NULL)
70{
71 m = new HostDnsServiceDarwin::Data();
72}
73
74HostDnsServiceDarwin::~HostDnsServiceDarwin()
75{
76 if (m != NULL)
77 delete m;
78}
79
80HRESULT HostDnsServiceDarwin::init(HostDnsMonitorProxy *pProxy)
81{
82 SCDynamicStoreContext ctx;
83 RT_ZERO(ctx);
84
85 ctx.info = this;
86
87 m->m_store = SCDynamicStoreCreate(NULL, CFSTR("org.virtualbox.VBoxSVC.HostDNS"),
88 (SCDynamicStoreCallBack)HostDnsServiceDarwin::hostDnsServiceStoreCallback,
89 &ctx);
90 AssertReturn(m->m_store, E_FAIL);
91
92 m->m_DnsWatcher = SCDynamicStoreCreateRunLoopSource(NULL, m->m_store, 0);
93 if (!m->m_DnsWatcher)
94 return E_OUTOFMEMORY;
95
96 int vrc = RTSemEventCreate(&m->m_evtStop);
97 AssertRCReturn(vrc, E_FAIL);
98
99 CFRunLoopSourceContext sctx;
100 RT_ZERO(sctx);
101 sctx.info = this;
102 sctx.perform = HostDnsServiceDarwin::Data::performShutdownCallback;
103
104 m->m_SourceStop = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &sctx);
105 AssertReturn(m->m_SourceStop, E_FAIL);
106
107 HRESULT hrc = HostDnsServiceBase::init(pProxy);
108 return hrc;
109}
110
111void HostDnsServiceDarwin::uninit(void)
112{
113 HostDnsServiceBase::uninit();
114
115 CFRelease(m->m_SourceStop);
116 m->m_SourceStop = NULL;
117 CFRelease(m->m_RunLoopRef);
118 m->m_RunLoopRef = NULL;
119 CFRelease(m->m_DnsWatcher);
120 m->m_DnsWatcher = NULL;
121 CFRelease(m->m_store);
122 m->m_store = NULL;
123
124 RTSemEventDestroy(m->m_evtStop);
125 m->m_evtStop = NIL_RTSEMEVENT;
126}
127
128int HostDnsServiceDarwin::monitorThreadShutdown(RTMSINTERVAL uTimeoutMs)
129{
130 RTCLock grab(m_LockMtx);
131 if (!m->m_fStop)
132 {
133 ASMAtomicXchgBool(&m->m_fStop, true);
134 CFRunLoopSourceSignal(m->m_SourceStop);
135 CFRunLoopStop(m->m_RunLoopRef);
136
137 grab.release(); /* bird 2025-01-31: May deadlock otherwise since hostDnsServiceStoreCallback takes the lock. */
138 RTSemEventWait(m->m_evtStop, uTimeoutMs);
139 }
140
141 return VINF_SUCCESS;
142}
143
144int HostDnsServiceDarwin::monitorThreadProc(void)
145{
146 m->m_RunLoopRef = CFRunLoopGetCurrent();
147 AssertReturn(m->m_RunLoopRef, VERR_INTERNAL_ERROR);
148
149 CFRetain(m->m_RunLoopRef);
150
151 CFRunLoopAddSource(m->m_RunLoopRef, m->m_SourceStop, kCFRunLoopCommonModes);
152
153 CFArrayRef watchingArrayRef = CFArrayCreate(NULL,
154 (const void **)&kStateNetworkGlobalDNSKey,
155 1, &kCFTypeArrayCallBacks);
156 if (!watchingArrayRef)
157 {
158 CFRelease(m->m_DnsWatcher);
159 return VERR_NO_MEMORY;
160 }
161
162 if (SCDynamicStoreSetNotificationKeys(m->m_store, watchingArrayRef, NULL))
163 CFRunLoopAddSource(CFRunLoopGetCurrent(), m->m_DnsWatcher, kCFRunLoopCommonModes);
164
165 CFRelease(watchingArrayRef);
166
167 onMonitorThreadInitDone();
168
169 /* Trigger initial update. */
170 int vrc = updateInfo(); /** @todo r=bird: Not holding the lock here, unlike what hostDnsServiceStoreCallback does... */
171 AssertRC(vrc); /* Not fatal in release builds. */ /** @todo r=bird: The function always returns VINF_SUCCESS. */
172
173 while (!ASMAtomicReadBool(&m->m_fStop))
174 {
175 CFRunLoopRun();
176 }
177
178 CFRunLoopRemoveSource(m->m_RunLoopRef, m->m_SourceStop, kCFRunLoopCommonModes);
179
180 /* We're notifying stopper thread. */
181 RTSemEventSignal(m->m_evtStop);
182
183 return VINF_SUCCESS;
184}
185
186DECLINLINE(bool) queryCFStringAsUtf8Str(CFStringRef hRefSrc, com::Utf8Str &a_rDst, size_t cbMax)
187{
188 a_rDst.reserve(_1K);
189 if (!CFStringGetCString(hRefSrc, a_rDst.mutableRaw(), (CFIndex)a_rDst.capacity(), kCFStringEncodingUTF8))
190 {
191 a_rDst.reserve(cbMax);
192 if (!CFStringGetCString(hRefSrc, a_rDst.mutableRaw(), (CFIndex)a_rDst.capacity(), kCFStringEncodingUTF8))
193 return false;
194 }
195 RTStrPurgeEncoding(a_rDst.mutableRaw()); /* paranoia */
196 a_rDst.jolt();
197 return true;
198}
199
200
201int HostDnsServiceDarwin::updateInfo(void)
202{
203 CFPropertyListRef propertyRef = SCDynamicStoreCopyValue(m->m_store, kStateNetworkGlobalDNSKey);
204 /*
205 * # scutil
206 * \> get State:/Network/Global/DNS
207 * \> d.show
208 * \<dictionary\> {
209 * DomainName : vvl-domain
210 * SearchDomains : \<array\> {
211 * 0 : vvl-domain
212 * 1 : de.vvl-domain.com
213 * }
214 * ServerAddresses : \<array\> {
215 * 0 : 192.168.1.4
216 * 1 : 192.168.1.1
217 * 2 : 8.8.4.4
218 * }
219 * }
220 */
221 if (!propertyRef)
222 return VINF_SUCCESS;
223 CFDictionaryRef const propertyAsDictRef = static_cast<CFDictionaryRef>(propertyRef);
224
225 HostDnsInformation info;
226 com::Utf8Str strTmp;
227
228 CFStringRef const domainNameRef = (CFStringRef)CFDictionaryGetValue(propertyAsDictRef, CFSTR("DomainName"));
229 if (domainNameRef)
230 if (queryCFStringAsUtf8Str(domainNameRef, strTmp, _16K))
231 info.domain = strTmp;
232
233 CFArrayRef const serverArrayRef = (CFArrayRef)CFDictionaryGetValue(propertyAsDictRef, CFSTR("ServerAddresses"));
234 if (serverArrayRef)
235 {
236 CFIndex const cItems = CFArrayGetCount(serverArrayRef);
237 for (CFIndex i = 0; i < cItems; ++i)
238 {
239 CFStringRef const serverAddressRef = (CFStringRef)CFArrayGetValueAtIndex(serverArrayRef, i);
240 if (serverAddressRef)
241 if (queryCFStringAsUtf8Str(serverAddressRef, strTmp, _16K))
242 info.servers.push_back(strTmp);
243 }
244 }
245
246 CFArrayRef const searchArrayRef = (CFArrayRef)CFDictionaryGetValue(propertyAsDictRef, CFSTR("SearchDomains"));
247 if (searchArrayRef)
248 {
249 CFIndex const cItems = CFArrayGetCount(searchArrayRef);
250 for (CFIndex i = 0; i < cItems; ++i)
251 {
252 CFStringRef searchStringRef = (CFStringRef)CFArrayGetValueAtIndex(searchArrayRef, i);
253 if (searchStringRef)
254 if (queryCFStringAsUtf8Str(searchStringRef, strTmp, _64K))
255 info.searchList.push_back(strTmp);
256 }
257 }
258
259 CFRelease(propertyRef);
260
261 setInfo(info);
262
263 return VINF_SUCCESS;
264}
265
266void HostDnsServiceDarwin::hostDnsServiceStoreCallback(void *, void *, void *pInfo)
267{
268 HostDnsServiceDarwin *pThis = (HostDnsServiceDarwin *)pInfo;
269 AssertPtrReturnVoid(pThis);
270
271 RTCLock grab(pThis->m_LockMtx);
272 pThis->updateInfo();
273}
274
275void HostDnsServiceDarwin::Data::performShutdownCallback(void *pInfo)
276{
277 HostDnsServiceDarwin *pThis = (HostDnsServiceDarwin *)pInfo;
278 AssertPtrReturnVoid(pThis);
279
280 AssertPtrReturnVoid(pThis->m);
281 ASMAtomicXchgBool(&pThis->m->m_fStop, true);
282}
283
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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