Mercurial > hg > freeDiameter
comparison 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 |
comparison
equal
deleted
inserted
replaced
84:03740d31e56e | 85:e5fcd672caff |
---|---|
116 | 116 |
117 uint8_t *msg_rawbuffer; /* data buffer that was received, saved during fd_msg_parse_buffer and freed in fd_msg_parse_dict */ | 117 uint8_t *msg_rawbuffer; /* data buffer that was received, saved during fd_msg_parse_buffer and freed in fd_msg_parse_dict */ |
118 int msg_routable; /* Is this a routable message? (0: undef, 1: routable, 2: non routable) */ | 118 int msg_routable; /* Is this a routable message? (0: undef, 1: routable, 2: non routable) */ |
119 struct msg *msg_query; /* the associated query if the message is a received answer */ | 119 struct msg *msg_query; /* the associated query if the message is a received answer */ |
120 struct rt_data *msg_rtdata; /* Routing list for the query */ | 120 struct rt_data *msg_rtdata; /* Routing list for the query */ |
121 struct session *msg_sess; /* Cached message session if any */ | |
121 struct { | 122 struct { |
122 void (*fct)(void *, struct msg **); | 123 void (*fct)(void *, struct msg **); |
123 void * data; | 124 void * data; |
124 } msg_cb; /* Callback to be called when an answer is received, if not NULL */ | 125 } msg_cb; /* Callback to be called when an answer is received, if not NULL */ |
125 char * msg_src_id; /* Diameter Id of the peer this message was received from. This string is malloc'd and must be freed */ | 126 char * msg_src_id; /* Diameter Id of the peer this message was received from. This string is malloc'd and must be freed */ |
570 | 571 |
571 if ((obj->type == MSG_MSG) && (_M(obj)->msg_rtdata != NULL)) { | 572 if ((obj->type == MSG_MSG) && (_M(obj)->msg_rtdata != NULL)) { |
572 fd_rtd_free(&_M(obj)->msg_rtdata); | 573 fd_rtd_free(&_M(obj)->msg_rtdata); |
573 } | 574 } |
574 | 575 |
576 if ((obj->type == MSG_MSG) && (_M(obj)->msg_sess != NULL)) { | |
577 CHECK_FCT_DO( fd_sess_reclaim_msg ( &_M(obj)->msg_sess ), /* continue */); | |
578 } | |
579 | |
575 /* free the object */ | 580 /* free the object */ |
576 free(obj); | 581 free(obj); |
577 | 582 |
578 return 0; | 583 return 0; |
579 } | 584 } |
658 msg->msg_public.msg_code, | 663 msg->msg_public.msg_code, |
659 msg->msg_public.msg_appl, | 664 msg->msg_public.msg_appl, |
660 msg->msg_public.msg_hbhid, | 665 msg->msg_public.msg_hbhid, |
661 msg->msg_public.msg_eteid | 666 msg->msg_public.msg_eteid |
662 ); | 667 ); |
663 fd_log_debug(INOBJHDR "intern: rwb:%p rt:%d cb:%p(%p) qry:%p src:%s\n", | 668 fd_log_debug(INOBJHDR "intern: rwb:%p rt:%d cb:%p(%p) qry:%p sess:%p src:%s\n", |
664 INOBJHDRVAL, msg->msg_rawbuffer, msg->msg_routable, msg->msg_cb.fct, msg->msg_cb.data, msg->msg_query, msg->msg_src_id?:"(nil)"); | 669 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)"); |
665 } | 670 } |
666 | 671 |
667 #define DUMP_VALUE(_format, _parms...) fd_log_debug(INOBJHDR "value : t:'%s' v:'" _format "'\n", INOBJHDRVAL, typename, ## _parms); | 672 #define DUMP_VALUE(_format, _parms...) fd_log_debug(INOBJHDR "value : t:'%s' v:'" _format "'\n", INOBJHDRVAL, typename, ## _parms); |
668 /* Dump an AVP value that is not a constant */ | 673 /* Dump an AVP value that is not a constant */ |
669 static void dump_basic_type(union avp_value * value, enum dict_avp_basetype type, const char * typename, int indent) | 674 static void dump_basic_type(union avp_value * value, enum dict_avp_basetype type, const char * typename, int indent) |
1126 | 1131 |
1127 /* done */ | 1132 /* done */ |
1128 return 0; | 1133 return 0; |
1129 } | 1134 } |
1130 | 1135 |
1136 /* Retrieve the session of the message */ | |
1137 int fd_msg_sess_get(struct dictionary * dict, struct msg * msg, struct session ** session, int * new) | |
1138 { | |
1139 struct avp * avp; | |
1140 | |
1141 TRACE_ENTRY("%p %p %p", msg, session, new); | |
1142 | |
1143 /* Check we received valid parameters */ | |
1144 CHECK_PARAMS( CHECK_MSG(msg) ); | |
1145 CHECK_PARAMS( session ); | |
1146 | |
1147 /* If we already resolved the session, just send it back */ | |
1148 if (msg->msg_sess) { | |
1149 *session = msg->msg_sess; | |
1150 if (new) | |
1151 *new = 0; | |
1152 return 0; | |
1153 } | |
1154 | |
1155 /* OK, we have to search for Session-Id AVP -- it is usually the first AVP, but let's be permissive here */ | |
1156 /* -- note: we accept messages that have not yet been dictionary parsed... */ | |
1157 CHECK_FCT( fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, &avp, NULL) ); | |
1158 while (avp) { | |
1159 if ( (avp->avp_public.avp_code == AC_SESSION_ID) | |
1160 && (avp->avp_public.avp_vendor == 0) ) | |
1161 break; | |
1162 | |
1163 /* Otherwise move to next AVP in the message */ | |
1164 CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) ); | |
1165 } | |
1166 | |
1167 if (!avp) { | |
1168 TRACE_DEBUG(FULL, "No Session-Id AVP found in message %p", msg); | |
1169 *session = NULL; | |
1170 return 0; | |
1171 } | |
1172 | |
1173 if (!avp->avp_model) { | |
1174 CHECK_FCT( fd_msg_parse_dict ( avp, dict ) ); | |
1175 } | |
1176 | |
1177 ASSERT( avp->avp_public.avp_value ); | |
1178 | |
1179 /* Resolve the session and we are done */ | |
1180 CHECK_FCT( fd_sess_fromsid_msg ( avp->avp_public.avp_value->os.data, avp->avp_public.avp_value->os.len, &msg->msg_sess, new) ); | |
1181 *session = msg->msg_sess; | |
1182 | |
1183 return 0; | |
1184 } | |
1185 | |
1186 | |
1131 /******************* End-to-end counter *********************/ | 1187 /******************* End-to-end counter *********************/ |
1132 uint32_t fd_eteid; | 1188 uint32_t fd_eteid; |
1133 pthread_mutex_t fd_eteid_lck = PTHREAD_MUTEX_INITIALIZER; | 1189 pthread_mutex_t fd_eteid_lck = PTHREAD_MUTEX_INITIALIZER; |
1134 | 1190 |
1135 void fd_msg_eteid_init(void) | 1191 void fd_msg_eteid_init(void) |