changeset 996:cf09fde3d7f5

Fix management of sessions in app_radgw: sessions are simply associated with messages, that is sufficient
author Sebastien Decugis <sdecugis@freediameter.net>
date Tue, 19 Mar 2013 16:13:14 +0100
parents 2016a0c46bda
children 632913581c37 ad6c1ee04d2d
files extensions/app_radgw/radius.c extensions/app_radgw/rgw.h extensions/app_radgw/rgw_common.h extensions/app_radgw/rgw_plugins.c extensions/app_radgw/rgw_servers.c extensions/app_radgw/rgw_worker.c extensions/app_radgw/rgwx_acct.c extensions/app_radgw/rgwx_auth.c extensions/app_radgw/rgwx_debug.c extensions/app_radgw/rgwx_echodrop.c extensions/app_radgw/rgwx_sample.c extensions/app_radgw/rgwx_sip.c
diffstat 12 files changed, 194 insertions(+), 225 deletions(-) [+]
line wrap: on
line diff
--- a/extensions/app_radgw/radius.c	Mon Mar 18 16:19:47 2013 +0100
+++ b/extensions/app_radgw/radius.c	Tue Mar 19 16:13:14 2013 +0100
@@ -57,10 +57,6 @@
 /*********************************************************************************/
 #include "rgw.h"
 
-/* Overwrite printf */
-#define printf(args...) fd_log_debug(args)
-
-
 static struct radius_attr_hdr *
 radius_get_attr_hdr(struct radius_msg *msg, int idx)
 {
@@ -236,22 +232,27 @@
 	return NULL;
 }
 
+static char print_char_buf[5];
 
-static void print_char(char c)
+static char * print_char(char c)
 {
 	if (c >= 32 && c < 127)
-		printf("%c", c);
+		sprintf(print_char_buf, "%c", c);
 	else
-		printf("<%02x>", c);
+		sprintf(print_char_buf, "<%02x>", c);
+	return print_char_buf;
 }
 
 
-static void radius_msg_dump_attr_val(struct radius_attr_hdr *hdr)
+static char * radius_msg_dump_attr_val(struct radius_attr_hdr *hdr, char * outbuf, size_t buflen)
 {
 	struct radius_attr_type *attr;
 	int i, len;
 	unsigned char *pos;
 	u8 attrtype;
+	size_t offset = 0;
+	
+	memset(outbuf, 0, buflen);
 
 	attr = radius_get_attr_type(hdr->type);
 
@@ -265,19 +266,19 @@
 
 	switch (attrtype) {
 	case RADIUS_ATTR_TEXT:
-		printf("      Value: '");
+		snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), "      Value: '");
 		for (i = 0; i < len; i++)
-			print_char(pos[i]);
-		printf("'\n");
+			snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), "%s", print_char(pos[i]));
+		snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), "'");
 		break;
 
 	case RADIUS_ATTR_IP:
 		if (len == 4) {
 			struct in_addr addr;
 			os_memcpy(&addr, pos, 4);
-			printf("      Value: %s\n", inet_ntoa(addr));
+			snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), "      Value: %s", inet_ntoa(addr));
 		} else
-			printf("      Invalid IP address length %d\n", len);
+			snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), "      Invalid IP address length %d", len);
 		break;
 
 	case RADIUS_ATTR_IPV6:
@@ -286,33 +287,35 @@
 			const char *atxt;
 			struct in6_addr *addr = (struct in6_addr *) pos;
 			atxt = inet_ntop(AF_INET6, addr, buf, sizeof(buf));
-			printf("      Value: %s\n", atxt ? atxt : "?");
+			snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), "      Value: %s", atxt ? atxt : "?");
 		} else
-			printf("      Invalid IPv6 address length %d\n", len);
+			snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), "      Invalid IPv6 address length %d", len);
 		break;
 
 	case RADIUS_ATTR_INT32:
 		if (len == 4)
-			printf("      Value: %u\n", WPA_GET_BE32(pos));
+			snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), "      Value: %u", WPA_GET_BE32(pos));
 		else
-			printf("      Invalid INT32 length %d\n", len);
+			snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), "      Invalid INT32 length %d", len);
 		break;
 
 	case RADIUS_ATTR_HEXDUMP:
 	case RADIUS_ATTR_UNDIST:
 	default:
-		printf("      Value:");
+		snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), "      Value:");
 		for (i = 0; i < len; i++)
-			printf(" %02x", pos[i]);
-		printf("\n");
+			snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), " %02x", pos[i]);
 		break;
 	}
+	
+	return outbuf;
 }
 
 /* Dump a message  */
 void rgw_msg_dump(struct rgw_radius_msg_meta * msg, int has_meta)
 {
 	unsigned char *auth;
+	char buf[256];
 	size_t i;
 	if (! TRACE_BOOL(FULL) )
 		return;
@@ -328,14 +331,14 @@
 	for (i = 0; i < msg->radius.attr_used; i++) {
 		struct radius_attr_hdr *attr = (struct radius_attr_hdr *)(msg->radius.buf + msg->radius.attr_pos[i]);
 		fd_log_debug("    - Type: 0x%02hhx (%s)       Len: %-3hhu", attr->type, rgw_msg_attrtype_str(attr->type), attr->length);
-		radius_msg_dump_attr_val(attr);
+		fd_log_debug("%s", radius_msg_dump_attr_val(attr, buf, sizeof(buf)));
 	}
 	if (has_meta && msg->ps_nb) {
 		fd_log_debug("---- hidden attributes:");
 		for (i = msg->ps_first; i < msg->ps_first + msg->ps_nb; i++) {
 			struct radius_attr_hdr *attr = (struct radius_attr_hdr *)(msg->radius.buf + msg->radius.attr_pos[i]);
 			fd_log_debug("    - Type: 0x%02hhx (%s)       Len: %-3hhu", attr->type, rgw_msg_attrtype_str(attr->type), attr->length);
-			radius_msg_dump_attr_val(attr);
+			fd_log_debug("%s", radius_msg_dump_attr_val(attr, buf, sizeof(buf)));
 		}
 	}
 	fd_log_debug("-----------------------------");
@@ -354,7 +357,7 @@
 					   RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
 					   auth, MD5_MAC_LEN);
 		if (attr == NULL) {
-			printf("WARNING: Could not add Message-Authenticator\n");
+			fd_log_debug("WARNING: Could not add Message-Authenticator");
 			return -1;
 		}
 		msg->hdr->length = htons(msg->buf_used);
@@ -364,7 +367,7 @@
 		msg->hdr->length = htons(msg->buf_used);
 
 	if (msg->buf_used > 0xffff) {
-		printf("WARNING: too long RADIUS message (%lu)\n",
+		fd_log_debug("WARNING: too long RADIUS message (%lu)",
 		       (unsigned long) msg->buf_used);
 		return -1;
 	}
@@ -385,7 +388,7 @@
 	    attr = radius_msg_add_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
 				       auth, MD5_MAC_LEN);
 	    if (attr == NULL) {
-		    printf("WARNING: Could not add Message-Authenticator\n");
+		    fd_log_debug("WARNING: Could not add Message-Authenticator");
 		    return -1;
 	    }
 	    msg->hdr->length = htons(msg->buf_used);
