VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/HostDnsService.h@ 52897

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

Main: DnsMonitorService: step on unicode rails: store network configuration in unicode-compatible containner (std::wstring) (preliminary tested on Linux, Mac and Windows); DnsMonitorService for Windows: reworked in order to subscribe to correct events and filter-out those ones we don't interested in. (Experimantal, needs more testing and review).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.5 KB
Line 
1/* $Id: HostDnsService.h 52897 2014-09-30 14:45:00Z vboxsync $ */
2/** @file
3 * Host DNS listener.
4 */
5
6/*
7 * Copyright (C) 2005-2012 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#ifndef ___H_DNSHOSTSERVICE
19#define ___H_DNSHOSTSERVICE
20#include "VirtualBoxBase.h"
21
22#include <iprt/cdefs.h>
23#include <iprt/critsect.h>
24#include <iprt/types.h>
25
26#include <list>
27#include <vector>
28
29typedef std::list<com::Utf8Str> Utf8StrList;
30typedef Utf8StrList::iterator Utf8StrListIterator;
31
32class HostDnsMonitorProxy;
33typedef const HostDnsMonitorProxy *PCHostDnsMonitorProxy;
34
35class Lockee
36{
37 public:
38 Lockee();
39 virtual ~Lockee();
40 const RTCRITSECT* lock() const;
41
42 private:
43 RTCRITSECT mLock;
44};
45
46class ALock
47{
48 public:
49 explicit ALock(const Lockee *l);
50 ~ALock();
51
52 private:
53 const Lockee *lockee;
54};
55
56class HostDnsInformation
57{
58 public:
59 std::vector<std::wstring> servers;
60 std::wstring domain;
61 std::vector<std::wstring> searchList;
62};
63
64/**
65 * This class supposed to be a real DNS monitor object it should be singleton,
66 * it lifecycle starts and ends together with VBoxSVC.
67 */
68class HostDnsMonitor : public Lockee
69{
70 public:
71 static const HostDnsMonitor *getHostDnsMonitor();
72 static void shutdown();
73
74 void addMonitorProxy(PCHostDnsMonitorProxy) const;
75 void releaseMonitorProxy(PCHostDnsMonitorProxy) const;
76 const HostDnsInformation &getInfo() const;
77 /* @note: method will wait till client call
78 HostDnsService::monitorThreadInitializationDone() */
79 virtual HRESULT init();
80
81 protected:
82 explicit HostDnsMonitor(bool fThreaded = false);
83 virtual ~HostDnsMonitor();
84
85 void notifyAll() const;
86 void setInfo(const HostDnsInformation &);
87
88 /* this function used only if HostDnsMonitor::HostDnsMonitor(true) */
89 void monitorThreadInitializationDone();
90 virtual void monitorThreadShutdown() = 0;
91 virtual int monitorWorker() = 0;
92
93 private:
94 HostDnsMonitor(const HostDnsMonitor &);
95 HostDnsMonitor& operator= (const HostDnsMonitor &);
96 static int threadMonitoringRoutine(RTTHREAD, void *);
97
98 public:
99 struct Data;
100 Data *m;
101};
102
103/**
104 * This class supposed to be a proxy for events on changing Host Name Resolving configurations.
105 */
106class HostDnsMonitorProxy : public Lockee
107{
108 public:
109 HostDnsMonitorProxy();
110 ~HostDnsMonitorProxy();
111 void init(const HostDnsMonitor *aMonitor, const VirtualBox *aParent);
112 void notify() const;
113
114 HRESULT GetNameServers(ComSafeArrayOut(BSTR, aNameServers));
115 HRESULT GetDomainName(BSTR *aDomainName);
116 HRESULT GetSearchStrings(ComSafeArrayOut(BSTR, aSearchStrings));
117
118 bool operator==(PCHostDnsMonitorProxy&);
119
120 private:
121 void updateInfo();
122
123 private:
124 struct Data;
125 Data *m;
126};
127
128# ifdef RT_OS_DARWIN
129class HostDnsServiceDarwin : public HostDnsMonitor
130{
131 public:
132 HostDnsServiceDarwin();
133 ~HostDnsServiceDarwin();
134 HRESULT init();
135
136 protected:
137 virtual void monitorThreadShutdown();
138 virtual int monitorWorker();
139
140 private:
141 HRESULT updateInfo();
142 static void hostDnsServiceStoreCallback(void *store, void *arrayRef, void *info);
143 struct Data;
144 Data *m;
145};
146# endif
147# ifdef RT_OS_WINDOWS
148/* Maximum size of Windows registry key (according to MSDN). */
149#define VBOX_KEY_NAME_LEN_MAX (255)
150class HostDnsServiceWin: public HostDnsMonitor
151{
152 public:
153
154 HostDnsServiceWin();
155 ~HostDnsServiceWin();
156
157 HRESULT init();
158
159 protected:
160
161 virtual void monitorThreadShutdown();
162 virtual int monitorWorker();
163
164 private:
165
166 /* This structure is used in order to link Windows registry key with
167 * an event which is generated once the key has been changed (when interface has updated its DNS setting)
168 * or one of the sub-keys has been deleted or added (when interface added or deleted). */
169 struct Item
170 {
171 HKEY hKey; /** Key handle. */
172 HANDLE hEvent; /** Event handle. */
173 TCHAR wcsInterface[VBOX_KEY_NAME_LEN_MAX]; /** Path to key within Windows registry. */
174 };
175
176 /* Bit flags to determine what was exactly was changed when Windows triggered event notification. */
177 enum {
178 VBOX_EVENT_NO_CHANGES = 0,
179 VBOX_EVENT_SERVERS_CHANGED = RT_BIT(1),
180 VBOX_EVENT_DOMAIN_CHANGED = RT_BIT(2),
181 VBOX_EVENT_SEARCHLIST_CHANGED = RT_BIT(3),
182 };
183
184 /* Keys and events storage.
185 * Size of this vector should not be greater than MAXIMUM_WAIT_OBJECTS because
186 * this is exactly maximum amount of events which we allowed to wait for. */
187 std::vector<struct Item> m_aWarehouse;
188 /* Cached host network configuration. */
189 HostDnsInformation m_hostInfoCache;
190
191 /* TCHAR[] constants initialized outside of class definition. */
192 static const TCHAR m_pwcKeyRoot[];
193
194 /* m_aWarehouse array offsets. */
195 enum {
196 VBOX_OFFSET_SHUTDOWN_EVENT = 0,
197 VBOX_OFFSET_TREE_EVENT = 1,
198 VBOX_OFFSET_SUBTREE_EVENTS = 2,
199 };
200
201 /* Do actual unsubscription for given item. */
202 bool releaseWarehouseItem(int idxItem);
203 /* Release all allocated resources and unsubscribe from everything. */
204 void releaseResources();
205 /* Remove subscription from DNS change notifications and release corresponding resources. */
206 bool dropSubTreeNotifications();
207
208 /* Create & add event into the list of events we monitor to. */
209 bool subscribeTo(TCHAR *wcsPath, TCHAR *wcsInterface, DWORD fFilter);
210 /* Subscribe to DNS changes. */
211 bool enumerateSubTree();
212
213 /* Get plain array of event handles. */
214 void getEventHandles(HANDLE *ahEvents);
215 void extendVectorWithStrings(std::vector<std::wstring>& pVectorToExtend, std::wstring &wcsParameter);
216 HRESULT updateInfo(uint8_t *fWhatsChanged);
217
218 /* This flag indicates whether constructor performed initialization correctly. If not set,
219 * monitorWorker() will not perform any action and will be terminated as soon as there will be
220 * an attempt to run it. */
221 bool m_fInitialized;
222};
223# endif
224# if defined(RT_OS_SOLARIS) || defined(RT_OS_LINUX) || defined(RT_OS_OS2) || defined(RT_OS_FREEBSD)
225class HostDnsServiceResolvConf: public HostDnsMonitor
226{
227 public:
228 explicit HostDnsServiceResolvConf(bool fThreaded = false) : HostDnsMonitor(fThreaded), m(NULL) {}
229 virtual ~HostDnsServiceResolvConf();
230 virtual HRESULT init(const char *aResolvConfFileName);
231 const std::string& resolvConf() const;
232
233 protected:
234 HRESULT readResolvConf();
235 /* While not all hosts supports Hosts DNS change notifiaction
236 * default implementation offers return VERR_IGNORE.
237 */
238 virtual void monitorThreadShutdown() {}
239 virtual int monitorWorker() {return VERR_IGNORED;}
240
241 protected:
242 struct Data;
243 Data *m;
244};
245# if defined(RT_OS_SOLARIS)
246/**
247 * XXX: https://blogs.oracle.com/praks/entry/file_events_notification
248 */
249class HostDnsServiceSolaris : public HostDnsServiceResolvConf
250{
251 public:
252 HostDnsServiceSolaris(){}
253 ~HostDnsServiceSolaris(){}
254 HRESULT init(){ return HostDnsServiceResolvConf::init("/etc/resolv.conf");}
255};
256
257# elif defined(RT_OS_LINUX)
258class HostDnsServiceLinux : public HostDnsServiceResolvConf
259{
260 public:
261 HostDnsServiceLinux():HostDnsServiceResolvConf(true){}
262 virtual ~HostDnsServiceLinux();
263 virtual HRESULT init(){ return HostDnsServiceResolvConf::init("/etc/resolv.conf");}
264
265 protected:
266 virtual void monitorThreadShutdown();
267 virtual int monitorWorker();
268};
269
270# elif defined(RT_OS_FREEBSD)
271class HostDnsServiceFreebsd: public HostDnsServiceResolvConf
272{
273 public:
274 HostDnsServiceFreebsd(){}
275 ~HostDnsServiceFreebsd(){}
276 HRESULT init(){ return HostDnsServiceResolvConf::init("/etc/resolv.conf");}
277};
278
279# elif defined(RT_OS_OS2)
280class HostDnsServiceOs2 : public HostDnsServiceResolvConf
281{
282 public:
283 HostDnsServiceOs2(){}
284 ~HostDnsServiceOs2(){}
285 /* XXX: \\MPTN\\ETC should be taken from environment variable ETC */
286 HRESULT init(){ return init("\\MPTN\\ETC\\RESOLV2");}
287};
288
289# endif
290# endif
291
292#endif /* !___H_DNSHOSTSERVICE */
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