Mercurial > hg > freeDiameter
diff libfreeDiameter/messages.c @ 85:e5fcd672caff
Added new function to retrieve messages sessions easily
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Thu, 03 Dec 2009 14:59:23 +0900 |
parents | c662d3eb6ff6 |
children | 2c9444152e4b |
line wrap: on
line diff
--- a/libfreeDiameter/messages.c Wed Dec 02 18:28:49 2009 +0900 +++ b/libfreeDiameter/messages.c Thu Dec 03 14:59:23 2009 +0900 @@ -118,6 +118,7 @@ int msg_routable; /* Is this a routable message? (0: undef, 1: routable, 2: non routable) */ struct msg *msg_query; /* the associated query if the message is a received answer */ struct rt_data *msg_rtdata; /* Routing list for the query */ + struct session *msg_sess; /* Cached message session if any */ struct { void (*fct)(void *, struct msg **); void * data; @@ -572,6 +573,10 @@ fd_rtd_free(&_M(obj)->msg_rtdata); } + if ((obj->type == MSG_MSG) && (_M(obj)->msg_sess != NULL)) { + CHECK_FCT_DO( fd_sess_reclaim_msg ( &_M(obj)->msg_sess ), /* continue */); + } + /* free the object */ free(obj); @@ -660,8 +665,8 @@ msg->msg_public.msg_hbhid, msg->msg_public.msg_eteid ); - fd_log_debug(INOBJHDR "intern: rwb:%p rt:%d cb:%p(%p) qry:%p src:%s\n", - INOBJHDRVAL, msg->msg_rawbuffer, msg->msg_routable, msg->msg_cb.fct, msg->msg_cb.data, msg->msg_query, msg->msg_src_id?:"(nil)"); + fd_log_debug(INOBJHDR "intern: rwb:%p rt:%d cb:%p(%p) qry:%p sess:%p src:%s\n", + INOBJHDRVAL, msg->msg_rawbuffer, msg->msg_routable, msg->msg_cb.fct, msg->msg_cb.data, msg->msg_query, msg->msg_sess, msg->msg_src_id?:"(nil)"); } #define DUMP_VALUE(_format, _parms...) fd_log_debug(INOBJHDR "value : t:'%s' v:'" _format "'\n", INOBJHDRVAL, typename, ## _parms); @@ -1128,6 +1133,57 @@ return 0; } +/* Retrieve the session of the message */ +int fd_msg_sess_get(struct dictionary * dict, struct msg * msg, struct session ** session, int * new) +{ + struct avp * avp; + + TRACE_ENTRY("%p %p %p", msg, session, new); + + /* Check we received valid parameters */ + CHECK_PARAMS( CHECK_MSG(msg) ); + CHECK_PARAMS( session ); + + /* If we already resolved the session, just send it back */ + if (msg->msg_sess) { + *session = msg->msg_sess; + if (new) + *new = 0; + return 0; + } + + /* OK, we have to search for Session-Id AVP -- it is usually the first AVP, but let's be permissive here */ + /* -- note: we accept messages that have not yet been dictionary parsed... */ + CHECK_FCT( fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, &avp, NULL) ); + while (avp) { + if ( (avp->avp_public.avp_code == AC_SESSION_ID) + && (avp->avp_public.avp_vendor == 0) ) + break; + + /* Otherwise move to next AVP in the message */ + CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) ); + } + + if (!avp) { + TRACE_DEBUG(FULL, "No Session-Id AVP found in message %p", msg); + *session = NULL; + return 0; + } + + if (!avp->avp_model) { + CHECK_FCT( fd_msg_parse_dict ( avp, dict ) ); + } + + ASSERT( avp->avp_public.avp_value ); + + /* Resolve the session and we are done */ + CHECK_FCT( fd_sess_fromsid_msg ( avp->avp_public.avp_value->os.data, avp->avp_public.avp_value->os.len, &msg->msg_sess, new) ); + *session = msg->msg_sess; + + return 0; +} + + /******************* End-to-end counter *********************/ uint32_t fd_eteid; pthread_mutex_t fd_eteid_lck = PTHREAD_MUTEX_INITIALIZER;