@@ -409,7 +412,7 @@
 	md5_vector(4, addr, len, msg->hdr->authenticator);
 
 	if (msg->buf_used > 0xffff) {
-		printf("WARNING: too long RADIUS message (%lu)\n",
+		fd_log_debug("WARNING: too long RADIUS message (%lu)",
 		       (unsigned long) msg->buf_used);
 		return -1;
 	}
@@ -432,7 +435,7 @@
 	md5_vector(2, addr, len, msg->hdr->authenticator);
 
 	if (msg->buf_used > 0xffff) {
-		printf("WARNING: too long RADIUS messages (%lu)\n",
+		fd_log_debug("WARNING: too long RADIUS messages (%lu)",
 		       (unsigned long) msg->buf_used);
 	}
 }
@@ -467,7 +470,7 @@
 	struct radius_attr_hdr *attr;
 
 	if (data_len > RADIUS_MAX_ATTR_LEN) {
-		printf("radius_msg_add_attr: too long attribute (%lu bytes)\n",
+		fd_log_debug("radius_msg_add_attr: too long attribute (%lu bytes)",
 		       (unsigned long) data_len);
 		return NULL;
 	}
@@ -691,7 +694,7 @@
 		tmp = radius_get_attr_hdr(msg, i);
 		if (tmp->type == RADIUS_ATTR_MESSAGE_AUTHENTICATOR) {
 			if (attr != NULL) {
-				printf("Multiple Message-Authenticator attributes in RADIUS message\n");
+				fd_log_debug("Multiple Message-Authenticator attributes in RADIUS message");
 				return 1;
 			}
 			attr = tmp;
@@ -699,7 +702,7 @@
 	}
 
 	if (attr == NULL) {
-		printf("No Message-Authenticator attribute found\n");
+		fd_log_debug("No Message-Authenticator attribute found");
 		return 1;
 	}
 
@@ -719,7 +722,7 @@
 	}
 
 	if (os_memcmp(orig, auth, MD5_MAC_LEN) != 0) {
-		printf("Invalid Message-Authenticator!\n");
+		fd_log_debug("Invalid Message-Authenticator!");
 		return 1;
 	}
 
@@ -735,7 +738,7 @@
 	u8 hash[MD5_MAC_LEN];
 
 	if (sent_msg == NULL) {
-		printf("No matching Access-Request message found\n");
+		fd_log_debug("No matching Access-Request message found");
 		return 1;
 	}
 
@@ -756,7 +759,7 @@
 	len[3] = secret_len;
 	md5_vector(4, addr, len, hash);
 	if (os_memcmp(hash, msg->hdr->authenticator, MD5_MAC_LEN) != 0) {
-		printf("Response Authenticator invalid!\n");
+		fd_log_debug("Response Authenticator invalid!");
 		return 1;
 	}
 
@@ -894,7 +897,7 @@
 	pos = key + 2;
 	left = len - 2;
 	if (left % 16) {
-		printf("Invalid ms key len %lu\n", (unsigned long) left);
+		fd_log_debug("Invalid ms key len %lu", (unsigned long) left);
 		return NULL;
 	}
 
@@ -928,7 +931,7 @@
 	}
 
 	if (plain[0] == 0 || plain[0] > plen - 1) {
-		printf("Failed to decrypt MPPE key\n");
+		fd_log_debug("Failed to decrypt MPPE key");
 		os_free(plain);
 		return NULL;
 	}
--- a/extensions/app_radgw/rgw.h	Mon Mar 18 16:19:47 2013 +0100
+++ b/extensions/app_radgw/rgw.h	Tue Mar 19 16:13:14 2013 +0100
@@ -115,8 +115,8 @@
 int rgw_plg_add( char * plgfile, char * conffile, int port, unsigned char ** codes_array, size_t codes_sz );
 void rgw_plg_dump(void);
 void rgw_plg_start_cache(void);
-int rgw_plg_loop_req(struct rgw_radius_msg_meta **rad, struct session **session, struct msg **diam_msg, struct rgw_client * cli);
-int rgw_plg_loop_ans(struct rgw_radius_msg_meta *req, struct session *session, struct msg **diam_ans, struct radius_msg ** rad_ans, struct rgw_client * cli, int * stateful);
+int rgw_plg_loop_req(struct rgw_radius_msg_meta **rad, struct msg **diam_msg, struct rgw_client * cli);
+int rgw_plg_loop_ans(struct rgw_radius_msg_meta *req, struct msg **diam_ans, struct radius_msg ** rad_ans, struct rgw_client * cli);
 void rgw_plg_fini(void);
 
 
--- a/extensions/app_radgw/rgw_common.h	Mon Mar 18 16:19:47 2013 +0100
+++ b/extensions/app_radgw/rgw_common.h	Tue Mar 19 16:13:14 2013 +0100
@@ -73,7 +73,7 @@
 	void (*rgwp_conf_free) (struct rgwp_config * state);
 
 	/* handle an incoming RADIUS message */
-	int	(*rgwp_rad_req) ( struct rgwp_config * conf, struct session ** session, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli );
+	int	(*rgwp_rad_req) ( struct rgwp_config * conf, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli );
 	/* ret >0: critical error (errno), log and exit.
 	   ret 0: continue; 
 	   ret -1: stop processing this message
@@ -81,9 +81,8 @@
 	 */
 	
 	/* handle the corresponding Diameter answer */
-	int	(*rgwp_diam_ans) ( struct rgwp_config * conf, struct session * session, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli, int * stateful );
+	int	(*rgwp_diam_ans) ( struct rgwp_config * conf, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli );
 	/* ret 0: continue; ret >0: error; ret: -1 ... (tbd) */
-	/* if *stateful = 1 on return, the session will not be destroyed after RADIUS answer is sent. The extension must ensure to register a timeout on the session in this case. */
 	
 } rgwp_descriptor;
 
--- a/extensions/app_radgw/rgw_plugins.c	Mon Mar 18 16:19:47 2013 +0100
+++ b/extensions/app_radgw/rgw_plugins.c	Tue Mar 19 16:13:14 2013 +0100
@@ -327,14 +327,14 @@
 	cache_started++;
 }
 
