Merge branch 'fixes' into main/rendor-staging
[ryzomcore.git] / nel / src / net / module_gateway.cpp
blobd4d07ea610637caf716ef1b995233400659839a6
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "stdnet.h"
18 #include "nel/net/module_gateway.h"
19 #include "nel/net/module.h"
20 #include "nel/net/module_manager.h"
21 #include "nel/net/module_socket.h"
22 #include "nel/net/module_message.h"
23 #include "nel/net/callback_client.h"
24 #include "nel/net/callback_server.h"
26 using namespace std;
27 using namespace NLMISC;
31 namespace NLNET
33 struct TSecurityDataDesc
35 TSecurityData *SecurityData;
37 TSecurityDataDesc()
38 : SecurityData(NULL)
42 void serial(CMemStream &s)
44 if (!s.isReading())
46 // write mode
47 TSecurityData *sd = SecurityData;
49 uint32 nbSecBlock = 0;
50 sint32 tagCountPos = s.reserve(4);
51 while (sd != NULL)
53 if (sd->DataTag == 0xff)
55 TUnknownSecurityData *usd = safe_cast<TUnknownSecurityData *>(sd);
56 s.serial(usd->RealDataTag);
58 else
60 s.serial(sd->DataTag);
62 // reserve a place to store the size of the next element
63 sint32 pos = s.reserve(4);
64 s.serial(*sd);
65 // store the size
66 uint32 size = s.getPos()-pos-4;
67 s.poke(size, pos);
69 nbSecBlock++;
70 sd = sd->NextItem;
73 // store the number of item
74 s.poke(nbSecBlock, tagCountPos);
76 else
78 nlassert(SecurityData == NULL);
79 TSecurityData **pLastSd = &SecurityData;
80 // read mode
81 uint32 nbSecBlock;
82 s.serial(nbSecBlock);
84 if (nbSecBlock == 0)
85 SecurityData = NULL;
87 for (uint i=0; i<nbSecBlock; ++i)
89 uint8 dataTag;
90 s.serial(dataTag);
91 uint32 blockSize;
92 s.serial(blockSize);
93 sint32 pos = s.getPos();
94 TSecurityData *sd;
96 try
98 TSecurityData::TCtorParam param(dataTag);
99 sd = NLMISC_GET_FACTORY(TSecurityData, uint8).createObject(dataTag, param);
101 if (sd == NULL)
103 // we don't know this type, create an unknow security block
104 sd = new TUnknownSecurityData(dataTag, blockSize);
105 sd->serial(s);
107 else
109 sd->serial(s);
112 catch(const EStreamOverflow &)
114 // FAILED to read the security block, rewind to old pos and serial as unknow
115 nlwarning("Error while reading stream for security data type %u", dataTag);
117 s.seek(pos, NLMISC::IStream::begin);
118 sd = new TUnknownSecurityData(dataTag, blockSize);
119 sd->serial(s);
122 *pLastSd = sd;
123 pLastSd = &(sd->NextItem);
130 /// Sub message for module description
131 struct TModuleDescCodec
133 TModuleId ModuleProxyId;
134 uint32 ModuleDistance;
135 string ModuleFullName;
136 string ModuleClass;
137 string ModuleManifest;
138 TSecurityDataDesc SecDesc;
141 TModuleDescCodec()
145 TModuleDescCodec(IModuleProxy *proxy)
147 ModuleProxyId = proxy->getModuleProxyId();
148 ModuleDistance = proxy->getModuleDistance()+1;
149 ModuleFullName = proxy->getModuleName();
150 ModuleClass = proxy->getModuleClassName();
151 ModuleManifest = proxy->getModuleManifest();
152 SecDesc.SecurityData = const_cast<TSecurityData*>(proxy->getFirstSecurityData());
155 void serial(NLMISC::CMemStream &s)
157 s.serial(ModuleProxyId);
158 s.serial(ModuleDistance);
159 s.serial(ModuleFullName);
160 s.serial(ModuleManifest);
161 s.serial(ModuleClass);
162 s.serial(SecDesc);
166 /// message for module distance update
167 struct TModuleDistanceChangeMsg
169 TModuleId ModuleId;
170 uint32 NewDistance;
172 void serial(NLMISC::IStream &s)
174 s.serial(ModuleId);
175 s.serial(NewDistance);
179 /// message for module security update
180 struct TModuleSecurityChangeMsg
182 TModuleId ModuleId;
184 TSecurityDataDesc SecDesc;
186 void serial(NLMISC::CMemStream &s)
188 s.serial(ModuleId);
189 s.serial(SecDesc);
192 /// Message for module removing
193 struct TModuleRemMsg
195 vector<TModuleId> RemovedModules;
197 void serial(NLMISC::IStream &s)
199 s.serialCont(RemovedModules);
203 /// Message for module operation
204 struct TModuleOperationMsg
206 TModuleId ModuleId;
207 string OperationName;
209 CMessage MessageBody;
211 void serial(NLMISC::IStream &s)
213 s.serial(ModuleId);
214 s.serial(OperationName);
215 s.serial(MessageBody);
220 /// message waiting next update for local dispatching
221 struct TLocalMessage
223 TModuleId SenderProxyId;
224 TModuleId AddresseProxyId;
225 CMessage Message;
229 /** Register the gateway in the module manager gateway registry
231 void CModuleGateway::registerGateway()
233 IModuleManager::getInstance().registerModuleGateway(this);
235 /** Unregister the gateway in the module manager gateway registry
237 void CModuleGateway::unregisterGateway()
239 IModuleManager::getInstance().unregisterModuleGateway(this);
243 /** The standard gateway that interconnect module
244 * across process.
246 class CStandardGateway :
247 public CModuleBase,
248 public CModuleGateway,
249 public CModuleSocket
251 typedef map<TModuleId, TModuleProxyPtr> TModuleProxies;
252 /// Module proxies managed by this gateway. The map key is the module proxy id
253 TModuleProxies _ModuleProxies;
255 typedef CTwinMap<TStringId, TModuleProxyPtr> TNamedProxyIdx;
256 /// Index of name to proxy id
257 TNamedProxyIdx _NameToProxyIdx;
259 /// A structure to hold foreign proxy information
260 struct TKnownModuleInfo
262 TModuleId ForeignProxyId;
263 CGatewayRoute *Route;
264 uint32 ModuleDistance;
265 TStringId ModuleClassId;
268 typedef multimap<TStringId, TKnownModuleInfo> TKnownModuleInfos;
269 /** List of known foreign module info.
271 TKnownModuleInfos _KnownModules;
273 typedef map<TModuleId, TModuleId> TLocalModuleIndex;
274 /// Translation table to find module proxies for locally plugged module
275 /// The map key is the local module id, the data is the associated proxy id
276 TLocalModuleIndex _LocalModuleIndex;
278 typedef map<std::string, IGatewayTransport*> TTransportList;
279 /// the list of active transport
280 TTransportList _Transports;
282 typedef set<CGatewayRoute*> TRouteList;
283 // the list of available routes
284 TRouteList _Routes;
286 /// The security plug-in (if any)
287 CGatewaySecurity *_SecurityPlugin;
289 /// Ping counter for debug purpose
290 uint32 _PingCounter;
292 typedef std::list<TLocalMessage> TLocalMessageList;
293 /// List of local message waiting dispatching at next update
294 TLocalMessageList _LocalMessages;
296 public:
298 CStandardGateway()
299 : _SecurityPlugin(NULL),
300 _PingCounter(0)
304 ~CStandardGateway()
306 // we need to unplug any plugged module
307 while (!_PluggedModules.getAToBMap().empty())
309 _PluggedModules.getAToBMap().begin()->second->unplugModule(this);
312 // delete all transport
313 while (!_Transports.empty())
315 deleteTransport(_Transports.begin()->first);
318 // delete security plug-in
319 if (_SecurityPlugin != NULL)
320 removeSecurityPlugin();
322 // must be done before the other destructors are called
323 unregisterSocket();
324 unregisterGateway();
327 CModuleProxy *getModuleProxy(TModuleId proxyId)
329 TModuleProxies::iterator it(_ModuleProxies.find(proxyId));
330 if (it == _ModuleProxies.end())
331 return NULL;
332 return static_cast<CModuleProxy*>(it->second.getPtr());
335 /***********************************************************
336 ** Gateway methods
337 ***********************************************************/
338 virtual const std::string &getGatewayName() const
340 return getModuleName();
342 virtual const std::string &getFullyQualifiedGatewayName() const
344 return getModuleFullyQualifiedName();
347 /// Create and bind to this gateway a new transport
348 virtual void createTransport(const std::string &transportClass, const std::string &instanceName)
350 if (_Transports.find(instanceName) != _Transports.end())
352 nlwarning("A transport with the name '%s' already exist in this gateway", instanceName.c_str());
353 return;
356 IGatewayTransport::TCtorParam param;
357 param.Gateway = this;
358 IGatewayTransport *transport = NLMISC_GET_FACTORY(IGatewayTransport, std::string).createObject(transportClass, param);
360 if (transport == NULL)
362 nlwarning("Failed to create a transport with the class '%s'", transportClass.c_str());
363 return;
366 // Store the transport
367 // TTransportInfo *ti = new TTransportInfo(transport);
368 _Transports.insert(make_pair(instanceName, transport));
369 // _TransportPtrIdx.insert(make_pair(transport, ti));
371 nldebug("NETL6: Gateway transport %s (%s) created", instanceName.c_str(), transportClass.c_str());
374 /// Delete a transport (this will close any open route)
375 virtual void deleteTransport(const std::string &instanceName)
377 TTransportList::iterator it(_Transports.find(instanceName));
378 if (it == _Transports.end())
380 nlwarning("Unknown transport named '%s'", instanceName.c_str());
381 return;
384 nldebug("NETL6: Gateway transport '%s' deleted", instanceName.c_str());
385 // delete the transport
386 IGatewayTransport *transport = it->second;
387 // nlassert(_TransportPtrIdx.find(transport) != _TransportPtrIdx.end());
388 // _TransportPtrIdx.erase(transport);
389 delete transport;
390 // delete it->second;
391 _Transports.erase(it);
394 /// Activate/stop peer invisible mode on a transport
395 virtual void setTransportPeerInvisible(const std::string &transportInstanceName, bool peerInvisible)
397 TTransportList::iterator it(_Transports.find(transportInstanceName));
398 if (it == _Transports.end())
400 nlwarning("Unknown transport named '%s'", transportInstanceName.c_str());
401 return;
404 IGatewayTransport *transport= it->second;
406 if (peerInvisible == transport->PeerInvisible)
407 // nothing more to do
408 return;
410 // set the mode
411 transport->PeerInvisible = peerInvisible;
413 nldebug("NETL6: Gateway transport %s peer invisible mode %s", transportInstanceName.c_str(), peerInvisible? "ON" : "OFF");
416 // For each route of this transport, we need to disclose/undisclose peer modules
417 TRouteList::iterator first(_Routes.begin()), last(_Routes.end());
418 for (; first != last; ++first)
420 CGatewayRoute *route = *first;
422 if (route->getTransport() == transport)
424 // this route need to be filtered
425 TModuleProxies::iterator first(_ModuleProxies.begin()), last(_ModuleProxies.end());
426 for (; first != last; ++first)
428 IModuleProxy *proxy = first->second;
429 if (proxy->getGatewayRoute() != NULL
430 && proxy->getGatewayRoute() != route
431 && proxy->getGatewayRoute()->getTransport() == transport)
433 // this module is on the same transport, but another route, remove/add it from the
434 // route
435 if (peerInvisible)
436 undiscloseModuleToRoute(route, proxy);
437 else
439 // check firewall rules
440 if (!route->getTransport()->Firewalled)
441 discloseModuleToRoute(route, proxy);
449 /// Activate/stop firewalling mode on a transport
450 virtual void setTransportFirewallMode(const std::string &transportInstanceName, bool firewalled)
452 TTransportList::iterator it(_Transports.find(transportInstanceName));
453 if (it == _Transports.end())
455 nlwarning("Unknown transport named '%s'", transportInstanceName.c_str());
456 return;
459 IGatewayTransport *transport = it->second;
461 if (firewalled == transport->Firewalled)
462 // nothing to do
463 return;
465 if (firewalled && transport->getRouteCount() != 0)
466 throw EGatewayFirewallBreak();
468 /// set the firewall mode
469 transport->Firewalled = firewalled;
471 nldebug("NETL6: Gateway transport %s firewall mode %s", transportInstanceName.c_str(), firewalled? "ON" : "OFF");
473 if (firewalled == false)
475 // we need to disclose all module not disclosed yet
476 TRouteList::iterator first(_Routes.begin()), last(_Routes.end());
477 for (; first != last; ++first)
479 CGatewayRoute *route = *first;
481 if (route->getTransport() == transport)
483 // this route need to be unfiltered
484 TModuleProxies::iterator first(_ModuleProxies.begin()), last(_ModuleProxies.end());
485 for (; first != last; ++first)
487 IModuleProxy *proxy = first->second;
488 if (proxy->getGatewayRoute() == NULL || (proxy->getGatewayRoute() != route ))
490 // this module is on another route, disclose it if needed
491 if (route->FirewallDisclosed.find(proxy->getModuleProxyId()) == route->FirewallDisclosed.end())
492 discloseModuleToRoute(route, proxy);
496 // clear the firewall disclosed table
497 route->FirewallDisclosed.clear();
502 /// Send a command to a transport
503 virtual void transportCommand(const TParsedCommandLine &commandLine)
505 for (uint i=1; i<commandLine.SubParams.size(); ++i)
507 const TParsedCommandLine * subParam = commandLine.SubParams[i];
509 std::string transportName = subParam->ParamName;
510 TTransportList::const_iterator it(_Transports.find(transportName));
511 if (it == _Transports.end())
513 nlwarning("Unknown transport named '%s', ignoring command.", transportName.c_str());
515 else if (subParam->SubParams.empty())
517 nlwarning("Can't find sub param list for transport '%s' command", transportName.c_str());
519 else
521 nldebug("NETL6: Gateway transport %s, sending command '%s'", transportName.c_str(), commandLine.toString().c_str());
522 // ok, we have a valid transport, send the command
523 IGatewayTransport *transport = it->second;
524 if (!transport->onCommand(*subParam))
525 return;
530 virtual IGatewayTransport *getGatewayTransport(const std::string &transportName) const
532 TTransportList::const_iterator it(_Transports.find(transportName));
534 if (it == _Transports.end())
535 return NULL;
536 else
537 return it->second;
540 virtual uint32 getTransportCount() const
542 return (uint32)_Transports.size();
545 virtual uint32 getRouteCount() const
547 return (uint32)_Routes.size();
550 virtual uint32 getReceivedPingCount() const
552 return _PingCounter;
555 virtual void onRouteAdded(CGatewayRoute *route)
557 nlassert(route != NULL);
558 // Remember the new route
559 nlassert(_Routes.find(route) == _Routes.end());
560 _Routes.insert(route);
562 // a new route is available, disclose known modules
564 TModuleProxies::iterator first(_ModuleProxies.begin()), last(_ModuleProxies.end());
565 for (; first != last; ++first)
567 IModuleProxy *modProx = first->second;
569 // only transmit module desc coming from other routes
570 // and other transport if peer invisible
571 if (isModuleProxyVisible(modProx, route))
573 discloseModuleToRoute(route, modProx);
579 /// A route is removed by a transport
580 virtual void onRouteRemoved(CGatewayRoute *route)
582 nlassert(route != NULL);
583 nlassert(_Routes.find(route) != _Routes.end());
584 // we need to remove all the proxy that come from this route
585 // CGatewayRoute::TForeignToLocalIdx::TAToBMap::const_iterator first(route->ForeignToLocalIdx.getAToBMap().begin()), last(route->ForeignToLocalIdx.getAToBMap().end());
586 // for (; first != last; ++first)
587 while (!route->ForeignToLocalIdx.getAToBMap().empty())
589 removeForeignModule(route, route->ForeignToLocalIdx.getAToBMap().begin()->first);
590 // TModuleId localProxyId = first->second;
591 // TModuleProxies::iterator it(_ModuleProxies.find(localProxyId));
592 // nlassert(it != _ModuleProxies.end());
594 // IModuleProxy *modProx = it->second;
596 // // trigger an event in the gateway
597 // onRemoveModuleProxy(modProx);
599 // // remove proxy record from the proxy list
600 // _ModuleProxies.erase(it);
601 // _NameToProxyIdx.removeWithB(modProx);
603 // // Release the proxy object
604 // IModuleManager::getInstance().releaseModuleProxy(modProx->getModuleProxyId());
606 // cleanup the translation table
607 // route->ForeignToLocalIdx.clear();
609 // clear the route tracker
610 _Routes.erase(route);
612 // cleanup route state
613 route->ForeignToLocalIdx.clear();
614 route->PendingEvents.clear();
615 route->FirewallDisclosed.clear();
616 route->NextMessageType = CModuleMessageHeaderCodec::mt_invalid;
617 route->NextSenderProxyId = 0;
618 route->NextAddresseeProxyId = 0;
621 /// A transport have received a message
622 virtual void onReceiveMessage(CGatewayRoute *from, const CMessage &msgin)
624 H_AUTO(CModuleGetaway_onReceiveMessage);
625 // dispatch the message
626 if (from->NextMessageType != CModuleMessageHeaderCodec::mt_invalid)
628 // this message must be dispatched to a module
629 onReceiveModuleMessageFromGateway(from, msgin);
631 // Not a module message, dispatch the gateway message
632 else if (msgin.getName() == "MOD_OP")
634 onReceiveModuleMessageHeader(from, msgin);
636 else if (msgin.getName() == "MOD_UPD")
638 onReceiveModuleUpdate(from, msgin);
640 // else if (msgin.getName() == "MOD_ADD")
641 // {
642 // onReceiveModuleAdd(from, msgin);
643 // }
644 // else if (msgin.getName() == "MOD_REM")
645 // {
646 // onReceiveModuleRemove(from, msgin);
647 // }
648 // else if (msgin.getName() == "MOD_DST_UPD")
649 // {
650 // onReceiveModuleDistanceUpdate(from, msgin);
651 // }
655 /***********************************/
656 /* security plug-in management*/
657 /***********************************/
658 /** create a security plug-in.
659 * There must be no security plug-in currently created.
661 virtual void createSecurityPlugin(const std::string &className)
663 if (_SecurityPlugin != NULL)
665 nlwarning("NLNETL5 : CStandardGateway::createSecurityPlugin : plug-in already created ");
666 return;
669 CGatewaySecurity::TCtorParam params;
670 params.Gateway = this;
671 CGatewaySecurity *gs = NLMISC_GET_FACTORY(CGatewaySecurity, std::string).createObject(className, params);
672 if (gs == NULL)
674 nlwarning("NLNETL5 : CStandardGateway::createSecurityPlugin : can't create a security plug-in for class '%s'", className.c_str());
675 return;
678 // store the security plug-in
679 _SecurityPlugin = gs;
681 // update security for all existing proxies
682 TModuleProxies::iterator first(_ModuleProxies.begin()), last(_ModuleProxies.end());
683 for (; first != last; ++first)
685 IModuleProxy *proxy = first->second;
686 _SecurityPlugin->onNewProxy(proxy);
689 /** Send a command to the security plug-in */
690 virtual void sendSecurityCommand(const TParsedCommandLine &command)
692 if (_SecurityPlugin != NULL)
694 nlwarning("NLNETL5 : CStandardGateway::sendSecurityCommand : plug-in NOT created ");
695 return;
698 _SecurityPlugin->onCommand(command);
701 /** Remove the security plug-in.
703 virtual void removeSecurityPlugin()
705 if (_SecurityPlugin == NULL)
707 nlwarning("NLNETL5 : CStandardGateway::removeSecurityPlugin : plug-in not created");
708 return;
711 // delete the plug-in (this can remove some security data)
712 _SecurityPlugin->onDelete();
713 delete _SecurityPlugin;
714 _SecurityPlugin = NULL;
717 /** Set a security data block. If a bloc of the same type
718 * already exist in the list, the new one will replace the
719 * existing one.
721 void setSecurityData(IModuleProxy *proxy, TSecurityData *securityData)
723 nlassert(proxy->getModuleGateway() == this);
724 nlassert(securityData->NextItem == NULL);
726 CModuleProxy *modProx = dynamic_cast<CModuleProxy*>(proxy);
727 nlassert(modProx != NULL);
729 // look in the existing security for a matching type and remove it
730 removeSecurityData(proxy, securityData->DataTag);
732 // now, store the security data
733 securityData->NextItem = modProx->_SecurityData;
734 modProx->_SecurityData = securityData;
739 /** Clear a block of security data
740 * The block is identified by the data tag
742 bool removeSecurityData(IModuleProxy *proxy, uint8 dataTag)
744 nlassert(proxy->getModuleGateway() == this);
746 CModuleProxy *modProx = dynamic_cast<CModuleProxy*>(proxy);
747 nlassert(modProx != NULL);
749 bool ret = false;
750 TSecurityData *prevSec = NULL;
751 TSecurityData *currentSec = modProx->_SecurityData;
752 while (currentSec != NULL)
754 if (currentSec->DataTag == dataTag)
756 if (prevSec != NULL)
757 prevSec->NextItem = currentSec->NextItem;
758 else
759 modProx->_SecurityData = currentSec->NextItem;
761 TSecurityData *toDelete = currentSec;
762 currentSec = currentSec->NextItem;
763 toDelete->NextItem = NULL;
764 delete toDelete;
765 ret = true;
767 else
769 prevSec = currentSec;
770 currentSec = currentSec->NextItem;
774 return ret;
777 void replaceAllSecurityDatas(IModuleProxy *proxy, TSecurityData *securityData)
779 nlassert(proxy->getModuleGateway() == this);
781 CModuleProxy *modProx = dynamic_cast<CModuleProxy*>(proxy);
782 nlassert(modProx != NULL);
783 nlassert(modProx->_SecurityData != securityData);
785 if (modProx->_SecurityData != NULL)
786 delete modProx->_SecurityData;
788 modProx->_SecurityData = securityData;
791 /** Ask the gateway to resend the security data.
792 * The plug-in call this method after having changed
793 * the security info for a plug-in outside of the
794 * onNewProxy call.
796 void forceSecurityUpdate(IModuleProxy *proxy)
798 TRouteList::iterator first(_Routes.begin()), last(_Routes.end());
799 for (; first != last; ++first)
801 CGatewayRoute *route = *first;
803 if (isModuleProxyVisible(proxy, route))
805 updateModuleSecurityDataToRoute(route, proxy);
810 /***********************************/
811 /* Inter gateway message reception */
812 /***********************************/
814 /** A gateway receive module operation */
815 void onReceiveModuleMessageFromGateway(CGatewayRoute *from, const CMessage &msgin)
817 H_AUTO(CModuleGetaway_onReceiveModuleMessage);
818 // clean the message type now, any return path will be safe
819 from->NextMessageType = CModuleMessageHeaderCodec::mt_invalid;
821 // Retrieve sender and destination proxy and recall gateway send method
822 IModuleProxy *senderProxy;
823 IModuleProxy *addresseeProxy;
825 TModuleProxies::iterator it;
827 // sender proxy
828 it = _ModuleProxies.find(from->NextSenderProxyId);
829 if (it == _ModuleProxies.end())
831 nlwarning("Can't dispatch the module message, sender proxy %u is not in this gateway", from->NextSenderProxyId);
832 return;
834 senderProxy = it->second;
835 // addressee proxy
836 it = _ModuleProxies.find(from->NextAddresseeProxyId);
837 if (it == _ModuleProxies.end())
839 nlwarning("Can't dispatch the module message '%s', sender proxy %u is not in this gateway", msgin.getName().c_str(), from->NextAddresseeProxyId);
840 return;
842 addresseeProxy = it->second;
844 // give the message to the gateway (either for local dispatch or for forwarding)
845 sendModuleProxyMessage(senderProxy, addresseeProxy, msgin);
848 // A gateway receive a module message header
849 void onReceiveModuleMessageHeader(CGatewayRoute *from, const CMessage &msgin)
851 H_AUTO(CModuleGetaway_onReceiveModuleMessageHeader);
852 if (from->NextMessageType != CModuleMessageHeaderCodec::mt_invalid)
854 // juste warn (but that is VERY BAD)
855 nlwarning("Receiving a new module message header without having received the previous module message !");
858 // store the message information in the route
859 CModuleMessageHeaderCodec::decode(
860 msgin,
861 from->NextMessageType,
862 from->NextSenderProxyId,
863 from->NextAddresseeProxyId);
865 // translate sender id
866 const TModuleId *pmoduleId = from->ForeignToLocalIdx.getB(from->NextSenderProxyId);
867 if (pmoduleId == NULL)
869 nlwarning("The sender proxy %u is unknown in the translation table, can't dispatch the message !", from->NextSenderProxyId);
870 from->NextMessageType = CModuleMessageHeaderCodec::mt_invalid;
871 return;
873 from->NextSenderProxyId = *pmoduleId;
874 // now, wait the message body
877 /** A gateway receive a general update message */
878 void onReceiveModuleUpdate(CGatewayRoute *from, const CMessage &msgin)
880 H_AUTO(CModuleGetaway_onReceiveModuleUpdate);
881 while (uint32(msgin.getPos()) != msgin.length())
883 CGatewayRoute::TPendingEventType type = CGatewayRoute::pet_disclose_module;
884 // msgin.serialShortEnum(type);
885 nlRead(msgin, serialShortEnum, type);
887 switch (type)
889 case CGatewayRoute::pet_disclose_module:
891 onReceiveModuleAdd(from, msgin);
893 break;
894 case CGatewayRoute::pet_undisclose_module:
896 onReceiveModuleRemove(from, msgin);
898 break;
899 case CGatewayRoute::pet_update_distance:
901 onReceiveModuleDistanceUpdate(from, msgin);
903 break;
904 case CGatewayRoute::pet_update_security:
906 onReceiveModuleSecurityUpdate(from, msgin);
908 break;
909 default:
910 // should not append
911 nlstop;
916 /** A gateway send new modules information */
917 void onReceiveModuleAdd(CGatewayRoute *from, const CMessage &msgin)
919 H_AUTO(CModuleGetaway_onReceiveModuleAdd);
920 TModuleDescCodec modDesc;
921 nlRead(msgin, serial, modDesc);
923 // for each received module info
924 TStringId modNameId = CStringMapper::map(modDesc.ModuleFullName);
925 /// store the module information
926 TKnownModuleInfo modInfo;
927 modInfo.ForeignProxyId = modDesc.ModuleProxyId;
928 modInfo.ModuleClassId = CStringMapper::map(modDesc.ModuleClass);
929 modInfo.ModuleDistance = modDesc.ModuleDistance;
930 modInfo.Route = from;
932 nldebug("Gateway '%s' : store module info for '%s' (foreign ID %u) @ %u hop",
933 getGatewayName().c_str(),
934 modDesc.ModuleFullName.c_str(),
935 modDesc.ModuleProxyId,
936 modDesc.ModuleDistance);
938 // Store module information
939 _KnownModules.insert(make_pair(modNameId, modInfo));
941 if (_NameToProxyIdx.getB(modNameId) != NULL)
943 // a proxy for this module already exist,
944 IModuleProxy *modProx = *(_NameToProxyIdx.getB(modNameId));
946 // fill the id translation table
947 // from->ForeignToLocalIdx.insert(make_pair(modDesc.ModuleProxyId, modProx->getModuleProxyId()));
948 from->ForeignToLocalIdx.add(modDesc.ModuleProxyId, modProx->getModuleProxyId());
950 // check if this route is better
951 if (modProx->getModuleDistance() > modInfo.ModuleDistance)
953 // update module distance and swap route
954 CModuleProxy *proxy = static_cast<CModuleProxy*>(modProx);
956 nldebug("Gateway '%s' : Use a shorter path for '%s' from %u to %u hops",
957 getGatewayName().c_str(),
958 modDesc.ModuleFullName.c_str(),
959 proxy->_Distance,
960 modInfo.ModuleDistance);
962 proxy->_Distance = modInfo.ModuleDistance;
963 proxy->_Route = modInfo.Route;
965 sendModuleDistanceUpdate(proxy);
968 // update the security if needed
969 if (modDesc.SecDesc.SecurityData != NULL)
971 CModuleProxy *proxy = static_cast<CModuleProxy *>(modProx);
972 if (_SecurityPlugin != NULL)
974 _SecurityPlugin->onNewSecurityData(from, proxy, modDesc.SecDesc.SecurityData);
976 else
978 if (proxy->_SecurityData != NULL)
979 delete proxy->_SecurityData;
980 proxy->_SecurityData = modDesc.SecDesc.SecurityData;
984 else
986 // we need to create a new proxy
987 // create a module proxy
988 IModuleProxy *modProx = IModuleManager::getInstance().createModuleProxy(
989 this,
990 from,
991 modDesc.ModuleDistance,
992 NULL,
993 modDesc.ModuleClass,
994 modDesc.ModuleFullName,
995 modDesc.ModuleManifest,
996 modDesc.ModuleProxyId);
998 // set the module security
999 CModuleProxy *proxy = static_cast<CModuleProxy *>(modProx);
1000 proxy->_SecurityData = modDesc.SecDesc.SecurityData;
1001 // let the security plug-in add/remove security data
1002 if (_SecurityPlugin != NULL)
1003 _SecurityPlugin->onNewProxy(proxy);
1005 // store the proxy in the proxy list
1006 _ModuleProxies.insert(make_pair(modProx->getModuleProxyId(), modProx));
1007 _NameToProxyIdx.add(modNameId, modProx);
1009 // Fill the proxy id translation table for this route
1010 // from->ForeignToLocalIdx.insert(make_pair(modDesc.ModuleProxyId, modProx->getModuleProxyId()));
1011 from->ForeignToLocalIdx.add(modDesc.ModuleProxyId, modProx->getModuleProxyId());
1013 // trigger an event in the gateway
1014 onAddModuleProxy(modProx);
1018 void onReceiveModuleRemove(CGatewayRoute *from, const CMessage &msgin)
1020 H_AUTO(CModuleGetaway_onReceiveModuleRemove);
1021 TModuleId moduleId;
1022 nlRead(msgin, serial, moduleId);
1024 removeForeignModule(from, moduleId);
1027 void onReceiveModuleDistanceUpdate(CGatewayRoute *from, const CMessage &msgin)
1029 H_AUTO(CModuleGetaway_onReceiveModuleDistanceUpdate);
1030 TModuleId moduleId;
1031 uint32 newDistance;
1033 nlRead(msgin, serial, moduleId);
1034 nlRead(msgin, serial, newDistance);
1036 // translate the module id
1037 const TModuleId *pModuleId = from->ForeignToLocalIdx.getB(moduleId);
1038 if (pModuleId == NULL)
1040 nlwarning("Receive a module distance update for foreign module %u, but no translation available", moduleId);
1041 return;
1044 TModuleId localId = *pModuleId;
1046 // now, retrieve the module info and update
1047 TModuleProxies::iterator it2(_ModuleProxies.find(localId));
1048 nlassert(it2 != _ModuleProxies.end());
1049 CModuleProxy *proxy = static_cast<CModuleProxy*>(it2->second.getPtr());
1051 pair<TKnownModuleInfos::iterator, TKnownModuleInfos::iterator> range;
1052 range = _KnownModules.equal_range(proxy->_FullyQualifiedModuleName);
1054 for (; range.first != range.second; ++range.first)
1056 TKnownModuleInfo &kmi = range.first->second;
1057 if (kmi.Route == from)
1059 // we found the module info, update the data
1060 nldebug("Gateway '%s' : updating distance from %u to %u hop for module '%s'",
1061 getGatewayName().c_str(),
1062 kmi.ModuleDistance,
1063 newDistance,
1064 CStringMapper::unmap(range.first->first).c_str());
1065 kmi.ModuleDistance = newDistance;
1066 break;
1069 nlassert(range.first != range.second);
1071 // check if the changed module is the one currently in use
1072 if (proxy->_Route == from)
1074 // two task : first, if the new distance is greater, look
1075 // in available route for a shorter path,
1076 // second, send a module distance update for this module.
1077 if (proxy->_Distance < newDistance)
1079 // look for a shorter path
1080 range = _KnownModules.equal_range(proxy->_FullyQualifiedModuleName);
1082 for (; range.first != range.second; ++range.first)
1084 TKnownModuleInfo &kmi = range.first->second;
1085 if (kmi.ModuleDistance < proxy->_Distance)
1087 nldebug("Gateway '%s' : proxy '%s' use a new path from %u to %u hop",
1088 getGatewayName().c_str(),
1089 proxy->getModuleName().c_str(),
1090 proxy->_Distance,
1091 kmi.ModuleDistance);
1092 // this path is shorter, use it now
1093 proxy->_Route = kmi.Route;
1094 proxy->_ForeignModuleId = kmi.ForeignProxyId;
1095 proxy->_Distance = kmi.ModuleDistance;
1096 break;
1099 if (range.first == range.second)
1101 // no shorter path found, update the proxy
1102 nldebug("Gateway '%s' : proxy '%s' path distance changed from %u to %u hop",
1103 getGatewayName().c_str(),
1104 proxy->getModuleName().c_str(),
1105 proxy->_Distance,
1106 newDistance);
1108 proxy->_Distance = newDistance;
1111 else
1113 // the new distance is shorter, just update
1114 nldebug("Gateway '%s' : proxy '%s' path distance reduced from %u to %u hop",
1115 getGatewayName().c_str(),
1116 proxy->getModuleName().c_str(),
1117 proxy->_Distance,
1118 newDistance);
1120 proxy->_Distance = newDistance;
1123 // send the distance update
1124 sendModuleDistanceUpdate(proxy);
1128 void onReceiveModuleSecurityUpdate(CGatewayRoute *from, const CMessage &msgin)
1130 H_AUTO(CModuleGetaway_onReceiveModuleSecurityUpdate);
1131 // TModuleId foreignModuleId;
1132 // TSecurityData *modSec;
1133 TModuleSecurityChangeMsg secChg;
1135 nlRead(msgin, serial, secChg);
1136 // msgin.serial(foreignModuleId);
1137 // msgin.serialPolyPtr(modSec);
1139 const TModuleId *pModuleId = from->ForeignToLocalIdx.getB(secChg.ModuleId);
1140 if (pModuleId == NULL)
1142 nlwarning("LNETL6 : receive module security update for unknown module foreign proxy %u", secChg.ModuleId);
1143 return;
1146 TModuleId moduleId = *pModuleId;
1148 CModuleProxy *modProx = getModuleProxy(moduleId);
1149 if (modProx == NULL)
1151 nlwarning("LNETL6 : receive module security update for unknown module proxy %u, foreign %u", moduleId, secChg.ModuleId);
1152 return;
1155 // allow the security plug-in to affect the data
1156 if( _SecurityPlugin != NULL)
1158 // let the plug-in update the security data
1159 _SecurityPlugin->onNewSecurityData(from, modProx, secChg.SecDesc.SecurityData);
1161 else
1163 // update the security data in the proxy
1164 replaceAllSecurityDatas(modProx, secChg.SecDesc.SecurityData);
1167 // warn local module about new security data
1169 TPluggedModules::TAToBMap::const_iterator first(_PluggedModules.getAToBMap().begin()), last(_PluggedModules.getAToBMap().end());
1170 for (; first != last; ++first)
1172 IModule *module = first->second;
1174 module->onModuleSecurityChange(modProx);
1178 // update the security to peers
1180 TRouteList::iterator first(_Routes.begin()), last(_Routes.end());
1181 for (; first != last; ++first)
1183 CGatewayRoute *route = *first;
1184 if (isModuleProxyVisible(modProx, route))
1186 updateModuleSecurityDataToRoute(route, modProx);
1193 virtual void onAddModuleProxy(IModuleProxy *addedModule)
1195 H_AUTO(CModuleGetaway_onAddmoduleProxy);
1196 // disclose module to local modules
1197 discloseModule(addedModule);
1199 // and send module info to any route
1201 // for each route
1202 TRouteList::iterator first(_Routes.begin()), last(_Routes.end());
1203 for (; first != last; ++first)
1205 CGatewayRoute *route = *first;
1206 // only send info to other routes
1207 if (isModuleProxyVisible(addedModule, route))
1209 discloseModuleToRoute(route, addedModule);
1214 virtual void onRemoveModuleProxy(IModuleProxy *removedModule)
1216 H_AUTO(CModuleGetaway_onRemoveModuleProxy);
1217 // for each route
1219 // for each route
1220 TRouteList::iterator first(_Routes.begin()), last(_Routes.end());
1221 for (; first != last; ++first)
1223 CGatewayRoute *route = *first;
1224 // only send info to other routes
1225 if (isModuleProxyVisible(removedModule, route))
1227 undiscloseModuleToRoute(route, removedModule);
1232 // warn any locally plugged module
1234 TPluggedModules::TAToBMap::const_iterator first(_PluggedModules.getAToBMap().begin()), last(_PluggedModules.getAToBMap().end());
1235 for (; first != last; ++first)
1237 IModule *module = first->second;
1238 if (removedModule->getGatewayRoute() != NULL
1239 || module->getModuleId() != removedModule->getForeignModuleId())
1241 module->_onModuleDown(removedModule);
1247 virtual void discloseModule(IModuleProxy *moduleProxy)
1249 nlassert(moduleProxy->getModuleGateway() == this);
1251 // warn any plugged module
1252 TPluggedModules::TAToBMap::const_iterator first(_PluggedModules.getAToBMap().begin()), last(_PluggedModules.getAToBMap().end());
1253 for (; first != last; ++first)
1255 IModule *module = first->second;
1256 if (moduleProxy->getGatewayRoute() != NULL
1257 || module->getModuleId() != moduleProxy->getForeignModuleId())
1259 module->_onModuleUp(moduleProxy);
1264 virtual IModuleProxy *getPluggedModuleProxy(IModule *pluggedModule)
1266 TLocalModuleIndex::iterator it(_LocalModuleIndex.find(pluggedModule->getModuleId()));
1268 if (it == _LocalModuleIndex.end())
1269 return NULL;
1270 else
1272 TModuleProxies::iterator it2(_ModuleProxies.find(it->second));
1273 nlassert(it2 != _ModuleProxies.end());
1274 return it2->second;
1278 virtual uint32 getProxyCount() const
1280 return (uint32)_ModuleProxies.size();
1283 /// Fill a vector with the list of proxies managed here. The module are filled in ascending proxy id order.
1284 virtual void getModuleProxyList(std::vector<IModuleProxy*> &resultList) const
1286 TModuleProxies::const_iterator first(_ModuleProxies.begin()), last(_ModuleProxies.end());
1287 for (; first != last; ++first)
1289 resultList.push_back(first->second);
1294 virtual void sendModuleProxyMessage(IModuleProxy *senderProxy, IModuleProxy *addresseeProxy, const NLNET::CMessage &message)
1296 H_AUTO(CModuleGetaway_sendModuleMessage);
1297 // manage firewall
1298 if (addresseeProxy->getGatewayRoute()
1299 && addresseeProxy->getGatewayRoute()->getTransport()->Firewalled)
1301 CGatewayRoute *route = addresseeProxy->getGatewayRoute();
1302 // the destination route is firewalled, we need to
1303 // disclose the sender module if it's not already done
1304 if (route->FirewallDisclosed.find(senderProxy->getModuleProxyId()) == route->FirewallDisclosed.end())
1306 discloseModuleToRoute(route, senderProxy);
1307 route->FirewallDisclosed.insert(senderProxy->getModuleProxyId());
1311 // check for visibility rules
1312 if (!isModuleProxyVisible(addresseeProxy, senderProxy->getGatewayRoute()))
1314 nlwarning("Module %u '%s' try to send message to %u '%s' but addressee is not visible, message discarded",
1315 senderProxy->getModuleProxyId(),
1316 senderProxy->getModuleName().c_str(),
1317 addresseeProxy->getModuleProxyId(),
1318 addresseeProxy->getModuleName().c_str());
1319 return;
1322 if (addresseeProxy->getGatewayRoute() == NULL)
1324 // the module is local, just forward the call to the dispatcher
1325 nlassert(senderProxy != NULL);
1326 nlassert(_ModuleProxies.find(senderProxy->getModuleProxyId()) != _ModuleProxies.end());
1328 // invert the message for immediate dispatching if needed
1329 if (!message.isReading())
1330 const_cast<CMessage&>(message).invert();
1332 // check if the module support immediate dispatching
1333 TModuleId addresseeModId = addresseeProxy->getForeignModuleId();
1335 const TModulePtr *adrcp = _PluggedModules.getB(addresseeModId);
1336 if (adrcp == NULL)
1338 nlwarning("sendModuleMessage : can't find addressee module %u that is not plugged here !", addresseeModId);
1339 return;
1342 IModule *addreseeMod = *adrcp;
1343 if (!addreseeMod->isImmediateDispatchingSupported())
1345 // dispatch the message at next gateway update
1346 // this provide a coherent behavior between local and distant module message exchange
1348 _LocalMessages.push_back(TLocalMessage());
1349 TLocalMessage &lm = _LocalMessages.back();
1350 lm.SenderProxyId = senderProxy->getModuleProxyId();
1351 lm.AddresseProxyId = addresseeProxy->getModuleProxyId();
1353 nldebug("NETL6 : gateway '%s' : queuing local message '%s' from proxy %u to proxy %u",
1354 getModuleName().c_str(),
1355 message.getName().c_str(),
1356 lm.SenderProxyId,
1357 lm.AddresseProxyId);
1359 if (message.hasLockedSubMessage())
1361 lm.Message.assignFromSubMessage(message);
1363 else
1365 lm.Message = message;
1368 else
1370 // immediate dispatching
1371 dispatchModuleMessage(senderProxy, addresseeProxy, message);
1374 else
1376 // the module is distant, send the message via the route
1377 // create a message for sending
1378 CMessage msgHeader("MOD_OP");
1379 CModuleMessageHeaderCodec::encode(
1380 msgHeader,
1381 CModuleMessageHeaderCodec::mt_oneway,
1382 senderProxy->getModuleProxyId(),
1383 addresseeProxy->getForeignModuleId());
1385 // send any pending module info
1386 sendPendingModuleUpdate(addresseeProxy->getGatewayRoute());
1388 // send the header
1389 addresseeProxy->getGatewayRoute()->sendMessage(msgHeader);
1390 // send the message
1391 addresseeProxy->getGatewayRoute()->sendMessage(message);
1394 virtual void dispatchModuleMessage(IModuleProxy *senderProxy, IModuleProxy *addresseeProxy, const CMessage &message)
1396 H_AUTO(CModuleGetaway_dispatchModuleMessage);
1397 CMessage::TMessageType msgType = message.getType();
1398 // retrieve the address module from the proxy
1399 nlassert(addresseeProxy->getGatewayRoute() == NULL);
1400 // As the addressee is local, the foreign proxy id is the local module id (a bit triky...)
1401 TModuleId addresseeModId = addresseeProxy->getForeignModuleId();
1403 const TModulePtr *adrcp = _PluggedModules.getB(addresseeModId);
1404 if (adrcp == NULL)
1406 nlwarning("dispatchModuleMessage : dispatching a message to module %u that is not plugged here !", addresseeModId);
1407 return;
1410 IModule *addreseeMod = *adrcp;
1412 // finally, transmit the message to the module
1413 // addreseeMod->onProcessModuleMessage(senderProxy, message);
1416 addreseeMod->onReceiveModuleMessage(senderProxy, message);
1418 catch(...)
1420 nlwarning("An exception was thrown while dispatching message '%s' from '%s' to '%s'",
1421 message.getName().c_str(),
1422 senderProxy->getModuleName().c_str(),
1423 addresseeProxy->getModuleName().c_str());
1425 if (msgType == CMessage::Request)
1427 // send back an exception message
1428 CMessage except;
1429 except.setType("EXCEPT", CMessage::Except);
1430 senderProxy->sendModuleMessage(addreseeMod, except);
1434 /***********************************************************
1435 ** Module methods
1436 ***********************************************************/
1437 bool initModule(const TParsedCommandLine &initInfo)
1439 bool ret = CModuleBase::initModule(initInfo);
1441 // no options for now
1443 registerSocket();
1444 registerGateway();
1446 return ret;
1449 std::string buildModuleManifest() const
1451 return string();
1455 void onServiceUp(const std::string &/* serviceName */, NLNET::TServiceId /* serviceId */)
1458 void onServiceDown(const std::string &/* serviceName */, NLNET::TServiceId /* serviceId */)
1461 void onModuleUpdate()
1463 H_AUTO(CModuleGetaway_onModuleUpdate);
1464 // send waiting local messages
1465 while (!_LocalMessages.empty())
1467 TLocalMessage &lm = _LocalMessages.front();
1469 IModuleProxy *senderProx = getModuleProxy(lm.SenderProxyId);
1470 IModuleProxy *addresseeProx = getModuleProxy(lm.AddresseProxyId);
1472 if (senderProx == NULL)
1474 nlwarning("CStandardGateway : local message dispatching : Failed to retrieve proxy for sender module %u while dispatching message '%s' to %u",
1475 lm.SenderProxyId,
1476 lm.Message.getName().c_str(),
1477 lm.AddresseProxyId);
1479 else if (addresseeProx == NULL)
1481 nlwarning("CStandardGateway : local message dispatching : Failed to retrieve proxy for addressee module %u while dispatching message '%s' from %u",
1482 lm.AddresseProxyId,
1483 lm.Message.getName().c_str(),
1484 lm.SenderProxyId);
1486 else
1488 // we can dispatch the message
1489 dispatchModuleMessage(senderProx, addresseeProx, lm.Message);
1492 _LocalMessages.pop_front();
1495 // send pending module un/disclosure
1497 TRouteList::iterator first(_Routes.begin()), last(_Routes.end());
1498 for (; first != last; ++first)
1500 CGatewayRoute *route = *first;
1501 sendPendingModuleUpdate(route);
1504 // update the transports
1506 TTransportList::iterator first(_Transports.begin()), last(_Transports.end());
1507 for (; first != last; ++first)
1509 IGatewayTransport *transport = first->second;
1511 transport->update();
1516 void onApplicationExit()
1518 // delete all transport
1519 while (!_Transports.empty())
1521 deleteTransport(_Transports.begin()->first);
1525 void onModuleUp(IModuleProxy * /* moduleProxy */)
1528 void onModuleDown(IModuleProxy * /* moduleProxy */)
1531 bool onProcessModuleMessage(IModuleProxy * /* senderModuleProxy */, const CMessage &message)
1533 // simple message for debug and unit testing
1534 if (message.getName() == "DEBUG_MOD_PING")
1536 _PingCounter++;
1538 return true;
1541 return false;
1544 void onModuleSecurityChange(IModuleProxy * /* moduleProxy */)
1548 void onModuleSocketEvent(IModuleSocket * /* moduleSocket */, TModuleSocketEvent /* eventType */)
1552 /***********************************************************
1553 ** Socket methods
1554 ***********************************************************/
1556 const std::string &getSocketName()
1558 return getModuleName();
1561 void _sendModuleMessage(IModule *senderModule, TModuleId destModuleProxyId, const NLNET::CMessage &message)
1563 // the socket implementation already checked that the module is plugged here
1564 // just check that the destination module effectively from here
1565 TLocalModuleIndex::iterator it(_LocalModuleIndex.find(senderModule->getModuleId()));
1566 nlassert(it != _LocalModuleIndex.end());
1568 // get the sender proxy
1569 TModuleProxies::iterator it2(_ModuleProxies.find(it->second));
1570 nlassert(it2 != _ModuleProxies.end());
1572 IModuleProxy *senderProx = it2->second;
1574 // get the addressee proxy
1575 it2 = _ModuleProxies.find(destModuleProxyId);
1576 nlassert(it2 != _ModuleProxies.end());
1578 IModuleProxy *destProx = it2->second;
1581 sendModuleProxyMessage(senderProx, destProx, message);
1584 virtual void _broadcastModuleMessage(IModule *senderModule, const NLNET::CMessage &message)
1586 H_AUTO(CModuleGetaway__broadcastModuleMessage);
1587 // send the message to all proxies (except the sender module)
1588 TLocalModuleIndex::iterator it(_LocalModuleIndex.find(senderModule->getModuleId()));
1589 nlassert(it != _LocalModuleIndex.end());
1591 TModuleProxies::iterator first(_ModuleProxies.begin()), last(_ModuleProxies.end());
1592 for (; first != last; ++first)
1594 IModuleProxy *proxy = first->second;
1596 proxy->sendModuleMessage(senderModule, message);
1600 void onModulePlugged(IModule *pluggedModule)
1602 nldebug("NETL6: Gateway %s : plugging module '%s' id=%u",
1603 getModuleName().c_str(),
1604 pluggedModule->getModuleName().c_str(),
1605 pluggedModule->getModuleId());
1607 // A module has just been plugged here, we need to disclose it to the
1608 // other module, and disclose other module to it.
1610 // create a proxy for this module
1611 IModuleProxy *modProx = IModuleManager::getInstance().createModuleProxy(
1612 this,
1613 NULL, // the module is local, so there is no route
1614 0, // the module is local, distance is 0
1615 pluggedModule, // the module is local, so store the module pointer
1616 pluggedModule->getModuleClassName(),
1617 pluggedModule->getModuleFullyQualifiedName(),
1618 pluggedModule->getModuleManifest(),
1619 pluggedModule->getModuleId() // the module is local, foreign id is the module id
1622 // and store it in the proxies container
1623 _ModuleProxies.insert(make_pair(modProx->getModuleProxyId(), modProx));
1624 _NameToProxyIdx.add(CStringMapper::map(modProx->getModuleName()), modProx);
1626 // and also in the local module index
1627 _LocalModuleIndex.insert(make_pair(pluggedModule->getModuleId(), modProx->getModuleProxyId()));
1630 // trigger the new module proxy event
1631 onAddModuleProxy(modProx);
1632 // // disclose the new module to other modules
1633 // discloseModule(modProx);
1635 // second, disclose already known proxies in the gateway to the plugged module
1637 TModuleProxies::iterator first(_ModuleProxies.begin()), last(_ModuleProxies.end());
1638 for (; first != last; ++first)
1640 IModuleProxy *modProx = first->second;
1642 // do not send a moduleUp on the module himself !
1643 // either the gateway is non null (distant module), or the
1644 // foreign module id is different of the local module (for local proxy,
1645 // the foreign module id store the local module id).
1646 if (modProx->getGatewayRoute() != NULL || modProx->getForeignModuleId() != pluggedModule->getModuleId())
1648 pluggedModule->_onModuleUp(modProx);
1655 /// Called just after a module as been effectively unplugged from a socket
1656 void onModuleUnplugged(IModule *unpluggedModule)
1658 nldebug("NETL6: Gateway %s : unplugging module '%s' id=%u",
1659 getModuleName().c_str(),
1660 unpluggedModule->getModuleName().c_str(),
1661 unpluggedModule->getModuleId());
1663 // remove the proxy info
1664 TLocalModuleIndex::iterator it(_LocalModuleIndex.find(unpluggedModule->getModuleId()));
1665 nlassert(it != _LocalModuleIndex.end());
1666 TModuleProxies::iterator it2(_ModuleProxies.find(it->second));
1667 nlassert(it2 != _ModuleProxies.end());
1669 IModuleProxy *modProx = it2->second;
1671 // warn the unplugged module that all proxies in this gateway become unavailable
1673 TModuleProxies::iterator first(_ModuleProxies.begin()), last(_ModuleProxies.end());
1674 for (; first != last; ++first)
1676 IModuleProxy *modProx = first->second;
1678 if (modProx->getGatewayRoute() != NULL
1679 || modProx->getForeignModuleId() != unpluggedModule->getModuleId())
1681 unpluggedModule->_onModuleDown(modProx);
1686 /// the gateway do the rest of the job
1687 onRemoveModuleProxy(modProx);
1689 TModuleId localProxyId = modProx->getModuleProxyId();
1690 // remove reference to the proxy
1691 _ModuleProxies.erase(it2);
1692 _NameToProxyIdx.removeWithB(modProx);
1693 _LocalModuleIndex.erase(it);
1695 // check in the local message queue if some message are to/from
1696 // this module
1697 TLocalMessageList::iterator first(_LocalMessages.begin()), last(_LocalMessages.end());
1698 for (; first != last; ++first)
1700 TLocalMessage &lm = *first;
1701 if (lm.AddresseProxyId == localProxyId
1702 || lm.SenderProxyId == localProxyId)
1704 // erase this message !
1705 nlwarning("CStandardGateway : while unplugging module %u from the gateway, locale message '%s' from proxy %u to proxy %u is lost",
1706 unpluggedModule->getModuleId(),
1707 lm.Message.getName().c_str(),
1708 lm.SenderProxyId,
1709 lm.AddresseProxyId);
1710 TLocalMessageList::iterator next = first;
1711 ++next;
1712 if (next == last)
1714 _LocalMessages.erase(first);
1715 break;
1717 else
1719 _LocalMessages.erase(first);
1720 first = next;
1726 // release the module proxy
1727 IModuleManager::getInstance().releaseModuleProxy(localProxyId);
1731 ////////////////////////////////////////////////////
1732 // Gateway internal methods
1733 ////////////////////////////////////////////////////
1735 void removeForeignModule(CGatewayRoute *route, TModuleId foreignModuleId)
1737 // translate the module id
1738 const TModuleId *pModuleId = route->ForeignToLocalIdx.getB(foreignModuleId);
1739 if (pModuleId == NULL)
1741 // oups !
1742 nlwarning("removeForeignModule : unknown foreign module id %u", foreignModuleId);
1743 return;
1746 TModuleId proxyId = *pModuleId;
1748 // retrieve the module proxy
1749 TModuleProxies::iterator it2(_ModuleProxies.find(proxyId));
1750 if (it2 == _ModuleProxies.end())
1752 // oups !
1753 nlwarning("Gateway '%s' : removeForeignModule : can't find proxy for id %u coming from foreign id %u",
1754 getGatewayName().c_str(),
1755 proxyId,
1756 foreignModuleId);
1758 // still remove the idx
1759 route->ForeignToLocalIdx.removeWithA(foreignModuleId);
1760 return;
1762 CModuleProxy *modProx = static_cast<CModuleProxy *>(it2->second.getPtr());
1764 // remove module information
1765 pair<TKnownModuleInfos::iterator, TKnownModuleInfos::iterator> range;
1766 range = _KnownModules.equal_range(modProx->_FullyQualifiedModuleName);
1767 nlassert(range.first != range.second);
1768 bool found = false;
1769 for (;range.first != range.second; ++range.first)
1771 TKnownModuleInfo &kmi = range.first->second;
1773 if (kmi.Route == route)
1775 nldebug("Gateway '%s' : removing foreign module info for '%s'",
1776 getGatewayName().c_str(),
1777 CStringMapper::unmap(range.first->first).c_str());
1778 // we have found the info relative to this module
1779 _KnownModules.erase(range.first);
1780 found = true;
1781 break;
1784 nlassert(found == true);
1785 // NB : stl debug mode don't allow to test with range.first when range;first is erased.
1786 // nlassert(range.first != range.second);
1788 // check if there is another view of this module
1789 // if so, we keep the proxy and, eventually, we update the distance
1790 range = _KnownModules.equal_range(modProx->_FullyQualifiedModuleName);
1791 if (range.first != range.second)
1793 // clean the translation table
1794 route->ForeignToLocalIdx.removeWithA(foreignModuleId);
1796 // we keep the proxy, choose the best route
1797 TKnownModuleInfos::iterator best(_KnownModules.end());
1799 for (; range.first != range.second; ++range.first)
1801 if (best == _KnownModules.end()
1802 || best->second.ModuleDistance > range.first->second.ModuleDistance)
1803 best = range.first;
1805 nlassert(best != _KnownModules.end());
1806 TKnownModuleInfo &kmi = best->second;
1808 if (modProx->_Route != kmi.Route)
1810 // the best route has changed, update the proxy
1812 nldebug("Gateway '%s' : use a new route for module '%s' from %u to %u hop",
1813 getGatewayName().c_str(),
1814 modProx->getModuleName().c_str(),
1815 modProx->_Distance,
1816 kmi.ModuleDistance);
1818 // update the proxy data
1819 modProx->_Route = kmi.Route;
1820 modProx->_ForeignModuleId = kmi.ForeignProxyId;
1821 if (modProx->_Distance != kmi.ModuleDistance)
1823 // the distance has changed, update and send the new distance to other gateway
1824 modProx->_Distance = kmi.ModuleDistance;
1825 sendModuleDistanceUpdate(modProx);
1829 else
1831 // do not remove proxy for local module from her !
1832 if (modProx->_Route != NULL)
1834 // this module is no longer reachable, remove the proxy
1836 // trigger an event in the gateway
1837 onRemoveModuleProxy(modProx);
1839 // remove from the proxy list
1840 _NameToProxyIdx.removeWithB(modProx);
1841 _ModuleProxies.erase(it2);
1842 // release the proxy
1843 IModuleManager::getInstance().releaseModuleProxy(proxyId);
1845 // clean the translation table
1846 route->ForeignToLocalIdx.removeWithA(foreignModuleId);
1850 void sendModuleDistanceUpdate(IModuleProxy *proxy)
1852 // in fact, don't send immediately, store update in each
1853 // route and wait the next update or module message sending
1854 // to effectively send the update
1856 // for each route
1857 TRouteList::iterator first(_Routes.begin()), last(_Routes.end());
1858 for (; first != last; ++first)
1860 CGatewayRoute *route = *first;
1861 if (isModuleProxyVisible(proxy, route))
1863 updateModuleDistanceToRoute(route, proxy);
1864 // // TODO : optimize by batch sending
1865 // TModuleDistanceChangeMsg mdu;
1867 // mdu.ModuleId = proxy->getModuleProxyId();
1868 // mdu.NewDistance = proxy->getModuleDistance()+1;
1870 // CMessage msg("MOD_DST_UPD");
1871 // msg.serial(mdu);
1873 // sendPendingModuleUpdate(route);
1874 // route->sendMessage(msg);
1879 /// Check if a module can be seen by a route
1880 bool isModuleProxyVisible(IModuleProxy *proxy, CGatewayRoute *route)
1882 if (route == NULL)
1884 // no route, we can see the proxy
1885 return true;
1887 // check firewall rules
1888 if (route->getTransport()->Firewalled)
1890 if (route->FirewallDisclosed.find(proxy->getModuleProxyId()) == route->FirewallDisclosed.end())
1891 return false;
1894 // if the module is local, then, it can be seen
1895 if (proxy->getGatewayRoute() == NULL)
1896 return true;
1898 // if the module is on the same route, it can't be seen (it is seen by the route outbound)
1899 if (proxy->getGatewayRoute() == route)
1900 return false;
1902 IGatewayTransport *transport = route->getTransport();
1903 // if the module is on a different transport, it can be seen
1904 if (proxy->getGatewayRoute()->getTransport() != transport)
1906 // we also need to check if this module is known in this route
1907 // CGatewayRoute::TForeignToLocalIdx::iterator it(route->ForeignToLocalIdx.find(proxy->getForeignModuleId()));
1908 if (route->ForeignToLocalIdx.getA(proxy->getModuleProxyId()) != NULL)
1909 // this module is known in this route, so not invisible
1910 return false;
1912 // ok, we can see
1913 return true;
1916 // if the transport in not in peer invisible, it can be seen
1917 if (!transport->PeerInvisible)
1918 return true;
1920 // not visible
1921 return false;
1924 /// Disclose module information to a gateway route
1925 void discloseModuleToRoute(CGatewayRoute *route, IModuleProxy *proxy)
1927 // route->PendingUndisclosure.erase(proxy->getModuleProxyId());
1928 CGatewayRoute::TPendingEvent pe;
1929 pe.EventType = CGatewayRoute::pet_disclose_module;
1930 pe.ModuleId = proxy->getModuleProxyId();
1931 route->PendingEvents.push_back(pe);
1932 // route->PendingDisclosure.insert(proxy);
1934 /// Undisclose module information to a gateway route
1935 void undiscloseModuleToRoute(CGatewayRoute *route, IModuleProxy *proxy)
1937 // route->PendingDisclosure.erase(proxy);
1938 // route->PendingUndisclosure.insert(proxy->getModuleProxyId());
1939 // route->FirewallDisclosed.erase(proxy->getModuleProxyId());
1941 CGatewayRoute::TPendingEvent pe;
1942 pe.EventType = CGatewayRoute::pet_undisclose_module;
1943 pe.ModuleId = proxy->getModuleProxyId();
1944 route->PendingEvents.push_back(pe);
1946 route->FirewallDisclosed.erase(proxy->getModuleProxyId());
1949 /// the distance of a module need to be update to peers
1950 void updateModuleDistanceToRoute(CGatewayRoute *route, IModuleProxy *proxy)
1952 CGatewayRoute::TPendingEvent pe;
1953 pe.EventType = CGatewayRoute::pet_update_distance;
1954 pe.ModuleId = proxy->getModuleProxyId();
1955 route->PendingEvents.push_back(pe);
1957 /// The security data need to be updated to peers
1958 void updateModuleSecurityDataToRoute(CGatewayRoute *route, IModuleProxy *proxy)
1960 CGatewayRoute::TPendingEvent pe;
1961 pe.EventType = CGatewayRoute::pet_update_security;
1962 pe.ModuleId = proxy->getModuleProxyId();
1963 route->PendingEvents.push_back(pe);
1966 void sendPendingModuleUpdate(CGatewayRoute *route)
1968 if (route->PendingEvents.empty())
1969 return;
1971 CMessage updateMsg("MOD_UPD");
1973 // compil all update in a single message
1974 while (!route->PendingEvents.empty())
1976 CGatewayRoute::TPendingEvent &pe = route->PendingEvents.front();
1977 switch (pe.EventType)
1979 case CGatewayRoute::pet_disclose_module:
1981 IModuleProxy *proxy = getModuleProxy(pe.ModuleId);
1982 if (proxy == NULL)
1983 break;
1985 // store the update type
1986 updateMsg.serialShortEnum(pe.EventType);
1988 // encode the message data
1989 TModuleDescCodec modDesc(proxy);
1990 updateMsg.serial(modDesc);
1991 // modDesc.encode(proxy, updateMsg);
1994 break;
1995 case CGatewayRoute::pet_undisclose_module:
1997 // store the update type
1998 updateMsg.serialShortEnum(pe.EventType);
2000 // store the module id
2001 updateMsg.serial(pe.ModuleId);
2004 break;
2005 case CGatewayRoute::pet_update_distance:
2007 IModuleProxy *proxy = getModuleProxy(pe.ModuleId);
2008 if (proxy == NULL)
2009 break;
2011 // store the update type
2012 updateMsg.serialShortEnum(pe.EventType);
2014 // store module ID and distance
2015 updateMsg.serial(pe.ModuleId);
2016 uint32 distance = proxy->getModuleDistance()+1;
2017 updateMsg.serial(distance);
2019 break;
2020 case CGatewayRoute::pet_update_security:
2022 IModuleProxy *proxy = getModuleProxy(pe.ModuleId);
2023 if (proxy == NULL)
2024 break;
2026 // store the update type
2027 updateMsg.serialShortEnum(pe.EventType);
2029 // store module ID and security data
2030 TModuleSecurityChangeMsg secChg;
2031 secChg.ModuleId = pe.ModuleId;
2032 secChg.SecDesc.SecurityData = const_cast<TSecurityData*>(proxy->getFirstSecurityData());
2033 updateMsg.serial(secChg);
2034 // updateMsg.serial(pe.ModuleId);
2035 // TSecurityData *modSec = const_cast<TSecurityData*>(proxy->getFirstSecurityData());
2036 // updateMsg.serialPolyPtr(modSec);
2038 break;
2039 default:
2040 // should not append
2041 nlstop;
2044 route->PendingEvents.pop_front();
2047 // now send the message
2048 route->sendMessage(updateMsg);
2050 // // send pending module proxy un/disclosure
2051 // if (!route->PendingDisclosure.empty())
2052 // {
2053 // // disclose new module
2054 // TModuleAddMsg message;
2055 // message.Modules.resize(route->PendingDisclosure.size());
2057 // std::set<IModuleProxy*>::iterator first(route->PendingDisclosure.begin()), last(route->PendingDisclosure.end());
2058 // for (uint i=0; first != last; ++i, ++first)
2059 // {
2060 // TModuleDescMsg &modDesc = message.Modules[i];
2061 // IModuleProxy *addedModule = *first;
2063 // modDesc.ModuleProxyId = addedModule->getModuleProxyId();
2064 // modDesc.ModuleClass = addedModule->getModuleClassName();
2065 // modDesc.ModuleFullName = addedModule->getModuleName();
2066 // modDesc.ModuleDistance = addedModule->getModuleDistance()+1;
2067 // }
2068 // route->PendingDisclosure.clear();
2070 // CMessage buffer("MOD_ADD");
2071 // buffer.serial(message);
2073 // route->sendMessage(buffer);
2074 // }
2075 // if (!route->PendingUndisclosure.empty())
2076 // {
2077 // // disclose new module
2078 // TModuleRemMsg message;
2079 // std::copy(route->PendingUndisclosure.begin(), route->PendingUndisclosure.end(), back_insert_iterator<vector<TModuleId> >(message.RemovedModules));
2080 // route->PendingUndisclosure.clear();
2082 // CMessage buffer("MOD_REM");
2083 // buffer.serial(message);
2085 // route->sendMessage(buffer);
2086 // }
2089 void getModuleList(std::vector<IModuleProxy*> &resultList)
2091 TModuleProxies::iterator first(_ModuleProxies.begin()), last(_ModuleProxies.end());
2092 for (; first != last; ++first)
2094 resultList.push_back(first->second);
2099 NLMISC_COMMAND_HANDLER_TABLE_EXTEND_BEGIN(CStandardGateway, CModuleBase)
2100 NLMISC_COMMAND_HANDLER_ADD(CStandardGateway, dump, "dump various information about the gateway statue", "")
2101 NLMISC_COMMAND_HANDLER_ADD(CStandardGateway, transportListAvailableClass, "list the available transport class", "no param")
2102 NLMISC_COMMAND_HANDLER_ADD(CStandardGateway, transportAdd, "add a new transport to this gateway", "<transportClass> <instanceName>")
2103 NLMISC_COMMAND_HANDLER_ADD(CStandardGateway, transportOptions, "set a gateway level option on a transport", "<transportClass> ( [PeerInvisible] [Firewalled] )")
2104 NLMISC_COMMAND_HANDLER_ADD(CStandardGateway, transportCmd, "send a command to a transport", "[<transportName> ( <cmd specific to transport> )]*")
2105 NLMISC_COMMAND_HANDLER_ADD(CStandardGateway, transportRemove, "remove an existing transport instance", "<transportName>")
2106 NLMISC_COMMAND_HANDLER_ADD(CStandardGateway, securityListAvailableClass, "list the available security class", "no param")
2107 NLMISC_COMMAND_HANDLER_ADD(CStandardGateway, securityCreate, "create a security plug-in", "<securityClassName>")
2108 NLMISC_COMMAND_HANDLER_ADD(CStandardGateway, securityCommand, "send a command to the security plug-in", "<cmd specific to plug-in>")
2109 NLMISC_COMMAND_HANDLER_ADD(CStandardGateway, securityRemove, "remove the security plug-in", "no parameter")
2110 NLMISC_COMMAND_HANDLER_TABLE_END
2112 NLMISC_CLASS_COMMAND_DECL(securityRemove)
2114 nlunreferenced(rawCommandString);
2115 nlunreferenced(args);
2116 nlunreferenced(quiet);
2117 nlunreferenced(human);
2119 if (_SecurityPlugin == NULL)
2121 log.displayNL("No security plug-in !");
2122 return true;
2125 removeSecurityPlugin();
2127 return true;
2130 NLMISC_CLASS_COMMAND_DECL(securityCommand)
2132 nlunreferenced(args);
2133 nlunreferenced(quiet);
2134 nlunreferenced(human);
2136 TParsedCommandLine command;
2138 if (!command.parseParamList(rawCommandString))
2140 log.displayNL("Invalid command line");
2141 return false;
2144 if (command.SubParams.size() < 2)
2146 log.displayNL("Invalid command line");
2147 return false;
2150 if (_SecurityPlugin == NULL)
2152 log.displayNL("No security plug-in !");
2153 return true;
2156 sendSecurityCommand(*command.SubParams[1]);
2158 return true;
2161 NLMISC_CLASS_COMMAND_DECL(securityCreate)
2163 nlunreferenced(rawCommandString);
2164 nlunreferenced(quiet);
2165 nlunreferenced(human);
2167 if (args.size() != 1)
2168 return false;
2170 if (_SecurityPlugin != NULL)
2172 log.displayNL("The gateway already have a security plug-in ! Remove it first");
2173 return true;
2176 log.displayNL("Creating a security plug-in '%s' in gateway '%s'",
2177 args[0].c_str(),
2178 getModuleName().c_str());
2179 createSecurityPlugin(args[0]);
2181 return true;
2184 NLMISC_CLASS_COMMAND_DECL(securityListAvailableClass)
2186 nlunreferenced(rawCommandString);
2187 nlunreferenced(quiet);
2188 nlunreferenced(human);
2190 if (args.size() != 0)
2191 return false;
2193 vector<string> list;
2194 NLMISC_GET_FACTORY(CGatewaySecurity, std::string).fillFactoryList(list);
2196 log.displayNL("List of %u available security class :", list.size());
2198 for (uint i=0; i<list.size(); ++i)
2200 log.displayNL(" '%s'", list[i].c_str());
2203 return true;
2206 NLMISC_CLASS_COMMAND_DECL(transportRemove)
2208 nlunreferenced(rawCommandString);
2209 nlunreferenced(log);
2210 nlunreferenced(quiet);
2211 nlunreferenced(human);
2213 if (args.size() != 1)
2214 return false;
2216 deleteTransport(args[0]);
2217 return true;
2220 NLMISC_CLASS_COMMAND_DECL(transportCmd)
2222 nlunreferenced(args);
2223 nlunreferenced(quiet);
2224 nlunreferenced(human);
2226 TParsedCommandLine pcl;
2227 if (!pcl.parseParamList(rawCommandString))
2229 log.displayNL("Invalid parameter string, parse error");
2230 return false;
2233 transportCommand(pcl);
2234 return true;
2237 NLMISC_CLASS_COMMAND_DECL(transportOptions)
2239 nlunreferenced(quiet);
2240 nlunreferenced(human);
2242 if (args.size() < 1)
2243 return false;
2245 // parse the params
2246 TParsedCommandLine cl;
2247 if (!cl.parseParamList(rawCommandString))
2248 return false;
2250 if (cl.SubParams.size() != 2)
2251 return false;
2253 string transName = cl.SubParams[1]->ParamName;
2254 if (_Transports.find(transName) == _Transports.end())
2256 log.displayNL("unknown transport '%s'", transName.c_str());
2257 return false;
2260 // IGatewayTransport *transport = _Transports.find(transName)->second;
2262 // check for peer invisible
2263 if (cl.SubParams[1]->getParam("PeerInvisible"))
2264 setTransportPeerInvisible(transName, true);
2265 else
2266 setTransportPeerInvisible(transName, false);
2268 // check for firewall mode
2269 if (cl.SubParams[1]->getParam("Firewalled"))
2270 setTransportFirewallMode(transName, true);
2271 else
2272 setTransportFirewallMode(transName, false);
2274 return true;
2277 NLMISC_CLASS_COMMAND_DECL(transportAdd)
2279 nlunreferenced(rawCommandString);
2280 nlunreferenced(quiet);
2281 nlunreferenced(human);
2283 if (args.size() != 2)
2284 return false;
2286 if (_Transports.find(args[1]) != _Transports.end())
2288 log.displayNL("A transport with that name already exist !");
2289 return true;
2292 createTransport(args[0], args[1]);
2293 return true;
2296 NLMISC_CLASS_COMMAND_DECL(transportListAvailableClass)
2298 nlunreferenced(rawCommandString);
2299 nlunreferenced(quiet);
2300 nlunreferenced(human);
2302 if (args.size() != 0)
2303 return false;
2305 vector<string> list;
2306 NLMISC_GET_FACTORY(IGatewayTransport, std::string).fillFactoryList(list);
2308 log.displayNL("List of %u available transport class :", list.size());
2310 for (uint i=0; i<list.size(); ++i)
2312 log.displayNL(" '%s'", list[i].c_str());
2314 return true;
2317 NLMISC_CLASS_COMMAND_DECL(dump)
2319 if (!args.empty())
2320 return false;
2322 // recall the dump for the module class
2323 NLMISC_CLASS_COMMAND_CALL_BASE(CModuleBase, dump);
2325 log.displayNL("-----------------------------");
2326 log.displayNL("Dumping gateway information :");
2327 log.displayNL("-----------------------------");
2329 log.displayNL("The gateway has %u locally plugged module :", _PluggedModules.getAToBMap().size());
2331 TPluggedModules::TAToBMap::const_iterator first(_PluggedModules.getAToBMap().begin()), last(_PluggedModules.getAToBMap().end());
2332 for (; first != last; ++first)
2334 IModule *module = first->second;
2335 log.displayNL(" ID:%5u : \tName = '%s' \tclass = '%s'",
2336 module->getModuleId(),
2337 module->getModuleName().c_str(),
2338 module->getModuleClassName().c_str());
2343 log.displayNL("The gateway as %u transport activated :", _Transports.size());
2345 TTransportList::iterator first(_Transports.begin()), last(_Transports.end());
2346 for (; first != last; ++first)
2348 const string &name = first->first;
2349 IGatewayTransport *transport = first->second;
2351 log.displayNL("Transport '%s' (transport class is '%s') :",
2352 name.c_str(),
2353 transport->getClassName().c_str());
2354 log.displayNL(" * %s", transport->PeerInvisible ? "Peer module are NON visible" : "Peer modules are visible");
2355 log.displayNL(" * %s", transport->Firewalled ? "Firewall ON" : "Firewall OFF");
2356 transport->dump(log);
2360 log.displayNL("------------------------------");
2361 log.displayNL("------- End of dump ----------");
2362 log.displayNL("------------------------------");
2363 return true;
2369 // register the module factory
2370 NLNET_REGISTER_MODULE_FACTORY(CStandardGateway, "StandardGateway");
2373 /** Set a security data block. If a bloc of the same type
2374 * already exist in the list, the new one will replace the
2375 * existing one.
2377 void CGatewaySecurity::setSecurityData(IModuleProxy *proxy, TSecurityData *securityData)
2379 // forward the call to standard gateway
2380 CStandardGateway *sg = static_cast<CStandardGateway*>(_Gateway);
2381 sg->setSecurityData(proxy, securityData);
2384 /** Clear a block of security data
2385 * The block is identified by the data tag
2387 bool CGatewaySecurity::removeSecurityData(IModuleProxy *proxy, uint8 dataTag)
2389 // forward the call to standard gateway
2390 CStandardGateway *sg = static_cast<CStandardGateway*>(_Gateway);
2391 return sg->removeSecurityData(proxy, dataTag);
2394 /** Replace the complete set of security data with the new one.
2395 * Security data allocated on the proxy are freed,
2397 void CGatewaySecurity::replaceAllSecurityDatas(IModuleProxy *proxy, TSecurityData *securityData)
2399 // forward the call to standard gateway
2400 CStandardGateway *sg = static_cast<CStandardGateway*>(_Gateway);
2401 sg->replaceAllSecurityDatas(proxy, securityData);
2404 /** Ask the gateway to resend the security data.
2405 * The plug-in call this method after having changed
2406 * the security info for a plug-in outside of the
2407 * onNewProxy call.
2409 void CGatewaySecurity::forceSecurityUpdate(IModuleProxy *proxy)
2411 // forward the call to standard gateway
2412 CStandardGateway *sg = static_cast<CStandardGateway*>(_Gateway);
2413 sg->forceSecurityUpdate(proxy);
2418 void forceGatewayLink()
2422 } // namespace NLNET