VirtualBox

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

Last change on this file since 72526 was 72483, checked in by vboxsync, 7 years ago

HostDnsService: G/c operator== that is no longer used.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.4 KB
Line 
1/* $Id: HostDnsService.cpp 72483 2018-06-08 13:58:25Z vboxsync $ */
2/** @file
3 * Base class for Host DNS & Co services.
4 */
5
6/*
7 * Copyright (C) 2013-2017 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/time.h>
27#include <iprt/thread.h>
28#include <iprt/semaphore.h>
29#include <iprt/critsect.h>
30
31#include <algorithm>
32#include <set>
33#include <string>
34#include "HostDnsService.h"
35
36
37static void dumpHostDnsInformation(const HostDnsInformation&);
38static void dumpHostDnsStrVector(const std::string&, const std::vector<std::string>&);
39
40
41bool HostDnsInformation::equals(const HostDnsInformation &info, uint32_t fLaxComparison) const
42{
43 bool fSameServers;
44 if ((fLaxComparison & IGNORE_SERVER_ORDER) == 0)
45 {
46 fSameServers = (servers == info.servers);
47 }
48 else
49 {
50 std::set<std::string> l(servers.begin(), servers.end());
51 std::set<std::string> r(info.servers.begin(), info.servers.end());
52
53 fSameServers = (l == r);
54 }
55
56 bool fSameDomain, fSameSearchList;
57 if ((fLaxComparison & IGNORE_SUFFIXES) == 0)
58 {
59 fSameDomain = (domain == info.domain);
60 fSameSearchList = (searchList == info.searchList);
61 }
62 else
63 {
64 fSameDomain = fSameSearchList = true;
65 }
66
67 return fSameServers && fSameDomain && fSameSearchList;
68}
69
70inline static void detachVectorOfString(const std::vector<std::string>& v,
71 std::vector<com::Utf8Str> &aArray)
72{
73 aArray.resize(v.size());
74 size_t i = 0;
75 for (std::vector<std::string>::const_iterator it = v.begin(); it != v.end(); ++it, ++i)
76 aArray[i] = Utf8Str(it->c_str());
77}
78
79struct HostDnsMonitor::Data
80{
81 Data(bool aThreaded)
82 : proxy(NULL),
83 fThreaded(aThreaded),
84 uLastExtraDataPoll(0),
85 fLaxComparison(0)
86 {}
87
88 HostDnsMonitorProxy *proxy;
89
90 const bool fThreaded;
91 RTSEMEVENT hDnsInitEvent;
92 RTTHREAD hMonitoringThread;
93
94 uint64_t uLastExtraDataPoll;
95 uint32_t fLaxComparison;
96 HostDnsInformation info;
97};
98
99struct HostDnsMonitorProxy::Data
100{
101 Data(HostDnsMonitor *aMonitor, VirtualBox *aParent)
102 : virtualbox(aParent),
103 monitor(aMonitor),
104 info(NULL)
105 {}
106
107 ~Data()
108 {
109 if (info)
110 {
111 delete info;
112 info = NULL;
113 }
114 }
115
116 VirtualBox *virtualbox;
117 HostDnsMonitor *monitor;
118 HostDnsInformation *info;
119};
120
121
122HostDnsMonitor::HostDnsMonitor(bool fThreaded)
123 : m(NULL)
124{
125 m = new HostDnsMonitor::Data(fThreaded);
126}
127
128HostDnsMonitor::~HostDnsMonitor()
129{
130 if (m)
131 {
132 delete m;
133 m = NULL;
134 }
135}
136
137HostDnsMonitor *HostDnsMonitor::createHostDnsMonitor()
138{
139 HostDnsMonitor *monitor = NULL;
140
141#if defined (RT_OS_DARWIN)
142 monitor = new HostDnsServiceDarwin();
143#elif defined(RT_OS_WINDOWS)
144 monitor = new HostDnsServiceWin();
145#elif defined(RT_OS_LINUX)
146 monitor = new HostDnsServiceLinux();
147#elif defined(RT_OS_SOLARIS)
148 monitor = new HostDnsServiceSolaris();
149#elif defined(RT_OS_FREEBSD)
150 monitor = new HostDnsServiceFreebsd();
151#elif defined(RT_OS_OS2)
152 monitor = new HostDnsServiceOs2();
153#else
154 monitor = new HostDnsService();
155#endif
156
157 return monitor;
158}
159
160
161void HostDnsMonitor::shutdown()
162{
163 /** @todo never called.
164 * HostDnsMonitor should be referenced by HostDnsMonitorProxy objects and the Host object
165 * and automatically deleted when not referenced anymore.
166 * Currently HostDnsMonitor can use already deleted m->virtualbox.
167 */
168}
169
170
171const HostDnsInformation &HostDnsMonitor::getInfo() const
172{
173 return m->info;
174}
175
176void HostDnsMonitor::setInfo(const HostDnsInformation &info)
177{
178 RTCLock grab(m_LockMtx);
179
180 pollGlobalExtraData();
181
182 if (info.equals(m->info))
183 return;
184
185 LogRel(("HostDnsMonitor: old information\n"));
186 dumpHostDnsInformation(m->info);
187 LogRel(("HostDnsMonitor: new information\n"));
188 dumpHostDnsInformation(info);
189
190 bool fIgnore = m->fLaxComparison && info.equals(m->info, m->fLaxComparison);
191 m->info = info;
192
193 if (fIgnore)
194 {
195 LogRel(("HostDnsMonitor: lax comparison %#x, not notifying\n", m->fLaxComparison));
196 return;
197 }
198
199 if (m->proxy != NULL)
200 m->proxy->notify();
201}
202
203HRESULT HostDnsMonitor::init(HostDnsMonitorProxy *proxy)
204{
205 m->proxy = proxy;
206
207 pollGlobalExtraData();
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::pollGlobalExtraData()
226{
227 VirtualBox *virtualbox = m->proxy->getVirtualBox();
228 if (RT_UNLIKELY(virtualbox == NULL))
229 return;
230
231 uint64_t uNow = RTTimeNanoTS();
232 if (virtualbox && (uNow - m->uLastExtraDataPoll >= RT_NS_30SEC || m->uLastExtraDataPoll == 0))
233 {
234 m->uLastExtraDataPoll = uNow;
235
236 /*
237 * Should we ignore the order of DNS servers?
238 */
239 const com::Bstr bstrHostDNSOrderIgnoreKey("VBoxInternal2/HostDNSOrderIgnore");
240 com::Bstr bstrHostDNSOrderIgnore;
241 virtualbox->GetExtraData(bstrHostDNSOrderIgnoreKey.raw(),
242 bstrHostDNSOrderIgnore.asOutParam());
243 uint32_t fDNSOrderIgnore = 0;
244 if (bstrHostDNSOrderIgnore.isNotEmpty())
245 {
246 if (bstrHostDNSOrderIgnore != "0")
247 fDNSOrderIgnore = HostDnsInformation::IGNORE_SERVER_ORDER;
248 }
249
250 if (fDNSOrderIgnore != (m->fLaxComparison & HostDnsInformation::IGNORE_SERVER_ORDER))
251 {
252
253 m->fLaxComparison ^= HostDnsInformation::IGNORE_SERVER_ORDER;
254 LogRel(("HostDnsMonitor: %ls=%ls\n",
255 bstrHostDNSOrderIgnoreKey.raw(),
256 bstrHostDNSOrderIgnore.raw()));
257 }
258
259 /*
260 * Should we ignore changes to the domain name or the search list?
261 */
262 const com::Bstr bstrHostDNSSuffixesIgnoreKey("VBoxInternal2/HostDNSSuffixesIgnore");
263 com::Bstr bstrHostDNSSuffixesIgnore;
264 virtualbox->GetExtraData(bstrHostDNSSuffixesIgnoreKey.raw(),
265 bstrHostDNSSuffixesIgnore.asOutParam());
266 uint32_t fDNSSuffixesIgnore = 0;
267 if (bstrHostDNSSuffixesIgnore.isNotEmpty())
268 {
269 if (bstrHostDNSSuffixesIgnore != "0")
270 fDNSSuffixesIgnore = HostDnsInformation::IGNORE_SUFFIXES;
271 }
272
273 if (fDNSSuffixesIgnore != (m->fLaxComparison & HostDnsInformation::IGNORE_SUFFIXES))
274 {
275
276 m->fLaxComparison ^= HostDnsInformation::IGNORE_SUFFIXES;
277 LogRel(("HostDnsMonitor: %ls=%ls\n",
278 bstrHostDNSSuffixesIgnoreKey.raw(),
279 bstrHostDNSSuffixesIgnore.raw()));
280 }
281 }
282}
283
284void HostDnsMonitor::monitorThreadInitializationDone()
285{
286 RTSemEventSignal(m->hDnsInitEvent);
287}
288
289
290DECLCALLBACK(int) HostDnsMonitor::threadMonitoringRoutine(RTTHREAD, void *pvUser)
291{
292 HostDnsMonitor *pThis = static_cast<HostDnsMonitor *>(pvUser);
293 return pThis->monitorWorker();
294}
295
296/* HostDnsMonitorProxy */
297HostDnsMonitorProxy::HostDnsMonitorProxy()
298 : m(NULL)
299{
300}
301
302HostDnsMonitorProxy::~HostDnsMonitorProxy()
303{
304 if (m)
305 {
306 /* XXX: m->monitor */
307 delete m;
308 m = NULL;
309 }
310}
311
312void HostDnsMonitorProxy::init(VirtualBox* aParent)
313{
314 HostDnsMonitor *monitor = HostDnsMonitor::createHostDnsMonitor();
315 m = new HostDnsMonitorProxy::Data(monitor, aParent);
316
317 m->monitor->init(this);
318 updateInfo();
319}
320
321
322VirtualBox *HostDnsMonitorProxy::getVirtualBox() const
323{
324 RTCLock grab(m_LockMtx);
325 return RT_LIKELY(m != NULL) ? m->virtualbox : NULL;
326}
327
328
329void HostDnsMonitorProxy::notify()
330{
331 LogRel(("HostDnsMonitorProxy::notify\n"));
332 updateInfo();
333 m->virtualbox->i_onHostNameResolutionConfigurationChange();
334}
335
336HRESULT HostDnsMonitorProxy::GetNameServers(std::vector<com::Utf8Str> &aNameServers)
337{
338 AssertReturn(m && m->info, E_FAIL);
339 RTCLock grab(m_LockMtx);
340
341 LogRel(("HostDnsMonitorProxy::GetNameServers:\n"));
342 dumpHostDnsStrVector("name server", m->info->servers);
343
344 detachVectorOfString(m->info->servers, aNameServers);
345
346 return S_OK;
347}
348
349HRESULT HostDnsMonitorProxy::GetDomainName(com::Utf8Str *pDomainName)
350{
351 AssertReturn(m && m->info, E_FAIL);
352 RTCLock grab(m_LockMtx);
353
354 LogRel(("HostDnsMonitorProxy::GetDomainName: %s\n",
355 m->info->domain.empty() ? "no domain set" : m->info->domain.c_str()));
356
357 *pDomainName = m->info->domain.c_str();
358
359 return S_OK;
360}
361
362HRESULT HostDnsMonitorProxy::GetSearchStrings(std::vector<com::Utf8Str> &aSearchStrings)
363{
364 AssertReturn(m && m->info, E_FAIL);
365 RTCLock grab(m_LockMtx);
366
367 LogRel(("HostDnsMonitorProxy::GetSearchStrings:\n"));
368 dumpHostDnsStrVector("search string", m->info->searchList);
369
370 detachVectorOfString(m->info->searchList, aSearchStrings);
371
372 return S_OK;
373}
374
375void HostDnsMonitorProxy::updateInfo()
376{
377 RTCLock grab(m_LockMtx);
378
379 HostDnsInformation *info = new HostDnsInformation(m->monitor->getInfo());
380 HostDnsInformation *old = m->info;
381
382 m->info = info;
383 if (old)
384 {
385 delete old;
386 }
387}
388
389
390static void dumpHostDnsInformation(const HostDnsInformation& info)
391{
392 dumpHostDnsStrVector("server", info.servers);
393
394 if (!info.domain.empty())
395 LogRel((" domain: %s\n", info.domain.c_str()));
396 else
397 LogRel((" no domain set\n"));
398
399 dumpHostDnsStrVector("search string", info.searchList);
400}
401
402
403static void dumpHostDnsStrVector(const std::string& prefix, const std::vector<std::string>& v)
404{
405 int i = 1;
406 for (std::vector<std::string>::const_iterator it = v.begin();
407 it != v.end();
408 ++it, ++i)
409 LogRel((" %s %d: %s\n", prefix.c_str(), i, it->c_str()));
410 if (v.empty())
411 LogRel((" no %s entries\n", prefix.c_str()));
412}
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