-int rgw_plg_loop_req(struct rgw_radius_msg_meta **rad, struct session **session, struct msg **diam_msg, struct rgw_client * cli)
+int rgw_plg_loop_req(struct rgw_radius_msg_meta **rad, struct msg **diam_msg, struct rgw_client * cli)
 {
 	int ret = 0;
 	struct fd_list * head = NULL, *li;
 	struct radius_msg * rad_ans = NULL;
 	
-	TRACE_ENTRY("%p %p %p %p", rad, session, diam_msg, cli);
-	CHECK_PARAMS( rad && *rad && session && diam_msg && *diam_msg && cli);
+	TRACE_ENTRY("%p %p %p", rad, diam_msg, cli);
+	CHECK_PARAMS( rad && *rad && diam_msg && *diam_msg && cli);
 	
 	/* First, get the list of extensions for this message */
 	CHECK_POSIX( pthread_rwlock_rdlock( &plg_lock) );
@@ -347,7 +347,7 @@
 		
 		if (plg->descriptor->rgwp_rad_req) {
 			TRACE_DEBUG(ANNOYING, "Calling next plugin: %s", plg->descriptor->rgwp_name);
-			ret = (*plg->descriptor->rgwp_rad_req)(plg->cs, session, &(*rad)->radius, &rad_ans, diam_msg, cli);
+			ret = (*plg->descriptor->rgwp_rad_req)(plg->cs, &(*rad)->radius, &rad_ans, diam_msg, cli);
 			if (ret)
 				break;
 		} else {
@@ -367,11 +367,6 @@
 		*diam_msg = NULL;
 	}
 	
-	/* Destroy the session, there won't be a reply message to retrieve the data */
-	if (*session) {
-		CHECK_FCT_DO( fd_sess_destroy(session), );
-	}
-	
 	/* Send the radius message back if required */
 	if ((ret == -2) && rad_ans && rad) {
 		CHECK_FCT_DO( rgw_client_finish_send(&rad_ans, *rad, cli), /* It failed, it can't be helped... */);
@@ -389,15 +384,13 @@
 }
 
 /* Loop in the extension list (same as req) to convert data from diam_ans to rad_ans */
-int rgw_plg_loop_ans(struct rgw_radius_msg_meta *req, struct session *session, struct msg **diam_ans, struct radius_msg ** rad_ans, struct rgw_client * cli, int * stateful)
+int rgw_plg_loop_ans(struct rgw_radius_msg_meta *req, struct msg **diam_ans, struct radius_msg ** rad_ans, struct rgw_client * cli)
 {
 	int ret = 0;
 	struct fd_list * head = NULL, *li;
 	
-	TRACE_ENTRY("%p %p %p %p %p %p", req, session, diam_ans, rad_ans, cli, stateful);
-	CHECK_PARAMS( req && session && diam_ans && *diam_ans && rad_ans && *rad_ans && cli && stateful);
-	
-	*stateful = 0; /* default: stateless gateway */
+	TRACE_ENTRY("%p %p %p %p", req, diam_ans, rad_ans, cli);
+	CHECK_PARAMS( req && diam_ans && *diam_ans && rad_ans && *rad_ans && cli);
 	
 	/* Get the list of extensions of the RADIUS request */
 	CHECK_POSIX( pthread_rwlock_rdlock( &plg_lock) );
@@ -411,10 +404,9 @@
 		
 		if (plg->descriptor->rgwp_diam_ans) {
 			TRACE_DEBUG(ANNOYING, "Calling next plugin: %s", plg->descriptor->rgwp_name);
-			ret = (*plg->descriptor->rgwp_diam_ans)(plg->cs, session, diam_ans, rad_ans, (void *)cli, &locstateful);
+			ret = (*plg->descriptor->rgwp_diam_ans)(plg->cs, diam_ans, rad_ans, (void *)cli);
 			if (ret)
 				break;
-			*stateful |= locstateful;
 		} else {
 			TRACE_DEBUG(ANNOYING, "Skipping extension '%s' (NULL callback)", plg->descriptor->rgwp_name);
 		}					
--- a/extensions/app_radgw/rgw_servers.c	Mon Mar 18 16:19:47 2013 +0100
+++ b/extensions/app_radgw/rgw_servers.c	Tue Mar 19 16:13:14 2013 +0100
@@ -132,8 +132,11 @@
 			continue;
 		}
 		
-		TRACE_DEBUG(FULL, "Received %d bytes", len);
-		TRACE_sSA(FD_LOG_DEBUG, FULL, " from ", &from, NI_NUMERICHOST | NI_NUMERICSERV, "" );
+		{
+			char __buf[1024];
+			sSA_DUMP_NODE_SERV(__buf, sizeof(__buf), &from, NI_NUMERICHOST | NI_NUMERICSERV );
+			TRACE_DEBUG(FULL, "Received %d bytes from %s", len, __buf);
+		}
 		
 		/* Search the associated client definition, if any */
 		CHECK_FCT_DO( rgw_clients_search((struct sockaddr *) &from, &nas_info),
@@ -272,8 +275,11 @@
 		((struct sockaddr_in6 *)&sto)->sin6_port = to_port;
 	}
 	
-	TRACE_DEBUG(FULL, "Sending %d bytes", buflen);
-	TRACE_sSA(FD_LOG_DEBUG, FULL, " to ", &sto, NI_NUMERICHOST | NI_NUMERICSERV, "" );
+	{
+		char __buf[1024];
+		sSA_DUMP_NODE_SERV(__buf, sizeof(__buf), &sto, NI_NUMERICHOST | NI_NUMERICSERV );
+		TRACE_DEBUG(FULL, "Sending %d bytes to %s", buflen, __buf);
+	}
 		
 	/* Send */
 	ret = sendto(SERVERS[idx].sock, buf, buflen, 0, (struct sockaddr *)&sto, sSAlen(&sto));
--- a/extensions/app_radgw/rgw_worker.c	Mon Mar 18 16:19:47 2013 +0100
+++ b/extensions/app_radgw/rgw_worker.c	Tue Mar 19 16:13:14 2013 +0100
@@ -53,7 +53,6 @@
 struct pending_answer {
 	struct rgw_radius_msg_meta * rad;  /* the RADIUS message that was received and translated */
 	struct rgw_client          * cli;  /* the client it was received from */
-	struct session 		   * sess; /* the Diameter session created for this message (useful?) */
 };
 
 /* Callback when a Diameter answer is received */
@@ -75,7 +74,6 @@
 		
 		struct rgw_radius_msg_meta * msg;
 		struct rgw_client * cli;
-		struct session * session;
 		struct msg * diam_msg;
 		int pb, a;
 		struct pending_answer * pa;
@@ -132,19 +130,14 @@
 				continue;
 			}  );
 		
-		session = NULL;
-		
 		/* Pass the message to the list of registered plugins */
