VirtualBox

source: vbox/trunk/src/VBox/Main/NATEngineImpl.cpp@ 33557

Last change on this file since 33557 was 33517, checked in by vboxsync, 14 years ago

Main/NATEngineImpl.cpp: copy'n'paste error

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.2 KB
Line 
1/* $Id: NATEngineImpl.cpp 33517 2010-10-27 14:34:51Z vboxsync $ */
2/** @file
3 * Implementation of INATEngine in VBoxSVC.
4 */
5
6/*
7 * Copyright (C) 2010 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 "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
30
31// constructor / destructor
32////////////////////////////////////////////////////////////////////////////////
33
34NATEngine::NATEngine():mParent(NULL){}
35NATEngine::~NATEngine(){}
36
37HRESULT NATEngine::FinalConstruct()
38{
39 return S_OK;
40}
41
42HRESULT NATEngine::init(Machine *aParent)
43{
44 AutoInitSpan autoInitSpan(this);
45 AssertReturn(autoInitSpan.isOk(), E_FAIL);
46 autoInitSpan.setSucceeded();
47 m_fModified = false;
48 mData.allocate();
49 mData->mNetwork.setNull();
50 mData->mBindIP.setNull();
51 unconst(mParent) = aParent;
52 return S_OK;
53}
54
55HRESULT NATEngine::init(Machine *aParent, NATEngine *aThat)
56{
57 AutoInitSpan autoInitSpan(this);
58 AssertReturn(autoInitSpan.isOk(), E_FAIL);
59 Log(("init that:%p this:%p\n", aThat, this));
60
61 AutoCaller thatCaller (aThat);
62 AssertComRCReturnRC(thatCaller.rc());
63
64 AutoReadLock thatLock(aThat COMMA_LOCKVAL_SRC_POS);
65
66 mData.share(aThat->mData);
67 NATRuleMap::iterator it;
68 mNATRules.clear();
69 for (it = aThat->mNATRules.begin(); it != aThat->mNATRules.end(); ++it)
70 {
71 mNATRules.insert(std::make_pair(it->first, it->second));
72 }
73 unconst(mParent) = aParent;
74 unconst(mPeer) = aThat;
75 autoInitSpan.setSucceeded();
76 return S_OK;
77}
78
79HRESULT NATEngine::initCopy (Machine *aParent, NATEngine *aThat)
80{
81 AutoInitSpan autoInitSpan(this);
82 AssertReturn(autoInitSpan.isOk(), E_FAIL);
83
84 Log(("initCopy that:%p this:%p\n", aThat, this));
85
86 AutoCaller thatCaller (aThat);
87 AssertComRCReturnRC(thatCaller.rc());
88
89 AutoReadLock thatLock(aThat COMMA_LOCKVAL_SRC_POS);
90
91 mData.attachCopy(aThat->mData);
92 NATRuleMap::iterator it;
93 mNATRules.clear();
94 for (it = aThat->mNATRules.begin(); it != aThat->mNATRules.end(); ++it)
95 {
96 mNATRules.insert(std::make_pair(it->first, it->second));
97 }
98 unconst(mParent) = aParent;
99 autoInitSpan.setSucceeded();
100 return S_OK;
101}
102
103
104void NATEngine::FinalRelease()
105{
106 uninit();
107}
108
109void NATEngine::uninit()
110{
111 AutoUninitSpan autoUninitSpan(this);
112 if (autoUninitSpan.uninitDone())
113 return;
114
115 mNATRules.clear();
116 mData.free();
117 unconst(mPeer) = NULL;
118 unconst(mParent) = NULL;
119}
120
121bool NATEngine::isModified()
122{
123 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
124 bool fModified = m_fModified;
125 return fModified;
126}
127
128bool NATEngine::rollback()
129{
130 AutoCaller autoCaller(this);
131 AssertComRCReturn (autoCaller.rc(), false);
132
133 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
134 bool fChanged = m_fModified;
135
136 if (m_fModified)
137 {
138 /* we need to check all data to see whether anything will be changed
139 * after rollback */
140 mData.rollback();
141 }
142 m_fModified = false;
143 return fChanged;
144}
145
146void NATEngine::commit()
147{
148 AutoCaller autoCaller(this);
149 AssertComRCReturnVoid (autoCaller.rc());
150
151 /* sanity too */
152 AutoCaller peerCaller (mPeer);
153 AssertComRCReturnVoid (peerCaller.rc());
154
155 /* lock both for writing since we modify both (mPeer is "master" so locked
156 * first) */
157 AutoMultiWriteLock2 alock(mPeer, this COMMA_LOCKVAL_SRC_POS);
158 if (m_fModified)
159 {
160 mData.commit();
161 if (mPeer)
162 {
163 mPeer->mData.attach (mData);
164 mPeer->mNATRules.clear();
165 NATRuleMap::iterator it;
166 for (it = mNATRules.begin(); it != mNATRules.end(); ++it)
167 {
168 mPeer->mNATRules.insert(std::make_pair(it->first, it->second));
169 }
170 }
171 }
172 m_fModified = false;
173}
174
175STDMETHODIMP
176NATEngine::GetNetworkSettings(ULONG *aMtu, ULONG *aSockSnd, ULONG *aSockRcv, ULONG *aTcpWndSnd, ULONG *aTcpWndRcv)
177{
178 AutoCaller autoCaller(this);
179 if (FAILED(autoCaller.rc())) return autoCaller.rc();
180
181 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
182 if (aMtu)
183 *aMtu = mData->mMtu;
184 if (aSockSnd)
185 *aSockSnd = mData->mSockSnd;
186 if (aSockRcv)
187 *aSockRcv = mData->mSockRcv;
188 if (aTcpWndSnd)
189 *aTcpWndSnd = mData->mTcpSnd;
190 if (aTcpWndRcv)
191 *aTcpWndRcv = mData->mTcpRcv;
192
193 return S_OK;
194}
195
196STDMETHODIMP
197NATEngine::SetNetworkSettings(ULONG aMtu, ULONG aSockSnd, ULONG aSockRcv, ULONG aTcpWndSnd, ULONG aTcpWndRcv)
198{
199 AutoCaller autoCaller(this);
200 if (FAILED(autoCaller.rc())) return autoCaller.rc();
201
202 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
203 if ( aMtu || aSockSnd || aSockRcv
204 || aTcpWndSnd || aTcpWndRcv)
205 {
206 mData.backup();
207 m_fModified = true;
208 }
209 if (aMtu)
210 mData->mMtu = aMtu;
211 if (aSockSnd)
212 mData->mSockSnd = aSockSnd;
213 if (aSockRcv)
214 mData->mSockRcv = aSockSnd;
215 if (aTcpWndSnd)
216 mData->mTcpSnd = aTcpWndSnd;
217 if (aTcpWndRcv)
218 mData->mTcpRcv = aTcpWndRcv;
219
220 if (m_fModified)
221 mParent->setModified(Machine::IsModified_NetworkAdapters);
222 return S_OK;
223}
224
225STDMETHODIMP
226NATEngine::COMGETTER(Redirects)(ComSafeArrayOut(BSTR , aNatRules))
227{
228 CheckComArgOutSafeArrayPointerValid(aNatRules);
229
230 AutoCaller autoCaller(this);
231 if (FAILED(autoCaller.rc())) return autoCaller.rc();
232
233 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
234
235
236 SafeArray<BSTR> sf(mNATRules.size());
237 size_t i = 0;
238 NATRuleMap::const_iterator it;
239 for (it = mNATRules.begin();
240 it != mNATRules.end(); ++it, ++i)
241 {
242 settings::NATRule r = it->second;
243 BstrFmt bstr("%s,%d,%s,%d,%s,%d",
244 r.strName.c_str(),
245 r.u32Proto,
246 r.strHostIP.c_str(),
247 r.u16HostPort,
248 r.strGuestIP.c_str(),
249 r.u16GuestPort);
250 bstr.detachTo(&sf[i]);
251 }
252 sf.detachTo(ComSafeArrayOutArg(aNatRules));
253 return S_OK;
254}
255
256
257STDMETHODIMP
258NATEngine::AddRedirect(IN_BSTR aName, NATProtocol_T aProto, IN_BSTR aBindIp, USHORT aHostPort, IN_BSTR aGuestIP, USHORT aGuestPort)
259{
260
261 AutoCaller autoCaller(this);
262 if (FAILED(autoCaller.rc())) return autoCaller.rc();
263
264 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
265 Utf8Str name = aName;
266 settings::NATRule r;
267 if (name.isEmpty())
268 {
269 const char *proto;
270 switch (aProto)
271 {
272 case NATProtocol_TCP:
273 proto = "tcp";
274 break;
275 case NATProtocol_UDP:
276 proto = "udp";
277 break;
278 default:
279 return E_INVALIDARG;
280 }
281 name = Utf8StrFmt("%s_%d_%d", proto, aHostPort, aGuestPort);
282 }
283 r.strName = name.c_str();
284 r.u32Proto = aProto;
285 r.strHostIP = aBindIp;
286 r.u16HostPort = aHostPort;
287 r.strGuestIP = aGuestIP;
288 r.u16GuestPort = aGuestPort;
289 mNATRules.insert(std::make_pair(name, r));
290 mParent->setModified(Machine::IsModified_NetworkAdapters);
291 m_fModified = true;
292 return S_OK;
293}
294
295STDMETHODIMP
296NATEngine::RemoveRedirect(IN_BSTR aName)
297{
298 AutoCaller autoCaller(this);
299 if (FAILED(autoCaller.rc())) return autoCaller.rc();
300
301 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
302 Utf8Str rule;
303 NATRuleMap::iterator it = mNATRules.find(aName);
304 if (it == mNATRules.end())
305 return E_INVALIDARG;
306 mData.backup();
307 mNATRules.erase(it);
308 mParent->setModified(Machine::IsModified_NetworkAdapters);
309 m_fModified = true;
310 return S_OK;
311}
312
313HRESULT NATEngine::loadSettings(const settings::NAT &data)
314{
315 AutoCaller autoCaller(this);
316 AssertComRCReturnRC(autoCaller.rc());
317
318 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
319 HRESULT rc = S_OK;
320 mData->mNetwork = data.strNetwork;
321 mData->mBindIP = data.strBindIP;
322 mData->mMtu = data.u32Mtu;
323 mData->mSockSnd = data.u32SockSnd;
324 mData->mTcpRcv = data.u32TcpRcv;
325 mData->mTcpSnd = data.u32TcpSnd;
326 /* TFTP */
327 mData->mTftpPrefix = data.strTftpPrefix;
328 mData->mTftpBootFile = data.strTftpBootFile;
329 mData->mTftpNextServer = data.strTftpNextServer;
330 /* DNS */
331 mData->mDnsPassDomain = data.fDnsPassDomain;
332 mData->mDnsProxy = data.fDnsProxy;
333 mData->mDnsUseHostResolver = data.fDnsUseHostResolver;
334 /* Alias */
335 mData->mAliasMode = (data.fAliasUseSamePorts ? NATAliasMode_AliasUseSamePorts : 0);
336 mData->mAliasMode |= (data.fAliasLog ? NATAliasMode_AliasLog : 0);
337 mData->mAliasMode |= (data.fAliasProxyOnly ? NATAliasMode_AliasProxyOnly : 0);
338 /* port forwarding */
339 mNATRules.clear();
340 for (settings::NATRuleList::const_iterator it = data.llRules.begin();
341 it != data.llRules.end(); ++it)
342 {
343 mNATRules.insert(std::make_pair(it->strName, *it));
344 }
345 m_fModified = false;
346 return rc;
347}
348
349
350HRESULT NATEngine::saveSettings(settings::NAT &data)
351{
352 AutoCaller autoCaller(this);
353 AssertComRCReturnRC(autoCaller.rc());
354
355 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
356 HRESULT rc = S_OK;
357 data.strNetwork = mData->mNetwork;
358 data.strBindIP = mData->mBindIP;
359 data.u32Mtu = mData->mMtu;
360 data.u32SockRcv = mData->mSockRcv;
361 data.u32SockSnd = mData->mSockSnd;
362 data.u32TcpRcv = mData->mTcpRcv;
363 data.u32TcpSnd = mData->mTcpSnd;
364 /* TFTP */
365 data.strTftpPrefix = mData->mTftpPrefix;
366 data.strTftpBootFile = mData->mTftpBootFile;
367 data.strTftpNextServer = mData->mTftpNextServer;
368 /* DNS */
369 data.fDnsPassDomain = !!mData->mDnsPassDomain;
370 data.fDnsProxy = !!mData->mDnsProxy;
371 data.fDnsUseHostResolver = !!mData->mDnsUseHostResolver;
372 /* Alias */
373 data.fAliasLog = !!(mData->mAliasMode & NATAliasMode_AliasLog);
374 data.fAliasProxyOnly = !!(mData->mAliasMode & NATAliasMode_AliasProxyOnly);
375 data.fAliasUseSamePorts = !!(mData->mAliasMode & NATAliasMode_AliasUseSamePorts);
376
377 for (NATRuleMap::iterator it = mNATRules.begin();
378 it != mNATRules.end(); ++it)
379 data.llRules.push_back(it->second);
380 m_fModified = false;
381 return rc;
382}
383
384
385STDMETHODIMP
386NATEngine::COMSETTER(Network)(IN_BSTR aNetwork)
387{
388 AutoCaller autoCaller(this);
389 AssertComRCReturnRC (autoCaller.rc());
390 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
391 if (Bstr(mData->mNetwork) != aNetwork)
392 {
393 mData.backup();
394 mData->mNetwork = aNetwork;
395 mParent->setModified(Machine::IsModified_NetworkAdapters);
396 m_fModified = true;
397 }
398 return S_OK;
399}
400
401STDMETHODIMP
402NATEngine::COMGETTER(Network)(BSTR *aNetwork)
403{
404 CheckComArgNotNull(aNetwork);
405 AutoCaller autoCaller(this);
406 AssertComRCReturnRC(autoCaller.rc());
407
408 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
409 if (!mData->mNetwork.isEmpty())
410 {
411 mData->mNetwork.cloneTo(aNetwork);
412 Log(("Getter (this:%p) Network: %s\n", this, mData->mNetwork.c_str()));
413 }
414 return S_OK;
415}
416
417STDMETHODIMP
418NATEngine::COMSETTER(HostIP) (IN_BSTR aBindIP)
419{
420 AutoCaller autoCaller(this);
421 AssertComRCReturnRC (autoCaller.rc());
422 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
423 if (Bstr(mData->mBindIP) != aBindIP)
424 {
425 mData.backup();
426 mData->mBindIP = aBindIP;
427 mParent->setModified(Machine::IsModified_NetworkAdapters);
428 m_fModified = true;
429 }
430 return S_OK;
431}
432STDMETHODIMP NATEngine::COMGETTER(HostIP) (BSTR *aBindIP)
433{
434 AutoCaller autoCaller(this);
435 AssertComRCReturnRC(autoCaller.rc());
436
437 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
438 if (!mData->mBindIP.isEmpty())
439 mData->mBindIP.cloneTo(aBindIP);
440 return S_OK;
441}
442
443
444STDMETHODIMP
445NATEngine::COMSETTER(TftpPrefix)(IN_BSTR aTftpPrefix)
446{
447 AutoCaller autoCaller(this);
448 AssertComRCReturnRC (autoCaller.rc());
449 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
450 if (Bstr(mData->mTftpPrefix) != aTftpPrefix)
451 {
452 mData.backup();
453 mData->mTftpPrefix = aTftpPrefix;
454 mParent->setModified(Machine::IsModified_NetworkAdapters);
455 m_fModified = true;
456 }
457 return S_OK;
458}
459
460STDMETHODIMP
461NATEngine::COMGETTER(TftpPrefix)(BSTR *aTftpPrefix)
462{
463 AutoCaller autoCaller(this);
464 AssertComRCReturnRC(autoCaller.rc());
465
466 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
467 if (!mData->mTftpPrefix.isEmpty())
468 {
469 mData->mTftpPrefix.cloneTo(aTftpPrefix);
470 Log(("Getter (this:%p) TftpPrefix: %s\n", this, mData->mTftpPrefix.c_str()));
471 }
472 return S_OK;
473}
474
475STDMETHODIMP
476NATEngine::COMSETTER(TftpBootFile)(IN_BSTR aTftpBootFile)
477{
478 AutoCaller autoCaller(this);
479 AssertComRCReturnRC (autoCaller.rc());
480 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
481 if (Bstr(mData->mTftpBootFile) != aTftpBootFile)
482 {
483 mData.backup();
484 mData->mTftpBootFile = aTftpBootFile;
485 mParent->setModified(Machine::IsModified_NetworkAdapters);
486 m_fModified = true;
487 }
488 return S_OK;
489}
490
491STDMETHODIMP
492NATEngine::COMGETTER(TftpBootFile)(BSTR *aTftpBootFile)
493{
494 AutoCaller autoCaller(this);
495 AssertComRCReturnRC(autoCaller.rc());
496
497 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
498 if (!mData->mTftpBootFile.isEmpty())
499 {
500 mData->mTftpBootFile.cloneTo(aTftpBootFile);
501 Log(("Getter (this:%p) BootFile: %s\n", this, mData->mTftpBootFile.c_str()));
502 }
503 return S_OK;
504}
505
506STDMETHODIMP
507NATEngine::COMSETTER(TftpNextServer)(IN_BSTR aTftpNextServer)
508{
509 AutoCaller autoCaller(this);
510 AssertComRCReturnRC (autoCaller.rc());
511 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
512 if (Bstr(mData->mTftpNextServer) != aTftpNextServer)
513 {
514 mData.backup();
515 mData->mTftpNextServer = aTftpNextServer;
516 mParent->setModified(Machine::IsModified_NetworkAdapters);
517 m_fModified = true;
518 }
519 return S_OK;
520}
521
522STDMETHODIMP
523NATEngine::COMGETTER(TftpNextServer)(BSTR *aTftpNextServer)
524{
525 AutoCaller autoCaller(this);
526 AssertComRCReturnRC(autoCaller.rc());
527
528 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
529 if (!mData->mTftpNextServer.isEmpty())
530 {
531 mData->mTftpNextServer.cloneTo(aTftpNextServer);
532 Log(("Getter (this:%p) NextServer: %s\n", this, mData->mTftpNextServer.c_str()));
533 }
534 return S_OK;
535}
536/* DNS */
537STDMETHODIMP
538NATEngine::COMSETTER(DnsPassDomain) (BOOL aDnsPassDomain)
539{
540 AutoCaller autoCaller(this);
541 AssertComRCReturnRC (autoCaller.rc());
542 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
543
544 if (mData->mDnsPassDomain != aDnsPassDomain)
545 {
546 mData.backup();
547 mData->mDnsPassDomain = aDnsPassDomain;
548 mParent->setModified(Machine::IsModified_NetworkAdapters);
549 m_fModified = true;
550 }
551 return S_OK;
552}
553STDMETHODIMP
554NATEngine::COMGETTER(DnsPassDomain)(BOOL *aDnsPassDomain)
555{
556 AutoCaller autoCaller(this);
557 AssertComRCReturnRC(autoCaller.rc());
558
559 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
560 *aDnsPassDomain = mData->mDnsPassDomain;
561 return S_OK;
562}
563STDMETHODIMP
564NATEngine::COMSETTER(DnsProxy)(BOOL aDnsProxy)
565{
566 AutoCaller autoCaller(this);
567 AssertComRCReturnRC (autoCaller.rc());
568 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
569
570 if (mData->mDnsProxy != aDnsProxy)
571 {
572 mData.backup();
573 mData->mDnsProxy = aDnsProxy;
574 mParent->setModified(Machine::IsModified_NetworkAdapters);
575 m_fModified = true;
576 }
577 return S_OK;
578}
579STDMETHODIMP
580NATEngine::COMGETTER(DnsProxy)(BOOL *aDnsProxy)
581{
582 AutoCaller autoCaller(this);
583 AssertComRCReturnRC(autoCaller.rc());
584
585 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
586 *aDnsProxy = mData->mDnsProxy;
587 return S_OK;
588}
589STDMETHODIMP
590NATEngine::COMGETTER(DnsUseHostResolver)(BOOL *aDnsUseHostResolver)
591{
592 AutoCaller autoCaller(this);
593 AssertComRCReturnRC (autoCaller.rc());
594 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
595 *aDnsUseHostResolver = mData->mDnsUseHostResolver;
596 return S_OK;
597}
598STDMETHODIMP
599NATEngine::COMSETTER(DnsUseHostResolver)(BOOL aDnsUseHostResolver)
600{
601 AutoCaller autoCaller(this);
602 AssertComRCReturnRC(autoCaller.rc());
603
604 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
605
606 if (mData->mDnsUseHostResolver != aDnsUseHostResolver)
607 {
608 mData.backup();
609 mData->mDnsUseHostResolver = aDnsUseHostResolver;
610 mParent->setModified(Machine::IsModified_NetworkAdapters);
611 m_fModified = true;
612 }
613 return S_OK;
614}
615
616STDMETHODIMP NATEngine::COMSETTER(AliasMode) (ULONG aAliasMode)
617{
618 AutoCaller autoCaller(this);
619 AssertComRCReturnRC(autoCaller.rc());
620
621 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
622
623 if (mData->mAliasMode != aAliasMode)
624 {
625 mData.backup();
626 mData->mAliasMode = aAliasMode;
627 mParent->setModified(Machine::IsModified_NetworkAdapters);
628 m_fModified = true;
629 }
630 return S_OK;
631}
632
633STDMETHODIMP NATEngine::COMGETTER(AliasMode) (ULONG *aAliasMode)
634{
635 AutoCaller autoCaller(this);
636 AssertComRCReturnRC (autoCaller.rc());
637 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
638 *aAliasMode = mData->mAliasMode;
639 return S_OK;
640}
641
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