Index: source/ariba/overlay/BaseOverlay.cpp
===================================================================
--- source/ariba/overlay/BaseOverlay.cpp	(revision 5860)
+++ source/ariba/overlay/BaseOverlay.cpp	(revision 5870)
@@ -49,9 +49,8 @@
 
 #include "ariba/overlay/LinkDescriptor.h"
+
 #include "ariba/overlay/messages/OverlayMsg.h"
 #include "ariba/overlay/messages/JoinRequest.h"
 #include "ariba/overlay/messages/JoinReply.h"
-#include "ariba/overlay/messages/LinkRequest.h"
-#include "ariba/overlay/messages/RelayMessage.h"
 
 #include "ariba/utility/misc/OvlVis.h"
@@ -59,4 +58,20 @@
 namespace ariba {
 namespace overlay {
+
+/* *****************************************************************************
+ * PREREQUESITES
+ * ****************************************************************************/
+
+CommunicationListener* BaseOverlay::getListener( const ServiceID& service ) {
+	if( !communicationListeners.contains( service ) ) {
+		logging_error( "No listener found for service " << service.toString() );
+		return NULL;
+	}
+	CommunicationListener* listener = communicationListeners.get( service );
+	assert( listener != NULL );
+	return listener;
+}
+
+// link descriptor handling ----------------------------------------------------
 
 LinkDescriptor* BaseOverlay::getDescriptor( const LinkID& link, bool communication ) {
@@ -91,5 +106,5 @@
 	if ( desc == NULL ) {
 		desc = new LinkDescriptor();
-		desc->overlayId = link;
+		if (!link.isUnspecified()) desc->overlayId = link;
 		links.push_back(desc);
 	}
@@ -99,7 +114,9 @@
 /// returns a auto-link descriptor
 LinkDescriptor* BaseOverlay::getAutoDescriptor( const NodeID& node, const ServiceID& service ) {
+	// search for a descriptor that is already up
 	BOOST_FOREACH( LinkDescriptor* lp, links )
 		if (lp->autolink && lp->remoteNode == node && lp->service == service && lp->up)
 			return lp;
+	// if not found, search for one that is about to come up...
 	BOOST_FOREACH( LinkDescriptor* lp, links )
 		if (lp->autolink && lp->remoteNode == node && lp->service == service )
@@ -108,7 +125,17 @@
 }
 
-/// returns a direct local link relay descriptor for the given remote node
-LinkDescriptor* BaseOverlay::getRelayDescriptor( const NodeID& id ) {
-
+/// stabilizes link information
+void BaseOverlay::stabilizeLinks() {
+	// send keep-alive messages over established links
+	BOOST_FOREACH( LinkDescriptor* ld, links ) {
+		if (!ld->up) continue;
+		OverlayMsg msg( OverlayMsg::typeLinkAlive,
+			OverlayInterface::OVERLAY_SERVICE_ID, nodeId, ld->remoteNode );
+		msg.setRelayed(true);
+		if (ld->relayed) msg.setRouteRecord(true);
+		send_link( &msg, ld->overlayId );
+	}
+
+<<<<<<< .working
 	// get used next hop towards node
 	LinkDescriptor* rld = NULL;
@@ -118,5 +145,15 @@
 		// get descriptor of first hop
 		rld = getDescriptor(rlid);
-
+=======
+	// iterate over all links and check for time boundaries
+	vector<LinkDescriptor*> oldlinks;
+	time_t now = time(NULL);
+	BOOST_FOREACH( LinkDescriptor* ld, links ) {
+		// remote used as relay flag
+		if ( ld->relaying && difftime( now, ld->timeRelaying ) > 10)
+			ld->relaying = false;
+>>>>>>> .merge-rechts.r5869
+
+<<<<<<< .working
 		// is first hop a relay path use local relay
 		if ( rld->relay ) relayNode = rld->localRelay;
@@ -125,21 +162,24 @@
 		else relayNode = rld->remoteNode;
 	}
-
-	// if first relay is unknown choose a arbitrary direct node as relay
-	if ( relayNode.isUnspecified() ) {
-		for (size_t i=0; i<links.size(); i++)
-			if (links[i]->up &&
-				links[i]->communicationUp &&
-				!links[i]->relay &&
-				links[i]->keepAliveMissed <= 1 &&
-				links[i]->service == OverlayInterface::OVERLAY_SERVICE_ID) {
-				relayNode = links[i]->remoteNode;
-				break;
+=======
+		// keep alives and not up? yes-> link connection request is stale!
+		if ( !ld->up && difftime( now, ld->keepAliveTime ) >= 2 ) {
+>>>>>>> .merge-rechts.r5869
+
+			// increase counter
+			ld->keepAliveMissed++;
+
+			// missed more than four keep-alive messages (10 sec)? -> drop link
+			if (ld->keepAliveMissed > 4) {
+				logging_info( "Link connection request is stale, closing: " << ld );
+				ld->relaying = false;
+				oldlinks.push_back( ld );
+				continue;
 			}
-	}
-
-	// no local relay found-> damn!
-	if (relayNode.isUnspecified()) return NULL;
-
+		}
+
+		if (!ld->up) continue;
+
+<<<<<<< .working
 	// get descriptor
 	BOOST_FOREACH( LinkDescriptor* lp, links )
@@ -149,156 +189,282 @@
 		    lp->up)
 			return lp;
-
+=======
+		// drop links that are dropped and not used as relay
+		if (ld->dropAfterRelaying && !ld->relaying && !ld->autolink) {
+			oldlinks.push_back( ld );
+			continue;
+		}
+
+		// auto-link time exceeded?
+		if ( ld->autolink && difftime( now, ld->lastuse ) > 30 ) {
+			oldlinks.push_back( ld );
+			continue;
+>>>>>>> .merge-rechts.r5869
+
+		// keep alives missed? yes->
+		if ( difftime( now, ld->keepAliveTime ) > 2 ) {
+
+			// increase counter
+			ld->keepAliveMissed++;
+
+			// missed more than four keep-alive messages (4 sec)? -> drop link
+			if (ld->keepAliveMissed >= 4) {
+				logging_info( "Link is stale, closing: " << ld );
+				ld->relaying = false;
+				oldlinks.push_back( ld );
+				continue;
+			}
+		}
+	}
+
+	// drop links
+	BOOST_FOREACH( const LinkDescriptor* ld, oldlinks ) {
+/*
+		vector<LinkID>::iterator it = std::find(
+				bootstrapLinks.begin(), bootstrapLinks.end(), ld->communicationId);
+
+		if (!ld->communicationId.isUnspecified() && it != bootstrapLinks.end() ){
+			logging_info( "Not dropping initiator link: " << ld );
+			continue;
+		}
+*/
+		logging_info( "Link timed out. Dropping " << ld );
+		dropLink( ld->overlayId );
+	}
+
+	// show link state
+	counter++;
+	if (counter>=4) showLinks();
+	if (counter>=4 || counter<0) counter = 0;
+}
+
+void BaseOverlay::showLinks() {
+	int i=0;
+	logging_info("--- link state -------------------------------");
+	BOOST_FOREACH( LinkDescriptor* ld, links ) {
+		logging_info("link " << i << ": " << ld);
+		i++;
+	}
+	logging_info("----------------------------------------------");
+}
+
+// internal message delivery ---------------------------------------------------
+
+/// routes a message to its destination node
+void BaseOverlay::route( OverlayMsg* message, LinkDescriptor* incomingLink ) {
+
+	// exceeded time-to-live? yes-> drop message
+	if (message->getNumHops() > message->getTimeToLive()) {
+		logging_warn("Message exceeded TTL -> drop message!");
+		return;
+
+	// no-> forward message
+	} else {
+		// destinastion myself? yes-> handle message
+		if (message->getDestinationNode() == nodeId)
+			handleMessage( message, incomingLink );
+		else
+			// no->send message to next hop
+			send( message, message->getDestinationNode() );
+	}
+}
+
+/// sends a message to another node, delivers it to the base overlay class
+seqnum_t BaseOverlay::send( OverlayMsg* message, const NodeID& destination ) {
+	LinkDescriptor* next_link = NULL;
+
+	// drop messages to unspecified destinations
+	if (destination.isUnspecified()) return -1;
+
+	// send messages to myself -> handle message and drop warning!
+	if (destination == nodeId) {
+		logging_warn("Sent message to myself. Handling message.")
+		Message msg;
+		msg.encapsulate(message);
+		handleMessage( &msg, NULL );
+		return -1;
+	}
+
+	// relay path known? yes-> send over relay link
+	next_link = getRelayLinkTo( destination );
+	if (next_link != NULL) {
+		next_link->setRelaying();
+		return send(message, next_link);
+	}
+
+	// no-> relay path! route over overlay path
+	LinkID next_id = overlayInterface->getNextLinkId( destination );
+	if (next_id.isUnspecified()) {
+		logging_error("Could not send message. No next hop found to " << destination );
+		return -1;
+	}
+
+	// get link descriptor, up and running? yes-> send message
+	next_link = getDescriptor(next_id);
+	if (next_link != NULL && next_link->up)
+		return send(message, next_link);
+
+	// no-> error, dropping message
+	else {
+		logging_error("Could not send message. Link not known or up");
+		return -1;
+	}
+
+	// not reached-> fail
+	return -1;
+}
+
+/// send a message using a link descriptor, delivers it to the base overlay class
+seqnum_t BaseOverlay::send( OverlayMsg* message, LinkDescriptor* ld, bool ignore_down ) {
+	assert(ld!=NULL);
+
+	// check if up
+	if (!ld->up && !ignore_down) {
+		logging_error("Can not send message. Link not up:" << ld );
+		return -1;
+	}
+
+	// handle relayed link
+	if (ld->relayed) {
+		logging_debug("send(): Resolving direct link for relayed link to "
+			<< ld->remoteNode);
+		ld = getRelayLinkTo( ld->remoteNode );
+		if (ld==NULL) {
+			logging_error("Direct link not found.");
+			return -1;
+		}
+		message->setRelayed();
+		ld->setRelaying();
+	}
+
+	// handle direct link
+	if (ld->communicationUp) {
+		logging_debug("send(): Sending message over direct link.");
+		return bc->sendMessage( ld->communicationId, message );
+	} else {
+		logging_error("send(): Could not send mesage. "
+				"Not a relayed link and direct link is not up.");
+		return -1;
+	}
+	return -1;
+}
+
+seqnum_t BaseOverlay::send_node( OverlayMsg* message, const NodeID& remote,
+	const ServiceID& service) {
+	message->setSourceNode(nodeId);
+	message->setService(service);
+	message->setDestinationNode(remote);
+	send( message, remote );
+}
+
+seqnum_t BaseOverlay::send_link( OverlayMsg* message, const LinkID& link,bool ignore_down ) {
+	LinkDescriptor* ld = getDescriptor(link);
+	if (ld==NULL) {
+		logging_error("Cannot find descriptor to link id=" << link.toString());
+		return -1;
+	}
+	message->setSourceNode(nodeId);
+	message->setSourceLink(ld->overlayId);
+	message->setService(ld->service);
+	message->setDestinationNode(ld->remoteNode);
+	message->setDestinationLink(ld->remoteLink);
+	return send( message, ld, ignore_down );
+}
+
+// relay route management ------------------------------------------------------
+
+/// stabilize relay information
+void BaseOverlay::stabilizeRelays() {
+	vector<relay_route>::iterator i = relay_routes.begin();
+	while (i!=relay_routes.end() ) {
+		relay_route& route = *i;
+		LinkDescriptor* ld = getDescriptor(route.link);
+		if (ld==NULL
+			|| !ld->up
+			|| difftime(route.used, time(NULL)) > 4) {
+			logging_info("Forgetting relay information to node "
+					<< route.node.toString() );
+			i = relay_routes.erase(i);
+		} else
+			i++;
+	}
+}
+
+void BaseOverlay::removeRelayLink( const LinkID& link ) {
+	vector<relay_route>::iterator i = relay_routes.begin();
+	while (i!=relay_routes.end() ) {
+		relay_route& route = *i;
+		if (route.link == link ) i = relay_routes.erase(i); else i++;
+	}
+}
+
+void BaseOverlay::removeRelayNode( const NodeID& remote ) {
+	vector<relay_route>::iterator i = relay_routes.begin();
+	while (i!=relay_routes.end() ) {
+		relay_route& route = *i;
+		if (route.node == remote ) i = relay_routes.erase(i); else i++;
+	}
+}
+
+/// refreshes relay information
+void BaseOverlay::refreshRelayInformation( const OverlayMsg* message, LinkDescriptor* ld ) {
+
+	// handle relayed messages from real links only
+	if (ld == NULL
+		|| ld->relayed
+		|| !message->isRelayed()
+		|| message->getSourceNode()==nodeId ) return;
+
+	// check wheter this node is already part of the routing table
+	LinkID next_link = overlayInterface->getNextLinkId(message->getSourceNode());
+	if (next_link == ld->overlayId) return;
+	ld->setRelaying();
+
+	// try to find source node
+	BOOST_FOREACH( relay_route& route, relay_routes ) {
+
+		// relay route found? yes->
+		if ( route.node == message->getSourceNode() ) {
+
+			// refresh timer
+			route.used = time(NULL);
+
+			// route has a shorter hop count? yes-> replace
+			if (route.hops > message->getNumHops() ) {
+				logging_info("Updating relay information to node "
+					<< route.node.toString()
+					<< " reducing to " << message->getNumHops() << " hops.");
+				route.hops = message->getNumHops();
+				route.link = ld->overlayId;
+			}
+			return;
+		}
+	}
+
+	// not found-> add new entry
+	relay_route route;
+	route.hops = message->getNumHops();
+	route.link = ld->overlayId;
+	route.node = message->getSourceNode();
+	route.used = time(NULL);
+	logging_info("Remembering relay information to node " << route.node.toString());
+	relay_routes.push_back(route);
+}
+
+/// returns a known "vital" relay link which is up and running
+LinkDescriptor* BaseOverlay::getRelayLinkTo( const NodeID& remote ) {
+	// try to find source node
+	BOOST_FOREACH( relay_route& route, relay_routes ) {
+		if (route.node == remote ) {
+			LinkDescriptor* ld = getDescriptor( route.link );
+			if (ld==NULL || !ld->up) return NULL; else return ld;
+		}
+	}
 	return NULL;
 }
 
-/// returns the link descriptor that is actually used for sending a message over the overÃ¶ay
-LinkDescriptor* BaseOverlay::getSendDescriptor( const NodeID& nodeid, bool follow ) {
-	for (size_t i=0; i<links.size(); i++)
-		if ( !links[i]->relay &&
-			links[i]->up &&
-			links[i]->communicationUp &&
-			links[i]->keepAliveMissed <= 1 &&
-			links[i]->remoteNode == nodeid &&
-			links[i]->service == OverlayInterface::OVERLAY_SERVICE_ID) {
-			return links[i];
-		}
-	LinkDescriptor* ld = getDescriptor(overlayInterface->getNextLinkId(nodeid));
-	if (ld != NULL && ld->relay && follow)
-		return getSendDescriptor(ld->localRelay, false);
-	return NULL;
-}
-
-NodeID BaseOverlay::getRelayNode( const NodeID& remoteNode ) {
-	LinkDescriptor* rld = getRelayDescriptor(remoteNode);
-	return rld!=NULL ? rld->remoteNode : NodeID::UNSPECIFIED;
-}
-
-/// routes a message over the overlay or directly sends it when a link is open
-seqnum_t BaseOverlay::sendOverlay( Message* message, const NodeID& nodeid, const NodeID& remoteRelay  ) {
-	/// send message directly to a neighbor
-	for (size_t i=0; i<links.size(); i++)
-		if ( !links[i]->relay &&
-			links[i]->up &&
-			links[i]->communicationUp &&
-			links[i]->keepAliveMissed <= 1 &&
-			links[i]->remoteNode == nodeid &&
-			links[i]->service == OverlayInterface::OVERLAY_SERVICE_ID) {
-
-			// mark as relay and send message
-			links[i]->markAsRelay();
-			return sendMessage( message, links[i] );
-		}
-
-	/// send relayed message over the overlay
-	if (!remoteRelay.isUnspecified()) {
-		// create a information relay message to inform the relay about
-		OverlayMsg overlay_msg(
-			OverlayMsg::typeRelay, OverlayInterface::OVERLAY_SERVICE_ID, nodeId);
-		RelayMessage relayMsg( RelayMessage::typeInform, remoteRelay, nodeid, LinkID::UNSPECIFIED );
-		relayMsg.encapsulate( message );
-		overlay_msg.encapsulate( &relayMsg );
-
-		// get local relay link
-		LinkDescriptor* rld = getRelayDescriptor(nodeid);
-
-		// local relay available? send to local relay!
-		if (rld!=NULL) {
-			rld->markAsRelay();
-			sendMessage(&overlay_msg, rld);
-		} else
-			overlayInterface->routeMessage(remoteRelay, &overlay_msg);
-
-		// finished
-		return 0;
-	}
-
-	// common case: send message over the overlay
-	overlayInterface->routeMessage(nodeid, message);
-	return 0;
-}
-
-/// forwards a message over relays/directly using link descriptor
-seqnum_t BaseOverlay::sendMessage( Message* message, const LinkDescriptor* ld ) {
-
-	// directly send message
-	if ( !ld->communicationId.isUnspecified() && ld->communicationUp ) {
-		logging_debug("Send: Sending message via Base Communication");
-		return bc->sendMessage( ld->communicationId, message );
-	}
-
-	// relay message
-	else if ( ld->relay ) {
-
-		// sending a relayed message
-		logging_debug("Send: Relaying message to node "
-			<< ld->remoteNode.toString()
-			<< " using relay " << ld->localRelay
-		);
-
-		// create a information relay message to inform the relay about
-		OverlayMsg overlay_msg( OverlayMsg::typeRelay, ld->service, nodeId );
-		RelayMessage relayMsg( RelayMessage::typeInform, ld->remoteRelay, ld->remoteNode, ld->remoteLinkId );
-		relayMsg.encapsulate( message );
-		overlay_msg.encapsulate( &relayMsg );
-
-		// route message to relay node in order to inform it!
-		logging_debug("sendMessage: Sending message over relayed link with" << ld );
-		sendOverlay( &overlay_msg, ld->localRelay );
-		return 0;
-	}
-
-	// error
-	else {
-		logging_error( "Could not send message descriptor=" << ld );
-		return -1;
-	}
-	return -1;
-}
-
-/// creates a link descriptor, apply relay semantics if possible
-LinkDescriptor* BaseOverlay::createLinkDescriptor(
-	const NodeID remoteNode, const ServiceID service, const LinkID link_id ) {
-
-	// find listener
-	if( !communicationListeners.contains( service ) ) {
-		logging_error( "No listener found for service " << service.toString() );
-		return NULL;
-	}
-	CommunicationListener* listener = communicationListeners.get( service );
-	assert( listener != NULL );
-
-	// copy link id
-	LinkID linkid = link_id;
-
-	// create link id if necessary
-	if ( linkid.isUnspecified() )
-		linkid = LinkID::create();
-
-	// create relay link descriptor
-	NodeID relayNode = getRelayNode(remoteNode);
-
-	// add descriptor
-	LinkDescriptor* ld = addDescriptor( linkid );
-	ld->overlayId  = linkid;
-	ld->service    = service;
-	ld->listener   = listener;
-	ld->remoteNode = remoteNode;
-
-	// set relay node if available
-	ld->relay      = !relayNode.isUnspecified();
-	ld->localRelay = relayNode;
-
-	if (!ld->relay)
-		logging_error("No relay found!");
-
-	// debug output
-	logging_debug( "Created link descriptor: " << ld );
-
-	return ld;
-}
-
-
-// ----------------------------------------------------------------------------
+/* *****************************************************************************
+ * PUBLIC MEMBERS
+ * ****************************************************************************/
 
 use_logging_cpp(BaseOverlay);
@@ -472,28 +638,21 @@
 // ----------------------------------------------------------------------------
 
-const LinkID BaseOverlay::establishLink(
-	const EndpointDescriptor& ep, const NodeID& nodeid,
-	const ServiceID& service, const NodeID& remoteRelay, const LinkID& linkid ) {
-
-	LinkID link_id = linkid;
+const LinkID BaseOverlay::establishLink( const EndpointDescriptor& remoteEp,
+	const NodeID& remoteId, const ServiceID& service ) {
 
 	// establish link via overlay
-	if (!nodeid.isUnspecified())
-		link_id = establishLink( nodeid, service, remoteRelay, link_id );
+	if (!remoteId.isUnspecified())
+		return establishLink( remoteId, service );
+	else
 
 	// establish link directly if only ep is known
-	if (nodeid.isUnspecified())
-		establishDirectLink( ep, service, link_id );
-
-	return link_id;
+	if (remoteId.isUnspecified())
+		return establishDirectLink(remoteEp, service );
+
 }
 
 /// call base communication's establish link and add link mapping
 const LinkID BaseOverlay::establishDirectLink( const EndpointDescriptor& ep,
-		const ServiceID& service, const LinkID& linkid ) {
-
-	// create a new link id if necessary
-	LinkID link_id = linkid;
-	if (link_id.isUnspecified()) link_id = LinkID::create();
+	const ServiceID& service ) {
 
 	/// find a service listener
@@ -505,51 +664,47 @@
 	assert( listener != NULL );
 
-	/// establish link and add mapping
-	logging_info("Establishing direct link " << link_id.toString()
-		<< " using " << ep.toString());
-
 	// create descriptor
-	LinkDescriptor* ld = addDescriptor( link_id );
-	ld->overlayId = link_id;
-	ld->communicationId = link_id;
+	LinkDescriptor* ld = addDescriptor();
+	ld->relayed = false;
 	ld->listener = listener;
 	ld->service = service;
-	bc->establishLink( ep, link_id );
-
-	return link_id;
+	ld->communicationId = bc->establishLink( ep );
+
+	/// establish link and add mapping
+	logging_info("Establishing direct link " << ld->communicationId.toString()
+		<< " using " << ep.toString());
+
+	return ld->communicationId;
 }
 
 /// establishes a link between two arbitrary nodes
-const LinkID BaseOverlay::establishLink( const NodeID& node,
-		const ServiceID& service, const NodeID& remoteRelay, const LinkID& link_id ) {
+const LinkID BaseOverlay::establishLink( const NodeID& remote,
+	const ServiceID& service ) {
 
 	// do not establish a link to myself!
-	if (node == nodeId) return LinkID::UNSPECIFIED;
+	if (remote == nodeId) return LinkID::UNSPECIFIED;
 
 	// create a link descriptor
-	LinkDescriptor* ld = createLinkDescriptor( node, service, link_id );
-	ld->remoteRelay = remoteRelay;
-
-	// create link request message with own link id
-	uint32_t nonce = (uint32_t)(rand() ^ (rand() << 16) ^ time(NULL));
-	LinkRequest link_request_msg(
-		nonce, &bc->getEndpointDescriptor(), false,
-		ld->overlayId, ld->localRelay );
-	OverlayMsg overlay_msg( OverlayMsg::typeLinkRequest, service, nodeId );
-	overlay_msg.encapsulate( &link_request_msg );
-	pendingLinks.insert( make_pair(nonce, ld->overlayId) );
+	LinkDescriptor* ld = addDescriptor();
+	ld->relayed = true;
+	ld->remoteNode = remote;
+	ld->service = service;
+	ld->listener = getListener(ld->service);
+
+	// create link request message
+	OverlayMsg msg(OverlayMsg::typeLinkRequest, service, nodeId, remote );
+	msg.setSourceLink(ld->overlayId);
+	msg.setRelayed(true);
 
 	// debug message
-	logging_debug(
+	logging_info(
 		"Sending link request with"
-		<< " link id="        << ld->overlayId
-		<< " node id="        << ld->remoteNode.toString()
-		<< " service id="     << ld->service.toString()
-		<< " local relay id=" << ld->localRelay.toString()
-		<< " nonce= "         << nonce
+		<< " link=" << ld->overlayId.toString()
+		<< " node=" << ld->remoteNode.toString()
+		<< " serv=" << ld->service.toString()
 	);
 
-	// sending message through new link
-	sendMessage( &overlay_msg, ld );
+	// sending message to node
+	send_node( &msg, ld->remoteNode, ld->service );
 
 	return ld->overlayId;
@@ -558,5 +713,5 @@
 /// drops an established link
 void BaseOverlay::dropLink(const LinkID& link) {
-	logging_debug( "Dropping link (initiated locally):" << link.toString() );
+	logging_info( "Dropping link (initiated locally):" << link.toString() );
 
 	// find the link item to drop
@@ -579,5 +734,5 @@
 
 	// do not drop relay links
-	if (!ld->usedAsRelay) {
+	if (!ld->relaying) {
 		// drop the link in base communication
 		if (ld->communicationUp) bc->dropLink( ld->communicationId );
@@ -586,5 +741,5 @@
 		eraseDescriptor( ld->overlayId );
 	} else
-		ld->dropWhenRelaysLeft = true;
+		ld->dropAfterRelaying = true;
 }
 
@@ -605,5 +760,5 @@
 	// check if the link is up yet, if its an auto link queue message
 	if( !ld->up ) {
-		ld->markAsUsed();
+		ld->setAutoUsed();
 		if( ld->autolink ) {
 			logging_info("Auto-link " << link.toString() << " not up, queue message");
@@ -618,9 +773,9 @@
 
 	// compile overlay message (has service and node id)
-	OverlayMsg overmsg( OverlayMsg::typeData, ld->service, nodeId );
+	OverlayMsg overmsg( OverlayMsg::typeData );
 	overmsg.encapsulate( const_cast<Message*>(message) );
 
 	// send message over relay/direct/overlay
-	return sendMessage( &overmsg, ld );
+	return send_link( &overmsg, ld->overlayId );
 }
 
@@ -640,9 +795,6 @@
 		);
 
-		// this will call onlinkup on us, if everything worked we now have a mapping
-		LinkID link = LinkID::create();
-
 		// call base overlay to create a link
-		link = establishLink( node, service, NodeID::UNSPECIFIED, link );
+		LinkID link = establishLink( node, service );
 		ld = getDescriptor( link );
 		if( ld == NULL ) {
@@ -658,5 +810,5 @@
 
 	// mark the link as used, as we now send a message through it
-	ld->markAsUsed();
+	ld->setAutoUsed();
 
 	// send / queue message
@@ -794,5 +946,6 @@
 
 		// send join request message
-		OverlayMsg overlayMsg( OverlayMsg::typeJoinRequest, nodeId );
+		OverlayMsg overlayMsg( OverlayMsg::typeJoinRequest,
+			OverlayInterface::OVERLAY_SERVICE_ID, nodeId );
 		JoinRequest joinRequest( spovnetId, nodeId );
 		overlayMsg.encapsulate( &joinRequest );
@@ -804,5 +957,5 @@
 	if (ld == NULL) {
 		ld = addDescriptor( id );
-		logging_debug( "onLinkUp (remote request) descriptor: " << ld );
+		logging_info( "onLinkUp (remote request) descriptor: " << ld );
 
 		// update descriptor
@@ -810,5 +963,6 @@
 		ld->communicationId = id;
 		ld->communicationUp = true;
-		ld->markAsUsed();
+		ld->setAutoUsed();
+		ld->setAlive();
 
 		// in this case, do not inform listener, since service it unknown
@@ -817,31 +971,34 @@
 	// link mapping found? -> send update message with node-id and service id
 	} else {
-		logging_debug( "onLinkUp descriptor (initiated locally):" << ld );
-
-		// note: necessary to validate the link on the remote side!
-		logging_debug( "Sending out update" <<
-			" for service " << ld->service.toString() <<
-			" with local node id " << nodeId.toString() <<
-			" on link " << ld->overlayId.toString() );
+		logging_info( "onLinkUp descriptor (initiated locally):" << ld );
 
 		// update descriptor
-		ld->markAsUsed();
+		ld->setAutoUsed();
+		ld->setAlive();
 		ld->communicationUp = true;
-
-		// if link is a relayed link ->convert to direct link
-		if (ld->relay && !ld->remoteLinkId.isUnspecified() ) {
+		ld->fromRemote = false;
+
+		// if link is a relayed link->convert to direct link
+		if (ld->relayed) {
 			logging_info( "Converting to direct link: " << ld );
 			ld->up = true;
-			ld->relay = false;
-			ld->localRelay = NodeID::UNSPECIFIED;
-			OverlayMsg overMsg( OverlayMsg::typeDirectLink, ld->service, nodeId );
-			overMsg.setRelayLink( ld->remoteLinkId );
-			bc->sendMessage( ld->communicationId, &overMsg );
-		}
-
-		// compile and send update message
-		OverlayMsg overlayMsg( OverlayMsg::typeUpdate, ld->service, nodeId );
-		overlayMsg.setAutoLink( ld->autolink );
-		bc->sendMessage( ld->communicationId, &overlayMsg );
+			ld->relayed = false;
+			OverlayMsg overMsg( OverlayMsg::typeLinkDirect );
+			overMsg.setSourceLink( ld->overlayId );
+			overMsg.setDestinationLink( ld->remoteLink );
+			send_link( &overMsg, ld->overlayId );
+		} else {
+			// note: necessary to validate the link on the remote side!
+			logging_info( "Sending out update" <<
+				" for service " << ld->service.toString() <<
+				" with local node id " << nodeId.toString() <<
+				" on link " << ld->overlayId.toString() );
+
+			// compile and send update message
+			OverlayMsg overlayMsg( OverlayMsg::typeLinkUpdate );
+			overlayMsg.setSourceLink(ld->overlayId);
+			overlayMsg.setAutoLink( ld->autolink );
+			send_link( &overlayMsg, ld->overlayId, true );
+		}
 	}
 }
@@ -859,8 +1016,13 @@
 	logging_info( "onLinkDown descriptor: " << ld );
 
+	// removing relay link information
+	removeRelayLink(ld->overlayId);
+
 	// inform listeners about link down
 	ld->communicationUp = false;
-	ld->listener->onLinkDown( ld->overlayId, ld->remoteNode );
-	sideport->onLinkDown( id, this->nodeId, ld->remoteNode, this->spovnetId );
+	if (!ld->service.isUnspecified()) {
+		getListener(ld->service)->onLinkDown( ld->overlayId, ld->remoteNode );
+		sideport->onLinkDown( id, this->nodeId, ld->remoteNode, this->spovnetId );
+	}
 
 	// delete all queued messages (auto links)
@@ -889,5 +1051,5 @@
 
 	// autolinks: refresh timestamp
-	ld->markAsUsed();
+	ld->setAutoUsed();
 }
 
@@ -908,7 +1070,4 @@
 	ld->listener->onLinkFail( ld->overlayId, ld->remoteNode );
 	sideport->onLinkFail( id, this->nodeId, ld->remoteNode, this->spovnetId );
-
-	// autolinks: refresh timestamp
-	ld->markAsUsed();
 }
 
@@ -921,7 +1080,4 @@
 	if ( ld == NULL ) return; // not found? ->ignore!
 	logging_debug( "Link quality changed id=" << ld->overlayId.toString() );
-
-	// autolinks: refresh timestamp
-	ld->markAsUsed();
 }
 
@@ -937,192 +1093,184 @@
 	// get descriptor for link
 	LinkDescriptor* ld = getDescriptor( link, true );
-
-	// link known?
-	if (ld == NULL) { // no-> handle with unspecified params
-		logging_debug("Received message from base communication, link descriptor unknown" );
-		return handleMessage( message, LinkID::UNSPECIFIED, link, NodeID::UNSPECIFIED );
-	} else { // yes -> handle with overlay link id
-		logging_debug("Received message from base communication, link id=" << ld->overlayId.toString() );
-		return handleMessage( message, ld->overlayId, link, NodeID::UNSPECIFIED );
-	}
+	return handleMessage( message, ld, link );
 }
 
 // ----------------------------------------------------------------------------
 
-/// handles a message from an overlay
-void BaseOverlay::incomingRouteMessage( Message* msg, const LinkID& link, const NodeID& source ) {
-	logging_debug("Received message from overlay -- "
-		<< " link id=" << link.toString()
-		<< " node id=" << source.toString() );
-	handleMessage( msg, link, LinkID::UNSPECIFIED, source );
-}
-
-// ----------------------------------------------------------------------------
-
-/// handles an incoming message
-bool BaseOverlay::handleMessage( const Message* message,
-	const LinkID& boLink, const LinkID& bcLink, const NodeID& remoteNode ) {
-	logging_debug( "Handling message: " << message->toString());
-
-	bool ret = false;
-
-	// decapsulate overlay message
-	OverlayMsg* overlayMsg =
-		const_cast<Message*>(message)->decapsulate<OverlayMsg>();
-	if( overlayMsg == NULL ) return false;
-
-	// mark the link as in action
-	LinkDescriptor* ld = getDescriptor(boLink);
-	if (ld == NULL) ld = getDescriptor(bcLink, true);
-	if (ld != NULL) {
-		ld->markAsUsed();
-		ld->markAlive();
-	}
-
-	switch ( overlayMsg->getType() ) {
-		// ---------------------------------------------------------------------
-		// Handle spovnet instance join requests
-		// ---------------------------------------------------------------------
-		case OverlayMsg::typeJoinRequest: {
-
-			// decapsulate message
-			JoinRequest* joinReq = overlayMsg->decapsulate<JoinRequest>();
-			logging_info( "Received join request for spovnet " <<
-					joinReq->getSpoVNetID().toString() );
-
-			// check spovnet id
-			if( joinReq->getSpoVNetID() != spovnetId ) {
-				logging_error(
-					"Received join request for spovnet we don't handle " <<
-					joinReq->getSpoVNetID().toString() );
-				ret = false;
-				break;
+/// Handle spovnet instance join requests
+bool BaseOverlay::handleJoinRequest( OverlayMsg* overlayMsg, const LinkID& bcLink ) {
+
+	// decapsulate message
+	JoinRequest* joinReq = overlayMsg->decapsulate<JoinRequest>();
+	logging_info( "Received join request for spovnet " <<
+			joinReq->getSpoVNetID().toString() );
+
+	// check spovnet id
+	if( joinReq->getSpoVNetID() != spovnetId ) {
+		logging_error(
+			"Received join request for spovnet we don't handle " <<
+			joinReq->getSpoVNetID().toString() );
+		return false;
+	}
+
+	// TODO: here you can implement mechanisms to deny joining of a node
+	bool allow = true;
+	logging_info( "Sending join reply for spovnet " <<
+			spovnetId.toString() << " to node " <<
+			overlayMsg->getSourceNode().toString() <<
+			". Result: " << (allow ? "allowed" : "denied") );
+	joiningNodes.push_back( overlayMsg->getSourceNode() );
+
+	// return overlay parameters
+	assert( overlayInterface != NULL );
+	logging_debug( "Using bootstrap end-point "
+		<< getEndpointDescriptor().toString() )
+	OverlayParameterSet parameters = overlayInterface->getParameters();
+	OverlayMsg retmsg( OverlayMsg::typeJoinReply,
+		OverlayInterface::OVERLAY_SERVICE_ID, nodeId );
+	JoinReply replyMsg( spovnetId, parameters,
+			allow, getEndpointDescriptor() );
+	retmsg.encapsulate(&replyMsg);
+	bc->sendMessage( bcLink, &retmsg );
+
+	return true;
+}
+
+/// Handle replies to spovnet instance join requests
+bool BaseOverlay::handleJoinReply( OverlayMsg* overlayMsg, const LinkID& bcLink ) {
+	// decapsulate message
+	logging_debug("received join reply message");
+	JoinReply* replyMsg = overlayMsg->decapsulate<JoinReply>();
+
+	// correct spovnet?
+	if( replyMsg->getSpoVNetID() != spovnetId ) { // no-> fail
+		logging_error( "Received SpoVNet join reply for " <<
+				replyMsg->getSpoVNetID().toString() <<
+				" != " << spovnetId.toString() );
+		delete replyMsg;
+		return false;
+	}
+
+	// access granted? no -> fail
+	if( !replyMsg->getJoinAllowed() ) {
+		logging_error( "Our join request has been denied" );
+
+		// drop initiator link
+		if( !bcLink.isUnspecified() ){
+			bc->dropLink( bcLink );
+
+			vector<LinkID>::iterator it = std::find(
+					bootstrapLinks.begin(), bootstrapLinks.end(), bcLink);
+			if( it != bootstrapLinks.end() )
+				bootstrapLinks.erase(it);
+		}
+
+		// inform all registered services of the event
+		BOOST_FOREACH( NodeListener* i, nodeListeners )
+			i->onJoinFailed( spovnetId );
+
+		delete replyMsg;
+		return true;
+	}
+
+	// access has been granted -> continue!
+	logging_info("Join request has been accepted for spovnet " <<
+			spovnetId.toString() );
+
+	logging_debug( "Using bootstrap end-point "
+		<< replyMsg->getBootstrapEndpoint().toString() );
+
+	// create overlay structure from spovnet parameter set
+	// if we have not boostrapped yet against some other node
+	if( overlayInterface == NULL ){
+
+		logging_debug("first-time bootstrapping");
+
+		overlayInterface = OverlayFactory::create(
+			*this, replyMsg->getParam(), nodeId, this );
+
+		// overlay structure supported? no-> fail!
+		if( overlayInterface == NULL ) {
+			logging_error( "overlay structure not supported" );
+
+			if( !bcLink.isUnspecified() ){
+				bc->dropLink( bcLink );
+
+				vector<LinkID>::iterator it = std::find(
+						bootstrapLinks.begin(), bootstrapLinks.end(), bcLink);
+				if( it != bootstrapLinks.end() )
+					bootstrapLinks.erase(it);
 			}
 
-			// TODO: here you can implement mechanisms to deny joining of a node
-			bool allow = true;
-			logging_info( "Sending join reply for spovnet " <<
-					spovnetId.toString() << " to node " <<
-					overlayMsg->getSourceNode().toString() <<
-					". Result: " << (allow ? "allowed" : "denied") );
-			joiningNodes.push_back( overlayMsg->getSourceNode() );
-
-			// return overlay parameters
-			assert( overlayInterface != NULL );
-			logging_debug( "Using bootstrap end-point "
-				<< getEndpointDescriptor().toString() )
-			OverlayParameterSet parameters = overlayInterface->getParameters();
-			OverlayMsg retmsg( OverlayMsg::typeJoinReply, nodeId );
-			JoinReply replyMsg( spovnetId, parameters,
-					allow, getEndpointDescriptor() );
-			retmsg.encapsulate(&replyMsg);
-			bc->sendMessage( bcLink, &retmsg );
-			ret = true;
-			break;
-		}
-
-		// ---------------------------------------------------------------------
-		// handle replies to spovnet instance join requests
-		// ---------------------------------------------------------------------
-		case OverlayMsg::typeJoinReply: {
-
-			// decapsulate message
-			logging_debug("received join reply message");
-			JoinReply* replyMsg = overlayMsg->decapsulate<JoinReply>();
-
-			// correct spovnet?
-			if( replyMsg->getSpoVNetID() != spovnetId ) { // no-> fail
-				logging_error( "Received SpoVNet join reply for " <<
-						replyMsg->getSpoVNetID().toString() <<
-						" != " << spovnetId.toString() );
-				ret = false;
-				delete replyMsg;
-				break;
-			}
-
-			// access granted? no -> fail
-			if( !replyMsg->getJoinAllowed() ) {
-				logging_error( "Our join request has been denied" );
-
-				// drop initiator link
-				if(bcLink != LinkID::UNSPECIFIED){
-					bc->dropLink( bcLink );
-
-					vector<LinkID>::iterator it = std::find(
-							bootstrapLinks.begin(), bootstrapLinks.end(), bcLink);
-					if( it != bootstrapLinks.end() )
-						bootstrapLinks.erase(it);
-				}
-
-				// inform all registered services of the event
-				BOOST_FOREACH( NodeListener* i, nodeListeners )
-					i->onJoinFailed( spovnetId );
-
-				ret = true;
-				delete replyMsg;
-				break;
-			}
-
-			// access has been granted -> continue!
-			logging_info("Join request has been accepted for spovnet " <<
-					spovnetId.toString() );
-
-			logging_debug( "Using bootstrap end-point "
-				<< replyMsg->getBootstrapEndpoint().toString() );
-
-			//
-			// create overlay structure from spovnet parameter set
-			// if we have not boostrapped yet against some other node
-			//
-
-			if( overlayInterface == NULL ){
-
-				logging_debug("first-time bootstrapping");
-
-				overlayInterface = OverlayFactory::create(
-					*this, replyMsg->getParam(), nodeId, this );
-
-				// overlay structure supported? no-> fail!
-				if( overlayInterface == NULL ) {
-					logging_error( "overlay structure not supported" );
-
-					if(bcLink != LinkID::UNSPECIFIED){
-						bc->dropLink( bcLink );
-
-						vector<LinkID>::iterator it = std::find(
-								bootstrapLinks.begin(), bootstrapLinks.end(), bcLink);
-						if( it != bootstrapLinks.end() )
-							bootstrapLinks.erase(it);
-					}
-
+			// inform all registered services of the event
+			BOOST_FOREACH( NodeListener* i, nodeListeners )
+			i->onJoinFailed( spovnetId );
+
+			delete replyMsg;
+			return true;
+		}
+
+		// everything ok-> join the overlay!
+		state = BaseOverlayStateCompleted;
+		overlayInterface->createOverlay();
+
+		overlayInterface->joinOverlay( replyMsg->getBootstrapEndpoint() );
+		overlayBootstrap.recordJoin( replyMsg->getBootstrapEndpoint() );
+
+		// update ovlvis
+		//ovl.visChangeNodeColor( ovlId, nodeId, OvlVis::NODE_COLORS_GREEN);
+
+		// inform all registered services of the event
+		BOOST_FOREACH( NodeListener* i, nodeListeners )
+			i->onJoinCompleted( spovnetId );
+
+		delete replyMsg;
+
+<<<<<<< .working
 					// inform all registered services of the event
 					BOOST_FOREACH( NodeListener* i, nodeListeners )
 						i->onJoinFailed( spovnetId );
-
-					delete replyMsg;
-					ret = true;
-					break;
-				}
-
-				// everything ok-> join the overlay!
-				state = BaseOverlayStateCompleted;
-				overlayInterface->createOverlay();
-				overlayInterface->joinOverlay( replyMsg->getBootstrapEndpoint() );
-
-				// update ovlvis
-				//ovl.visChangeNodeColor( ovlId, nodeId, OvlVis::NODE_COLORS_GREEN);
-
-				// inform all registered services of the event
-				BOOST_FOREACH( NodeListener* i, nodeListeners )
-					i->onJoinCompleted( spovnetId );
-
-			} else {
-
-				// this is not the first bootstrap, just join the additional node
-				logging_debug("not first-time bootstrapping");
-				overlayInterface->joinOverlay( replyMsg->getBootstrapEndpoint() );
-
-			} // if( overlayInterface == NULL )
-
+=======
+	} else {
+>>>>>>> .merge-rechts.r5869
+
+		// this is not the first bootstrap, just join the additional node
+		logging_debug("not first-time bootstrapping");
+		overlayInterface->joinOverlay( replyMsg->getBootstrapEndpoint() );
+		overlayBootstrap.recordJoin( replyMsg->getBootstrapEndpoint() );
+
+		delete replyMsg;
+	} // if( overlayInterface == NULL )
+
+	return true;
+}
+
+
+<<<<<<< .working
+=======
+bool BaseOverlay::handleData( OverlayMsg* overlayMsg, LinkDescriptor* ld ) {
+	// get service
+	const ServiceID& service = overlayMsg->getService();
+	logging_debug( "Received data for service " << service.toString()
+		<< " on link " << overlayMsg->getDestinationLink().toString() );
+
+>>>>>>> .merge-rechts.r5869
+	// delegate data message
+	getListener(service)->onMessage(
+		overlayMsg,
+		overlayMsg->getSourceNode(),
+		overlayMsg->getDestinationLink()
+	);
+
+	return true;
+}
+
+<<<<<<< .working
+=======
+
+>>>>>>> .merge-rechts.r5869
+bool BaseOverlay::handleLinkUpdate( OverlayMsg* overlayMsg, LinkDescriptor* ld ) {
+
+<<<<<<< .working
 			//record bootstrap ep as good endpoint to join
 			overlayBootstrap.recordJoin( replyMsg->getBootstrapEndpoint() );
@@ -1132,272 +1280,230 @@
 			break;
 		}
-
-		// ---------------------------------------------------------------------
-		// handle data forward messages
-		// ---------------------------------------------------------------------
-		case OverlayMsg::typeData: {
-
-			// get service
-			const ServiceID& service = overlayMsg->getService();
-			logging_debug( "received data for service " << service.toString() );
-
-			// find listener
-			CommunicationListener* listener =
-				communicationListeners.get( service );
-			if( listener == NULL ) {
-				ret = true;
-				break;
-			}
-
+=======
+	if( ld == NULL ) {
+		logging_warn( "received overlay update message for link for "
+				<< "which we have no mapping" );
+		return false;
+	}
+	logging_info("Received type update message on link " << ld );
+>>>>>>> .merge-rechts.r5869
+
+	// update our link mapping information for this link
+	bool changed =
+		( ld->remoteNode != overlayMsg->getSourceNode() )
+		|| ( ld->service != overlayMsg->getService() );
+
+	// set parameters
+	ld->up         = true;
+	ld->remoteNode = overlayMsg->getSourceNode();
+	ld->remoteLink = overlayMsg->getSourceLink();
+	ld->service    = overlayMsg->getService();
+	ld->autolink   = overlayMsg->isAutoLink();
+
+	// if our link information changed, we send out an update, too
+	if( changed ) {
+		overlayMsg->swapRoles();
+		overlayMsg->setSourceNode(nodeId);
+		overlayMsg->setSourceLink(ld->overlayId);
+		overlayMsg->setService(ld->service);
+		send( overlayMsg, ld );
+	}
+
+<<<<<<< .working
 			// delegate data message
 			listener->onMessage( overlayMsg,
 				overlayMsg->getSourceNode(), ld->overlayId );
-
-			ret = true;
-			break;
-		}
-
-		// ---------------------------------------------------------------------
-		// handle update messages for link establishment
-		// ---------------------------------------------------------------------
-		case OverlayMsg::typeUpdate: {
-			// get info
-			const NodeID& sourcenode = overlayMsg->getSourceNode();
-			const ServiceID& service = overlayMsg->getService();
-
-			// no link descriptor available -> error!
-			if( ld == NULL ) {
-				logging_warn( "received overlay update message for link for "
-						<< "which we have no mapping" );
-				ret = false;
-				break;
-			}
-			logging_debug("Received type update message on link " << ld );
-
-			// update our link mapping information for this link
-			bool changed =
-				( ld->remoteNode != sourcenode ) || ( ld->service != service );
-			ld->remoteNode = sourcenode;
-			ld->service = service;
-			ld->autolink = overlayMsg->isAutoLink();
-
-			// if our link information changed, we send out an update, too
-			if( changed ) {
-				OverlayMsg overMsg( OverlayMsg::typeUpdate, ld->service, nodeId );
-				overMsg.setAutoLink(ld->autolink);
-				bc->sendMessage( ld->communicationId, &overMsg );
-			}
-
-			// service registered? no-> error!
-			if( !communicationListeners.contains( service ) ) {
-				logging_warn( "Link up: event listener has not been registered" );
-				ret = false;
-				break;
-			}
-
-			// default or no service registered?
-			CommunicationListener* listener = communicationListeners.get( service );
-			if( listener == NULL || listener == &CommunicationListener::DEFAULT ) {
-				logging_warn("Link up: event listener is default or null!" );
-				ret = true;
-				break;
-			}
-
-			// update descriptor
-			ld->listener = listener;
-			ld->markAsUsed();
-			ld->markAlive();
-
-			// ask the service whether it wants to accept this link
-			if( !listener->onLinkRequest(sourcenode) ) {
-
-				logging_debug("Link id=" << ld->overlayId.toString() <<
-					" has been denied by service " << service.toString() << ", dropping link");
-
-				// prevent onLinkDown calls to the service
-				ld->listener = &CommunicationListener::DEFAULT;
-
-				// drop the link
-				dropLink( ld->overlayId );
-				ret = true;
-				break;
-			}
-
-			// set link up
-			ld->up = true;
-			logging_debug(
-				   "Link " << ld->overlayId.toString()
-				<< " has been accepted by service " << service.toString()
-				<< " and is now up"
-			);
-
-			// auto links: link has been accepted -> send queued messages
-			if( ld->messageQueue.size() > 0 ) {
-				logging_info( "sending out queued messages on link " <<
-					ld->overlayId.toString() );
-				BOOST_FOREACH( Message* msg, ld->messageQueue ) {
-					sendMessage( msg, ld->overlayId );
-					delete msg;
-				}
-				ld->messageQueue.clear();
-			}
-
-			// call the notification functions
-			listener->onLinkUp( ld->overlayId, sourcenode );
-			sideport->onLinkUp( ld->overlayId, nodeId, sourcenode, this->spovnetId );
-
-			ret = true;
-			break;
-		}
-
-		// ---------------------------------------------------------------------
-		// handle link request forwarded through the overlay
-		// ---------------------------------------------------------------------
-		case OverlayMsg::typeLinkRequest: {
-
-			logging_debug( "received link request on link" );
-
-			// decapsulate message
-			LinkRequest* linkReq = overlayMsg->decapsulate<LinkRequest>();
-			const ServiceID& service = overlayMsg->getService();
-
-			// is request reply?
-			if ( linkReq->isReply() ) {
-
-				// find link
-				PendingLinkMap::iterator i = pendingLinks.find( linkReq->getNonce() );
-				if ( i == pendingLinks.end() ) {
-					logging_error( "Nonce not found in link request" );
-					ret = true;
-					break;
-				}
-
-				// debug message
-				logging_debug( "Link request reply received. Establishing link "
-					<< i->second << " to " << (linkReq->getEndpoint()->toString())
-					<< " for service " << service.toString()
-					<< " with nonce "  << linkReq->getNonce()
-					<< " using relay " << linkReq->getRelay().toString()
-					<< " and remote link id=" << linkReq->getRemoteLinkId()
-				);
-
-				// get descriptor
-				LinkDescriptor* ldn = getDescriptor(i->second);
-				if (ldn==NULL) {
-					delete linkReq;
-					ret = true;
-					break;
-				}
-
-				// check if link request reply has a relay node ...
-				if (!linkReq->getRelay().isUnspecified()) { // yes->
-					ldn->up = true;
-					ldn->relay = true;
-					if (ldn->localRelay.isUnspecified())  {
-						logging_error("On LinkRequest reply: local relay is unspecifed on link " << ldn );
-						showLinkState();
-					}
-					ldn->remoteRelay  = linkReq->getRelay();
-					ldn->remoteLinkId = linkReq->getRemoteLinkId();
-					ldn->remoteNode   = overlayMsg->getSourceNode();
-
-					ldn->markAlive();
-
-					// compile and send update message
-					OverlayMsg _overlayMsg( OverlayMsg::typeUpdate, ldn->service, nodeId );
-					_overlayMsg.setAutoLink(ldn->autolink);
-					sendMessage( &_overlayMsg, ldn );
-
-					// auto links: link has been accepted -> send queued messages
-					if( ldn->messageQueue.size() > 0 ) {
-						logging_info( "Sending out queued messages on link " <<
-							ldn->overlayId.toString() );
-						BOOST_FOREACH( Message* msg, ldn->messageQueue ) {
-							sendMessage( msg, ldn->overlayId );
-							delete msg;
-						}
-						ldn->messageQueue.clear();
-					}
-
-					ldn->listener->onLinkUp( ldn->overlayId, ldn->remoteNode );
-
-					// try to establish a direct link
-					ldn->communicationId =
-						bc->establishLink( *linkReq->getEndpoint(), i->second );
-				}
-
-				// no relay node-> use overlay routing
-				else {
-					ldn->up = true;
-
-					// establish direct link
-					ldn->communicationId =
-							bc->establishLink( *linkReq->getEndpoint(), i->second );
-				}
-			} else {
-				logging_debug( "Link request received from node id="
-						<< overlayMsg->getSourceNode() );
-
-				// create link descriptor
-				LinkDescriptor* ldn =
-					createLinkDescriptor(overlayMsg->getSourceNode(),
-							overlayMsg->getService(), LinkID::UNSPECIFIED );
-				assert(!ldn->overlayId.isUnspecified());
-
-				// create reply message
-				OverlayMsg overlay_msg( OverlayMsg::typeLinkRequest, service, nodeId );
-				LinkRequest link_request_msg(
-					linkReq->getNonce(),
-					&bc->getEndpointDescriptor(),
-					true, ldn->overlayId, ldn->localRelay
-				);
-				overlay_msg.encapsulate( &link_request_msg );
-
-				// debug message
-				logging_debug( "Sending LinkRequest reply for link with nonce " <<
-						linkReq->getNonce() );
-
-				// if this is a relay link-> update information & inform listeners
-				if (!linkReq->getRelay().isUnspecified()) {
-					// set flags
-					ldn->up = true;
-					ldn->relay = true;
-					if (ldn->localRelay.isUnspecified()) {
-						logging_error("On LinkRequest request: local relay is unspecifed on link " << ldn );
-						showLinkState();
-					}
-					ldn->remoteRelay  = linkReq->getRelay();
-					ldn->remoteNode   = overlayMsg->getSourceNode();
-					ldn->remoteLinkId = linkReq->getRemoteLinkId();
-					ldn->listener->onLinkUp( ldn->overlayId, ldn->remoteNode );
-				}
-
-				// route message back over overlay
-				sendMessage( &overlay_msg, ldn );
-			}
-			delete linkReq;
-			ret = true;
-			break;
-		}
-
-		// ---------------------------------------------------------------------
-		// handle relay message to forward messages
-		// ---------------------------------------------------------------------
-		case OverlayMsg::typeRelay: {
-
-			logging_debug( "received relay request on link" );
-
-			// decapsulate message
-			RelayMessage* relayMsg = overlayMsg->decapsulate<RelayMessage>();
-
-			// is relay message informative?
-			switch (relayMsg->getType()) {
-
-				// handle relay notification
-				case RelayMessage::typeInform: {
-					logging_info("Received relay information message with"
-							<< " relay " << relayMsg->getRelayNode()
-							<< " destination " << relayMsg->getDestNode() );
-
+=======
+	// service registered? no-> error!
+	if( !communicationListeners.contains( ld->service ) ) {
+		logging_warn( "Link up: event listener has not been registered" );
+		return false;
+	}
+>>>>>>> .merge-rechts.r5869
+
+	// default or no service registered?
+	CommunicationListener* listener = communicationListeners.get( ld->service );
+	if( listener == NULL || listener == &CommunicationListener::DEFAULT ) {
+		logging_warn("Link up: event listener is default or null!" );
+		return true;
+	}
+
+	// update descriptor
+	ld->listener = listener;
+	ld->setAutoUsed();
+	ld->setAlive();
+
+	// ask the service whether it wants to accept this link
+	if( !listener->onLinkRequest(ld->remoteNode) ) {
+
+		logging_debug("Link id=" << ld->overlayId.toString() <<
+			" has been denied by service " << ld->service.toString() << ", dropping link");
+
+		// prevent onLinkDown calls to the service
+		ld->listener = &CommunicationListener::DEFAULT;
+
+		// drop the link
+		dropLink( ld->overlayId );
+		return true;
+	}
+
+	// set link up
+	ld->up = true;
+	logging_info( "Link has been accepted by service and is up: " << ld );
+
+	// auto links: link has been accepted -> send queued messages
+	if( ld->messageQueue.size() > 0 ) {
+		logging_info( "Sending out queued messages on link " << ld );
+		BOOST_FOREACH( Message* msg, ld->messageQueue ) {
+			sendMessage( msg, ld->overlayId );
+			delete msg;
+		}
+		ld->messageQueue.clear();
+	}
+
+	// call the notification functions
+	listener->onLinkUp( ld->overlayId, ld->remoteNode );
+	sideport->onLinkUp( ld->overlayId, nodeId, ld->remoteNode, this->spovnetId );
+
+	return true;
+}
+
+/// handle a link request and reply
+bool BaseOverlay::handleLinkRequest( OverlayMsg* overlayMsg, LinkDescriptor* ld ) {
+	logging_info( "Link request received from node id=" << overlayMsg->getSourceNode() );
+
+	//TODO: Check if a request has already been sent using getSourceLink() ...
+
+	// create link descriptor
+	LinkDescriptor* ldn = addDescriptor();
+
+	// flags
+	ldn->up = true;
+	ldn->fromRemote = true;
+	ldn->relayed = true;
+
+	// parameters
+	ldn->service = overlayMsg->getService();
+	ldn->listener = getListener(ldn->service);
+	ldn->remoteNode = overlayMsg->getSourceNode();
+	ldn->remoteLink = overlayMsg->getSourceLink();
+
+	// update time-stamps
+	ldn->setAlive();
+	ldn->setAutoUsed();
+
+	// create reply message and send back!
+	overlayMsg->swapRoles(); // swap source/destination
+	overlayMsg->setType(OverlayMsg::typeLinkReply);
+	overlayMsg->setSourceLink(ldn->overlayId);
+	overlayMsg->setSourceEndpoint( bc->getEndpointDescriptor() );
+	overlayMsg->setRelayed(true);
+	send( overlayMsg, ld ); // send back to link
+
+	// inform listener
+	ldn->listener->onLinkUp( ldn->overlayId, ldn->remoteNode );
+
+	return true;
+}
+
+bool BaseOverlay::handleLinkReply( OverlayMsg* overlayMsg, LinkDescriptor* ld ) {
+
+	// find link request
+	LinkDescriptor* ldn = getDescriptor(overlayMsg->getDestinationLink());
+
+	// not found? yes-> drop with error!
+	if (ldn == NULL) {
+		logging_error( "No link request pending for "
+			<< overlayMsg->getDestinationLink().toString() );
+		return false;
+	}
+	logging_debug("Handling link reply for " << ldn )
+
+	// check if already up
+	if (ldn->up) {
+		logging_warn( "Link already up: " << ldn );
+		return true;
+	}
+
+	// debug message
+	logging_debug( "Link request reply received. Establishing link"
+		<< " for service " << overlayMsg->getService().toString()
+		<< " with local id=" << overlayMsg->getDestinationLink()
+		<< " and remote link id=" << overlayMsg->getSourceLink()
+		<< " to " << overlayMsg->getSourceEndpoint().toString()
+	);
+
+	// set local link descriptor data
+	ldn->up = true;
+	ldn->relayed = true;
+	ldn->service = overlayMsg->getService();
+	ldn->listener = getListener(ldn->service);
+	ldn->remoteLink = overlayMsg->getSourceLink();
+	ldn->remoteNode = overlayMsg->getSourceNode();
+
+	// update timestamps
+	ldn->setAlive();
+	ldn->setAutoUsed();
+
+	// auto links: link has been accepted -> send queued messages
+	if( ldn->messageQueue.size() > 0 ) {
+		logging_info( "Sending out queued messages on link " <<
+			ldn->overlayId.toString() );
+		BOOST_FOREACH( Message* msg, ldn->messageQueue ) {
+			sendMessage( msg, ldn->overlayId );
+			delete msg;
+		}
+		ldn->messageQueue.clear();
+	}
+
+	// inform listeners about new link
+	ldn->listener->onLinkUp( ldn->overlayId, ldn->remoteNode );
+
+	// try to replace relay link with direct link
+	ldn->communicationId =
+		bc->establishLink( overlayMsg->getSourceEndpoint() );
+
+	return true;
+}
+
+<<<<<<< .working
+=======
+/// handle a keep-alive message for a link
+bool BaseOverlay::handleLinkAlive( OverlayMsg* overlayMsg, LinkDescriptor* ld ) {
+	LinkDescriptor* rld = getDescriptor(overlayMsg->getDestinationLink());
+	if ( rld != NULL ) {
+		logging_debug("Keep-Alive for " <<
+			overlayMsg->getDestinationLink() );
+		if (overlayMsg->isRouteRecord())
+			rld->routeRecord = overlayMsg->getRouteRecord();
+		rld->setAlive();
+		return true;
+	} else {
+		logging_error("Keep-Alive for "
+				<< overlayMsg->getDestinationLink() << ": link unknown." );
+		return false;
+	}
+}
+
+/// handle a direct link message
+bool BaseOverlay::handleLinkDirect( OverlayMsg* overlayMsg, LinkDescriptor* ld ) {
+	logging_debug( "Received direct link replacement request" );
+
+>>>>>>> .merge-rechts.r5869
+	/// get destination overlay link
+	LinkDescriptor* rld = getDescriptor( overlayMsg->getDestinationLink() );
+	if (rld == NULL || ld == NULL) {
+		logging_error("Direct link replacement: Link "
+				<< overlayMsg->getDestinationLink() << "not found error." );
+		return false;
+	}
+	logging_info( "Received direct link convert notification for " << rld );
+
+	// update information
+	rld->communicationId = ld->communicationId;
+	rld->communicationUp = true;
+	rld->relayed = false;
+
+<<<<<<< .working
 					// mark incoming link as relay
 					if (ld!=NULL) ld->markAsRelay();
@@ -1417,23 +1523,20 @@
 					_relayMsg.setType( RelayMessage::typeRoute );
 					_overMsg.encapsulate( &_relayMsg );
-
-					// forward message
-					if (relayMsg->getRelayNode() == nodeId || relayMsg->getRelayNode().isUnspecified()) {
-						logging_info("Routing relay message to " << relayMsg->getDestNode().toString() );
-						sendOverlay( &_overMsg, relayMsg->getDestNode() );
-					} else {
-						logging_info("Routing relay message to " << relayMsg->getRelayNode().toString() );
-						sendOverlay( &_overMsg, relayMsg->getRelayNode() );
-					}
-					ret = true;
-					break;
-				}
-
-				// handle relay routing
-				case RelayMessage::typeRoute: {
-					logging_info("Received relay route message with"
-							<< " relay " << relayMsg->getRelayNode()
-							<< " destination " << relayMsg->getDestNode() );
-
+=======
+	// mark used and alive!
+	rld->setAlive();
+	rld->setAutoUsed();
+>>>>>>> .merge-rechts.r5869
+
+	// erase the original descriptor
+	eraseDescriptor(ld->overlayId);
+}
+
+/// handles an incoming message
+bool BaseOverlay::handleMessage( const Message* message, LinkDescriptor* ld,
+	const LinkID bcLink ) {
+	logging_debug( "Handling message: " << message->toString());
+
+<<<<<<< .working
 					// mark incoming link as relay
 					if (ld!=NULL) ld->markAsRelay();
@@ -1454,85 +1557,77 @@
 						RelayMessage _relayMsg( *relayMsg );
 						_overMsg.encapsulate(&_relayMsg);
-
-						/// this must be handled by using relay link!
-						sendOverlay(&_overMsg, relayMsg->getDestNode());
-						ret = true;
-						break;
-					}
-
-					// error: I'm not a relay or destination!
-					logging_error("This node is neither relay nor destination. Dropping Message!");
-					ret = true;
-					break;
-				}
-				default: {
-					logging_error("RelayMessage Unknown!");
-					ret = true;
-					break;
-				}
-			}
-			delete relayMsg;
-			break;
-		}
-
-		// ---------------------------------------------------------------------
-		// handle keep-alive messages
-		// ---------------------------------------------------------------------
-		case OverlayMsg::typeKeepAlive: {
-			logging_debug( "received keep-alive on link" );
-			if ( ld != NULL ) {
-				logging_info("Keep-Alive for "<< ld->overlayId);
-				ld->markAlive();
-			}
-			break;
-		}
-
-		// ---------------------------------------------------------------------
-		// handle direct link replacement messages
-		// ---------------------------------------------------------------------
-		case OverlayMsg::typeDirectLink: {
-
-			logging_debug( "Received direct link replacement request" );
-
-			LinkDescriptor* rld = getDescriptor( overlayMsg->getRelayLink() );
-			if (rld == NULL || ld == NULL) {
-				logging_error("Direct link replacement: Link "
-						<< overlayMsg->getRelayLink() << "not found error." );
-				break;
-			}
-			logging_info( "Received direct link convert notification for " << rld );
-
-			// set communcation link id and set it up
-			rld->communicationId = ld->communicationId;
-
-			// this is neccessary since this link was a relay link before!
-			rld->communicationUp = true;
-
-			// this is not a relay link anymore!
-			rld->relay = false;
-			rld->localRelay  = NodeID::UNSPECIFIED;
-			rld->remoteRelay = NodeID::UNSPECIFIED;
-
-			// mark used and alive!
-			rld->markAsUsed();
-			rld->markAlive();
-
-			// erase the original descriptor
-			eraseDescriptor(ld->overlayId);
-			break;
-		}
-
-		// ---------------------------------------------------------------------
+=======
+	// decapsulate overlay message
+	OverlayMsg* overlayMsg =
+		const_cast<Message*>(message)->decapsulate<OverlayMsg>();
+	if( overlayMsg == NULL ) return false;
+>>>>>>> .merge-rechts.r5869
+
+	// refresh relay information
+	refreshRelayInformation( overlayMsg, ld );
+
+	// increase number of hops
+	overlayMsg->increaseNumHops();
+
+	// update route record
+	overlayMsg->addRouteRecord(nodeId);
+
+	// handle signaling messages (do not route!)
+	if (overlayMsg->getType()>=OverlayMsg::typeSignalingStart &&
+		overlayMsg->getType()<=OverlayMsg::typeSignalingEnd ) {
+		overlayInterface->onMessage(overlayMsg, NodeID::UNSPECIFIED, LinkID::UNSPECIFIED);
+		delete overlayMsg;
+		return true;
+	}
+
+	// message for reached destination? no-> route message
+	if (!overlayMsg->getDestinationNode().isUnspecified() &&
+ 		 overlayMsg->getDestinationNode() != nodeId ) {
+		logging_debug("Routing message "
+			<< " from " << overlayMsg->getSourceNode()
+			<< " to " << overlayMsg->getDestinationNode()
+		);
+
+		route( overlayMsg, ld );
+		delete overlayMsg;
+		return true;
+	}
+
+	// handle base overlay message
+	bool ret = false; // return value
+	switch ( overlayMsg->getType() ) {
+
+		// data transport messages
+		case OverlayMsg::typeData:
+			ret = handleData(overlayMsg, ld); 			break;
+
+		// overlay setup messages
+		case OverlayMsg::typeJoinRequest:
+			ret = handleJoinRequest(overlayMsg, bcLink ); 	break;
+		case OverlayMsg::typeJoinReply:
+			ret = handleJoinReply(overlayMsg, bcLink ); 	break;
+
+		// link specific messages
+		case OverlayMsg::typeLinkRequest:
+			ret = handleLinkRequest(overlayMsg, ld ); 	break;
+		case OverlayMsg::typeLinkReply:
+			ret = handleLinkReply(overlayMsg, ld ); 	break;
+		case OverlayMsg::typeLinkUpdate:
+			ret = handleLinkUpdate(overlayMsg, ld );  	break;
+		case OverlayMsg::typeLinkAlive:
+			ret = handleLinkAlive(overlayMsg, ld );   	break;
+		case OverlayMsg::typeLinkDirect:
+			ret = handleLinkDirect(overlayMsg, ld );  	break;
+
 		// handle unknown message type
-		// ---------------------------------------------------------------------
 		default: {
 			logging_error( "received message in invalid state! don't know " <<
-					"what to do with this message of type " <<
-					overlayMsg->getType() );
+				"what to do with this message of type " << overlayMsg->getType() );
 			ret = false;
 			break;
 		}
-	} /* switch */
-
+	}
+
+	// free overlay message and return value
 	delete overlayMsg;
 	return ret;
@@ -1554,12 +1649,11 @@
 }
 
+/// return the overlay neighbors
 vector<NodeID> BaseOverlay::getOverlayNeighbors(bool deep) const {
 
 	vector<NodeID> nodes = overlayInterface->getKnownNodes(deep);
-
 	// the known nodes _can_ also include our node, so we remove ourself
 	vector<NodeID>::iterator i = find( nodes.begin(), nodes.end(), this->nodeId );
 	if( i != nodes.end() ) nodes.erase( i );
-
 	return nodes;
 }
@@ -1594,4 +1688,5 @@
 
 void BaseOverlay::eventFunction() {
+<<<<<<< .working
 
 	// send keep-alive messages over established links
@@ -1673,14 +1768,8 @@
 	if (counter>=4) showLinkState();
 	if (counter>=4 || counter<0) counter = 0;
-}
-
-void BaseOverlay::showLinkState() {
-	int i=0;
-	logging_info("--- link state -------------------------------");
-	BOOST_FOREACH( LinkDescriptor* ld, links ) {
-		logging_info("link " << i << ": " << ld);
-		i++;
-	}
-	logging_info("----------------------------------------------");
+=======
+	stabilizeRelays();
+	stabilizeLinks();
+>>>>>>> .merge-rechts.r5869
 }
 