-		CHECK_FCT_DO( rgw_plg_loop_req(&msg, &session, &diam_msg, cli), 
+		CHECK_FCT_DO( rgw_plg_loop_req(&msg, &diam_msg, cli), 
 			{
 				/* An error occurred, discard message */
 				if (diam_msg) {
 					CHECK_FCT_DO( fd_msg_free(diam_msg), );
 					diam_msg = NULL;
 				}
-				if (session) {
-					CHECK_FCT_DO( fd_sess_destroy(&session), );
-				}
 				rgw_msg_free(&msg);
 				rgw_clients_dispose(&cli);
 				continue;
@@ -180,10 +173,6 @@
 		
 		if (pb) {
 			/* Something went wrong during the conversion */
-			if (session) {
-				CHECK_FCT_DO( fd_sess_destroy(&session), );
-			}
-			
 			if (diam_msg) {
 				CHECK_FCT_DO( fd_msg_free(diam_msg), );
 				diam_msg = NULL;
@@ -201,15 +190,11 @@
 		memset(pa, 0, sizeof(*pa));
 		pa->rad = msg;
 		pa->cli = cli;
-		pa->sess= session;
 		
 		CHECK_FCT_DO( fd_msg_send( &diam_msg, receive_diam_answer, pa), 
 			{
 				/* If an error occurs, log and destroy the data */
 				fd_log_debug("An error occurred while sending Diameter message, please turn Debug on for detail.");
-				if (session) {
-					CHECK_FCT_DO( fd_sess_destroy(&session), );
-				}
 
 				if (diam_msg) {
 					CHECK_FCT_DO( fd_msg_free(diam_msg), );
@@ -238,7 +223,6 @@
 	struct avp *avp;
 	struct avp_hdr  *ahdr;
 	int pb = 0;
-	int keepsession=0;
 	
 	TRACE_ENTRY("%p %p", pa, ans);
 	CHECK_PARAMS_DO( pa && ans, return );
@@ -247,7 +231,7 @@
 	CHECK_MALLOC_DO( rad_ans = radius_msg_new(0, pa->rad->radius.hdr->identifier), goto out );
 	
 	/* Pass the Diameter answer to the same extensions as the request */
-	CHECK_FCT_DO( rgw_plg_loop_ans(pa->rad, pa->sess, ans, &rad_ans, pa->cli, &keepsession), goto out );
+	CHECK_FCT_DO( rgw_plg_loop_ans(pa->rad, ans, &rad_ans, pa->cli), goto out );
 
 	if (*ans != NULL) {
 
@@ -299,11 +283,6 @@
 		*ans = NULL;
 	}
 	
-	if (!keepsession) {
-		/* Destroy remaining session data (stateless gateway) */
-		CHECK_FCT_DO( fd_sess_destroy(&pa->sess),  );
-	}
-	
 	/* Clear the RADIUS request */
 	if (pa->rad) {
 		rgw_msg_free(&pa->rad);
--- a/extensions/app_radgw/rgwx_acct.c	Mon Mar 18 16:19:47 2013 +0100
+++ b/extensions/app_radgw/rgwx_acct.c	Tue Mar 19 16:13:14 2013 +0100
@@ -288,7 +288,7 @@
 }
 
 /* Incoming RADIUS request */
-static int acct_rad_req( struct rgwp_config * cs, struct session ** session, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli )
+static int acct_rad_req( struct rgwp_config * cs, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli )
 {
 	int idx;
 	int send_str=0;
@@ -302,6 +302,7 @@
 	size_t nattr_used = 0;
 	union avp_value value;
 	struct avp ** avp_tun = NULL, *avp = NULL;
+	struct session * sess;
 	
 	const char * prefix = "Diameter/";
 	size_t pref_len;
@@ -310,7 +311,7 @@
 	os0_t un = NULL;
 	size_t un_len = 0;
 	
-	TRACE_ENTRY("%p %p %p %p %p %p", cs, session, rad_req, rad_ans, diam_fw, cli);
+	TRACE_ENTRY("%p %p %p %p %p", cs, rad_req, rad_ans, diam_fw, cli);
 	CHECK_PARAMS(rad_req && (rad_req->hdr->code == RADIUS_CODE_ACCOUNTING_REQUEST) && rad_ans && diam_fw && *diam_fw);
 	
 	pref_len = strlen(prefix);
@@ -451,12 +452,12 @@
 	
 	if (status_type == RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_OFF) {
 		TRACE_DEBUG(FULL, "[acct.rgwx] Received Accounting-Off Acct-Status-Type attribute, we must terminate all active sessions.");
-		TODO("RADIUS side is rebooting, send STR on all sessions?");
+		TODO("RADIUS side is rebooting, send STR on all sessions???");
 		return ENOTSUP;
 	}
 	
 	/* Check if we got a valid session information, otherwise the server will not be able to handle the data... */
-	if (!*session && !si) {
+	if (!si) {
 		TRACE_DEBUG(INFO, "[acct.rgwx] RADIUS Account-Request from %s did not contain a CLASS attribute with Diameter session information, reject.", rgw_clients_id(cli));
 		return EINVAL;
 	}
@@ -482,11 +483,11 @@
 		value.os.len  = un_len - idx;
 	}
 	CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
-	CHECK_FCT( fd_msg_avp_add ( *diam_fw, *session ? MSG_BRW_LAST_CHILD : MSG_BRW_FIRST_CHILD, avp) );
+	CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
 	
-	/* Create the Session-Id AVP if needed */
-	if (!*session) {
-		CHECK_FCT( fd_sess_fromsid ( si, si_len, session, NULL) );
+	/* Create the Session-Id AVP */
+	{
+		CHECK_FCT( fd_sess_fromsid_msg ( si, si_len, &sess, NULL) );
 		
 		TRACE_DEBUG(FULL, "[acct.rgwx] Translating new accounting message for session '%.*s'...", si_len, si);
 		
@@ -496,6 +497,7 @@
 		value.os.len = si_len;
 		CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
 		CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
+		CHECK_FCT( fd_msg_sess_set(*diam_fw, sess) );
 	}
 	
 		
@@ -1176,7 +1178,6 @@
 	/* Store useful information in the session */
 	{
 		struct sess_state * st;
-		CHECK_PARAMS(session);
 		
 		CHECK_MALLOC( st = malloc(sizeof(struct sess_state)) );
 		memset(st, 0, sizeof(struct sess_state));
@@ -1185,7 +1186,7 @@
 			st->send_str = send_str;
 		}
 		st->term_cause = str_cause;
-		CHECK_FCT( fd_sess_state_store( cs->sess_hdl, *session, &st ) );
+		CHECK_FCT( fd_sess_state_store( cs->sess_hdl, sess, &st ) );
 	}
 	
 	return 0;
@@ -1221,17 +1222,22 @@
 	return;
 }
 
-static int acct_diam_ans( struct rgwp_config * cs, struct session * session, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli, int * stateful )
+static int acct_diam_ans( struct rgwp_config * cs, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli )
 {
+	struct session * sess;
 	struct sess_state * st = NULL, stloc;
 	struct avp *avp, *next;
-	struct avp_hdr *ahdr, *sid, *oh, *or;
+	struct avp_hdr *ahdr, *oh, *or;
+	os0_t sid = NULL;
+	size_t sidlen;
 	
-	TRACE_ENTRY("%p %p %p %p %p", cs, session, diam_ans, rad_fw, cli);
+	TRACE_ENTRY("%p %p %p %p", cs, diam_ans, rad_fw, cli);
 	CHECK_PARAMS(cs);
 	
-	if (session) {
-		CHECK_FCT( fd_sess_state_retrieve( cs->sess_hdl, session, &st ) );
+	CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, *diam_ans, &sess, NULL) );
+	if (sess) {
+		CHECK_FCT( fd_sess_state_retrieve( cs->sess_hdl, sess, &st ) );
+		CHECK_FCT( fd_sess_getsid(sess, &sid, &sidlen) );
 	}
 	
 	if (!st) {
@@ -1245,9 +1251,6 @@
 	st = &stloc;
 	
 	/* Search these AVPs first */
-	CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Session_Id, &avp) );
-	CHECK_FCT( fd_msg_avp_hdr ( avp, &sid ) );
-	
 	CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Origin_Host, &avp) );
 	CHECK_FCT( fd_msg_avp_hdr ( avp, &oh ) );
 
@@ -1268,7 +1271,7 @@
 			fd_log_debug("[acct.rgwx] Received Diameter answer with error code '%d' from server '%.*s', session %.*s, not translating into Accounting-Response",
 					ahdr->avp_value->u32, 
 					oh->avp_value->os.len, oh->avp_value->os.data,
-					sid->avp_value->os.len, sid->avp_value->os.data);
+					sidlen, sid);
 			CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Error_Message, &avp) );
 			if (avp) {
 				CHECK_FCT( fd_msg_avp_hdr ( avp, &ahdr ) );
@@ -1309,14 +1312,17 @@
 		/* Create a new STR message */
 		CHECK_FCT(  fd_msg_new ( cs->dict.Session_Termination_Request, MSGFL_ALLOC_ETEID, &str )  );
 		
-		/* Set the application-id to the auth application if available, accouting otherwise (not sure what is actually expected...) */
+		/* Set the application-id to the auth application if available, accounting otherwise (not sure what is actually expected...) */
 		CHECK_FCT( fd_msg_hdr ( str, &hdr ) );
 		hdr->msg_appl = st->auth_appl ?: AI_ACCT;
 		
 		/* Add the Session-Id AVP as first AVP */
 		CHECK_FCT( fd_msg_avp_new (  cs->dict.Session_Id, 0, &avp ) );
-		CHECK_FCT( fd_msg_avp_setvalue ( avp, sid->avp_value ) );
+		avp_val.os.data = sid;
+		avp_val.os.len = sidlen;
+		CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) );
 		CHECK_FCT( fd_msg_avp_add ( str, MSG_BRW_FIRST_CHILD, avp) );
+		CHECK_FCT( fd_sess_ref_msg(sess) );
 
 		/* Add the Destination-Realm as next AVP */
 		CHECK_FCT( fd_msg_avp_new ( cs->dict.Destination_Realm, 0, &avp ) );
--- a/extensions/app_radgw/rgwx_auth.c	Mon Mar 18 16:19:47 2013 +0100
+++ b/extensions/app_radgw/rgwx_auth.c	Tue Mar 19 16:13:14 2013 +0100
@@ -228,7 +228,7 @@
 }
 
 /* Handle an incoming RADIUS request */
