Index: source/ariba/overlay/BaseOverlay.cpp
===================================================================
--- source/ariba/overlay/BaseOverlay.cpp	(revision 10432)
+++ source/ariba/overlay/BaseOverlay.cpp	(revision 10572)
@@ -1832,6 +1832,9 @@
 
 	// handle dht messages (do not route)
-	if (overlayMsg->isDHTMessage())
-		return handleDHTMessage(overlayMsg);
+	if (overlayMsg->isDHTMessage()) {
+		bool ret = handleDHTMessage(overlayMsg);
+		delete overlayMsg;
+		return ret;
+	}
 
 	// handle signaling messages (do not route!)
@@ -2161,11 +2164,11 @@
 
 	// route message to closest node
-	if (!overlayInterface->isClosestNodeTo(msg->getDestinationNode())) {
+	if (!overlayInterface->isClosestNodeTo(dhtMsg->getHashedKey())) {
 		logging_debug("Routing DHT message to closest node "
 			<< " from " << msg->getSourceNode()
-			<< " to " << msg->getDestinationNode()
+			<< " to " << dhtMsg->getHashedKey()
 		);
-		route( msg );
-		delete msg;
+		dhtSend(msg, dhtMsg->getHashedKey());
+		delete dhtMsg;
 		return true;
 	}
@@ -2219,5 +2222,5 @@
 		return false;
 	}
-	delete msg;
+	delete dhtMsg;
 	return true;
 }
@@ -2239,6 +2242,4 @@
 	}
 
-	// calculate hash
-	NodeID dest = NodeID::sha1(key.getBuffer(), key.getLength() / 8);
 	DHTMessage dhtmsg( key, value );
 	dhtmsg.setReplace( replace );
@@ -2247,5 +2248,5 @@
 	OverlayMsg msg( OverlayMsg::typeDHTPut );
 	msg.encapsulate( &dhtmsg );
-	dhtSend(&msg, dest);
+	dhtSend(&msg, dhtmsg.getHashedKey());
 }
 
@@ -2255,6 +2256,4 @@
 	localDHT->remove(key,value);
 
-	// calculate hash
-	NodeID dest = NodeID::sha1(key.getBuffer(), key.getLength() / 8);
 	DHTMessage dhtmsg(key,value);
 
@@ -2262,5 +2261,5 @@
 	OverlayMsg msg(OverlayMsg::typeDHTRemove);
 	msg.encapsulate( &dhtmsg );
-	dhtSend(&msg, dest);
+	dhtSend(&msg, dhtmsg.getHashedKey());
 }
 
@@ -2270,6 +2269,4 @@
 	logging_info("DHT-Remove: Removing key=" << key );
 
-	// calculate hash
-	NodeID dest = NodeID::sha1(key.getBuffer(), key.getLength() / 8);
 	DHTMessage dhtmsg(key);
 
@@ -2277,5 +2274,5 @@
 	OverlayMsg msg(OverlayMsg::typeDHTRemove);
 	msg.encapsulate( &dhtmsg );
-	dhtSend(&msg, dest);
+	dhtSend(&msg, dhtmsg.getHashedKey());
 }
 
@@ -2286,6 +2283,4 @@
 			key << " for service=" << service.toString() );
 
-	// calculate hash
-	NodeID dest = NodeID::sha1(key.getBuffer(), key.getLength() / 8);
 	DHTMessage dhtmsg(key);
 
@@ -2294,5 +2289,5 @@
 	msg.setService(service);
 	msg.encapsulate( &dhtmsg );
-	dhtSend(&msg, dest);
+	dhtSend(&msg, dhtmsg.getHashedKey());
 }
 
@@ -2303,18 +2298,27 @@
 	/// set source and destination
 	msg->setSourceNode(this->nodeId);
-	msg->setDestinationNode(dest);
 
 	// local storage? yes-> put into DHT directly
-	if (overlayInterface->isClosestNodeTo(msg->getDestinationNode())) {
+	if (overlayInterface->isClosestNodeTo(dest)) {
+		// be compatible with old code so set destination to hashed key
+		msg->setDestinationNode(dest);
+		
 		Data d = data_serialize(msg);
-		Message* m2 = new Message(d);
-		OverlayMsg* m3 = m2->decapsulate<OverlayMsg>();
+		Message m2(d);
+		OverlayMsg* m3 = m2.decapsulate<OverlayMsg>();
+		
 		handleDHTMessage(m3);
-		delete m2;
+		
+		delete m3;
 		return;
-	}
-
-	// send message "normally"
-	send( msg, dest );
+	} else {
+		// need to route
+		NodeID next_hop = overlayInterface->getNextNodeId(dest);
+		msg->setDestinationNode(next_hop);
+		
+		send(msg, next_hop);
+		
+		return;
+	}
 }
 
Index: source/ariba/overlay/messages/DHTMessage.cpp
===================================================================
--- source/ariba/overlay/messages/DHTMessage.cpp	(revision 10432)
+++ source/ariba/overlay/messages/DHTMessage.cpp	(revision 10572)
@@ -8,34 +8,31 @@
 vsznDefault(DHTMessage);
 
-DHTMessage::DHTMessage() {
-	this->key.setLength(0);
-	this->ttl = 0;
-	this->replace = false;
-}
+DHTMessage::DHTMessage() :
+	ttl( 0 ),
+	replace( false )
+{}
 
