Mercurial > hg > freeDiameter
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; }