VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/HostDnsService.cpp@ 50403

Last change on this file since 50403 was 50355, checked in by vboxsync, 11 years ago

6813 stage 7 VirtualBoxImpl.cpp etc

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.1 KB
Line 
1/* $Id: HostDnsService.cpp 50355 2014-02-06 17:55:07Z vboxsync $ */
2/** @file
3 * Base class fo Host DNS & Co services.
4 */
5
6/*
7 * Copyright (C) 2013 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/array.h>
19#include <VBox/com/ptr.h>
20#include <VBox/com/string.h>
21
22#include <iprt/cpp/utils.h>
23
24#include "Logging.h"
25#include "VirtualBoxImpl.h"
26#include <iprt/thread.h>
27#include <iprt/semaphore.h>
28#include <iprt/critsect.h>
29
30#include <algorithm>
31#include <string>
32#include "HostDnsService.h"
33
34
35static HostDnsMonitor *g_monitor;
36
37static void dumpHostDnsInformation(const HostDnsInformation&);
38static void dumpHostDnsStrVector(const std::string&, const std::vector<std::string>&);
39
40/* Lockee */
41Lockee::Lockee()
42{
43 RTCritSectInit(&mLock);
44}
45
46Lockee::~Lockee()
47{
48 RTCritSectDelete(&mLock);
49}
50
51const RTCRITSECT* Lockee::lock() const
52{
53 return &mLock;
54}
55
56/* ALock */
57ALock::ALock(const Lockee *aLockee)
58 : lockee(aLockee)
59{
60 RTCritSectEnter(const_cast<PRTCRITSECT>(lockee->lock()));
61}
62
63ALock::~ALock()
64{
65 RTCritSectLeave(const_cast<PRTCRITSECT>(lockee->lock()));
66}
67
68inline static void detachVectorOfString(const std::vector<std::string>& v,
69 ComSafeArrayOut(BSTR, aBstrArray))
70{
71 com::SafeArray<BSTR> aBstr(v.size());
72
73 std::vector<std::string>::const_iterator it;
74
75 int i = 0;
76 it = v.begin();
77 for (; it != v.end(); ++it, ++i)
78 Utf8Str(it->c_str()).cloneTo(&aBstr[i]);
79
80 aBstr.detachTo(ComSafeArrayOutArg(aBstrArray));
81}
82
83struct HostDnsMonitor::Data
84{
85 Data(bool aThreaded):fThreaded(aThreaded){}
86
87 std::vector<PCHostDnsMonitorProxy> proxies;
88 HostDnsInformation info;
89 const bool fThreaded;
90 RTTHREAD hMonitoringThread;
91 RTSEMEVENT hDnsInitEvent;
92};
93
94struct HostDnsMonitorProxy::Data
95{
96 Data(const HostDnsMonitor *aMonitor, const VirtualBox *aParent)
97 : info(NULL)
98 , virtualbox(aParent)
99 , monitor(aMonitor)
100 , fModified(true)
101 {}
102
103 virtual ~Data()
104 {
105 if (info)
106 {
107 delete info;
108 info = NULL;
109 }
110 }
111
112 HostDnsInformation *info;
113 const VirtualBox *virtualbox;
114 const HostDnsMonitor *monitor;
115 bool fModified;
116};
117
118
119HostDnsMonitor::HostDnsMonitor(bool fThreaded)
120 : m(NULL)
121{
122 m = new HostDnsMonitor::Data(fThreaded);
123}
124
125HostDnsMonitor::~HostDnsMonitor()
126{
127 if (m)
128 {
129 delete m;
130 m = NULL;
131 }
132}
133
134const HostDnsMonitor *HostDnsMonitor::getHostDnsMonitor()
135{
136 /* XXX: Moved initialization from HostImpl.cpp */
137 if (!g_monitor)
138 {
139# if defined (RT_OS_DARWIN)
140 g_monitor = new HostDnsServiceDarwin();
141# elif defined(RT_OS_WINDOWS)
142 g_monitor = new HostDnsServiceWin();
143# elif defined(RT_OS_LINUX)
144 g_monitor = new HostDnsServiceLinux();
145# elif defined(RT_OS_SOLARIS)
146 g_monitor = new HostDnsServiceSolaris();
147# elif defined(RT_OS_FREEBSD)
148 g_monitor = new HostDnsServiceFreebsd();
149# elif defined(RT_OS_OS2)
150 g_monitor = new HostDnsServiceOs2();
151# else
152 g_monitor = new HostDnsService();
153# endif
154 g_monitor->init();
155 }
156
157 return g_monitor;
158}
159
160void HostDnsMonitor::addMonitorProxy(PCHostDnsMonitorProxy proxy) const
161{
162 ALock l(this);
163 m->proxies.push_back(proxy);
164 proxy->notify();
165}
166
167void HostDnsMonitor::releaseMonitorProxy(PCHostDnsMonitorProxy proxy) const
168{
169 ALock l(this);
170 std::vector<PCHostDnsMonitorProxy>::iterator it;
171 it = std::find(m->proxies.begin(), m->proxies.end(), proxy);
172
173 if (it == m->proxies.end())
174 return;
175
176 m->proxies.erase(it);
177}
178
179void HostDnsMonitor::shutdown()
180{
181 if (g_monitor)
182 {
183 delete g_monitor;
184 g_monitor = NULL;
185 }
186}
187
188const HostDnsInformation &HostDnsMonitor::getInfo() const
189{
190 return m->info;
191}
192
193void HostDnsMonitor::notifyAll() const
194{
195 ALock l(this);
196 std::vector<PCHostDnsMonitorProxy>::const_iterator it;
197 for (it = m->proxies.begin(); it != m->proxies.end(); ++it)
198 (*it)->notify();
199}
200
201void HostDnsMonitor::setInfo(const HostDnsInformation &info)
202{
203 ALock l(this);
204 m->info = info;
205}
206
207HRESULT HostDnsMonitor::init()
208{
209 if (m->fThreaded)
210 {
211 int rc = RTSemEventCreate(&m->hDnsInitEvent);
212 AssertRCReturn(rc, E_FAIL);
213
214 rc = RTThreadCreate(&m->hMonitoringThread,
215 HostDnsMonitor::threadMonitoringRoutine,
216 this, 128 * _1K, RTTHREADTYPE_IO, 0, "dns-monitor");
217 AssertRCReturn(rc, E_FAIL);
218
219 RTSemEventWait(m->hDnsInitEvent, RT_INDEFINITE_WAIT);
220 }
221 return S_OK;
222}
223
224
225void HostDnsMonitor::monitorThreadInitializationDone()
226{
227 RTSemEventSignal(m->hDnsInitEvent);
228}
229
230
231int HostDnsMonitor::threadMonitoringRoutine(RTTHREAD, void *pvUser)
232{
233 HostDnsMonitor *pThis = static_cast<HostDnsMonitor *>(pvUser);
234 return pThis->monitorWorker();
235}
236
237/* HostDnsMonitorProxy */
238HostDnsMonitorProxy::HostDnsMonitorProxy()
239 : m(NULL)
240{
241}
242
243HostDnsMonitorProxy::~HostDnsMonitorProxy()
244{
245 if (m)
246 {
247 if (m->monitor)
248 m->monitor->releaseMonitorProxy(this);
249 delete m;
250 m = NULL;
251 }
252}
253
254void HostDnsMonitorProxy::init(const HostDnsMonitor *mon, const VirtualBox* aParent)
255{
256 m = new HostDnsMonitorProxy::Data(mon, aParent);
257 m->monitor->addMonitorProxy(this);
258 updateInfo();
259}
260
261void HostDnsMonitorProxy::notify() const
262{
263 m->fModified = true;
264 const_cast<VirtualBox *>(m->virtualbox)->i_onHostNameResolutionConfigurationChange();
265}
266
267HRESULT HostDnsMonitorProxy::GetNameServers(ComSafeArrayOut(BSTR, aNameServers))
268{
269 AssertReturn(m && m->info, E_FAIL);
270 ALock l(this);
271
272 if (m->fModified)
273 updateInfo();
274
275 LogRel(("HostDnsMonitorProxy::GetNameServers:\n"));
276 dumpHostDnsStrVector("Name Server", m->info->servers);
277
278 detachVectorOfString(m->info->servers, ComSafeArrayOutArg(aNameServers));
279
280 return S_OK;
281}
282
283HRESULT HostDnsMonitorProxy::GetDomainName(BSTR *aDomainName)
284{
285 AssertReturn(m && m->info, E_FAIL);
286 ALock l(this);
287
288 if (m->fModified)
289 updateInfo();
290
291 LogRel(("HostDnsMonitorProxy::GetDomainName:%s\n", m->info->domain.c_str()));
292
293 Utf8Str(m->info->domain.c_str()).cloneTo(aDomainName);
294
295 return S_OK;
296}
297
298HRESULT HostDnsMonitorProxy::GetSearchStrings(ComSafeArrayOut(BSTR, aSearchStrings))
299{
300 AssertReturn(m && m->info, E_FAIL);
301 ALock l(this);
302
303 if (m->fModified)
304 updateInfo();
305
306 LogRel(("HostDnsMonitorProxy::GetSearchStrings:\n"));
307 dumpHostDnsStrVector("Search String", m->info->searchList);
308
309 detachVectorOfString(m->info->searchList, ComSafeArrayOutArg(aSearchStrings));
310
311 return S_OK;
312}
313
314bool HostDnsMonitorProxy::operator==(PCHostDnsMonitorProxy& rhs)
315{
316 if (!m || !rhs->m)
317 return false;
318
319 /**
320 * we've assigned to the same instance of VirtualBox.
321 */
322 return m->virtualbox == rhs->m->virtualbox;
323}
324
325void HostDnsMonitorProxy::updateInfo()
326{
327 HostDnsInformation *info = new HostDnsInformation(m->monitor->getInfo());
328 HostDnsInformation *old = m->info;
329
330 LogRel(("HostDnsMonitorProxy: Host's DNS information updated:\n"));
331 dumpHostDnsInformation(*info);
332
333 m->info = info;
334 if (old)
335 {
336 LogRel(("HostDnsMonitorProxy: Old host information:\n"));
337 dumpHostDnsInformation(*old);
338
339 delete old;
340 }
341
342 m->fModified = false;
343}
344
345
346static void dumpHostDnsInformation(const HostDnsInformation& info)
347{
348 dumpHostDnsStrVector("DNS server", info.servers);
349 dumpHostDnsStrVector("SearchString", info.searchList);
350
351 if (!info.domain.empty())
352 LogRel(("DNS domain: %s\n", info.domain.c_str()));
353}
354
355
356static void dumpHostDnsStrVector(const std::string& prefix, const std::vector<std::string>& v)
357{
358 int i = 0;
359 for (std::vector<std::string>::const_iterator it = v.begin();
360 it != v.end();
361 ++it, ++i)
362 LogRel(("%s %d: %s\n", prefix.c_str(), i, it->c_str()));
363}
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