Index: source/ariba/overlay/messages/JoinReply.h
===================================================================
--- source/ariba/overlay/messages/JoinReply.h	(revision 4625)
+++ source/ariba/overlay/messages/JoinReply.h	(revision 5151)
@@ -85,5 +85,7 @@
 
 sznBeginDefault( ariba::overlay::JoinReply, X ) {
-	X && &spovnetid && param && bootstrapEp && joinAllowed && cI(0,7);
+	uint8_t ja = joinAllowed;
+	X && &spovnetid && param && &bootstrapEp && ja;
+	if (X.isDeserializer()) joinAllowed = ja;
 } sznEnd();
 
Index: source/ariba/overlay/messages/LinkRequest.cpp
===================================================================
--- source/ariba/overlay/messages/LinkRequest.cpp	(revision 4625)
+++ source/ariba/overlay/messages/LinkRequest.cpp	(revision 5151)
@@ -7,12 +7,4 @@
 vsznDefault(LinkRequest);
 
-LinkRequest::LinkRequest() {
-
-}
-
-LinkRequest::LinkRequest( uint32_t nonce, const EndpointDescriptor* endpoint, bool reply ) :
-	flags(reply&1), nonce(nonce), endpoint(endpoint) {
-}
-
 LinkRequest::~LinkRequest() {
 }
Index: source/ariba/overlay/messages/LinkRequest.h
===================================================================
--- source/ariba/overlay/messages/LinkRequest.h	(revision 4625)
+++ source/ariba/overlay/messages/LinkRequest.h	(revision 5151)
@@ -27,10 +27,17 @@
 	uint32_t nonce;
 	const EndpointDescriptor* endpoint;
+	LinkID remoteLinkId;
+	NodeID relay;
 
 public:
-	LinkRequest();
+	LinkRequest() {
+
+	}
 
 	LinkRequest( uint32_t nonce, const EndpointDescriptor* endpoint,
-			bool reply = false );
+			bool reply = false, const LinkID& remoteLinkId = LinkID::UNSPECIFIED,
+			const NodeID& relay = NodeID::UNSPECIFIED ) :
+			flags(reply&1), nonce(nonce), endpoint(endpoint), remoteLinkId(remoteLinkId), relay(relay) {
+	}
 
 	virtual ~LinkRequest();
@@ -38,4 +45,12 @@
 	const EndpointDescriptor* getEndpoint() const {
 		return endpoint;
+	}
+
+	const LinkID& getRemoteLinkId() const {
+		return remoteLinkId;
+	}
+
+	const NodeID& getRelay() const {
+		return relay;
 	}
 
@@ -53,5 +68,7 @@
 sznBeginDefault( ariba::overlay::LinkRequest, X ) {
 	if (X.isDeserializer()) endpoint = new EndpointDescriptor();
-	X && flags && nonce && reinterpret_cast<VSerializeable*>(const_cast<EndpointDescriptor*>(endpoint));
+	X && flags && nonce;
+	X && const_cast<EndpointDescriptor*>(endpoint);
+	X && &relay && &remoteLinkId;
 } sznEnd();
 
Index: source/ariba/overlay/messages/OverlayMsg.cpp
===================================================================
--- source/ariba/overlay/messages/OverlayMsg.cpp	(revision 4625)
+++ source/ariba/overlay/messages/OverlayMsg.cpp	(revision 5151)
@@ -44,30 +44,6 @@
 vsznDefault(OverlayMsg);
 
-OverlayMsg::OverlayMsg(OverlayMessageType _type, const ServiceID _service, const NodeID _sourceNode)
-	: type( (uint8_t)_type), service( _service ), sourceNode( _sourceNode ) {
-}
-
-OverlayMsg::OverlayMsg(OverlayMessageType _type, const NodeID _sourceNode)
-	: type( (uint8_t)_type), service( ServiceID::UNSPECIFIED ), sourceNode( _sourceNode ){
-}
-
 OverlayMsg::~OverlayMsg(){
 }
 
