Mercurial > hg > freeDiameter
diff libfdcore/messages.c @ 706:4ffbc9f1e922
Large UNTESTED commit with the following changes:
* Improved DiameterIdentity handling (esp. interationalization issues),
and improve efficiency of some string operations in peers, sessions,
and dictionary modules (closes #7)
* Cleanup in the session module to free only unreferenced sessions (#16)
* Removed fd_cpu_flush_cache(), replaced by more robust alternatives.
* Improved peer state machine algorithm to counter SCTP multistream race
condition.
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Wed, 09 Feb 2011 15:26:58 +0900 |
parents | 8c3dc8584dab |
children | 4a9f08d6b6ba |
line wrap: on
line diff
--- a/libfdcore/messages.c Mon Jan 31 17:22:21 2011 +0900 +++ b/libfdcore/messages.c Wed Feb 09 15:26:58 2011 +0900 @@ -35,6 +35,7 @@ #include "fdcore-internal.h" +static struct dict_object * dict_avp_SI = NULL; /* Session-Id */ static struct dict_object * dict_avp_OH = NULL; /* Origin-Host */ static struct dict_object * dict_avp_OR = NULL; /* Origin-Realm */ static struct dict_object * dict_avp_EM = NULL; /* Error-Message */ @@ -53,6 +54,7 @@ TRACE_ENTRY(""); /* Initialize the dictionary objects that we may use frequently */ + CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &dict_avp_SI , ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Host", &dict_avp_OH , ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Realm", &dict_avp_OR , ENOENT) ); CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-State-Id", &fd_dict_avp_OSI , ENOENT) ); @@ -88,7 +90,7 @@ /* Set its value */ memset(&val, 0, sizeof(val)); - val.os.data = (unsigned char *)fd_g_config->cnf_diamid; + val.os.data = (os0_t)fd_g_config->cnf_diamid; val.os.len = fd_g_config->cnf_diamid_len; CHECK_FCT( fd_msg_avp_setvalue( avp_OH, &val ) ); @@ -101,7 +103,7 @@ /* Set its value */ memset(&val, 0, sizeof(val)); - val.os.data = (unsigned char *)fd_g_config->cnf_diamrlm; + val.os.data = (os0_t)fd_g_config->cnf_diamrlm; val.os.len = fd_g_config->cnf_diamrlm_len; CHECK_FCT( fd_msg_avp_setvalue( avp_OR, &val ) ); @@ -124,6 +126,43 @@ return 0; } +/* Create a new Session-Id and add at the beginning of the message. */ +int fd_msg_new_session( struct msg * msg, os0_t opt, size_t optlen ) +{ + union avp_value val; + struct avp * avp = NULL; + struct session * sess = NULL; + os0_t sid; + size_t sidlen; + + TRACE_ENTRY("%p %p %zd", msg, opt, optlen); + CHECK_PARAMS( msg ); + + /* Check there is not already a session in the message */ + CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, msg, &sess, NULL) ); + CHECK_PARAMS( sess == NULL ); + + /* Ok, now create the session */ + CHECK_FCT( fd_sess_new ( &sess, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, opt, optlen ) ); + CHECK_FCT( fd_sess_getsid( sess, &sid, &sidlen) ); + + /* Create an AVP to hold it */ + CHECK_FCT( fd_msg_avp_new( dict_avp_SI, 0, &avp ) ); + + /* Set its value */ + memset(&val, 0, sizeof(val)); + val.os.data = sid; + val.os.len = sidlen; + CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) ); + + /* Add it to the message */ + CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_FIRST_CHILD, avp ) ); + + /* Done! */ + return 0; +} + + /* Add Result-Code and eventually Failed-AVP, Error-Message and Error-Reporting-Host AVPs */ int fd_msg_rescode_set( struct msg * msg, char * rescode, char * errormsg, struct avp * optavp, int type_id ) { @@ -146,7 +185,7 @@ struct dict_enumval_request req; memset(&req, 0, sizeof(struct dict_enumval_request)); - /* First, get the enumerated type of the Result-Code AVP */ + /* First, get the enumerated type of the Result-Code AVP (this is fast, no need to cache the object) */ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_TYPE, TYPE_OF_AVP, dict_avp_RC, &(req.type_obj), ENOENT ) ); /* Now search for the value given as parameter */ @@ -183,7 +222,7 @@ /* Set its value */ memset(&val, 0, sizeof(val)); - val.os.data = (unsigned char *)fd_g_config->cnf_diamid; + val.os.data = (uint8_t *)fd_g_config->cnf_diamid; val.os.len = fd_g_config->cnf_diamid_len; CHECK_FCT( fd_msg_avp_setvalue( avp_ERH, &val ) ); @@ -245,10 +284,10 @@ memset(&val, 0, sizeof(val)); if (errormsg) { - val.os.data = (unsigned char *)errormsg; + val.os.data = (uint8_t *)errormsg; val.os.len = strlen(errormsg); } else { - val.os.data = (unsigned char *)rescode; + val.os.data = (uint8_t *)rescode; val.os.len = strlen(rescode); } CHECK_FCT( fd_msg_avp_setvalue( avp_EM, &val ) ); @@ -310,7 +349,7 @@ ret = fd_msg_parse_rules ( m, fd_g_config->cnf_dict, &pei); if ((ret != EBADMSG) /* Parsing grouped AVP failed / Conflicting rule found */ && (ret != ENOTSUP)) /* Command is not supported / Mandatory AVP is not supported */ - return ret; + return ret; /* 0 or another error */ TRACE_DEBUG(INFO, "A message does not comply to the dictionary and/or rules (%s)", pei.pei_errcode); fd_msg_dump_walk(FULL, m);