// [Licence] // The Ariba-Underlay Copyright // // Copyright (c) 2008-2009, Institute of Telematics, Universität Karlsruhe (TH) // // Institute of Telematics // Universität Karlsruhe (TH) // Zirkel 2, 76128 Karlsruhe // Germany // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE INSTITUTE OF TELEMATICS ``AS IS'' AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ARIBA PROJECT OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // The views and conclusions contained in the software and documentation // are those of the authors and should not be interpreted as representing // official policies, either expressed or implied, of the Institute of // Telematics. // [Licence] #include "BaseOverlay.h" #include "ariba/utility/misc/OvlVis.h" using ariba::utility::OvlVis; namespace ariba { namespace overlay { use_logging_cpp(BaseOverlay); BaseOverlay::BaseOverlay( BaseCommunication& _basecomm, const NodeID& _nodeid ) : bc( _basecomm ), nodeId( _nodeid ), spovnetId( SpoVNetID::UNSPECIFIED), overlayInterface( NULL ), initiatorLink( LinkID::UNSPECIFIED ), state( BaseOverlayStateInvalid ) { logging_info("creating base overlay"); bc.registerMessageReceiver( this ); bc.registerEventListener( this ); ovl.visCreate( ovlId, nodeId, string(""), string("") ); ovl.visChangeNodeColor(ovlId, nodeId, OvlVis::NODE_COLORS_GREY); // if (Identifier(Configuration::instance().read("BASE_nodeid")) == // Identifier(Configuration::instance().read("SOURCE"))) { // ovl.visChangeNodeIcon(ovlId, nodeId, OvlVis::ICON_ID_CAMERA); // } else if (Identifier(Configuration::instance().read("BASE_nodeid")) == // Identifier(Configuration::instance().read("MR_A"))) { // ovl.visChangeNodeIcon(ovlId, nodeId, OvlVis::ICON_ID_CHARACTER_A); // } else if (Identifier(Configuration::instance().read("BASE_nodeid")) == // Identifier(Configuration::instance().read("MR_W"))) { // ovl.visChangeNodeIcon(ovlId, nodeId, OvlVis::ICON_ID_CHARACTER_W); // } // timer for auto link management Timer::setInterval( 5000 ); Timer::start(); } BaseOverlay::~BaseOverlay() { logging_info("deleting base overlay"); Timer::stop(); bc.unregisterMessageReceiver( this ); bc.unregisterEventListener( this ); } void BaseOverlay::joinSpoVNet(const SpoVNetID& id, const EndpointDescriptor& bootstrapEp){ ovl.visShowNodeBubble ( ovlId, nodeId, "joining..." ); logging_info( "starting to join spovnet " << id.toString() << "..."); // // contact the spovnet initiator and request // to join. if the join is granted we will // receive further information on the structure // of the overlay that is used in the spovnet // // but first, we have to establish a link to the initiator... // spovnetId = id; state = BaseOverlayStateJoinInitiated; initiatorLink = bc.establishLink( bootstrapEp ); } void BaseOverlay::leaveSpoVNet(){ logging_info( "leaving spovnet " << spovnetId ); logging_debug( "dropping all auto-links ..." ); BOOST_FOREACH( LinkPair item, linkMapping ){ if( item.second.autolink ) dropLink( item.first ); } logging_debug( "leaving overlay" ); // first, leave the overlay interface overlayInterface->leaveOverlay(); if( state != BaseOverlayStateInitiator ){ // then, leave the spovnet baseoverlay OverlayMsg overMsg( OverlayMsg::OverlayMessageTypeBye, nodeId ); bc.sendMessage( initiatorLink, &overMsg ); // drop the link and set to correct state bc.dropLink( initiatorLink ); initiatorLink = LinkID::UNSPECIFIED; } state = BaseOverlayStateInvalid; ovl.visShutdown( ovlId, nodeId, string("") ); // inform all registered services of the event BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){ i->onOverlayDestroy( spovnetId ); } } void BaseOverlay::createSpoVNet(const SpoVNetID& id, const OverlayParameterSet& param, const SecurityParameterSet& sec, const QoSParameterSet& qos){ // // set the state that we are an initiator, // this way incoming messages are handled correctly // logging_info("creating spovnet " + id.toString()); spovnetId = id; state = BaseOverlayStateInitiator; overlayInterface = OverlayFactory::create( *this, param, nodeId, this ); if( overlayInterface == NULL ){ logging_fatal( "overlay structure not supported" ); state = BaseOverlayStateInvalid; return; } // // create the overlay // overlayInterface->createOverlay(); BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){ i->onOverlayCreate( spovnetId ); } // // bootstrap against ourselfs // overlayInterface->joinOverlay(); BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){ i->onJoinSuccess( spovnetId ); } ovl.visChangeNodeIcon ( ovlId, nodeId, OvlVis::ICON_ID_CAMERA ); ovl.visChangeNodeColor( ovlId, nodeId, OvlVis::NODE_COLORS_GREEN); } const EndpointDescriptor& BaseOverlay::getEndpointDescriptor(const LinkID& link) const { return bc.getEndpointDescriptor( link ); } const EndpointDescriptor& BaseOverlay::getEndpointDescriptor(const NodeID& node) const { if( node == nodeId || node == NodeID::UNSPECIFIED ) return bc.getEndpointDescriptor(); if( overlayInterface == NULL ){ logging_error( "overlay interface not set, cannot resolve endpoint" ); return EndpointDescriptor::UNSPECIFIED; } // TODO: if this is not a onehop overlay the operation will go asynchronously return overlayInterface->resolveNode( node ); } const LinkID BaseOverlay::establishLink(const NodeID& node, const ServiceID& service){ // TODO: if this is not a onehop overlay the operation will go asynchronously const EndpointDescriptor& endpoint = overlayInterface->resolveNode( node ); if( endpoint == EndpointDescriptor::UNSPECIFIED ){ logging_error( "could not resolve node to endpoint. unable to establish link" ); return LinkID::UNSPECIFIED; } logging_debug( "baseoverlay called to establish link between node " << node.toString() << " on endpoint " << endpoint.toString() << " for service " << service.toString() ); return establishLink( endpoint, service ); } const LinkID BaseOverlay::establishLink(const EndpointDescriptor& ep, const ServiceID& service){ if( !listenerMux.contains( service ) ){ logging_error( "no registered listener on serviceid " << service.toString() ); return LinkID::UNSPECIFIED; } ServiceInterface* receiver = listenerMux.get( service ); const LinkID link = bc.establishLink( ep ); LinkItem item (link, NodeID::UNSPECIFIED, service, receiver); linkMapping.insert( make_pair(link, item) ); return link; } void BaseOverlay::dropLink(const LinkID& link){ logging_debug( "baseoverlay dropping link " << link.toString() ); LinkMapping::iterator i = linkMapping.find( link ); if( i == linkMapping.end() ){ logging_warn( "can't drop link, mapping unknown " << link.toString() ); return; } linkMapping.erase( i ); LinkItem item = i->second; bc.dropLink( link ); if( item.interface != NULL ) item.interface->onLinkDown( spovnetId, nodeId, item.node ); } seqnum_t BaseOverlay::sendMessage(const Message* message, const LinkID& link ){ logging_debug( "baseoverlay is sending message on link " << link.toString() ); LinkMapping::iterator i = linkMapping.find( link ); if( i == linkMapping.end() ){ logging_error( "could not send message. link not found " << link.toString() ); return -1; } OverlayMsg overmsg( OverlayMsg::OverlayMessageTypeData, i->second.service, nodeId ); overmsg.encapsulate( const_cast(message) ); i->second.markused(); return bc.sendMessage( link, &overmsg ); } seqnum_t BaseOverlay::sendMessage(const Message* message, const NodeID& node, const ServiceID& service){ LinkID link = LinkID::UNSPECIFIED; LinkMapping::iterator i = linkMapping.begin(); LinkMapping::iterator iend = linkMapping.end(); for( ; i != iend; i++ ){ if( i->second.node == node && i->second.service == service ){ link = i->second.link; break; } } if( link == LinkID::UNSPECIFIED ){ logging_info( "no link could be found to send message to node " << node.toString() << " for service " << service.toString() << ". creating auto link ..."); const LinkID link = establishLink( node, service ); LinkMapping::iterator i = linkMapping.find( link ); if( i == linkMapping.end() ){ logging_error( "failed to establish auto link to node " << node.toString() << " for service " << service.toString() ); return -1; } i->second.autolink = true; } // if( link != LinkID::UNSPECIFIED ) i->second.markused(); return sendMessage( message, link ); } bool BaseOverlay::bind(ServiceInterface* service, const ServiceID& sid) { logging_debug( "binding service " << service << " on serviceid " << sid.toString() ); if( listenerMux.contains( sid ) ){ logging_error( "some service already registered for service id " << sid.toString() ); return false; } listenerMux.registerItem( service, sid ); return true; } ServiceInterface* BaseOverlay::unbind(const ServiceID& sid){ logging_debug( "unbinding service from serviceid " << sid.toString() ); if( !listenerMux.contains( sid ) ){ logging_warn( "cannot unbind service. no service registered on service id " << sid.toString() ); return NULL; } ServiceInterface* iface = listenerMux.get( sid ); listenerMux.unregisterItem( sid ); return NULL; //iface; } void BaseOverlay::onLinkUp(const LinkID& id, const NetworkLocator* local, const NetworkLocator* remote){ logging_debug( "base overlay received linkup event " + id.toString() ); // TODO: updateOvlVis( getNodeID(id) ); // // if we get up a link while we are in the // join phase and this is the link that // we have initiated towards the spovnet owner // continue the join process by sending // a join request message through the link // if( state == BaseOverlayStateJoinInitiated && id == initiatorLink){ logging_info( "join has been initiated by me and the link is now up. " << "sending out join request for spovnet " << spovnetId.toString() ); OverlayMsg overMsg( OverlayMsg::OverlayMessageTypeJoinRequest, nodeId ); JoinRequest joinmsg( spovnetId, nodeId ); overMsg.encapsulate( &joinmsg ); state = BaseOverlayStateJoinInitiated; // state remains in JoinInitiated bc.sendMessage( id, &overMsg ); return; } // if( state == BaseOverlayStateJoinInitiated && id == initiatorLink) // // otherwise this is a link initiated by a service // then we exchange update messages to exchange the // service id and node id for the link. in this case // we should have a link mapping for this link. if // we have no link mapping this link was initiated by // the remote side. // LinkMapping::iterator i = linkMapping.find( id ); if( i == linkMapping.end() ){ LinkItem item (id, NodeID::UNSPECIFIED, ServiceID::UNSPECIFIED, NULL ); linkMapping.insert( make_pair(id, item) ); } else { logging_debug( "sending out OverlayMessageTypeUpdate" << " for service " << i->second.service.toString() << " with local node id " << nodeId.toString() << " on link " << id.toString() ); OverlayMsg overMsg( OverlayMsg::OverlayMessageTypeUpdate, i->second.service, nodeId ); bc.sendMessage( id, &overMsg ); i->second.markused(); } // if( i == linkMapping.end() ) // the link is only valid for the service when we receive // the OverlayMessageTypeUpdate from the remote node and // have the nodeid and serviceid for the link! } void BaseOverlay::onLinkDown(const LinkID& id, const NetworkLocator* local, const NetworkLocator* remote){ logging_debug( "link went down " << id.toString() ); // // tell the service that the link went // down and remove the mapping // LinkMapping::iterator i = linkMapping.find( id ); if( i == linkMapping.end() ) { // this can also be one of the baseoverlay links that // no mapping is stored for. therefore we issue no warning return; } if( i->second.interface != NULL ) i->second.interface->onLinkDown( id, nodeId, i->second.node ); linkMapping.erase( i ); } void BaseOverlay::onLinkChanged(const LinkID& id, const NetworkLocator* oldlocal, const NetworkLocator* newlocal, const NetworkLocator* oldremote, const NetworkLocator* newremote){ logging_debug( "link changed " << id.toString() ); // // tell the service that the link changed // LinkMapping::iterator i = linkMapping.find( id ); if( i == linkMapping.end() ) return; if( i->second.interface != NULL ) i->second.interface->onLinkChanged( id, nodeId, i->second.node ); i->second.markused(); } void BaseOverlay::onLinkFail(const LinkID& id, const NetworkLocator* local, const NetworkLocator* remote){ logging_debug( "link failed " << id.toString() ); // // tell the service that the link failed // LinkMapping::iterator i = linkMapping.find( id ); if( i == linkMapping.end() ) return; if( i->second.interface != NULL ) i->second.interface->onLinkFail( id, nodeId, i->second.node ); i->second.markused(); } void BaseOverlay::onLinkQoSChanged(const LinkID& id, const NetworkLocator* local, const NetworkLocator* remote, const QoSParameterSet& qos) { logging_debug( "link qos changed " << id.toString() ); // // tell the service that the link qos has changed // LinkMapping::iterator i = linkMapping.find( id ); if( i == linkMapping.end() ) return; if( i->second.interface != NULL ) i->second.interface->onLinkQoSChanged( id, nodeId, i->second.node, qos ); i->second.markused(); } bool BaseOverlay::receiveMessage(const Message* message, const LinkID& link, const NodeID& /*the nodeid is invalid in this case! removed var to prevent errors*/ ){ OverlayMsg* overlayMsg = ((Message*)message)->decapsulate(); if( overlayMsg == NULL ) return false; // mark the link as in action LinkMapping::iterator item = linkMapping.find( link ); if( item != linkMapping.end() ) item->second.markused(); // // handle user date that we forward to the // appropriate service using the service id // in the message. as we don't know the class // of message that the service handles, we // forward it as a pure Message* // if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeData) ) { logging_debug( "baseoverlay received message of type OverlayMessageTypeData" ); const ServiceID& service = overlayMsg->getService(); ServiceInterface* serviceListener = listenerMux.get( service ); logging_debug( "received data for service " << service.toString() ); if( serviceListener != NULL ) serviceListener->receiveMessage( overlayMsg, link, overlayMsg->getSourceNode() ); return true; } // if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeData) ) // // handle spovnet instance join requests // else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeJoinRequest) && state == BaseOverlayStateInitiator){ logging_debug( "baseoverlay received message of type OverlayMessageTypeJoinRequest" ); JoinRequest* joinReq = overlayMsg->decapsulate(); logging_info( "received join request for spovnet " << joinReq->getSpoVNetID().toString() ); // // make sure that the node actually wants to join // the correct spovnet id that we administrate // if( joinReq->getSpoVNetID() != spovnetId ){ logging_error( "received join request for spovnet we don't handle " << joinReq->getSpoVNetID().toString() ); return false; } // // only if all services allow the node to join it is allowed // using the isJoinAllowed interface security policies can be // implemented by higher layer services // bool allow = true; BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){ allow &= i->isJoinAllowed( overlayMsg->getSourceNode(), spovnetId ); } logging_info( "sending back join reply for spovnet " << spovnetId.toString() << " to node " << overlayMsg->getSourceNode().toString() << ". result: " << (allow ? "allowed" : "denied") ); joiningNodes.push_back( overlayMsg->getSourceNode() ); // // send back our spovnetid, default overlay parameters, // join allow result, and ourself as the endpoint // to bootstrap the overlay against // OverlayMsg retmsg( OverlayMsg::OverlayMessageTypeJoinReply, nodeId ); JoinReply replyMsg( spovnetId, OverlayParameterSet::DEFAULT, allow, getEndpointDescriptor() ); retmsg.encapsulate(&replyMsg); bc.sendMessage( link, &retmsg ); return true; } // else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeJoinRequest) && state == BaseOverlayStateInitiator) // // handle replies to spovnet instance join requests // else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeJoinReply) && state == BaseOverlayStateJoinInitiated){ logging_debug( "baseoverlay received message of type OverlayMessageTypeJoinReply" ); JoinReply* replyMsg = overlayMsg->decapsulate(); logging_info( "received spovnet join reply" ); // // make sure that we actually wanted to get // into the spovnet whose id is in the message // if( replyMsg->getSpoVNetID() != spovnetId ){ logging_error( "received spovnet join reply for spovnet " << replyMsg->getSpoVNetID().toString() << " but we wanted to join spovnet " << spovnetId.toString() ); // state does not change here, maybe // the reply does come in later return false; } // // if we did not get access to the spovnet // notify of the failure and // close the link to the initiator // if( ! replyMsg->getJoinAllowed() ){ logging_warn( "our join request has been denied" ); bc.dropLink( initiatorLink ); initiatorLink = LinkID::UNSPECIFIED; state = BaseOverlayStateInvalid; // inform all registered services of the event BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){ i->onJoinFail( spovnetId ); } return true; } logging_info( "join request has been accepted for spovnet " << spovnetId.toString() ); // // if we did get access to the spovnet // we try to create the overlay structure // as given in the reply message // overlayInterface = OverlayFactory::create( *this, replyMsg->getParam(), nodeId, this ); if( overlayInterface == NULL ){ logging_error( "overlay structure not supported" ); bc.dropLink( initiatorLink ); initiatorLink = LinkID::UNSPECIFIED; state = BaseOverlayStateInvalid; // inform all registered services of the event BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){ i->onJoinFail( spovnetId ); } return true; } // // now start the join process for the overlay. // the join process for the spovnet baseoverlay // is now complete. we use the endpoint for // overlay structure bootstrapping that the // initiator provided in his reply message // state = BaseOverlayStateCompleted; ovl.visChangeNodeColor( ovlId, nodeId, OvlVis::NODE_COLORS_GREEN); overlayInterface->createOverlay(); // inform all registered services of the event BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){ i->onOverlayCreate( spovnetId ); } overlayInterface->joinOverlay( replyMsg->getBootstrapEndpoint() ); // inform all registered services of the event BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){ i->onJoinSuccess( spovnetId ); } return true; } // else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeJoinReply) && state == BaseOverlayStateJoinInitiated) // // handle update messages for link establishment // else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeUpdate) ){ logging_debug( "baseoverlay received message of type OverlayMessageTypeUpdate" ); const NodeID& sourcenode = overlayMsg->getSourceNode(); const ServiceID& service = overlayMsg->getService(); // // we should have a linkmapping for the link, otherwise // we ignore update messages // LinkMapping::iterator i = linkMapping.find( link ); if( i == linkMapping.end() ){ logging_warn( "received overlay update message for link " << link.toString() << " for which we have no mapping" ); return false; } // // update our link mapping information for this link // bool changed = ( i->second.node != sourcenode ) || ( i->second.service != service ); i->second.node = sourcenode; i->second.service = service; // // if our link information changed, we send out an update, too // if( changed ){ OverlayMsg overMsg( OverlayMsg::OverlayMessageTypeUpdate, i->second.service, nodeId ); bc.sendMessage( link, &overMsg ); } // // set the correct listener service for the linkitem // now we can tell the registered service of the linkup event // if( !listenerMux.contains( service ) ){ logging_warn( "linkup event for service that has not been registered" ); return false; } ServiceInterface* iface = listenerMux.get( service ); if( iface == NULL ){ logging_warn( "linkup event for service that has been registered with a NULL interface" ); return true; } i->second.interface = iface; iface->onLinkUp( link, nodeId, sourcenode ); i->second.markused(); return true ; } // else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeUpdate) ) // // bye messages to say goodbye // else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeBye)){ logging_debug( "baseoverlay received message of type OverlayMessageTypeBye" ); logging_debug( "received bye message from " << overlayMsg->getSourceNode().toString() ); // // if we are the initiator and receive a bye from a node // the node just left. if we are a node and receive a bye // from the initiator, we have to close, too. // if( overlayMsg->getSourceNode() == spovnetInitiator ){ bc.dropLink( initiatorLink ); initiatorLink = LinkID::UNSPECIFIED; state = BaseOverlayStateInvalid; logging_fatal( "initiator ended spovnet" ); // inform all registered services of the event BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){ i->onOverlayDestroy( spovnetId ); } } else { // a node that said goodbye and we are the initiator // don't have to do much here, as the node also // will go out of the overlay structure logging_info( "node left " << overlayMsg->getSourceNode() ); // inform all registered services of the event BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){ i->onNodeLeave( overlayMsg->getSourceNode(), spovnetId ); } } return true; } // else if( overlayMsg->isType(OverlayMsg::OverlayMessageTypeBye)) // // something wrong ... // else { logging_error( "received message in invalid state! don't know " << "what to do with this message of type " << overlayMsg->getType() ); return false; } // else return false; } void BaseOverlay::broadcastMessage(Message* message, const ServiceID& service){ logging_debug( "broadcasting message to all known nodes " << "in the overlay from service " + service.toString() ); OverlayInterface::NodeList nodes = overlayInterface->getKnownNodes(); OverlayInterface::NodeList::iterator i = nodes.begin(); OverlayInterface::NodeList::iterator iend = nodes.end(); for( ; i != iend; i++ ){ if( *i == nodeId) continue; // don't send to ourselfs sendMessage( message, *i, service ); // TODO: sollte auto links aufbauen für sowas } } void BaseOverlay::updateOvlVis( const NodeID& n ) { NodeID node = n; /* void visShowNodeBubble ( NETWORK_ID network, NodeID& node, string label ); */ using namespace std; if (node == nodeId || node.isUnspecified()) return; // min/max if ( node < min || min.isUnspecified() ) min = node; if ( node > max || max.isUnspecified() ) max = node; // successor if ( succ.isUnspecified() || (node > nodeId && (succ < nodeId || (node-nodeId) < (succ-nodeId))) ) { if (!succ.isUnspecified() && node != succ) ovl.visDisconnect(ovlId, nodeId, succ, string("")); succ = node; ovl.visConnect(ovlId, nodeId, succ, string("")); } // set successor (circle-wrap) if (succ.isUnspecified() && !min.isUnspecified()) { succ = min; ovl.visConnect(ovlId, nodeId, succ, string("")); } } const NodeID& BaseOverlay::getNodeID(const LinkID& lid) const { if( lid == LinkID::UNSPECIFIED ) return nodeId; LinkMapping::const_iterator i = linkMapping.find( lid ); if( i == linkMapping.end() ) return NodeID::UNSPECIFIED; else return i->second.node; } void BaseOverlay::incomingRouteMessage(Message* msg){ // gets handled as normal data message // TODO: passt das so? receiveMessage( msg, LinkID::UNSPECIFIED, NodeID::UNSPECIFIED ); } void BaseOverlay::onNodeJoin(const NodeID& node){ JoiningNodes::iterator i = std::find( joiningNodes.begin(), joiningNodes.end(), node ); if( i == joiningNodes.end() ) return; logging_info( "node has successfully joined baseoverlay and overlay structure " << node.toString() ); BOOST_FOREACH( ServiceInterface* i, listenerMux.getOneList() ){ i->onNodeJoin( node, spovnetId ); } joiningNodes.erase( i ); } void BaseOverlay::eventFunction(){ list oldlinks; time_t now = time(NULL); // first gather all the links from linkMapping that need droppin // don't directly drop, as the dropLink function affects the // linkMapping structure that we are traversing here. // drop links after a timeout of 30s BOOST_FOREACH( LinkPair item, linkMapping ){ if( item.second.autolink && difftime(now, item.second.lastuse) > 30) oldlinks.push_back( item.first ); } BOOST_FOREACH( const LinkID lnk, oldlinks ){ logging_debug( "auto-link " << lnk.toString() << " timed out and is getting dropped" ); dropLink( lnk ); } } }} // namespace ariba, overlay