-OverlayMsg::OverlayMessageType OverlayMsg::getType(){
-	return (OverlayMessageType)type;
-}
-
-const ServiceID& OverlayMsg::getService(){
-	return service;
-}
-
-bool OverlayMsg::isType(OverlayMessageType _type){
-	return (OverlayMessageType)type == _type;
-}
-
-const NodeID& OverlayMsg::getSourceNode(){
-	return sourceNode;
-}
-
 }} // ariba::overlay
Index: source/ariba/overlay/messages/OverlayMsg.h
===================================================================
--- source/ariba/overlay/messages/OverlayMsg.h	(revision 4625)
+++ source/ariba/overlay/messages/OverlayMsg.h	(revision 5151)
@@ -55,49 +55,93 @@
 namespace overlay {
 
-using_serialization;
+using_serialization
+;
 
-class OverlayMsg : public Message {
-	VSERIALIZEABLE;
+class OverlayMsg: public Message {
+VSERIALIZEABLE
+	;
 public:
 
-	typedef enum _OverlayMessageType {
-		OverlayMessageTypeInvalid     = 0, // invalid type (no encapsulated messages)
-		OverlayMessageTypeData        = 1, // message contains data for higher layers
-		OverlayMessageTypeJoinRequest = 2, // spovnet join request
-		OverlayMessageTypeJoinReply   = 3, // spovnet join reply
-		OverlayMessageTypeUpdate      = 4, // update message for link association
-		OverlayMessageTypeBye         = 5, // spovnet leave (no encapsulated messages)
-		OverlayMessageTypeLinkRequest = 6, // link request (sent over the overlay)
-	} OverlayMessageType;
+	/// (payload-) message types
+	enum type_ {
+		typeInvalid = 0, ///< invalid type (no encapsulated messages)
+		typeData = 1, ///< message contains data for higher layers
+		typeJoinRequest = 2, ///< join request
+		typeJoinReply = 3, ///< join reply
+		typeUpdate = 4, ///< update message for link association
+		typeBye = 5, ///< leave (no encapsulated messages)
+		typeLinkRequest = 6, ///< link request (sent over the overlay)
+		typeRelay = 7, ///< relay message
+		typeKeepAlive = 8, ///< a keep-alive message
+		typeDirectLink = 9,
+	///< a direct connection has been established
+	};
 
-	OverlayMsg(
-		OverlayMessageType _type       = OverlayMessageTypeInvalid,
-		const ServiceID    _service    = ServiceID::UNSPECIFIED,
-		const NodeID       _sourceNode = NodeID::UNSPECIFIED
-	);
+	/// default constructor
+	OverlayMsg(type_ type = typeInvalid, const ServiceID _service =
+			ServiceID::UNSPECIFIED, const NodeID _sourceNode =
+			NodeID::UNSPECIFIED) :
+		type((uint8_t) type), service(_service), sourceNode(_sourceNode),
+				relayLink(LinkID::UNSPECIFIED), autoLink(false) {
+	}
 
-	OverlayMsg(
-		OverlayMessageType _type,
-		const NodeID       _sourceNode
-	);
+	OverlayMsg(const OverlayMsg& rhs) :
+		type(rhs.type), service(rhs.service), sourceNode(rhs.sourceNode),
+				relayLink(rhs.relayLink), autoLink(rhs.autoLink) {
+	}
 
-	virtual ~OverlayMsg();
+	/// type and source node constructor
+	OverlayMsg(type_ type, const NodeID _sourceNode) :
+		type((uint8_t) type), service(ServiceID::UNSPECIFIED), sourceNode(
+				_sourceNode), relayLink(LinkID::UNSPECIFIED), autoLink(false) {
+	}
 
-	bool isType(OverlayMessageType _type);
-	OverlayMessageType getType();
-	const ServiceID& getService();
-	const NodeID& getSourceNode();
+	/// destructor
+	~OverlayMsg();
 
+	type_ getType() const {
+		return (type_) type;
+	}
+
+	const ServiceID& getService() const {
+		return service;
+	}
+
+	const NodeID& getSourceNode() const {
+		return sourceNode;
+	}
+
+	const LinkID& getRelayLink() const {
+		return relayLink;
+	}
+
+	void setRelayLink(const LinkID& relayLink) {
+		this->relayLink = relayLink;
+	}
+
+	const bool isAutoLink() const {
+		return autoLink;
+	}
+
+	void setAutoLink(bool autoLink) {
+		this->autoLink = autoLink;
+	}
 private:
 	uint8_t type;
 	ServiceID service;
 	NodeID sourceNode;
+	LinkID relayLink;
+	uint8_t autoLink;
 };
 
-}} // ariba::overlay
+}
+} // ariba::overlay
 