-static int auth_rad_req( struct rgwp_config * cs, struct session ** session, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli )
+static int auth_rad_req( struct rgwp_config * cs, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli )
 {
 	int idx;
 	int got_id = 0;
@@ -249,9 +249,10 @@
 	size_t nattr_used = 0;
 	struct avp ** avp_tun = NULL, *avp = NULL;
 	union avp_value value;
+	struct session * sess;
 	
-	TRACE_ENTRY("%p %p %p %p %p %p", cs, session, rad_req, rad_ans, diam_fw, cli);
-	CHECK_PARAMS(cs && session && rad_req && (rad_req->hdr->code == RADIUS_CODE_ACCESS_REQUEST) && rad_ans && diam_fw && *diam_fw);
+	TRACE_ENTRY("%p %p %p %p %p", cs, rad_req, rad_ans, diam_fw, cli);
+	CHECK_PARAMS(cs && rad_req && (rad_req->hdr->code == RADIUS_CODE_ACCESS_REQUEST) && rad_ans && diam_fw && *diam_fw);
 	
 	pref_len = strlen(prefix);
 	
@@ -439,7 +440,7 @@
 		}
 	}
 	CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
-	CHECK_FCT( fd_msg_avp_add ( *diam_fw, *session ? MSG_BRW_LAST_CHILD : MSG_BRW_FIRST_CHILD, avp) );
+	CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
 	
 	/* Add the Destination-Host if found */
 	if (dh) {
@@ -447,17 +448,17 @@
 		value.os.data = (unsigned char *)dh;
 		value.os.len = dh_len;
 		CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
-		CHECK_FCT( fd_msg_avp_add ( *diam_fw, *session ? MSG_BRW_LAST_CHILD : MSG_BRW_FIRST_CHILD, avp) );
+		CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
 	}
 	
 	/* Create the session if it is not already done */
-	if (*session == NULL) {
+	{
 		os0_t sess_str = NULL;
 		size_t sess_strlen;
 		
 		if (si_len) {
 			/* We already have the Session-Id, just use it */
-			CHECK_FCT( fd_sess_fromsid_msg ( si, si_len, session, NULL) );
+			CHECK_FCT( fd_sess_fromsid_msg ( si, si_len, &sess, NULL) );
 		} else {
 			/* Create a new Session-Id string */
 			
@@ -475,7 +476,7 @@
 				/* If not found, create a new Session-Id. Our format is: {fqdn;hi32;lo32;username;diamid} */
 				CHECK_MALLOC( sess_str = malloc(un_len + 1 /* ';' */ + fd_g_config->cnf_diamid_len + 1 /* '\0' */) );
 				len = sprintf((char *)sess_str, "%.*s;%s", (int)un_len, un, fd_g_config->cnf_diamid);
-				CHECK_FCT( fd_sess_new(session, fqdn, fqdnlen, sess_str, len) );
+				CHECK_FCT( fd_sess_new(&sess, fqdn, fqdnlen, sess_str, len) );
 				free(sess_str);
 			} else {
 				/* We don't have enough information to create the Session-Id, the RADIUS message is probably invalid */
@@ -485,17 +486,16 @@
 		}
 		
 		/* Now, add the Session-Id AVP at beginning of Diameter message */
-		CHECK_FCT( fd_sess_getsid(*session, &sess_str, &sess_strlen) );
-		
+		CHECK_FCT( fd_sess_getsid(sess, &sess_str, &sess_strlen) );
 		TRACE_DEBUG(FULL, "[auth.rgwx] Translating new message for session '%s'...", sess_str);
 		
-		/* Add the Session-Id AVP as first AVP */
+		/* Now add this session in the message */
 		CHECK_FCT( fd_msg_avp_new ( cs->dict.Session_Id, 0, &avp ) );
 		value.os.data = sess_str;
 		value.os.len = sess_strlen;
 		CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
 		CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
-		CHECK_FCT( fd_msg_sess_set( *diam_fw, *session) );
+		CHECK_FCT( fd_msg_sess_set(*diam_fw, sess) );
 	}
 	
 	
@@ -1055,22 +1055,22 @@
 	rad_req->attr_used = nattr_used;
 
 	/* Store the request identifier in the session (if provided) */
-	if (*session) {
+	{
 		unsigned char * req_auth;
 		CHECK_MALLOC(req_auth = malloc(16));
 		memcpy(req_auth, &rad_req->hdr->authenticator[0], 16);
 		
-		CHECK_FCT( fd_sess_state_store( cs->sess_hdl, *session, &req_auth ) );
+		CHECK_FCT( fd_sess_state_store( cs->sess_hdl, sess, &req_auth ) );
 	}
 	
 	return 0;
 }
 
-static int auth_diam_ans( struct rgwp_config * cs, struct session * session, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli, int * stateful )
+static int auth_diam_ans( struct rgwp_config * cs, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli )
 {
 	struct msg_hdr * hdr;
-	struct avp *avp, *next, *avp_x, *avp_y, *asid, *aoh;
-	struct avp_hdr *ahdr, *sid, *oh;
+	struct avp *avp, *next, *avp_x, *avp_y, *aoh;
+	struct avp_hdr *ahdr, *oh;
 	uint8_t buf[254]; /* to store some attributes values (with final '\0') */
 	size_t sz;
 	int ta_set = 0;
@@ -1078,14 +1078,19 @@
 	uint8_t	tuntag = 0;
 	unsigned char * req_auth = NULL;
 	int error_cause = 0;
+	struct session * sess;
+	os0_t sid = NULL;
+	size_t sidlen;
 	
-	TRACE_ENTRY("%p %p %p %p %p", cs, session, diam_ans, rad_fw, cli);
-	CHECK_PARAMS(cs && session && diam_ans && *diam_ans && rad_fw && *rad_fw);
+	TRACE_ENTRY("%p %p %p %p", cs, diam_ans, rad_fw, cli);
+	CHECK_PARAMS(cs && diam_ans && *diam_ans && rad_fw && *rad_fw);
 	
 	/* Retrieve the request identified which was stored in the session */
-	if (session) {
-		CHECK_FCT( fd_sess_state_retrieve( cs->sess_hdl, session, &req_auth ) );
-	}
+	CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, *diam_ans, &sess, NULL) );
+	if (sess) {
+		CHECK_FCT( fd_sess_state_retrieve( cs->sess_hdl, sess, &req_auth ) );
+		CHECK_FCT( fd_sess_getsid(sess, &sid, &sidlen) );
+	} /* else ? */
 	
 	/*	
 	      -  If the Diameter Command-Code is set to AA-Answer and the
@@ -1144,8 +1149,6 @@
 	}
 
 	/* Search the different AVPs we handle here */
