VirtualBox

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

Last change on this file since 55198 was 55198, checked in by vboxsync, 10 years ago

Main/HostDnsService: drop const from VirtualBox *aParent as
GetExtraData() method is not const.

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