-DHTMessage::DHTMessage( const Data& key ) {
-	// calculate hash of key
-	this->hash = NodeID::sha1( key.getBuffer(), key.getLength() / 8 );
-	this->key = key.clone();
-	this->ttl = 0;
-	this->replace = false;
-}
+DHTMessage::DHTMessage( const Data& key ) :
+	ttl( 0 ),
+	replace( false ),
+	key( key.clone() )
+{}
 
-DHTMessage::DHTMessage( const Data& key, const Data& value ) {
-	// calculate hash of key
-	this->hash = NodeID::sha1( key.getBuffer(), key.getLength() / 8 );
-	this->key = key.clone();
-	this->values.push_back( value.clone() );
-	this->ttl = 0;
-	this->replace = false;
-}
+DHTMessage::DHTMessage( const Data& key, const Data& value ) :
+	ttl( 0 ),
+	replace( false ),
+	key( key.clone() ),
+	values(1, value.clone())
+{}
 
-DHTMessage::DHTMessage( const Data& key, const vector<Data>& values ) {
-	this->hash = NodeID::sha1( key.getBuffer(), key.getLength() / 8 );
-	this->key = key.clone();
+DHTMessage::DHTMessage( const Data& key, const vector<Data>& values ) :
+	ttl( 0 ),
+	replace( false ),
+	key( key.clone() )
+{
+	// preallocate enough room so we don't need to copy a lot
+	this->values.reserve(values.size());
 	BOOST_FOREACH(const Data value, values )
 		this->values.push_back( value.clone() );
-	this->ttl = 0;
-	this->replace = false;
 }
 
Index: source/ariba/overlay/messages/DHTMessage.h
===================================================================
--- source/ariba/overlay/messages/DHTMessage.h	(revision 10432)
+++ source/ariba/overlay/messages/DHTMessage.h	(revision 10572)
@@ -20,5 +20,5 @@
 
 	const NodeID& getHashedKey() const {
-		return hash;
+		return NodeID::sha1( key.getBuffer(), key.getLength() / 8 );
 	}
 
@@ -58,5 +58,4 @@
 
 private:
-	NodeID hash;
 	uint16_t ttl;
 	bool replace;
Index: source/ariba/overlay/modules/OverlayInterface.h
===================================================================
--- source/ariba/overlay/modules/OverlayInterface.h	(revision 10432)
+++ source/ariba/overlay/modules/OverlayInterface.h	(revision 10572)
@@ -145,4 +145,12 @@
 	 */
 	virtual const LinkID& getNextLinkId( const NodeID& id ) const = 0;
+	
+	/**
+	 * Returns the NodeID of the next hop a route message would take.
+	 * 
+	 * @param id The destination node id
+	 * @return The node id of the next hop
+	 */
+	virtual const NodeID& getNextNodeId( const NodeID& id ) const;
 
 	//--- functions from CommunicationListener that we _can_ use as overlay ---
Index: source/ariba/overlay/modules/chord/Chord.cpp
===================================================================
--- source/ariba/overlay/modules/chord/Chord.cpp	(revision 10432)
+++ source/ariba/overlay/modules/chord/Chord.cpp	(revision 10572)
@@ -201,4 +201,17 @@
 }
 
+/// @see OverlayInterface.h
+const NodeID& Chord::getNextNodeId( const NodeID& id ) const {
+	// get next hop
+	const route_item* item = table->get_next_hop(id);
+	
+	// return unspecified if no next hop could be found
+	if (item == NULL) {
+		return NodeID::UNSPECIFIED;
+	}
+	
+	return item->id;
+}
+
 OverlayInterface::NodeList Chord::getKnownNodes(bool deep) const {
 	OverlayInterface::NodeList nodelist;
Index: source/ariba/overlay/modules/chord/Chord.h
===================================================================
--- source/ariba/overlay/modules/chord/Chord.h	(revision 10432)
+++ source/ariba/overlay/modules/chord/Chord.h	(revision 10572)
@@ -104,4 +104,7 @@
 	/// @see OverlayInterface.h
 	virtual const LinkID& getNextLinkId( const NodeID& id ) const;
+	
+	/// @see OverlayInterface.h
+	virtual const NodeID& getNextNodeId( const NodeID& id ) const;
 
 	/// @see OverlayInterface.h
Index: source/ariba/overlay/modules/onehop/OneHop.cpp
===================================================================
--- source/ariba/overlay/modules/onehop/OneHop.cpp	(revision 10432)
+++ source/ariba/overlay/modules/onehop/OneHop.cpp	(revision 10572)
@@ -122,4 +122,16 @@
 }
 
+/// @see OverlayInterface.h
+const NodeID& OneHop::getNextNodeId( const NodeID& id ) const {
+	OverlayNodeMapping::const_iterator i = overlayNodes.find( id );
+	
+	// FIXME: in case the NodeID is not known we should return the nearest node
+	if (i == overlayNodes.end()) {
+		return NodeID::UNSPECIFIED;
+	}
+	
+	return i->first;
+}
+
 void OneHop::createOverlay() {
 	// don't need to bootstrap against ourselfs.
Index: source/ariba/overlay/modules/onehop/OneHop.h
===================================================================
--- source/ariba/overlay/modules/onehop/OneHop.h	(revision 10432)
+++ source/ariba/overlay/modules/onehop/OneHop.h	(revision 10572)
@@ -85,4 +85,7 @@
 	/// @see OverlayInterface.h
 	virtual const LinkID& getNextLinkId( const NodeID& id ) const;
+	
+	/// @see OverlayInterface.h
+	virtual const NodeID& getNextNodeId( const NodeID& id ) const;
 
 	/// @see OverlayInterface.h