-	CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Session_Id, &asid) );
-	CHECK_FCT( fd_msg_avp_hdr ( asid, &sid ) );
 	CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Origin_Host, &aoh) );
 	CHECK_FCT( fd_msg_avp_hdr ( aoh, &oh ) );
 
@@ -1239,7 +1242,7 @@
 			fd_log_debug("[auth.rgwx] Received Diameter answer with error code '%d' from server '%.*s', session %.*s, translating into Access-Reject",
 					ahdr->avp_value->u32, 
 					oh->avp_value->os.len, oh->avp_value->os.data,
-					sid->avp_value->os.len, sid->avp_value->os.data);
+					sidlen, sid);
 			CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Error_Message, &avp_x) );
 			if (avp_x) {
 				CHECK_FCT( fd_msg_avp_hdr ( avp_x, &ahdr ) );
@@ -1270,7 +1273,7 @@
 		if (sizeof(buf) < (sz = snprintf((char *)buf, sizeof(buf), "Diameter/%.*s/%.*s/%.*s", 
 				(int)oh->avp_value->os.len,  (char *)oh->avp_value->os.data,
 				(int)ahdr->avp_value->os.len,  (char *)ahdr->avp_value->os.data,
-				(int)sid->avp_value->os.len, (char *)sid->avp_value->os.data))) {
+				(int)sidlen, (char *)sid))) {
 			TRACE_DEBUG(INFO, "Data truncated in State attribute: %s", buf);
 		}
 		CONV2RAD_STR(RADIUS_ATTR_STATE, buf, sz, 0);
@@ -1279,7 +1282,7 @@
 	if ((*rad_fw)->hdr->code == RADIUS_CODE_ACCESS_ACCEPT) {
 		/* Add the Session-Id */
 		if (sizeof(buf) < (sz = snprintf((char *)buf, sizeof(buf), "Diameter/%.*s", 
-				(int)sid->avp_value->os.len, sid->avp_value->os.data))) {
+				(int)sidlen, sid))) {
 			TRACE_DEBUG(INFO, "Data truncated in Class attribute: %s", buf);
 		}
 		CONV2RAD_STR(RADIUS_ATTR_CLASS, buf, sz, 0);
@@ -1454,7 +1457,7 @@
 								(ahdr->avp_value->u32 == 1) ? "AUTHENTICATE_ONLY" :
 									((ahdr->avp_value->u32 == 2) ? "AUTHORIZE_ONLY" : "???"),
 								oh->avp_value->os.len, oh->avp_value->os.data, 
-								sid->avp_value->os.len, sid->avp_value->os.len);
+								sidlen, sid);
 					}
 					break;
 				
@@ -1615,7 +1618,7 @@
 					/* This is not translatable to RADIUS */
 					fd_log_debug("[auth.rgwx] Received Diameter answer with non-translatable NAS-Filter-Rule AVP from '%.*s' (session: '%.*s'), ignoring.",
 							oh->avp_value->os.len, oh->avp_value->os.data,
-							sid->avp_value->os.len, sid->avp_value->os.data);
+							sidlen, sid);
 					handled = 0;
 					break;
 					
@@ -1648,7 +1651,7 @@
 					/* This is not translatable to RADIUS */
 					fd_log_debug("[auth.rgwx] Received Diameter answer with non-translatable QoS-Filter-Rule AVP from '%.*s' (session: '%.*s'), ignoring.",
 							oh->avp_value->os.len, oh->avp_value->os.data,
-							sid->avp_value->os.len, sid->avp_value->os.data);
+							sidlen, sid);
 					handled = 0;
 					break;
 					
@@ -1920,7 +1923,6 @@
 		}
 	}
 	
-	CHECK_FCT( fd_msg_free( asid ) );
 	CHECK_FCT( fd_msg_free( aoh ) );
 	free(req_auth);
 	
@@ -1929,7 +1931,7 @@
 			TRACE_DEBUG(INFO, "Error while adding Error-Cause attribute in RADIUS message");
 			return ENOMEM;
 		}
-	}		
+	}
 
 	if ((*rad_fw)->hdr->code == RADIUS_CODE_ACCESS_ACCEPT) {
 		/* Add the auth-application-id required for STR, or 0 if no STR is required */
--- a/extensions/app_radgw/rgwx_debug.c	Mon Mar 18 16:19:47 2013 +0100
+++ b/extensions/app_radgw/rgwx_debug.c	Tue Mar 19 16:13:14 2013 +0100
@@ -71,9 +71,9 @@
 }
 
 /* Function called when a new RADIUS message is being converted to Diameter */
-static int debug_rad_req( struct rgwp_config * cs, struct session ** session, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli )
+static int debug_rad_req( struct rgwp_config * cs, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli )
 {
-	TRACE_ENTRY("%p %p %p %p %p %p", cs, session, rad_req, rad_ans, diam_fw, cli);
+	TRACE_ENTRY("%p %p %p %p %p", cs, rad_req, rad_ans, diam_fw, cli);
 	
 	fd_log_debug("------------- RADIUS/Diameter Request Debug%s%s%s -------------", cs ? " [" : "", cs ? (char *)cs : "", cs ? "]" : "");
 	
@@ -98,25 +98,15 @@
 		fd_msg_dump_walk(0, *diam_fw);
 	}
 	
-	if (!session || ! *session) {
-		fd_log_debug(" Diameter session: NULL pointer");
-	} else {
-		os0_t str;
-		size_t str_len;
-		CHECK_FCT( fd_sess_getsid(*session, &str, &str_len) );
-
-		fd_log_debug(" Diameter session: %s", str);
-	}
-	
 	fd_log_debug("===========  Debug%s%s%s complete =============", cs ? " [" : "", cs ? (char *)cs : "", cs ? "]" : "");
 	
 	return 0;
 }
 
 /* This one, when Diameter answer is converted to RADIUS */
