Index: libfdcore/fdcore-internal.h
===================================================================
--- libfdcore/fdcore-internal.h	(revision 1015)
+++ libfdcore/fdcore-internal.h	(revision 1016)
@@ -134,5 +134,5 @@
 	pthread_mutex_t	mtx; /* mutex to protect these lists */
 	pthread_cond_t  cnd; /* cond var used by the thread that handles timeouts */
-	pthread_t       thr; /* the thread that handles timeouts (and calls the anscb) */
+	pthread_t       thr; /* the thread that handles timeouts (expirecb called in separate forked threads) */
 };
 
Index: libfdcore/messages.c
===================================================================
--- libfdcore/messages.c	(revision 928)
+++ libfdcore/messages.c	(revision 1014)
@@ -321,5 +321,5 @@
 	
 	/* Save the callback in the message */
-	CHECK_FCT(  fd_msg_anscb_associate( *pmsg, anscb, data, NULL /* we should maybe use a safeguard here like 1 hour or so? */ )  );
+	CHECK_FCT(  fd_msg_anscb_associate( *pmsg, anscb, data, NULL, NULL /* we should maybe use a safeguard here like 1 hour or so? */ )  );
 	
 	/* Post the message in the outgoing queue */
@@ -330,11 +330,11 @@
 
 /* The variation of the same function with a timeout callback */
-int fd_msg_send_timeout ( struct msg ** pmsg, void (*anscb)(void *, struct msg **), void * data, const struct timespec *timeout )
-{
-	TRACE_ENTRY("%p %p %p", pmsg, anscb, data, timeout);
-	CHECK_PARAMS( pmsg && anscb && timeout );
+int fd_msg_send_timeout ( struct msg ** pmsg, void (*anscb)(void *, struct msg **), void * data, void (*expirecb)(void *, DiamId_t, size_t, struct msg **), const struct timespec *timeout )
+{
+	TRACE_ENTRY("%p %p %p %p %p", pmsg, anscb, data, expirecb, timeout);
+	CHECK_PARAMS( pmsg && expirecb && timeout );
 	
 	/* Save the callback in the message, with the timeout */
-	CHECK_FCT(  fd_msg_anscb_associate( *pmsg, anscb, data, timeout )  );
+	CHECK_FCT(  fd_msg_anscb_associate( *pmsg, anscb, data, expirecb, timeout )  );
 	
 	/* Post the message in the outgoing queue */
Index: libfdcore/p_sr.c
===================================================================
--- libfdcore/p_sr.c	(revision 974)
+++ libfdcore/p_sr.c	(revision 1014)
@@ -85,10 +85,15 @@
 }
 
+struct expire_data {
+	struct msg * request;
+	struct fd_peer * sentto;
+};
+
 /* (detached) thread that calls the anscb on expired messages. 
   We do it in a separate thread to avoid blocking the reception of new messages during this time */
-static void * call_anscb_expire(void * arg) {
-	struct msg * expired_req = arg;
-	
-	void (*anscb)(void *, struct msg **);
+static void * call_expirecb(void * arg) {
+	struct expire_data * ed = arg;
+	
+	void (*expirecb)(void *, DiamId_t, size_t, struct msg **);
 	void * data;
 	
@@ -103,18 +108,20 @@
 	
 	/* Retrieve callback in the message */
-	CHECK_FCT_DO( fd_msg_anscb_get( expired_req, &anscb, &data ), return NULL);
-	ASSERT(anscb);
+	CHECK_FCT_DO( fd_msg_anscb_get( ed->request, NULL, &expirecb, &data ), return NULL);
+	ASSERT(expirecb);
 	
 	/* Clean up this data from the message */
-	CHECK_FCT_DO( fd_msg_anscb_associate( expired_req, NULL, NULL, NULL ), return NULL);
+	CHECK_FCT_DO( fd_msg_anscb_associate( ed->request, NULL, NULL, NULL, NULL ), return NULL);
 
 	/* Call it */
-	(*anscb)(data, &expired_req);
+	(*expirecb)(data, ed->sentto->p_hdr.info.pi_diamid, ed->sentto->p_hdr.info.pi_diamidlen, &ed->request);
 	
 	/* If the callback did not dispose of the message, do it now */
-	if (expired_req) {
-		fd_msg_log(FD_MSG_LOG_DROPPED, expired_req, "Expiration period completed without an answer, and the expiry callback did not dispose of the message.");
-		CHECK_FCT_DO( fd_msg_free(expired_req), /* ignore */ );
-	}
+	if (ed->request) {
+		fd_msg_log(FD_MSG_LOG_DROPPED, ed->request, "Expiration period completed without an answer, and the expiry callback did not dispose of the message.");
+		CHECK_FCT_DO( fd_msg_free(ed->request), /* ignore */ );
+	}
+	
+	free(ed);
 	
 	/* Finish */
@@ -125,6 +132,6 @@
 static void * sr_expiry_th(void * arg) {
 	struct sr_list * srlist = arg;
-	struct msg * expired_req;
 	pthread_attr_t detached;
+	struct expire_data * ed;
 	
 	TRACE_ENTRY("%p", arg);
@@ -177,10 +184,12 @@
 		
 		/* Now, the first request in the list is expired; remove it and call the anscb for it in a new thread */
+		CHECK_MALLOC_DO( ed = malloc(sizeof(struct expire_data)), goto error );
+		ed->sentto = first->chain.head->o;
+		ed->request = first->req;
 		fd_list_unlink(&first->chain);
 		fd_list_unlink(&first->expire);
-		expired_req = first->req;
 		free(first);
 		
-		CHECK_POSIX_DO( pthread_create( &th, &detached, call_anscb_expire, expired_req ), goto error );
+		CHECK_POSIX_DO( pthread_create( &th, &detached, call_expirecb, ed ), goto error );
 
 		/* loop */
Index: libfdcore/routing_dispatch.c
===================================================================
--- libfdcore/routing_dispatch.c	(revision 974)
+++ libfdcore/routing_dispatch.c	(revision 1014)
@@ -467,5 +467,5 @@
 
 		/* Retrieve any registered handler */
-		CHECK_FCT( fd_msg_anscb_get( qry, &anscb, &data ) );
+		CHECK_FCT( fd_msg_anscb_get( qry, &anscb, NULL, &data ) );
 
 		/* If a callback was registered, pass the message to it */
@@ -793,4 +793,6 @@
 	struct rtd_candidate * c;
 	struct msg *msgptr = msg;
+	DiamId_t qry_src = NULL;
+	size_t qry_src_len = 0;
 	
 	/* Read the message header */
@@ -801,6 +803,4 @@
 	if ( ! is_req ) {
 		struct msg * qry;
-		DiamId_t qry_src = NULL;
-		size_t qry_src_len = 0;
 		struct msg_hdr * qry_hdr;
 		struct fd_peer * peer = NULL;
@@ -832,4 +832,6 @@
 	
 	/* From that point, the message is a request */
+	CHECK_FCT( fd_msg_source_get( msgptr, &qry_src, &qry_src_len ) );
+	/* if qry_src != NULL, this message is relayed, otherwise it is locally issued */
 
 	/* Get the routing data out of the message if any (in case of re-transmit) */
