VirtualBox

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

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

HostDnsServiceDarwin: listener for host's DNS configuration update.

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