-static int debug_diam_ans( struct rgwp_config * cs, struct session * session, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli, int * stateful )
+static int debug_diam_ans( struct rgwp_config * cs, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli )
 {
-	TRACE_ENTRY("%p %p %p %p %p %p", cs, session, diam_ans, rad_fw, cli, stateful);
+	TRACE_ENTRY("%p %p %p %p", cs, diam_ans, rad_fw, cli);
 
 	fd_log_debug("------------- RADIUS/Diameter Answer Debug%s%s%s -------------", cs ? " [" : "", cs ? (char *)cs : "", cs ? "]" : "");
 	
--- a/extensions/app_radgw/rgwx_echodrop.c	Mon Mar 18 16:19:47 2013 +0100
+++ b/extensions/app_radgw/rgwx_echodrop.c	Tue Mar 19 16:13:14 2013 +0100
@@ -118,16 +118,15 @@
 
 
 /* Handle attributes from a RADIUS request as specified in the configuration */
-static int ed_rad_req( struct rgwp_config * cs, struct session ** session, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli )
+static int ed_rad_req( struct rgwp_config * cs, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli )
 {
 	size_t nattr_used = 0;
 	int idx;
-	
 	struct fd_list echo_list = FD_LIST_INITIALIZER(echo_list);
 	struct fd_list *li;
 	
-	TRACE_ENTRY("%p %p %p %p %p %p", cs, session, rad_req, rad_ans, diam_fw, cli);
-	CHECK_PARAMS(cs && rad_req && session);
+	TRACE_ENTRY("%p %p %p %p %p", cs, rad_req, rad_ans, diam_fw, cli);
+	CHECK_PARAMS(cs && rad_req);
 	
 	/* For each attribute in the original message */
 	for (idx = 0; idx < rad_req->attr_used; idx++) {
@@ -216,7 +215,11 @@
 	
 	/* Save the echoed values in the session, if any */
 	if (!FD_IS_LIST_EMPTY(&echo_list)) {
-		CHECK_PARAMS_DO(*session,
+		struct session * sess;
+		
+		CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, *diam_fw, &sess, NULL) );
+
+		CHECK_PARAMS_DO(sess,
 			{
 				fd_log_debug(	"[echodrop.rgwx] The extension is configured to echo some attributes from this message, but no session object has been created for it (yet)."
 						" Please check your configuration file and include a session-generating extension BEFORE calling echodrop.rgwx to echo attributes."
@@ -230,28 +233,31 @@
 		fd_list_move_end(li, &echo_list);
 		
 		/* Save the list in the session */
-		CHECK_FCT( fd_sess_state_store( cs->sess_hdl, *session, &li ) );
+		CHECK_FCT( fd_sess_state_store( cs->sess_hdl, sess, &li ) );
 	}
 	
 	return 0;
 }
 
 /* Process an answer: add the ECHO attributes back, if any */
-static int ed_diam_ans( struct rgwp_config * cs, struct session * session, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli, int * stateful )
+static int ed_diam_ans( struct rgwp_config * cs, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli )
 {
 	struct fd_list * list = NULL;
+	struct session * sess;
 	
-	TRACE_ENTRY("%p %p %p %p %p %p", cs, session, diam_ans, rad_fw, cli, stateful);
+	TRACE_ENTRY("%p %p %p %p", cs, diam_ans, rad_fw, cli);
 	CHECK_PARAMS(cs);
 	
+	CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, *diam_ans, &sess, NULL) );
+	
 	/* If there is no session associated, just give up */
-	if (! session ) {
+	if (! sess ) {
 		TRACE_DEBUG(FULL, "No session associated with the message, nothing to do here...");
 		return 0;
 	}
 	
 	/* Now try and retrieve any data from the session */
-	CHECK_FCT( fd_sess_state_retrieve( cs->sess_hdl, session, &list ) );
+	CHECK_FCT( fd_sess_state_retrieve( cs->sess_hdl, sess, &list ) );
 	if (list == NULL) {
 		/* No attribute saved in the session, just return */
 		return 0;
--- a/extensions/app_radgw/rgwx_sample.c	Mon Mar 18 16:19:47 2013 +0100
+++ b/extensions/app_radgw/rgwx_sample.c	Tue Mar 19 16:13:14 2013 +0100
@@ -69,18 +69,18 @@
 }
 
 /* This function is called on incoming RADIUS messages. It should handle (some) RADIUS data and store into the Diameter message. */
-static int sample_rad_req( struct rgwp_config * cs, struct session ** session, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli )
+static int sample_rad_req( struct rgwp_config * cs, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli )
 {
-	TRACE_ENTRY("%p %p %p %p %p %p", cs, session, rad_req, rad_ans, diam_fw, cli);
+	TRACE_ENTRY("%p %p %p %p %p", cs, rad_req, rad_ans, diam_fw, cli);
 	CHECK_PARAMS(cs);
 	TRACE_DEBUG(INFO, "RADIUS/Diameter Sample plugin received a new RADIUS message.");
 	return 0;
 }
 
 /* This function is called when a Diameter answer is coming back. It should remove the AVPs and add the attributes in the RADIUS message. */
-static int sample_diam_ans( struct rgwp_config * cs, struct session * session, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli, int * stateful )
+static int sample_diam_ans( struct rgwp_config * cs, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli )
 {
-	TRACE_ENTRY("%p %p %p %p %p %p", cs, session, diam_ans, rad_fw, cli, stateful);
+	TRACE_ENTRY("%p %p %p %p", cs, diam_ans, rad_fw, cli);
 	CHECK_PARAMS(cs);
 	TRACE_DEBUG(INFO, "RADIUS/Diameter Sample plugin received a new Diameter answer.");
 	return 0;
--- a/extensions/app_radgw/rgwx_sip.c	Mon Mar 18 16:19:47 2013 +0100
+++ b/extensions/app_radgw/rgwx_sip.c	Tue Mar 19 16:13:14 2013 +0100
@@ -1,7 +1,8 @@
 /*********************************************************************************************************
 * Software License Agreement (BSD License)                                                               *
 * Author: Alexandre Westfahl <awestfahl@freediameter.net>						 *
-*													 *
+*													 *												 *
+* Copyright (c) 2013, WIDE Project and NICT								 *
 * Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (Keio University), and the WIDE Project. 	 *		
 *													 *
 * All rights reserved.											 *
@@ -321,7 +322,7 @@
 
 
 /* Handle an incoming RADIUS request */
-static int sip_rad_req( struct rgwp_config * cs, struct session ** session, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli )
+static int sip_rad_req( struct rgwp_config * cs, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli )
 {
 	int idx;
 	int got_AOR = 0;
@@ -339,21 +340,20 @@
 	size_t nattr_used = 0;
 	struct avp *auth_data=NULL, *auth=NULL, *avp = NULL;
 	union avp_value value;
-	
-	TRACE_ENTRY("%p %p %p %p %p %p", cs, session, rad_req, rad_ans, diam_fw, cli);
-	
-	CHECK_PARAMS(rad_req && (rad_req->hdr->code == RADIUS_CODE_ACCESS_REQUEST) && rad_ans && diam_fw && *diam_fw && session);
+	struct session * sess;
 	
-	//We check that session is not already filled
-	if(*session)
-	{
-		TRACE_DEBUG(INFO,"INTERNAL ERROR: We are not supposed to receive a session in radSIP plugin.");
-		return EINVAL;
-	}
+	TRACE_ENTRY("%p %p %p %p %p", cs, rad_req, rad_ans, diam_fw, cli);
+	
+	CHECK_PARAMS(rad_req && (rad_req->hdr->code == RADIUS_CODE_ACCESS_REQUEST) && rad_ans && diam_fw && *diam_fw);
 	
 	/*
 	   RFC5090 RADIUS Extension Digest Application
 	*/
+	CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, *diam_fw, &sess, NULL) );
+	if (sess != NULL) {
+		TRACE_DEBUG(INFO,"INTERNAL ERROR: We are not supposed to receive a session in radSIP plugin.");
+		return EINVAL;		
+	}
 	
 	/* Check basic information is there */
 	for (idx = 0; idx < rad_req->attr_used; idx++) {
@@ -397,7 +397,7 @@
 					TRACE_DEBUG(INFO,"We haven't found the session.'");
 					return EINVAL;
 				}
-				CHECK_FCT(fd_sess_fromsid (sid, sidlen, session, NULL));
+				CHECK_FCT(fd_sess_fromsid_msg (sid, sidlen, &sess, NULL));
 				free(sid);
 							
 				
@@ -423,25 +423,34 @@
 	}
 
 	/* Create the session if it is not already done */
-	if (!*session) {
+	if (!sess) {
 		
 		DiamId_t fqdn;
 		size_t fqdn_len;
 		DiamId_t realm;
 		size_t realm_len;
 		
-		
-		
-		
 		/* Get information on the RADIUS client */
 		CHECK_FCT( rgw_clients_get_origin(cli, &fqdn, &fqdn_len, &realm, &realm_len) );
 		
 		/* Create a new Session-Id. The format is: {fqdn;hi32;lo32;username;diamid} */
 		CHECK_MALLOC( sid = malloc(un_len + 1 /* ';' */ + fd_g_config->cnf_diamid_len + 1 /* '\0' */) );
 		sidlen = sprintf((char *)sid, "%.*s;%s", (int)un_len, un, fd_g_config->cnf_diamid);
-		CHECK_FCT( fd_sess_new(session, fqdn, fqdn_len, sid, sidlen) );
+		CHECK_FCT( fd_sess_new(&sess, fqdn, fqdn_len, sid, sidlen) );
 		free(sid);
 	}
+	
+	/* Now, add the Session-Id AVP at beginning of Diameter message */
+	CHECK_FCT( fd_msg_avp_new ( cs->dict.Session_Id, 0, &avp ) );
+	value.os.data = sid;
+	value.os.len = sidlen;
+	CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+	CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
+	
+	TRACE_DEBUG(FULL, "[sip.rgwx] Translating new message for session '%s'...", sid);
+	
+	/* Now add this session in the message */
+	CHECK_FCT( fd_msg_sess_set(*diam_fw, sess) );
 		
 	/* Add the Destination-Realm AVP */
 	CHECK_FCT( fd_msg_avp_new ( cs->dict.Destination_Realm, 0, &avp ) );
@@ -466,20 +475,7 @@
 	}
 	
 	CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
-	CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
-	
-	/* Now, add the Session-Id AVP at beginning of Diameter message */
-	CHECK_FCT( fd_sess_getsid(*session, &sid, &sidlen) );
-	
-	TRACE_DEBUG(FULL, "[sip.rgwx] Translating new message for session '%s'...", sid);
-	
-	/* Add the Session-Id AVP as first AVP */
-	CHECK_FCT( fd_msg_avp_new ( cs->dict.Session_Id, 0, &avp ) );
-	value.os.data = sid;
-	value.os.len = sidlen;
-	CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
-	CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
-	CHECK_FCT( fd_msg_sess_set( *diam_fw, *session) );
+	CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
 	
 	/*
 	If the RADIUS Access-Request message does not
@@ -720,33 +716,33 @@
 
 	//fd_msg_dump_walk(1,*diam_fw);
 	
-	/* Store the request identifier in the session (if provided) */
-	if (*session) {
+	/* Store the request identifier in the session */
+	{
 		unsigned char * req_sip;
 		CHECK_MALLOC(req_sip = malloc(16));
 		memcpy(req_sip, &rad_req->hdr->authenticator[0], 16);
 		
-		CHECK_FCT( fd_sess_state_store( cs->sess_hdl, *session, &req_sip ) );
+		CHECK_FCT( fd_sess_state_store( cs->sess_hdl, sess, &req_sip ) );
 	}
 	
 	
 	return 0;
 }
 
-static int sip_diam_ans( struct rgwp_config * cs, struct session * session, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli, int * statefull )
+static int sip_diam_ans( struct rgwp_config * cs, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli )
 {
 	
 	
-	struct avp *avp, *next, *asid;
-	struct avp_hdr *ahdr, *sid;
+	struct avp *avp, *next;
+	struct avp_hdr *ahdr;
 	//char buf[254]; /* to store some attributes values (with final '\0') */
 	unsigned char * req_sip = NULL;
+	struct session * sess;
+	os0_t sid = NULL;
+	size_t sidlen;
 	
-	TRACE_ENTRY("%p %p %p %p %p", cs, session, diam_ans, rad_fw, cli);
-	CHECK_PARAMS(cs && session && diam_ans && *diam_ans && rad_fw && *rad_fw);
-	
-	
-	
+	TRACE_ENTRY("%p %p %p %p", cs, diam_ans, rad_fw, cli);
+	CHECK_PARAMS(cs && diam_ans && *diam_ans && rad_fw && *rad_fw);
 	
 	
 	/* MACROS to help in the process: convert AVP data to RADIUS attributes. */
@@ -776,10 +772,12 @@
 		CHECK_MALLOC(radius_msg_add_attr(*rad_fw, (_attr_), (uint8_t *)&__v, sizeof(__v)));	\
 	}
 
+	/* Search the different AVPs we handle here */
+	CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, *diam_ans, &sess, NULL) );
+	if (sess) {
+		CHECK_FCT( fd_sess_getsid(sess, &sid, &sidlen) );
+	}
 
-	/* Search the different AVPs we handle here */
-	CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Session_Id, &asid) );
-	CHECK_FCT( fd_msg_avp_hdr ( asid, &sid ) );
 
 	/* Check the Diameter error code */
 	CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Result_Code, &avp) );
