VirtualBox

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

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

Main/src-server/HostDnsService.cpp: log each DNS info change notification, it is useful to know and on reasonably configured system very low volume

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