VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/NATEngineImpl.cpp@ 60786

最後變更 在這個檔案從60786是 60786,由 vboxsync 提交於 9 年 前

Main/NATNetwork+NATEngine: simplify settings handling greatly by directly using the structs without tedious translation

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 15.7 KB
 
1/* $Id: NATEngineImpl.cpp 60786 2016-05-02 13:00:02Z vboxsync $ */
2/** @file
3 * Implementation of INATEngine in VBoxSVC.
4 */
5
6/*
7 * Copyright (C) 2010-2016 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.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 "NATEngineImpl.h"
19#include "AutoCaller.h"
20#include "Logging.h"
21#include "MachineImpl.h"
22#include "GuestOSTypeImpl.h"
23
24#include <iprt/string.h>
25#include <iprt/cpp/utils.h>
26
27#include <VBox/err.h>
28#include <VBox/settings.h>
29#include <VBox/com/array.h>
30
31struct NATEngineData
32{
33 NATEngineData()
34 {}
35
36 settings::NAT s;
37};
38
39struct NATEngine::Data
40{
41 Backupable<NATEngineData> m;
42};
43
44
45// constructor / destructor
46////////////////////////////////////////////////////////////////////////////////
47
48NATEngine::NATEngine():mData(NULL), mParent(NULL), mAdapter(NULL) {}
49NATEngine::~NATEngine(){}
50
51HRESULT NATEngine::FinalConstruct()
52{
53 return BaseFinalConstruct();
54}
55
56void NATEngine::FinalRelease()
57{
58 uninit();
59 BaseFinalRelease();
60}
61
62
63HRESULT NATEngine::init(Machine *aParent, INetworkAdapter *aAdapter)
64{
65 AutoInitSpan autoInitSpan(this);
66 AssertReturn(autoInitSpan.isOk(), E_FAIL);
67 autoInitSpan.setSucceeded();
68 mData = new Data();
69 mData->m.allocate();
70 mData->m->s.strNetwork.setNull();
71 mData->m->s.strBindIP.setNull();
72 unconst(mParent) = aParent;
73 unconst(mAdapter) = aAdapter;
74 return S_OK;
75}
76
77HRESULT NATEngine::init(Machine *aParent, INetworkAdapter *aAdapter, NATEngine *aThat)
78{
79 AutoInitSpan autoInitSpan(this);
80 AssertReturn(autoInitSpan.isOk(), E_FAIL);
81 Log(("init that:%p this:%p\n", aThat, this));
82
83 AutoCaller thatCaller(aThat);
84 AssertComRCReturnRC(thatCaller.rc());
85
86 AutoReadLock thatLock(aThat COMMA_LOCKVAL_SRC_POS);
87
88 mData = new Data();
89 mData->m.share(aThat->mData->m);
90 unconst(mParent) = aParent;
91 unconst(mAdapter) = aAdapter;
92 unconst(mPeer) = aThat;
93 autoInitSpan.setSucceeded();
94 return S_OK;
95}
96
97HRESULT NATEngine::initCopy(Machine *aParent, INetworkAdapter *aAdapter, NATEngine *aThat)
98{
99 AutoInitSpan autoInitSpan(this);
100 AssertReturn(autoInitSpan.isOk(), E_FAIL);
101
102 Log(("initCopy that:%p this:%p\n", aThat, this));
103
104 AutoCaller thatCaller(aThat);
105 AssertComRCReturnRC(thatCaller.rc());
106
107 AutoReadLock thatLock(aThat COMMA_LOCKVAL_SRC_POS);
108
109 mData = new Data();
110 mData->m.attachCopy(aThat->mData->m);
111 unconst(mAdapter) = aAdapter;
112 unconst(mParent) = aParent;
113 autoInitSpan.setSucceeded();
114 return BaseFinalConstruct();
115}
116
117
118void NATEngine::uninit()
119{
120 AutoUninitSpan autoUninitSpan(this);
121 if (autoUninitSpan.uninitDone())
122 return;
123
124 mData->m.free();
125 delete mData;
126 mData = NULL;
127 unconst(mPeer) = NULL;
128 unconst(mParent) = NULL;
129}
130
131bool NATEngine::i_isModified()
132{
133 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
134 bool fModified = mData->m.isBackedUp();
135 return fModified;
136}
137
138void NATEngine::i_rollback()
139{
140 AutoCaller autoCaller(this);
141 AssertComRCReturnVoid(autoCaller.rc());
142
143 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
144
145 mData->m.rollback();
146}
147
148void NATEngine::i_commit()
149{
150 AutoCaller autoCaller(this);
151 AssertComRCReturnVoid(autoCaller.rc());
152
153 /* sanity too */
154 AutoCaller peerCaller(mPeer);
155 AssertComRCReturnVoid(peerCaller.rc());
156
157 /* lock both for writing since we modify both (mPeer is "master" so locked
158 * first) */
159 AutoMultiWriteLock2 alock(mPeer, this COMMA_LOCKVAL_SRC_POS);
160 if (mData->m.isBackedUp())
161 {
162 mData->m.commit();
163 if (mPeer)
164 mPeer->mData->m.attach(mData->m);
165 }
166}
167
168void NATEngine::i_copyFrom(NATEngine *aThat)
169{
170 AssertReturnVoid(aThat != NULL);
171
172 /* sanity */
173 AutoCaller autoCaller(this);
174 AssertComRCReturnVoid(autoCaller.rc());
175
176 /* sanity too */
177 AutoCaller thatCaller(aThat);
178 AssertComRCReturnVoid(thatCaller.rc());
179
180 /* peer is not modified, lock it for reading (aThat is "master" so locked
181 * first) */
182 AutoReadLock rl(aThat COMMA_LOCKVAL_SRC_POS);
183 AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS);
184
185 /* this will back up current data */
186 mData->m.assignCopy(aThat->mData->m);
187}
188
189HRESULT NATEngine::getNetworkSettings(ULONG *aMtu, ULONG *aSockSnd, ULONG *aSockRcv, ULONG *aTcpWndSnd, ULONG *aTcpWndRcv)
190{
191 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
192 if (aMtu)
193 *aMtu = mData->m->s.u32Mtu;
194 if (aSockSnd)
195 *aSockSnd = mData->m->s.u32SockSnd;
196 if (aSockRcv)
197 *aSockRcv = mData->m->s.u32SockRcv;
198 if (aTcpWndSnd)
199 *aTcpWndSnd = mData->m->s.u32TcpSnd;
200 if (aTcpWndRcv)
201 *aTcpWndRcv = mData->m->s.u32TcpRcv;
202
203 return S_OK;
204}
205
206HRESULT NATEngine::setNetworkSettings(ULONG aMtu, ULONG aSockSnd, ULONG aSockRcv, ULONG aTcpWndSnd, ULONG aTcpWndRcv)
207{
208 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
209 if ( aMtu || aSockSnd || aSockRcv
210 || aTcpWndSnd || aTcpWndRcv)
211 {
212 mData->m.backup();
213 mParent->i_setModified(Machine::IsModified_NetworkAdapters);
214 }
215 if (aMtu)
216 mData->m->s.u32Mtu = aMtu;
217 if (aSockSnd)
218 mData->m->s.u32SockSnd = aSockSnd;
219 if (aSockRcv)
220 mData->m->s.u32SockRcv = aSockSnd;
221 if (aTcpWndSnd)
222 mData->m->s.u32TcpSnd = aTcpWndSnd;
223 if (aTcpWndRcv)
224 mData->m->s.u32TcpRcv = aTcpWndRcv;
225
226 return S_OK;
227}
228
229
230HRESULT NATEngine::getRedirects(std::vector<com::Utf8Str> &aRedirects)
231{
232 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
233
234 aRedirects.resize(mData->m->s.mapRules.size());
235 size_t i = 0;
236 settings::NATRulesMap::const_iterator it;
237 for (it = mData->m->s.mapRules.begin(); it != mData->m->s.mapRules.end(); ++it, ++i)
238 {
239 settings::NATRule r = it->second;
240 aRedirects[i] = Utf8StrFmt("%s,%d,%s,%d,%s,%d",
241 r.strName.c_str(),
242 r.proto,
243 r.strHostIP.c_str(),
244 r.u16HostPort,
245 r.strGuestIP.c_str(),
246 r.u16GuestPort);
247 }
248 return S_OK;
249}
250
251HRESULT NATEngine::addRedirect(const com::Utf8Str &aName, NATProtocol_T aProto, const com::Utf8Str &aHostIP,
252 USHORT aHostPort, const com::Utf8Str &aGuestIP, USHORT aGuestPort)
253{
254 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
255 Utf8Str name = aName;
256 settings::NATRule r;
257 const char *proto;
258 switch (aProto)
259 {
260 case NATProtocol_TCP:
261 proto = "tcp";
262 break;
263 case NATProtocol_UDP:
264 proto = "udp";
265 break;
266 default:
267 return E_INVALIDARG;
268 }
269 if (name.isEmpty())
270 name = Utf8StrFmt("%s_%d_%d", proto, aHostPort, aGuestPort);
271
272 settings::NATRulesMap::iterator it;
273 for (it = mData->m->s.mapRules.begin(); it != mData->m->s.mapRules.end(); ++it)
274 {
275 r = it->second;
276 if (it->first == name)
277 return setError(E_INVALIDARG,
278 tr("A NAT rule of this name already exists"));
279 if ( r.strHostIP == aHostIP
280 && r.u16HostPort == aHostPort
281 && r.proto == aProto)
282 return setError(E_INVALIDARG,
283 tr("A NAT rule for this host port and this host IP already exists"));
284 }
285
286 mData->m.backup();
287 r.strName = name.c_str();
288 r.proto = aProto;
289 r.strHostIP = aHostIP;
290 r.u16HostPort = aHostPort;
291 r.strGuestIP = aGuestIP;
292 r.u16GuestPort = aGuestPort;
293 mData->m->s.mapRules.insert(std::make_pair(name, r));
294 mParent->i_setModified(Machine::IsModified_NetworkAdapters);
295
296 ULONG ulSlot;
297 mAdapter->COMGETTER(Slot)(&ulSlot);
298
299 alock.release();
300 mParent->i_onNATRedirectRuleChange(ulSlot, FALSE, Bstr(name).raw(), aProto, Bstr(r.strHostIP).raw(),
301 r.u16HostPort, Bstr(r.strGuestIP).raw(), r.u16GuestPort);
302 return S_OK;
303}
304
305HRESULT NATEngine::removeRedirect(const com::Utf8Str &aName)
306{
307 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
308 settings::NATRulesMap::iterator it = mData->m->s.mapRules.find(aName);
309 if (it == mData->m->s.mapRules.end())
310 return E_INVALIDARG;
311 mData->m.backup();
312 /*
313 * NB: "it" may now point to the backup! In that case it's ok to
314 * get data from the backup copy of s.mapRules via it, but we can't
315 * erase(it) from potentially new s.mapRules.
316 */
317 settings::NATRule r = it->second;
318 Utf8Str strHostIP = r.strHostIP;
319 Utf8Str strGuestIP = r.strGuestIP;
320 NATProtocol_T proto = r.proto;
321 uint16_t u16HostPort = r.u16HostPort;
322 uint16_t u16GuestPort = r.u16GuestPort;
323 ULONG ulSlot;
324 mAdapter->COMGETTER(Slot)(&ulSlot);
325
326 mData->m->s.mapRules.erase(aName); /* NB: erase by key, "it" may not be valid */
327 mParent->i_setModified(Machine::IsModified_NetworkAdapters);
328 alock.release();
329 mParent->i_onNATRedirectRuleChange(ulSlot, TRUE, Bstr(aName).raw(), proto, Bstr(strHostIP).raw(),
330 u16HostPort, Bstr(strGuestIP).raw(), u16GuestPort);
331 return S_OK;
332}
333
334HRESULT NATEngine::i_loadSettings(const settings::NAT &data)
335{
336 AutoCaller autoCaller(this);
337 AssertComRCReturnRC(autoCaller.rc());
338
339 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
340 mData->m->s = data;
341 return S_OK;
342}
343
344
345HRESULT NATEngine::i_saveSettings(settings::NAT &data)
346{
347 AutoCaller autoCaller(this);
348 AssertComRCReturnRC(autoCaller.rc());
349
350 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
351 HRESULT rc = S_OK;
352 data = mData->m->s;
353 return rc;
354}
355
356HRESULT NATEngine::setNetwork(const com::Utf8Str &aNetwork)
357{
358 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
359 if (mData->m->s.strNetwork != aNetwork)
360 {
361 mData->m.backup();
362 mData->m->s.strNetwork = aNetwork;
363 mParent->i_setModified(Machine::IsModified_NetworkAdapters);
364 }
365 return S_OK;
366}
367
368
369HRESULT NATEngine::getNetwork(com::Utf8Str &aNetwork)
370{
371 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
372 if (!mData->m->s.strNetwork.isEmpty())
373 {
374 aNetwork = mData->m->s.strNetwork;
375 Log(("Getter (this:%p) Network: %s\n", this, mData->m->s.strNetwork.c_str()));
376 }
377 return S_OK;
378}
379
380HRESULT NATEngine::setHostIP(const com::Utf8Str &aHostIP)
381{
382 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
383 if (mData->m->s.strBindIP != aHostIP)
384 {
385 mData->m.backup();
386 mData->m->s.strBindIP = aHostIP;
387 mParent->i_setModified(Machine::IsModified_NetworkAdapters);
388 }
389 return S_OK;
390}
391
392HRESULT NATEngine::getHostIP(com::Utf8Str &aBindIP)
393{
394 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
395
396 if (!mData->m->s.strBindIP.isEmpty())
397 aBindIP = mData->m->s.strBindIP;
398 return S_OK;
399}
400
401HRESULT NATEngine::setTFTPPrefix(const com::Utf8Str &aTFTPPrefix)
402{
403 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
404 if (mData->m->s.strTFTPPrefix != aTFTPPrefix)
405 {
406 mData->m.backup();
407 mData->m->s.strTFTPPrefix = aTFTPPrefix;
408 mParent->i_setModified(Machine::IsModified_NetworkAdapters);
409 }
410 return S_OK;
411}
412
413
414HRESULT NATEngine::getTFTPPrefix(com::Utf8Str &aTFTPPrefix)
415{
416 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
417
418 if (!mData->m->s.strTFTPPrefix.isEmpty())
419 {
420 aTFTPPrefix = mData->m->s.strTFTPPrefix;
421 Log(("Getter (this:%p) TFTPPrefix: %s\n", this, mData->m->s.strTFTPPrefix.c_str()));
422 }
423 return S_OK;
424}
425
426HRESULT NATEngine::setTFTPBootFile(const com::Utf8Str &aTFTPBootFile)
427{
428 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
429 if (mData->m->s.strTFTPBootFile != aTFTPBootFile)
430 {
431 mData->m.backup();
432 mData->m->s.strTFTPBootFile = aTFTPBootFile;
433 mParent->i_setModified(Machine::IsModified_NetworkAdapters);
434 }
435 return S_OK;
436}
437
438
439HRESULT NATEngine::getTFTPBootFile(com::Utf8Str &aTFTPBootFile)
440{
441 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
442 if (!mData->m->s.strTFTPBootFile.isEmpty())
443 {
444 aTFTPBootFile = mData->m->s.strTFTPBootFile;
445 Log(("Getter (this:%p) BootFile: %s\n", this, mData->m->s.strTFTPBootFile.c_str()));
446 }
447 return S_OK;
448}
449
450
451HRESULT NATEngine::setTFTPNextServer(const com::Utf8Str &aTFTPNextServer)
452{
453 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
454 if (mData->m->s.strTFTPNextServer != aTFTPNextServer)
455 {
456 mData->m.backup();
457 mData->m->s.strTFTPNextServer = aTFTPNextServer;
458 mParent->i_setModified(Machine::IsModified_NetworkAdapters);
459 }
460 return S_OK;
461}
462
463HRESULT NATEngine::getTFTPNextServer(com::Utf8Str &aTFTPNextServer)
464{
465 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
466 if (!mData->m->s.strTFTPNextServer.isEmpty())
467 {
468 aTFTPNextServer = mData->m->s.strTFTPNextServer;
469 Log(("Getter (this:%p) NextServer: %s\n", this, mData->m->s.strTFTPNextServer.c_str()));
470 }
471 return S_OK;
472}
473
474/* DNS */
475HRESULT NATEngine::setDNSPassDomain(BOOL aDNSPassDomain)
476{
477 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
478
479 if (mData->m->s.fDNSPassDomain != RT_BOOL(aDNSPassDomain))
480 {
481 mData->m.backup();
482 mData->m->s.fDNSPassDomain = RT_BOOL(aDNSPassDomain);
483 mParent->i_setModified(Machine::IsModified_NetworkAdapters);
484 }
485 return S_OK;
486}
487
488HRESULT NATEngine::getDNSPassDomain(BOOL *aDNSPassDomain)
489{
490 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
491 *aDNSPassDomain = mData->m->s.fDNSPassDomain;
492 return S_OK;
493}
494
495
496HRESULT NATEngine::setDNSProxy(BOOL aDNSProxy)
497{
498 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
499
500 if (mData->m->s.fDNSProxy != RT_BOOL(aDNSProxy))
501 {
502 mData->m.backup();
503 mData->m->s.fDNSProxy = RT_BOOL(aDNSProxy);
504 mParent->i_setModified(Machine::IsModified_NetworkAdapters);
505 }
506 return S_OK;
507}
508
509HRESULT NATEngine::getDNSProxy(BOOL *aDNSProxy)
510{
511 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
512 *aDNSProxy = mData->m->s.fDNSProxy;
513 return S_OK;
514}
515
516
517HRESULT NATEngine::getDNSUseHostResolver(BOOL *aDNSUseHostResolver)
518{
519 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
520 *aDNSUseHostResolver = mData->m->s.fDNSUseHostResolver;
521 return S_OK;
522}
523
524
525HRESULT NATEngine::setDNSUseHostResolver(BOOL aDNSUseHostResolver)
526{
527 if (mData->m->s.fDNSUseHostResolver != RT_BOOL(aDNSUseHostResolver))
528 {
529 mData->m.backup();
530 mData->m->s.fDNSUseHostResolver = RT_BOOL(aDNSUseHostResolver);
531 mParent->i_setModified(Machine::IsModified_NetworkAdapters);
532 }
533 return S_OK;
534}
535
536HRESULT NATEngine::setAliasMode(ULONG aAliasMode)
537{
538 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
539 ULONG uAliasMode = (mData->m->s.fAliasUseSamePorts ? NATAliasMode_AliasUseSamePorts : 0);
540 uAliasMode |= (mData->m->s.fAliasLog ? NATAliasMode_AliasLog : 0);
541 uAliasMode |= (mData->m->s.fAliasProxyOnly ? NATAliasMode_AliasProxyOnly : 0);
542 if (uAliasMode != aAliasMode)
543 {
544 mData->m.backup();
545 mData->m->s.fAliasUseSamePorts = RT_BOOL(aAliasMode & NATAliasMode_AliasUseSamePorts);
546 mData->m->s.fAliasLog = RT_BOOL(aAliasMode & NATAliasMode_AliasLog);
547 mData->m->s.fAliasProxyOnly = RT_BOOL(aAliasMode & NATAliasMode_AliasProxyOnly);
548 mParent->i_setModified(Machine::IsModified_NetworkAdapters);
549 }
550 return S_OK;
551}
552
553HRESULT NATEngine::getAliasMode(ULONG *aAliasMode)
554{
555 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
556 ULONG uAliasMode = (mData->m->s.fAliasUseSamePorts ? NATAliasMode_AliasUseSamePorts : 0);
557 uAliasMode |= (mData->m->s.fAliasLog ? NATAliasMode_AliasLog : 0);
558 uAliasMode |= (mData->m->s.fAliasProxyOnly ? NATAliasMode_AliasProxyOnly : 0);
559 *aAliasMode = uAliasMode;
560 return S_OK;
561}
562
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette