VirtualBox

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

Last change on this file since 49235 was 49235, checked in by vboxsync, 12 years ago

Main/HostDnsService: splits HostDnsService on "singleton" HostDnsMonitor
which monitors host changes and share DnsInformation to per HostImpl/VirtualBoxImpl objects
HostDnsMonitorProxy.

TODO: Win/Darwin parts might burn (not tested)
TODO: find good place to call HostDnsMonitor::shutdown() to stop
monitoring thread. (ref counting could be used on
HostDnsMonitor::addMonitorProxy and HostDnsMonitor::releaseMonitorProxy,
but it better to pausing monitoring on no --auto-shutdown launches of VBoxSVC).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.0 KB
Line 
1/* $Id: HostDnsServiceDarwin.cpp 49235 2013-10-22 18:56:03Z 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.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#include "../HostDnsService.h"
22
23#include <iprt/err.h>
24#include <iprt/thread.h>
25#include <iprt/semaphore.h>
26
27#include <CoreFoundation/CoreFoundation.h>
28#include <SystemConfiguration/SCDynamicStore.h>
29
30
31
32SCDynamicStoreRef g_store;
33CFRunLoopSourceRef g_DnsWatcher;
34CFRunLoopRef g_RunLoopRef;
35RTTHREAD g_DnsMonitoringThread;
36RTSEMEVENT g_DnsInitEvent;
37
38static const CFStringRef kStateNetworkGlobalDNSKey = CFSTR("State:/Network/Global/DNS");
39
40static int hostMonitoringRoutine(RTTHREAD ThreadSelf, void *pvUser)
41{
42 NOREF(ThreadSelf);
43 NOREF(pvUser);
44 g_RunLoopRef = CFRunLoopGetCurrent();
45 AssertReturn(g_RunLoopRef, VERR_INTERNAL_ERROR);
46
47 CFRetain(g_RunLoopRef);
48
49 CFArrayRef watchingArrayRef = CFArrayCreate(NULL,
50 (const void **)&kStateNetworkGlobalDNSKey,
51 1, &kCFTypeArrayCallBacks);
52 if (!watchingArrayRef)
53 {
54 CFRelease(g_DnsWatcher);
55 return E_OUTOFMEMORY;
56 }
57
58 if(SCDynamicStoreSetNotificationKeys(g_store, watchingArrayRef, NULL))
59 CFRunLoopAddSource(CFRunLoopGetCurrent(), g_DnsWatcher, kCFRunLoopCommonModes);
60
61 CFRelease(watchingArrayRef);
62
63 RTSemEventSignal(g_DnsInitEvent);
64
65 CFRunLoopRun();
66
67 CFRelease(g_RunLoopRef);
68
69 return VINF_SUCCESS;
70}
71
72
73HostDnsServiceDarwin::HostDnsServiceDarwin(){}
74
75
76HostDnsServiceDarwin::~HostDnsServiceDarwin()
77{
78 if (g_RunLoopRef)
79 CFRunLoopStop(g_RunLoopRef);
80
81 CFRelease(g_DnsWatcher);
82
83 CFRelease(g_store);
84}
85
86
87void HostDnsServiceDarwin::hostDnsServiceStoreCallback(void *arg0, void *arg1, void *info)
88{
89 HostDnsServiceDarwin *pThis = (HostDnsServiceDarwin *)info;
90
91 NOREF(arg0); /* SCDynamicStore */
92 NOREF(arg1); /* CFArrayRef */
93
94 RTCritSectEnter(&pThis->m_hCritSect);
95 pThis->updateInfo();
96 pThis->notifyAll();
97 RTCritSectLeave(&pThis->m_hCritSect);
98}
99
100
101HRESULT HostDnsServiceDarwin::init(const VirtualBox *aParent)
102{
103 SCDynamicStoreContext ctx;
104 RT_ZERO(ctx);
105
106 ctx.info = this;
107
108 g_store = SCDynamicStoreCreate(NULL, CFSTR("org.virtualbox.VBoxSVC"),
109 (SCDynamicStoreCallBack)HostDnsServiceDarwin::hostDnsServiceStoreCallback,
110 &ctx);
111 AssertReturn(g_store, E_FAIL);
112
113 g_DnsWatcher = SCDynamicStoreCreateRunLoopSource(NULL, g_store, 0);
114 if (!g_DnsWatcher)
115 return E_OUTOFMEMORY;
116
117 HRESULT hrc = HostDnsService::init(aParent);
118 AssertComRCReturn(hrc, hrc);
119
120 int rc = RTSemEventCreate(&g_DnsInitEvent);
121 AssertRCReturn(rc, E_FAIL);
122
123 rc = RTThreadCreate(&g_DnsMonitoringThread, hostMonitoringRoutine,
124 this, 128 * _1K, RTTHREADTYPE_IO, 0, "dns-monitor");
125 AssertRCReturn(rc, E_FAIL);
126
127 RTSemEventWait(g_DnsInitEvent, RT_INDEFINITE_WAIT);
128 return updateInfo();
129}
130
131
132HRESULT HostDnsServiceDarwin::updateInfo()
133{
134 CFPropertyListRef propertyRef = SCDynamicStoreCopyValue(g_store,
135 kStateNetworkGlobalDNSKey);
136 /**
137 * 0:vvl@nb-mbp-i7-2(0)# scutil
138 * > get State:/Network/Global/DNS
139 * > d.show
140 * <dictionary> {
141 * DomainName : vvl-domain
142 * SearchDomains : <array> {
143 * 0 : vvl-domain
144 * 1 : de.vvl-domain.com
145 * }
146 * ServerAddresses : <array> {
147 * 0 : 192.168.1.4
148 * 1 : 192.168.1.1
149 * 2 : 8.8.4.4
150 * }
151 * }
152 */
153
154 if (!propertyRef)
155 return S_OK;
156
157 HostDnsInformation info;
158 CFStringRef domainNameRef = (CFStringRef)CFDictionaryGetValue(
159 static_cast<CFDictionaryRef>(propertyRef), CFSTR("DomainName"));
160 if (domainNameRef)
161 {
162 const char *pszDomainName = CFStringGetCStringPtr(domainNameRef,
163 CFStringGetSystemEncoding());
164 if (pszDomainName)
165 info.domain = pszDomainName;
166 }
167
168 int i, arrayCount;
169 CFArrayRef serverArrayRef = (CFArrayRef)CFDictionaryGetValue(
170 static_cast<CFDictionaryRef>(propertyRef), CFSTR("ServerAddresses"));
171 if (serverArrayRef)
172 {
173 arrayCount = CFArrayGetCount(serverArrayRef);
174 for (i = 0; i < arrayCount; ++i)
175 {
176 CFStringRef serverAddressRef = (CFStringRef)CFArrayGetValueAtIndex(serverArrayRef, i);
177 if (!serverArrayRef)
178 continue;
179
180 const char *pszServerAddress = CFStringGetCStringPtr(serverAddressRef,
181 CFStringGetSystemEncoding());
182 if (!pszServerAddress)
183 continue;
184
185 info.servers.push_back(std::string(pszServerAddress));
186 }
187 }
188
189 CFArrayRef searchArrayRef = (CFArrayRef)CFDictionaryGetValue(
190 static_cast<CFDictionaryRef>(propertyRef), CFSTR("SearchDomains"));
191 if (searchArrayRef)
192 {
193 arrayCount = CFArrayGetCount(searchArrayRef);
194
195 for (i = 0; i < arrayCount; ++i)
196 {
197 CFStringRef searchStringRef = (CFStringRef)CFArrayGetValueAtIndex(searchArrayRef, i);
198 if (!searchArrayRef)
199 continue;
200
201 const char *pszSearchString = CFStringGetCStringPtr(searchStringRef,
202 CFStringGetSystemEncoding());
203 if (!pszSearchString)
204 continue;
205
206 info.searchList.push_back(std::string(pszSearchString));
207 }
208 }
209
210 CFRelease(propertyRef);
211
212 setInfo(info);
213
214 return S_OK;
215}
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