-sznBeginDefault( ariba::overlay::OverlayMsg, X ) {
-	X && type && &service && &sourceNode && Payload();
-} sznEnd();
+sznBeginDefault( ariba::overlay::OverlayMsg, X ){
+X && type && &service && &sourceNode;
+if (type == typeDirectLink) X && &relayLink;
+if (type == typeUpdate) X && autoLink;
+X && Payload();
+}sznEnd();
 
 #endif // OVERLAY_MSG_H__
Index: source/ariba/overlay/messages/RelayMessage.cpp
===================================================================
--- source/ariba/overlay/messages/RelayMessage.cpp	(revision 5151)
+++ source/ariba/overlay/messages/RelayMessage.cpp	(revision 5151)
@@ -0,0 +1,12 @@
+#include "RelayMessage.h"
+
+namespace ariba {
+namespace overlay {
+
+vsznDefault(RelayMessage);
+
+RelayMessage::~RelayMessage() {
+}
+
+}} // ariba::overlay
+
Index: source/ariba/overlay/messages/RelayMessage.h
===================================================================
--- source/ariba/overlay/messages/RelayMessage.h	(revision 5151)
+++ source/ariba/overlay/messages/RelayMessage.h	(revision 5151)
@@ -0,0 +1,79 @@
+#ifndef RELAYMESSAGE_H_
+#define RELAYMESSAGE_H_
+
+#include "ariba/utility/messages.h"
+#include "ariba/utility/serialization.h"
+#include "ariba/communication/EndpointDescriptor.h"
+
+using ariba::communication::EndpointDescriptor;
+
+namespace ariba {
+namespace overlay {
+
+using_serialization;
+
+using ariba::utility::Message;
+
+/**
+ * This message is sent to another overlay node to request a new link.
+ *
+ * @author Sebastian Mies <mies@tm.uka.de>
+ */
+class RelayMessage : public Message {
+	VSERIALIZEABLE;
+private:
+	uint8_t type;
+	NodeID relayNode;
+	NodeID destNode;
+	LinkID destLink;
+
+public:
+	enum type_ {
+		typeInvalid = 0,
+		typeInform = 1,
+		typeRoute = 2
+	};
+
+	/// contructs a unspecified relay message
+	RelayMessage() :
+		type(typeInvalid), relayNode(NodeID::UNSPECIFIED), destNode(NodeID::UNSPECIFIED) {
+	}
+
+	RelayMessage( type_ type, const NodeID& relayNode, const NodeID& destNode, const LinkID& destLink = LinkID::UNSPECIFIED ) :
+		type(type), relayNode(relayNode), destNode(destNode), destLink(destLink) {
+	}
+
+	~RelayMessage();
+
+	/// returns the type of this message
+	type_ getType() const {
+		return (type_)type;
+	}
+
+	/// sets the type of this message
+	void setType( type_ type ) {
+		this->type = type;
+	}
+
+	/// returns the remote (destination) node id
+	const NodeID& getDestNode() const {
+		return destNode;
+	}
+
+	const LinkID& getDestLink() const {
+		return destLink;
+	}
+
+	/// returns the relay node for the destination
+	const NodeID& getRelayNode() const {
+		return relayNode;
+	}
+};
+
+}} // ariba::overlay
+
+sznBeginDefault( ariba::overlay::RelayMessage, X ) {
+	X && type && &relayNode && &destNode && &destLink && Payload();
+} sznEnd();
+
+#endif /* RELAYMESSAGE_H_ */