@@ -803,8 +801,7 @@
 		default:
 			(*rad_fw)->hdr->code = RADIUS_CODE_ACCESS_REJECT;
 			fd_log_debug("[sip.rgwx] Received Diameter answer with error code '%d', session %.*s, translating into Access-Reject",
-					ahdr->avp_value->u32, 
-					sid->avp_value->os.len, sid->avp_value->os.data);
+					ahdr->avp_value->u32, sidlen, sid);
 			return 0;
 	}
 	/* Remove this Result-Code avp */
@@ -826,14 +823,7 @@
 				
 				case DIAM_ATTR_DIGEST_NONCE:
 					CONV2RAD_STR(DIAM_ATTR_DIGEST_NONCE, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 0);
-					/* Retrieve the request identified which was stored in the session */
-					if (session) {
-						os0_t sid=NULL;
-						size_t sidlen;
-						fd_sess_getsid (session, &sid, &sidlen );
-						
-						nonce_add_element(ahdr->avp_value->os.data, ahdr->avp_value->os.len, sid, sidlen, cs);
-					}
+					nonce_add_element(ahdr->avp_value->os.data, ahdr->avp_value->os.len, sid, sidlen, cs);
 					break;
 				case DIAM_ATTR_DIGEST_REALM:
 					CONV2RAD_STR(DIAM_ATTR_DIGEST_REALM, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
@@ -866,13 +856,9 @@
 		}
 	}
 	
-	if (session) 
-	{
-		CHECK_FCT( fd_sess_state_retrieve( cs->sess_hdl, session, &req_sip ) );
-	}
+	CHECK_FCT( fd_sess_state_retrieve( cs->sess_hdl, sess, &req_sip ) );
 	free(req_sip);
 	
-	
 	return 0;
 }
 
"Welcome to our mercurial repository"