Mercurial > hg > freeDiameter
annotate libfdproto/messages.c @ 1327:82b386714795
Set callback data also when only setting expire callback (and not answer callback as well).
It is used when calling the expire callback, so not setting it makes no sense.
author | Thomas Klausner <tk@giga.or.at> |
---|---|
date | Mon, 27 Nov 2017 15:21:20 +0100 |
parents | 84a3c9c4b834 |
children | 6a35c5470ef4 3cbe458fbfa9 |
rev | line source |
---|---|
0 | 1 /********************************************************************************************************* |
2 * Software License Agreement (BSD License) * | |
740
4a9f08d6b6ba
Updated my mail address
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
730
diff
changeset
|
3 * Author: Sebastien Decugis <sdecugis@freediameter.net> * |
0 | 4 * * |
1305
84a3c9c4b834
Updated copyright information
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1300
diff
changeset
|
5 * Copyright (c) 2015, WIDE Project and NICT * |
0 | 6 * All rights reserved. * |
7 * * | |
8 * Redistribution and use of this software in source and binary forms, with or without modification, are * | |
9 * permitted provided that the following conditions are met: * | |
10 * * | |
11 * * Redistributions of source code must retain the above * | |
12 * copyright notice, this list of conditions and the * | |
13 * following disclaimer. * | |
14 * * | |
15 * * Redistributions in binary form must reproduce the above * | |
16 * copyright notice, this list of conditions and the * | |
17 * following disclaimer in the documentation and/or other * | |
18 * materials provided with the distribution. * | |
19 * * | |
20 * * Neither the name of the WIDE Project or NICT nor the * | |
21 * names of its contributors may be used to endorse or * | |
22 * promote products derived from this software without * | |
23 * specific prior written permission of WIDE Project and * | |
24 * NICT. * | |
25 * * | |
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * | |
27 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * | |
28 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * | |
29 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * | |
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * | |
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * | |
32 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * | |
33 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * | |
34 *********************************************************************************************************/ | |
35 | |
36 /* Messages module. | |
37 * | |
38 * This module allows to manipulate the msg and avp structures that represents a Diameter message in memory. | |
39 */ | |
40 | |
658
f198d16fa7f4
Initial commit for 1.1.0:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
656
diff
changeset
|
41 #include "fdproto-internal.h" |
0 | 42 |
43 #include <sys/param.h> | |
44 | |
45 /* Type of object */ | |
46 enum msg_objtype { | |
47 MSG_MSG = 1, | |
48 MSG_AVP | |
49 }; | |
50 | |
51 /* Chaining of elements as a free hierarchy */ | |
52 struct msg_avp_chain { | |
53 struct fd_list chaining; /* Chaining information at this level. */ | |
54 struct fd_list children; /* sentinel for the children of this object */ | |
55 enum msg_objtype type; /* Type of this object, _MSG_MSG or _MSG_AVP */ | |
56 }; | |
57 | |
58 /* Return the chain information from an AVP or MSG. Since it's the first field, we just cast */ | |
59 #define _C(_x) ((struct msg_avp_chain *)(_x)) | |
60 | |
61 /* Some details about chaining: | |
62 * | |
63 * A message is made of a header ( msg ) and 0 or more AVPs ( avp ). | |
64 * The structure is a kind of tree, where some AVPs (grouped AVPs) can contain other AVPs. | |
871 | 65 * Example: |
0 | 66 * msg |
67 * |-avp | |
68 * |-gavp | |
69 * | |-avp | |
70 * | |-avp | |
71 * | \-avp | |
72 * |-avp | |
73 * \-avp | |
74 * | |
75 * Each item (msg or avp) structure begins with a msg_avp_chain structure. | |
76 * The element at the top of the hierarchy (msg in our example) has all the fields of its "chaining" equal to the same value. | |
77 * | |
78 * All elements at the same level are linked by their "chaining" list. | |
79 * The "children" list is the sentinel for the lists of children of this element. | |
80 */ | |
81 | |
82 /* The following definitions are used to recognize objects in memory. */ | |
83 #define MSG_MSG_EYEC (0x11355463) | |
84 #define MSG_AVP_EYEC (0x11355467) | |
85 | |
86 /* The following structure represents an AVP instance. */ | |
87 struct avp { | |
88 struct msg_avp_chain avp_chain; /* Chaining information of this AVP */ | |
89 int avp_eyec; /* Must be equal to MSG_AVP_EYEC */ | |
90 struct dict_object *avp_model; /* If not NULL, pointer to the dictionary object of this avp */ | |
1092
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
91 struct { |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
92 avp_code_t mnf_code; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
93 vendor_id_t mnf_vendor; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
94 } avp_model_not_found; /* When model resolution has failed, store a copy of the data here to avoid searching again */ |
0 | 95 struct avp_hdr avp_public; /* AVP data that can be managed by other modules */ |
96 | |
97 uint8_t *avp_source; /* If the message was parsed from a buffer, pointer to the AVP data start in the buffer. */ | |
98 uint8_t *avp_rawdata; /* when the data can not be interpreted, the raw data is copied here. The header is not part of it. */ | |
99 size_t avp_rawlen; /* The length of the raw buffer. */ | |
100 union avp_value avp_storage; /* To avoid many alloc/free, store the integer values here and set avp_public.avp_data to &storage */ | |
101 int avp_mustfreeos; /* 1 if an octetstring is malloc'd in avp_storage and must be freed. */ | |
102 }; | |
103 | |
104 /* Macro to compute the AVP header size */ | |
105 #define AVPHDRSZ_NOVEND 8 | |
106 #define AVPHDRSZ_VENDOR 12 | |
107 #define GETAVPHDRSZ( _flag ) ((_flag & AVP_FLAG_VENDOR) ? AVPHDRSZ_VENDOR : AVPHDRSZ_NOVEND) | |
108 | |
109 /* Macro to cast a msg_avp_t */ | |
110 #define _A(_x) ((struct avp *)(_x)) | |
111 /* Check the type and eyecatcher */ | |
915
9bd18fa4e601
Fix macro to avoid infinite loop in some situations
Sebastien Decugis <sdecugis@freediameter.net>
parents:
903
diff
changeset
|
112 #define CHECK_AVP(_x) ((_x) && (_C(_x)->type == MSG_AVP) && (_A(_x)->avp_eyec == MSG_AVP_EYEC)) |
0 | 113 |
114 /* The following structure represents an instance of a message (command and children AVPs). */ | |
115 struct msg { | |
116 struct msg_avp_chain msg_chain; /* List of the AVPs in the message */ | |
117 int msg_eyec; /* Must be equal to MSG_MSG_EYEC */ | |
118 struct dict_object *msg_model; /* If not NULL, pointer to the dictionary object of this message */ | |
1092
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
119 struct { |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
120 command_code_t mnf_code; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
121 uint8_t mnf_flags; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
122 } msg_model_not_found; /* When model resolution has failed, store a copy of the data here to avoid searching again */ |
0 | 123 struct msg_hdr msg_public; /* Message data that can be managed by extensions. */ |
124 | |
125 uint8_t *msg_rawbuffer; /* data buffer that was received, saved during fd_msg_parse_buffer and freed in fd_msg_parse_dict */ | |
126 int msg_routable; /* Is this a routable message? (0: undef, 1: routable, 2: non routable) */ | |
127 struct msg *msg_query; /* the associated query if the message is a received answer */ | |
637
22e8fac3b2d6
Split interface file in modules
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
400
diff
changeset
|
128 int msg_associated; /* and the counter part information in the query, to avoid double free */ |
83
c662d3eb6ff6
Started support for routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
37
diff
changeset
|
129 struct rt_data *msg_rtdata; /* Routing list for the query */ |
85
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
130 struct session *msg_sess; /* Cached message session if any */ |
0 | 131 struct { |
1014
908ffbb81f60
Added a second callback in fd_msg_send_timeout to handle more easily the timeout situation
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1009
diff
changeset
|
132 void (*anscb)(void *, struct msg **); |
908ffbb81f60
Added a second callback in fd_msg_send_timeout to handle more easily the timeout situation
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1009
diff
changeset
|
133 void (*expirecb)(void *, DiamId_t, size_t, struct msg **); |
0 | 134 void * data; |
646
cfc8da9264f4
Prepared first part of the changes for #10
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
638
diff
changeset
|
135 struct timespec timeout; |
1014
908ffbb81f60
Added a second callback in fd_msg_send_timeout to handle more easily the timeout situation
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1009
diff
changeset
|
136 } msg_cb; /* Callback to be called when an answer is received, or timeout expires, if not NULL */ |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
137 DiamId_t msg_src_id; /* Diameter Id of the peer this message was received from. This string is malloc'd and must be freed */ |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
138 size_t msg_src_id_len; /* cached length of this string */ |
1098
f38d77f9cfd3
Initial implementation of the hook mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1096
diff
changeset
|
139 struct fd_msg_pmdl msg_pmdl; /* list of permessagedata structures. */ |
0 | 140 }; |
141 | |
142 /* Macro to compute the message header size */ | |
143 #define GETMSGHDRSZ() 20 | |
144 | |
145 /* Macro to cast a msg_avp_t */ | |
146 #define _M(_x) ((struct msg *)(_x)) | |
147 /* Check the type and eyecatcher */ | |
704
289632905e19
Added new sanity check
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
690
diff
changeset
|
148 #define CHECK_MSG(_x) ((_x) && (_C(_x)->type == MSG_MSG) && (_M(_x)->msg_eyec == MSG_MSG_EYEC)) |
0 | 149 |
150 #define VALIDATE_OBJ(_x) ( (CHECK_MSG(_x)) || (CHECK_AVP(_x)) ) | |
151 | |
152 | |
153 /* Macro to validate a MSGFL_ value */ | |
638
9448cba86673
Improved usability of dbg_interactive
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
637
diff
changeset
|
154 #define CHECK_AVPFL(_fl) ( ((_fl) & (- (AVPFL_MAX << 1) )) == 0 ) |
0 | 155 #define CHECK_MSGFL(_fl) ( ((_fl) & (- (MSGFL_MAX << 1) )) == 0 ) |
156 | |
157 | |
158 /* initial sizes of AVP from their types, in bytes. */ | |
159 static int avp_value_sizes[] = { | |
160 0, /* AVP_TYPE_GROUPED: size is dynamic */ | |
161 0, /* AVP_TYPE_OCTETSTRING: size is dynamic */ | |
162 4, /* AVP_TYPE_INTEGER32: size is 32 bits */ | |
163 8, /* AVP_TYPE_INTEGER64: size is 64 bits */ | |
164 4, /* AVP_TYPE_UNSIGNED32: size is 32 bits */ | |
165 8, /* AVP_TYPE_UNSIGNED64: size is 64 bits */ | |
166 4, /* AVP_TYPE_FLOAT32: size is 32 bits */ | |
167 8 /* AVP_TYPE_FLOAT64: size is 64 bits */ | |
168 }; | |
169 #define CHECK_BASETYPE( _type ) ( ((_type) <= AVP_TYPE_MAX) && ((_type) >= 0) ) | |
170 #define GETINITIALSIZE( _type, _vend ) (avp_value_sizes[ CHECK_BASETYPE(_type) ? (_type) : 0] + GETAVPHDRSZ(_vend)) | |
171 | |
172 /* Forward declaration */ | |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
173 static int parsedict_do_msg(struct dictionary * dict, struct msg * msg, int only_hdr, struct fd_pei *error_info); |
0 | 174 |
175 /***************************************************************************************************************/ | |
176 /* Creating objects */ | |
177 | |
178 /* Initialize a msg_avp_chain structure */ | |
179 static void init_chain(struct msg_avp_chain * chain, int type) | |
180 { | |
181 fd_list_init( &chain->chaining, (void *)chain); | |
182 fd_list_init( &chain->children, (void *)chain); | |
183 chain->type = type; | |
184 } | |
185 | |
186 /* Initialize a new AVP object */ | |
187 static void init_avp ( struct avp * avp ) | |
188 { | |
189 TRACE_ENTRY("%p", avp); | |
190 | |
191 memset(avp, 0, sizeof(struct avp)); | |
192 init_chain( &avp->avp_chain, MSG_AVP); | |
193 avp->avp_eyec = MSG_AVP_EYEC; | |
194 } | |
195 | |
196 /* Initialize a new MSG object */ | |
197 static void init_msg ( struct msg * msg ) | |
198 { | |
199 TRACE_ENTRY("%p", msg); | |
200 | |
201 memset(msg, 0, sizeof(struct msg)); | |
202 init_chain( &msg->msg_chain, MSG_MSG); | |
203 msg->msg_eyec = MSG_MSG_EYEC; | |
1103
d8591b1c56cd
Implemented a few hooks
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1101
diff
changeset
|
204 |
d8591b1c56cd
Implemented a few hooks
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1101
diff
changeset
|
205 fd_list_init(&msg->msg_pmdl.sentinel, NULL); |
d8591b1c56cd
Implemented a few hooks
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1101
diff
changeset
|
206 CHECK_POSIX_DO( pthread_mutex_init(&msg->msg_pmdl.lock, NULL), ); |
0 | 207 } |
208 | |
209 | |
210 /* Create a new AVP instance */ | |
211 int fd_msg_avp_new ( struct dict_object * model, int flags, struct avp ** avp ) | |
212 { | |
213 struct avp *new = NULL; | |
214 | |
215 TRACE_ENTRY("%p %x %p", model, flags, avp); | |
216 | |
217 /* Check the parameters */ | |
638
9448cba86673
Improved usability of dbg_interactive
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
637
diff
changeset
|
218 CHECK_PARAMS( avp && CHECK_AVPFL(flags) ); |
0 | 219 |
220 if (model) { | |
221 enum dict_object_type dicttype; | |
222 CHECK_PARAMS( (fd_dict_gettype(model, &dicttype) == 0) && (dicttype == DICT_AVP) ); | |
223 } | |
224 | |
225 /* Create a new object */ | |
226 CHECK_MALLOC( new = malloc (sizeof(struct avp)) ); | |
227 | |
228 /* Initialize the fields */ | |
229 init_avp(new); | |
230 | |
231 if (model) { | |
232 struct dict_avp_data dictdata; | |
233 | |
1298
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
234 CHECK_FCT_DO( fd_dict_getval(model, &dictdata), { free(new); return __ret__; } ); |
0 | 235 |
236 new->avp_model = model; | |
237 new->avp_public.avp_code = dictdata.avp_code; | |
238 new->avp_public.avp_flags = dictdata.avp_flag_val; | |
239 new->avp_public.avp_len = GETINITIALSIZE(dictdata.avp_basetype, dictdata.avp_flag_val ); | |
240 new->avp_public.avp_vendor = dictdata.avp_vendor; | |
241 } | |
242 | |
638
9448cba86673
Improved usability of dbg_interactive
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
637
diff
changeset
|
243 if (flags & AVPFL_SET_BLANK_VALUE) { |
9448cba86673
Improved usability of dbg_interactive
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
637
diff
changeset
|
244 new->avp_public.avp_value = &new->avp_storage; |
9448cba86673
Improved usability of dbg_interactive
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
637
diff
changeset
|
245 } |
9448cba86673
Improved usability of dbg_interactive
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
637
diff
changeset
|
246 |
892
b2e8f1a3ef76
Allow the content of the Failed-AVP to be parseable to bufferize the message. The content is only padded currently
Sebastien Decugis <sdecugis@freediameter.net>
parents:
891
diff
changeset
|
247 if (flags & AVPFL_SET_RAWDATA_FROM_AVP) { |
b2e8f1a3ef76
Allow the content of the Failed-AVP to be parseable to bufferize the message. The content is only padded currently
Sebastien Decugis <sdecugis@freediameter.net>
parents:
891
diff
changeset
|
248 new->avp_rawlen = (*avp)->avp_public.avp_len - GETAVPHDRSZ( (*avp)->avp_public.avp_flags ); |
b2e8f1a3ef76
Allow the content of the Failed-AVP to be parseable to bufferize the message. The content is only padded currently
Sebastien Decugis <sdecugis@freediameter.net>
parents:
891
diff
changeset
|
249 if (new->avp_rawlen) { |
1298
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
250 CHECK_MALLOC_DO( new->avp_rawdata = malloc(new->avp_rawlen), { free(new); return __ret__; } ); |
916
058e95c3a336
Initialize dummy AVP for Failed-AVP content with 0s instead of FFs
Sebastien Decugis <sdecugis@freediameter.net>
parents:
915
diff
changeset
|
251 memset(new->avp_rawdata, 0x00, new->avp_rawlen); |
892
b2e8f1a3ef76
Allow the content of the Failed-AVP to be parseable to bufferize the message. The content is only padded currently
Sebastien Decugis <sdecugis@freediameter.net>
parents:
891
diff
changeset
|
252 } |
b2e8f1a3ef76
Allow the content of the Failed-AVP to be parseable to bufferize the message. The content is only padded currently
Sebastien Decugis <sdecugis@freediameter.net>
parents:
891
diff
changeset
|
253 } |
b2e8f1a3ef76
Allow the content of the Failed-AVP to be parseable to bufferize the message. The content is only padded currently
Sebastien Decugis <sdecugis@freediameter.net>
parents:
891
diff
changeset
|
254 |
0 | 255 /* The new object is ready, return */ |
256 *avp = new; | |
257 return 0; | |
258 } | |
259 | |
260 /* Create a new message instance */ | |
261 int fd_msg_new ( struct dict_object * model, int flags, struct msg ** msg ) | |
262 { | |
263 struct msg * new = NULL; | |
264 | |
265 TRACE_ENTRY("%p %x %p", model, flags, msg); | |
266 | |
267 /* Check the parameters */ | |
268 CHECK_PARAMS( msg && CHECK_MSGFL(flags) ); | |
269 | |
270 if (model) { | |
271 enum dict_object_type dicttype; | |
272 CHECK_PARAMS( (fd_dict_gettype(model, &dicttype) == 0) && (dicttype == DICT_COMMAND) ); | |
273 } | |
274 | |
275 /* Create a new object */ | |
276 CHECK_MALLOC( new = malloc (sizeof(struct msg)) ); | |
277 | |
278 /* Initialize the fields */ | |
279 init_msg(new); | |
280 new->msg_public.msg_version = DIAMETER_VERSION; | |
281 new->msg_public.msg_length = GETMSGHDRSZ(); /* This will be updated later */ | |
282 | |
283 if (model) { | |
284 struct dictionary *dict; | |
285 struct dict_cmd_data dictdata; | |
286 struct dict_object *dictappl; | |
287 | |
1298
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
288 CHECK_FCT_DO( fd_dict_getdict(model, &dict), { free(new); return __ret__; } ); |
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
289 CHECK_FCT_DO( fd_dict_getval(model, &dictdata), { free(new); return __ret__; } ); |
0 | 290 |
291 new->msg_model = model; | |
292 new->msg_public.msg_flags = dictdata.cmd_flag_val; | |
293 new->msg_public.msg_code = dictdata.cmd_code; | |
294 | |
295 /* Initialize application from the parent, if any */ | |
1298
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
296 CHECK_FCT_DO( fd_dict_search( dict, DICT_APPLICATION, APPLICATION_OF_COMMAND, model, &dictappl, 0), { free(new); return __ret__; } ); |
0 | 297 if (dictappl != NULL) { |
298 struct dict_application_data appdata; | |
1298
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
299 CHECK_FCT_DO( fd_dict_getval(dictappl, &appdata), { free(new); return __ret__; } ); |
0 | 300 new->msg_public.msg_appl = appdata.application_id; |
301 } | |
302 } | |
303 | |
304 if (flags & MSGFL_ALLOC_ETEID) { | |
305 new->msg_public.msg_eteid = fd_msg_eteid_get(); | |
306 } | |
307 | |
308 /* The new object is ready, return */ | |
309 *msg = new; | |
310 return 0; | |
311 } | |
312 | |
992
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
313 static int bufferize_avp(unsigned char * buffer, size_t buflen, size_t * offset, struct avp * avp); |
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
314 static int parsebuf_list(unsigned char * buf, size_t buflen, struct fd_list * head); |
1001
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
315 static int parsedict_do_chain(struct dictionary * dict, struct fd_list * head, int mandatory, struct fd_pei *error_info); |
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
316 |
992
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
317 |
0 | 318 /* Create answer from a request */ |
319 int fd_msg_new_answer_from_req ( struct dictionary * dict, struct msg ** msg, int flags ) | |
320 { | |
321 struct dict_object * model = NULL; | |
322 struct msg *qry, *ans; | |
112
6a294d977878
Default to add Session-Id in answers
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
100
diff
changeset
|
323 struct session * sess = NULL; |
0 | 324 |
325 TRACE_ENTRY("%p %x", msg, flags); | |
326 | |
327 /* Check the parameters */ | |
328 CHECK_PARAMS( msg ); | |
329 qry = *msg; | |
330 CHECK_PARAMS( CHECK_MSG(qry) && (qry->msg_public.msg_flags & CMD_FLAG_REQUEST) ); | |
331 | |
112
6a294d977878
Default to add Session-Id in answers
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
100
diff
changeset
|
332 if (! (flags & MSGFL_ANSW_NOSID)) { |
6a294d977878
Default to add Session-Id in answers
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
100
diff
changeset
|
333 /* Get the session of the message */ |
6a294d977878
Default to add Session-Id in answers
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
100
diff
changeset
|
334 CHECK_FCT_DO( fd_msg_sess_get(dict, qry, &sess, NULL), /* ignore an error */ ); |
6a294d977878
Default to add Session-Id in answers
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
100
diff
changeset
|
335 } |
6a294d977878
Default to add Session-Id in answers
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
100
diff
changeset
|
336 |
0 | 337 /* Find the model for the answer */ |
338 if (flags & MSGFL_ANSW_ERROR) { | |
339 /* The model is the generic error format */ | |
340 CHECK_FCT( fd_dict_get_error_cmd(dict, &model) ); | |
341 } else { | |
342 /* The model is the answer corresponding to the query. It supposes that these are defined in the dictionary */ | |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
343 CHECK_FCT_DO( parsedict_do_msg( dict, qry, 1, NULL), /* continue */ ); |
0 | 344 if (qry->msg_model) { |
345 CHECK_FCT( fd_dict_search ( dict, DICT_COMMAND, CMD_ANSWER, qry->msg_model, &model, EINVAL ) ); | |
346 } | |
347 } | |
348 | |
349 /* Create the answer */ | |
350 CHECK_FCT( fd_msg_new( model, flags, &ans ) ); | |
351 | |
352 /* Set informations in the answer as in the query */ | |
353 ans->msg_public.msg_code = qry->msg_public.msg_code; /* useful for MSGFL_ANSW_ERROR */ | |
354 ans->msg_public.msg_appl = qry->msg_public.msg_appl; | |
355 ans->msg_public.msg_eteid = qry->msg_public.msg_eteid; | |
356 ans->msg_public.msg_hbhid = qry->msg_public.msg_hbhid; | |
357 | |
112
6a294d977878
Default to add Session-Id in answers
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
100
diff
changeset
|
358 /* Add the Session-Id AVP if session is known */ |
6a294d977878
Default to add Session-Id in answers
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
100
diff
changeset
|
359 if (sess && dict) { |
1092
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
360 static struct dict_object * sess_id_avp = NULL; |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
361 os0_t sid; |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
362 size_t sidlen; |
112
6a294d977878
Default to add Session-Id in answers
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
100
diff
changeset
|
363 struct avp * avp; |
6a294d977878
Default to add Session-Id in answers
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
100
diff
changeset
|
364 union avp_value val; |
6a294d977878
Default to add Session-Id in answers
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
100
diff
changeset
|
365 |
1092
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
366 if (!sess_id_avp) { |
1298
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
367 CHECK_FCT_DO( fd_dict_search( dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &sess_id_avp, ENOENT), { free(ans); return __ret__; } ); |
1092
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
368 } |
1298
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
369 CHECK_FCT_DO( fd_sess_getsid ( sess, &sid, &sidlen ), { free(ans); return __ret__; } ); |
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
370 CHECK_FCT_DO( fd_msg_avp_new ( sess_id_avp, 0, &avp ), { free(ans); return __ret__; } ); |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
371 val.os.data = sid; |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
372 val.os.len = sidlen; |
1298
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
373 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), { free(avp); free(ans); return __ret__; } ); |
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
374 CHECK_FCT_DO( fd_msg_avp_add( ans, MSG_BRW_FIRST_CHILD, avp ), { free(avp); free(ans); return __ret__; } ); |
291
2d3a799ad29c
Cache the session pointer in answers when it was present in queries
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
280
diff
changeset
|
375 ans->msg_sess = sess; |
1298
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
376 CHECK_FCT_DO( fd_sess_ref_msg(sess), { free(ans); return __ret__; } ); |
112
6a294d977878
Default to add Session-Id in answers
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
100
diff
changeset
|
377 } |
6a294d977878
Default to add Session-Id in answers
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
100
diff
changeset
|
378 |
992
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
379 /* Add all Proxy-Info AVPs from the query if any */ |
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
380 if (! (flags & MSGFL_ANSW_NOPROXYINFO)) { |
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
381 struct avp * avp; |
1001
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
382 struct fd_pei pei; |
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
383 struct fd_list avpcpylist = FD_LIST_INITIALIZER(avpcpylist); |
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
384 |
1298
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
385 CHECK_FCT_DO( fd_msg_browse(qry, MSG_BRW_FIRST_CHILD, &avp, NULL) , { free(ans); return __ret__; } ); |
992
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
386 while (avp) { |
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
387 if ( (avp->avp_public.avp_code == AC_PROXY_INFO) |
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
388 && (avp->avp_public.avp_vendor == 0) ) { |
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
389 /* We found a Proxy-Info, need to duplicate it in the answer */ |
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
390 |
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
391 /* In order to avoid dealing with all different possibilities of states, we just create a buffer then parse it */ |
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
392 unsigned char * buf = NULL; |
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
393 size_t offset = 0; |
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
394 |
1001
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
395 /* Create a buffer with the content of the AVP. This is easier than going through the list */ |
1298
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
396 CHECK_FCT_DO( fd_msg_update_length(avp), { free(ans); return __ret__; } ); |
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
397 CHECK_MALLOC_DO( buf = malloc(avp->avp_public.avp_len), { free(ans); return __ret__; } ); |
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
398 CHECK_FCT_DO( bufferize_avp(buf, avp->avp_public.avp_len, &offset, avp), { free(buf); free(ans); return __ret__; } ); |
992
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
399 |
1001
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
400 /* Now we parse this buffer to create a copy AVP */ |
1298
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
401 CHECK_FCT_DO( parsebuf_list(buf, avp->avp_public.avp_len, &avpcpylist), { free(buf); free(ans); return __ret__; } ); |
1001
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
402 |
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
403 /* Parse dictionary objects now to remove the dependency on the buffer */ |
1298
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
404 CHECK_FCT_DO( parsedict_do_chain(dict, &avpcpylist, 0, &pei), { /* leaking the avpcpylist -- this should never happen anyway */ free(buf); free(ans); return __ret__; } ); |
992
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
405 |
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
406 /* Done for this AVP */ |
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
407 free(buf); |
1001
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
408 |
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
409 /* We move this AVP now so that we do not parse again in next loop */ |
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
410 fd_list_move_end(&ans->msg_chain.children, &avpcpylist); |
992
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
411 } |
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
412 /* move to next AVP in the message, we can have several Proxy-Info instances */ |
1298
0f215b0dda5e
Fix some possible memory leaks in fd_msg_new
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1248
diff
changeset
|
413 CHECK_FCT_DO( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL), { free(ans); return __ret__; } ); |
992
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
414 } |
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
415 } |
80584f0e851a
Copy by default the Proxy-Info AVP included in requests into the answers. Use MSGFL_ANSW_NOPROXYINFO to ignore. This code has not been tested yet.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
979
diff
changeset
|
416 |
0 | 417 /* associate with query */ |
418 ans->msg_query = qry; | |
637
22e8fac3b2d6
Split interface file in modules
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
400
diff
changeset
|
419 qry->msg_associated = 1; |
0 | 420 |
421 /* Done */ | |
422 *msg = ans; | |
423 return 0; | |
424 } | |
425 | |
426 /***************************************************************************************************************/ | |
427 | |
428 /* Explore a message */ | |
429 int fd_msg_browse_internal ( msg_or_avp * reference, enum msg_brw_dir dir, msg_or_avp ** found, int * depth ) | |
430 { | |
431 struct msg_avp_chain *result = NULL; | |
432 int diff = 0; | |
433 struct fd_list *li = NULL; | |
434 | |
435 TRACE_ENTRY("%p %d %p %p", reference, dir, found, depth); | |
436 | |
437 /* Initialize the "found" result if any */ | |
438 if (found) | |
439 *found = NULL; | |
440 | |
441 /* Check the parameters */ | |
442 CHECK_PARAMS( VALIDATE_OBJ(reference) ); | |
443 | |
444 TRACE_DEBUG(FCTS, "chaining(%p): nxt:%p prv:%p hea:%p top:%p", | |
445 &_C(reference)->chaining, | |
446 _C(reference)->chaining.next, | |
447 _C(reference)->chaining.prev, | |
448 _C(reference)->chaining.head, | |
449 _C(reference)->chaining.o); | |
450 TRACE_DEBUG(FCTS, "children(%p): nxt:%p prv:%p hea:%p top:%p", | |
451 &_C(reference)->children, | |
452 _C(reference)->children.next, | |
453 _C(reference)->children.prev, | |
454 _C(reference)->children.head, | |
455 _C(reference)->children.o); | |
456 | |
457 /* Now search */ | |
458 switch (dir) { | |
459 case MSG_BRW_NEXT: | |
460 /* Check the reference is an AVP */ | |
461 CHECK_PARAMS( _C(reference)->type == MSG_AVP ); | |
462 | |
463 li = &_C(reference)->chaining; | |
464 | |
465 /* Check if the next element is not the sentinel ( ==> the parent) */ | |
466 if (li->next != li->head) | |
467 result = _C(li->next->o); | |
468 break; | |
469 | |
470 case MSG_BRW_PREV: | |
471 /* Check the reference is an AVP */ | |
472 CHECK_PARAMS( _C(reference)->type == MSG_AVP ); | |
473 | |
474 li = &_C(reference)->chaining; | |
475 | |
476 /* Check if the prev element is not the sentinel ( ==> the parent) */ | |
477 if (li->prev != li->head) | |
478 result = _C(li->prev->o); | |
479 break; | |
480 | |
481 case MSG_BRW_FIRST_CHILD: | |
482 li = &_C(reference)->children; | |
483 if (! FD_IS_LIST_EMPTY(li)) { | |
484 result = _C(li->next->o); | |
485 diff = 1; | |
486 } | |
487 break; | |
488 | |
489 case MSG_BRW_LAST_CHILD: | |
490 li = &_C(reference)->children; | |
491 if (! FD_IS_LIST_EMPTY(li)) { | |
492 result = _C(li->prev->o); | |
493 diff = 1; | |
494 } | |
495 break; | |
496 | |
497 case MSG_BRW_PARENT: | |
498 /* If the object is not chained, it has no parent */ | |
499 li = &_C(reference)->chaining; | |
500 if (li != li->head) { | |
501 /* The sentinel is the parent's children list */ | |
502 result = _C(li->head->o); | |
503 diff = -1; | |
504 } | |
505 break; | |
506 | |
507 case MSG_BRW_WALK: | |
508 /* First, try to find a child */ | |
509 li = &_C(reference)->children; | |
510 if ( ! FD_IS_LIST_EMPTY(li) ) { | |
511 result = _C(li->next->o); | |
512 diff = 1; | |
513 break; | |
514 } | |
515 | |
516 /* Then try to find a "next" at this level or one of the parent's */ | |
517 li = &_C(reference)->chaining; | |
518 do { | |
519 /* If this element has a "next" element, return it */ | |
520 if (li->next != li->head) { | |
521 result = _C(li->next->o); | |
522 break; | |
523 } | |
524 /* otherwise, check if we have a parent */ | |
525 if (li == li->head) { | |
526 /* no parent */ | |
527 break; | |
528 } | |
529 /* Go to the parent's chaining information and loop */ | |
530 diff -= 1; | |
531 li = &_C(li->head->o)->chaining; | |
532 } while (1); | |
533 break; | |
534 | |
535 default: | |
536 /* Other directions are invalid */ | |
537 CHECK_PARAMS( dir = 0 ); | |
538 } | |
539 | |
540 /* Save the found object, if any */ | |
541 if (found && result) | |
542 *found = (void *)result; | |
543 | |
544 /* Modify the depth according to the walk direction */ | |
545 if (depth && diff) | |
546 (*depth) += diff; | |
547 | |
548 /* Return ENOENT if found was NULL */ | |
549 if ((!found) && (!result)) | |
550 return ENOENT; | |
551 else | |
552 return 0; | |
553 } | |
554 | |
555 /* Add an AVP into a tree */ | |
556 int fd_msg_avp_add ( msg_or_avp * reference, enum msg_brw_dir dir, struct avp *avp) | |
557 { | |
558 TRACE_ENTRY("%p %d %p", reference, dir, avp); | |
559 | |
560 /* Check the parameters */ | |
561 CHECK_PARAMS( VALIDATE_OBJ(reference) && CHECK_AVP(avp) && FD_IS_LIST_EMPTY(&avp->avp_chain.chaining) ); | |
562 | |
563 /* Now insert */ | |
564 switch (dir) { | |
565 case MSG_BRW_NEXT: | |
566 /* Check the reference is an AVP -- we do not chain AVPs at same level as msgs. */ | |
567 CHECK_PARAMS( _C(reference)->type == MSG_AVP ); | |
568 | |
569 /* Insert the new avp after the reference */ | |
570 fd_list_insert_after( &_A(reference)->avp_chain.chaining, &avp->avp_chain.chaining ); | |
571 break; | |
572 | |
573 case MSG_BRW_PREV: | |
574 /* Check the reference is an AVP */ | |
575 CHECK_PARAMS( _C(reference)->type == MSG_AVP ); | |
576 | |
577 /* Insert the new avp before the reference */ | |
578 fd_list_insert_before( &_A(reference)->avp_chain.chaining, &avp->avp_chain.chaining ); | |
579 break; | |
580 | |
581 case MSG_BRW_FIRST_CHILD: | |
582 /* Insert the new avp after the children sentinel */ | |
583 fd_list_insert_after( &_C(reference)->children, &avp->avp_chain.chaining ); | |
584 break; | |
585 | |
586 case MSG_BRW_LAST_CHILD: | |
587 /* Insert the new avp before the children sentinel */ | |
588 fd_list_insert_before( &_C(reference)->children, &avp->avp_chain.chaining ); | |
589 break; | |
590 | |
591 default: | |
592 /* Other directions are invalid */ | |
593 CHECK_PARAMS( dir = 0 ); | |
594 } | |
595 | |
596 return 0; | |
597 } | |
598 | |
599 /* Search a given AVP model in a message */ | |
600 int fd_msg_search_avp ( struct msg * msg, struct dict_object * what, struct avp ** avp ) | |
601 { | |
602 struct avp * nextavp; | |
603 struct dict_avp_data dictdata; | |
604 enum dict_object_type dicttype; | |
605 | |
606 TRACE_ENTRY("%p %p %p", msg, what, avp); | |
607 | |
608 CHECK_PARAMS( CHECK_MSG(msg) && what ); | |
609 | |
610 CHECK_PARAMS( (fd_dict_gettype(what, &dicttype) == 0) && (dicttype == DICT_AVP) ); | |
611 CHECK_FCT( fd_dict_getval(what, &dictdata) ); | |
612 | |
613 /* Loop on all top AVPs */ | |
614 CHECK_FCT( fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, (void *)&nextavp, NULL) ); | |
615 while (nextavp) { | |
616 | |
617 if ( (nextavp->avp_public.avp_code == dictdata.avp_code) | |
618 && (nextavp->avp_public.avp_vendor == dictdata.avp_vendor) ) /* always 0 if no V flag */ | |
619 break; | |
620 | |
621 /* Otherwise move to next AVP in the message */ | |
622 CHECK_FCT( fd_msg_browse(nextavp, MSG_BRW_NEXT, (void *)&nextavp, NULL) ); | |
623 } | |
624 | |
625 if (avp) | |
626 *avp = nextavp; | |
627 | |
628 if (avp && nextavp) { | |
629 struct dictionary * dict; | |
630 CHECK_FCT( fd_dict_getdict( what, &dict) ); | |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
631 CHECK_FCT_DO( fd_msg_parse_dict( nextavp, dict, NULL ), /* nothing */ ); |
0 | 632 } |
633 | |
634 if (avp || nextavp) | |
635 return 0; | |
636 else | |
637 return ENOENT; | |
638 } | |
639 | |
640 | |
641 /***************************************************************************************************************/ | |
642 /* Deleting objects */ | |
643 | |
644 /* Destroy and free an AVP or message */ | |
645 static int destroy_obj (struct msg_avp_chain * obj ) | |
646 { | |
647 TRACE_ENTRY("%p", obj); | |
648 | |
649 /* Check the parameter is a valid object */ | |
650 CHECK_PARAMS( VALIDATE_OBJ(obj) && FD_IS_LIST_EMPTY( &obj->children ) ); | |
651 | |
652 /* Unlink this object if needed */ | |
653 fd_list_unlink( &obj->chaining ); | |
654 | |
655 /* Free the octetstring if needed */ | |
656 if ((obj->type == MSG_AVP) && (_A(obj)->avp_mustfreeos == 1)) { | |
657 free(_A(obj)->avp_storage.os.data); | |
658 } | |
659 /* Free the rawdata if needed */ | |
660 if ((obj->type == MSG_AVP) && (_A(obj)->avp_rawdata != NULL)) { | |
661 free(_A(obj)->avp_rawdata); | |
662 } | |
663 if ((obj->type == MSG_MSG) && (_M(obj)->msg_rawbuffer != NULL)) { | |
664 free(_M(obj)->msg_rawbuffer); | |
665 } | |
666 | |
667 if ((obj->type == MSG_MSG) && (_M(obj)->msg_src_id != NULL)) { | |
668 free(_M(obj)->msg_src_id); | |
669 } | |
670 | |
83
c662d3eb6ff6
Started support for routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
37
diff
changeset
|
671 if ((obj->type == MSG_MSG) && (_M(obj)->msg_rtdata != NULL)) { |
c662d3eb6ff6
Started support for routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
37
diff
changeset
|
672 fd_rtd_free(&_M(obj)->msg_rtdata); |
0 | 673 } |
674 | |
85
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
675 if ((obj->type == MSG_MSG) && (_M(obj)->msg_sess != NULL)) { |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
676 CHECK_FCT_DO( fd_sess_reclaim_msg ( &_M(obj)->msg_sess ), /* continue */); |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
677 } |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
678 |
1098
f38d77f9cfd3
Initial implementation of the hook mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1096
diff
changeset
|
679 if ((obj->type == MSG_MSG) && (_M(obj)->msg_pmdl.sentinel.o != NULL)) { |
f38d77f9cfd3
Initial implementation of the hook mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1096
diff
changeset
|
680 ((void (*)(struct fd_msg_pmdl *))_M(obj)->msg_pmdl.sentinel.o)(&_M(obj)->msg_pmdl); |
f38d77f9cfd3
Initial implementation of the hook mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1096
diff
changeset
|
681 } |
f38d77f9cfd3
Initial implementation of the hook mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1096
diff
changeset
|
682 |
0 | 683 /* free the object */ |
684 free(obj); | |
685 | |
686 return 0; | |
687 } | |
688 | |
689 /* Destroy an object and all its children */ | |
690 static void destroy_tree(struct msg_avp_chain * obj) | |
691 { | |
692 struct fd_list *rem; | |
693 | |
694 TRACE_ENTRY("%p", obj); | |
695 | |
696 /* Destroy any subtree */ | |
697 while ( (rem = obj->children.next) != &obj->children) | |
698 destroy_tree(_C(rem->o)); | |
699 | |
700 /* Then unlink and destroy the object */ | |
701 CHECK_FCT_DO( destroy_obj(obj), /* nothing */ ); | |
702 } | |
703 | |
704 /* Free an object and its tree */ | |
705 int fd_msg_free ( msg_or_avp * object ) | |
706 { | |
707 TRACE_ENTRY("%p", object); | |
708 | |
1205
165569e8cba8
Allow NULL parameter in fd_msg_free
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1173
diff
changeset
|
709 if (object == NULL) |
165569e8cba8
Allow NULL parameter in fd_msg_free
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1173
diff
changeset
|
710 return 0; |
165569e8cba8
Allow NULL parameter in fd_msg_free
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1173
diff
changeset
|
711 |
0 | 712 if (CHECK_MSG(object)) { |
713 if (_M(object)->msg_query) { | |
637
22e8fac3b2d6
Split interface file in modules
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
400
diff
changeset
|
714 _M(_M(object)->msg_query)->msg_associated = 0; |
0 | 715 CHECK_FCT( fd_msg_free( _M(object)->msg_query ) ); |
716 _M(object)->msg_query = NULL; | |
637
22e8fac3b2d6
Split interface file in modules
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
400
diff
changeset
|
717 } else { |
22e8fac3b2d6
Split interface file in modules
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
400
diff
changeset
|
718 if (_M(object)->msg_associated) { |
22e8fac3b2d6
Split interface file in modules
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
400
diff
changeset
|
719 TRACE_DEBUG(INFO, "Not freeing query %p referenced in an answer (will be freed along the answer).", object); |
22e8fac3b2d6
Split interface file in modules
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
400
diff
changeset
|
720 return 0; |
22e8fac3b2d6
Split interface file in modules
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
400
diff
changeset
|
721 } |
0 | 722 } |
723 } | |
724 | |
725 destroy_tree(_C(object)); | |
726 return 0; | |
727 } | |
728 | |
729 | |
730 /***************************************************************************************************************/ | |
731 /* Debug functions: dumping */ | |
732 | |
1093
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
733 /* messages and AVP formatters */ |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
734 typedef DECLARE_FD_DUMP_PROTOTYPE( (*msg_dump_formatter_msg), struct msg * msg ); |
1095
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
735 typedef DECLARE_FD_DUMP_PROTOTYPE( (*msg_dump_formatter_avp), struct avp * avp, int level, int first, int last ); |
1093
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
736 |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
737 /* Core function to process the dumping */ |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
738 static DECLARE_FD_DUMP_PROTOTYPE( msg_dump_process, msg_dump_formatter_msg msg_format, msg_dump_formatter_avp avp_format, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ) |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
739 { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
740 FD_DUMP_HANDLE_OFFSET(); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
741 |
1172
83d55d26ae80
Hand the case of invalid objects in the msg_dump functions
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1125
diff
changeset
|
742 if (!VALIDATE_OBJ(obj)) { |
1173 | 743 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID MESSAGE OR AVP @%p", obj), return NULL); |
1172
83d55d26ae80
Hand the case of invalid objects in the msg_dump functions
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1125
diff
changeset
|
744 return *buf; |
83d55d26ae80
Hand the case of invalid objects in the msg_dump functions
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1125
diff
changeset
|
745 } |
83d55d26ae80
Hand the case of invalid objects in the msg_dump functions
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1125
diff
changeset
|
746 |
1093
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
747 if (force_parsing) { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
748 (void) fd_msg_parse_dict(obj, dict, NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
749 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
750 |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
751 switch (_C(obj)->type) { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
752 case MSG_AVP: |
1095
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
753 CHECK_MALLOC_DO( (*avp_format)(FD_DUMP_STD_PARAMS, (struct avp *)obj, 0, 1, 1), return NULL); |
1093
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
754 break; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
755 |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
756 case MSG_MSG: |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
757 CHECK_MALLOC_DO( (*msg_format)(FD_DUMP_STD_PARAMS, (struct msg *)obj), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
758 break; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
759 |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
760 default: |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
761 ASSERT(0); |
1173 | 762 free(*buf); |
1172
83d55d26ae80
Hand the case of invalid objects in the msg_dump functions
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1125
diff
changeset
|
763 *buf = NULL; |
83d55d26ae80
Hand the case of invalid objects in the msg_dump functions
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1125
diff
changeset
|
764 return NULL; |
1093
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
765 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
766 |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
767 if (recurse) { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
768 struct avp * avp = NULL; |
1095
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
769 int first = 1; |
1093
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
770 CHECK_FCT_DO( fd_msg_browse ( obj, MSG_BRW_FIRST_CHILD, &avp, NULL ), avp = NULL ); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
771 while (avp) { |
1095
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
772 struct avp * nextavp = NULL; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
773 CHECK_FCT_DO( fd_msg_browse ( avp, MSG_BRW_NEXT, &nextavp, NULL ), nextavp = NULL ); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
774 CHECK_MALLOC_DO( (*avp_format)(FD_DUMP_STD_PARAMS, avp, 1, first, nextavp ? 0 : 1), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
775 avp = nextavp; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
776 first = 0; |
1093
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
777 }; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
778 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
779 |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
780 return *buf; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
781 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
782 |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
783 /* |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
784 * Tree View message dump |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
785 */ |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
786 static DECLARE_FD_DUMP_PROTOTYPE( msg_format_treeview, struct msg * msg ) |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
787 { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
788 if (!CHECK_MSG(msg)) { |
1125
98d1ad9bf85a
Fix initialization of random number; Cleanup the dump message display
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1121
diff
changeset
|
789 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID MESSAGE"), return NULL); |
1093
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
790 return *buf; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
791 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
792 |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
793 if (!msg->msg_model) { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
794 if (msg->msg_model_not_found.mnf_code) { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
795 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(not found in dictionary)\n"), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
796 } else { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
797 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(not searched in dictionary)\n"), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
798 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
799 } else { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
800 enum dict_object_type dicttype; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
801 struct dict_cmd_data dictdata; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
802 if (fd_dict_gettype(msg->msg_model, &dicttype) || (dicttype != DICT_COMMAND)) { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
803 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(invalid model information)\n"), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
804 } else if (fd_dict_getval(msg->msg_model, &dictdata)) { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
805 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(error getting model information)\n"), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
806 } else { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
807 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'\n", dictdata.cmd_name), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
808 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
809 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
810 |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
811 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Version: 0x%02hhX\n", msg->msg_public.msg_version), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
812 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Length: %d\n", msg->msg_public.msg_length), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
813 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Flags: 0x%02hhX (" DUMP_CMDFL_str ")\n", msg->msg_public.msg_flags, DUMP_CMDFL_val(msg->msg_public.msg_flags)), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
814 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Command Code: %u\n", msg->msg_public.msg_code), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
815 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " ApplicationId: %d\n", msg->msg_public.msg_appl), return NULL); |
1120
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
816 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Hop-by-Hop Identifier: 0x%08X\n", msg->msg_public.msg_hbhid), return NULL); |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
817 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " End-to-End Identifier: 0x%08X\n", msg->msg_public.msg_eteid), return NULL); |
1125
98d1ad9bf85a
Fix initialization of random number; Cleanup the dump message display
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1121
diff
changeset
|
818 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {internal data}: src:%s(%zd) rwb:%p rt:%d cb:%p,%p(%p) qry:%p asso:%d sess:%p", msg->msg_src_id?:"(nil)", msg->msg_src_id_len, msg->msg_rawbuffer, msg->msg_routable, msg->msg_cb.anscb, msg->msg_cb.expirecb, msg->msg_cb.data, msg->msg_query, msg->msg_associated, msg->msg_sess), return NULL); |
1093
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
819 |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
820 return *buf; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
821 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
822 |
1095
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
823 static DECLARE_FD_DUMP_PROTOTYPE( avp_format_treeview, struct avp * avp, int level, int first, int last ) |
1085
7d7266115a34
Cleaning of the traces in progress
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1084
diff
changeset
|
824 { |
1093
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
825 char * name; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
826 struct dict_avp_data dictdata; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
827 struct dict_avp_data *dictinfo = NULL; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
828 struct dict_vendor_data vendordata; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
829 struct dict_vendor_data *vendorinfo = NULL; |
1095
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
830 |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
831 if (level) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
832 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n"), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
833 } |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
834 |
1093
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
835 if (!CHECK_AVP(avp)) { |
1125
98d1ad9bf85a
Fix initialization of random number; Cleanup the dump message display
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1121
diff
changeset
|
836 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID AVP"), return NULL); |
1093
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
837 return *buf; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
838 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
839 |
1125
98d1ad9bf85a
Fix initialization of random number; Cleanup the dump message display
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1121
diff
changeset
|
840 if (level) { |
1093
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
841 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*sAVP: ", level * 3, ""), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
842 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
843 |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
844 if (!avp->avp_model) { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
845 if (avp->avp_model_not_found.mnf_code) { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
846 name = "(not found in dictionary)"; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
847 } else { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
848 name = "(not searched in dictionary)"; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
849 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
850 } else { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
851 enum dict_object_type dicttype; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
852 if (fd_dict_gettype(avp->avp_model, &dicttype) || (dicttype != DICT_AVP)) { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
853 name = "(invalid model information)"; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
854 } else if (fd_dict_getval(avp->avp_model, &dictdata)) { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
855 name = "(error getting model information)"; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
856 } else { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
857 name = dictdata.avp_name; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
858 dictinfo = &dictdata; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
859 if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
860 struct dictionary * dict; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
861 struct dict_object * vendor; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
862 if ((!fd_dict_getdict(avp->avp_model, &dict)) |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
863 && (!fd_dict_search(dict, DICT_VENDOR, VENDOR_OF_AVP, avp->avp_model, &vendor, ENOENT)) |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
864 && (!fd_dict_getval(vendor, &vendordata))) { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
865 vendorinfo = &vendordata; |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
866 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
867 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
868 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
869 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
870 |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
871 if (dictinfo) { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
872 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'(%u)", name, avp->avp_public.avp_code), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
873 } else { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
874 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%u%s", avp->avp_public.avp_code, name), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
875 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
876 |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
877 if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
878 if (vendorinfo) { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
879 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " vend='%s'(%u)", vendorinfo->vendor_name, avp->avp_public.avp_vendor), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
880 } else { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
881 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " vend=%u", avp->avp_public.avp_vendor), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
882 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
883 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
884 |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
885 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " l=%d f=" DUMP_AVPFL_str " val=", avp->avp_public.avp_len, DUMP_AVPFL_val(avp->avp_public.avp_flags)), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
886 |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
887 if (dictinfo && (dictinfo->avp_basetype == AVP_TYPE_GROUPED)) { |
1095
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
888 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(grouped)"), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
889 if (level) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
890 struct avp * inavp = NULL; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
891 int first = 1; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
892 CHECK_FCT_DO( fd_msg_browse ( avp, MSG_BRW_FIRST_CHILD, &inavp, NULL ), inavp = NULL ); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
893 while (inavp) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
894 struct avp * nextavp = NULL; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
895 CHECK_FCT_DO( fd_msg_browse ( inavp, MSG_BRW_NEXT, &nextavp, NULL ), inavp = NULL ); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
896 CHECK_MALLOC_DO( avp_format_treeview(FD_DUMP_STD_PARAMS, inavp, level + 1, first, nextavp ? 0 : 1), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
897 inavp = nextavp; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
898 first = 0; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
899 }; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
900 } |
1093
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
901 } else { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
902 if (avp->avp_public.avp_value) { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
903 CHECK_MALLOC_DO( fd_dict_dump_avp_value(FD_DUMP_STD_PARAMS, avp->avp_public.avp_value, avp->avp_model, 0, 0), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
904 } else if (avp->avp_rawdata) { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
905 CHECK_MALLOC_DO( fd_dump_extend_hexdump(FD_DUMP_STD_PARAMS, avp->avp_rawdata, avp->avp_rawlen, 0, 0), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
906 } else { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
907 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(not set)"), return NULL); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
908 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
909 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
910 |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
911 return *buf; |
1085
7d7266115a34
Cleaning of the traces in progress
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1084
diff
changeset
|
912 } |
1093
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
913 |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
914 /* multi-line human-readable dump similar to wireshark output */ |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
915 DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_treeview, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ) |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
916 { |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
917 return msg_dump_process(FD_DUMP_STD_PARAMS, msg_format_treeview, avp_format_treeview, obj, dict, force_parsing, recurse); |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
918 } |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
919 |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
920 |
1095
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
921 /* |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
922 * One-line dumper for compact but complete traces |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
923 */ |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
924 static DECLARE_FD_DUMP_PROTOTYPE( msg_format_full, struct msg * msg ) |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
925 { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
926 int success = 0; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
927 struct dict_cmd_data dictdata; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
928 |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
929 if (!CHECK_MSG(msg)) { |
1119
79dd22145f52
Fix a number of compilation warnings
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1113
diff
changeset
|
930 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID MESSAGE"), return NULL); |
1095
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
931 return *buf; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
932 } |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
933 |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
934 if (!msg->msg_model) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
935 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(no model) "), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
936 } else { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
937 enum dict_object_type dicttype=0; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
938 if (fd_dict_gettype(msg->msg_model, &dicttype) || (dicttype != DICT_COMMAND)) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
939 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(invalid model %d) ", dicttype), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
940 } else if (fd_dict_getval(msg->msg_model, &dictdata)) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
941 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(error getting model data) "), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
942 } else { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
943 success = 1; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
944 } |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
945 } |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
946 if (msg->msg_public.msg_appl) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
947 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
948 "%s(%u/%u)[" DUMP_CMDFL_str "], Length=%u, Hop-By-Hop-Id=0x%08x, End-to-End=0x%08x", |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
949 success ? dictdata.cmd_name : "unknown", msg->msg_public.msg_appl, msg->msg_public.msg_code, DUMP_CMDFL_val(msg->msg_public.msg_flags), |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
950 msg->msg_public.msg_length, msg->msg_public.msg_hbhid, msg->msg_public.msg_eteid), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
951 } else { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
952 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
953 "%s(%u)[" DUMP_CMDFL_str "], Length=%u, Hop-By-Hop-Id=0x%08x, End-to-End=0x%08x", |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
954 success ? dictdata.cmd_name : "unknown", msg->msg_public.msg_code, DUMP_CMDFL_val(msg->msg_public.msg_flags), |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
955 msg->msg_public.msg_length, msg->msg_public.msg_hbhid, msg->msg_public.msg_eteid), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
956 } |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
957 return *buf; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
958 } |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
959 |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
960 static DECLARE_FD_DUMP_PROTOTYPE( avp_format_full, struct avp * avp, int level, int first, int last ) |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
961 { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
962 int success = 0; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
963 struct dict_avp_data dictdata; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
964 |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
965 if (level) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
966 if ((first) && ((*buf)[*offset - 1] == '=')) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
967 /* We are first AVP of a grouped AVP */ |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
968 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{ "), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
969 } else { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
970 /* We follow another AVP, or a message header */ |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
971 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, ", { "), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
972 } |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
973 } |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
974 |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
975 if (!CHECK_AVP(avp)) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
976 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID AVP"), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
977 goto end; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
978 } |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
979 |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
980 |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
981 if (avp->avp_model) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
982 enum dict_object_type dicttype; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
983 if (fd_dict_gettype(avp->avp_model, &dicttype) || (dicttype != DICT_AVP)) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
984 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(invalid model: %d) ", dicttype), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
985 } else if (fd_dict_getval(avp->avp_model, &dictdata)) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
986 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(error getting model data) "), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
987 } else { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
988 success = 1; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
989 } |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
990 } |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
991 |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
992 if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
993 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s(%u/%u)[" DUMP_AVPFL_str "]=", |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
994 success ? dictdata.avp_name : "unknown", avp->avp_public.avp_vendor, avp->avp_public.avp_code, DUMP_AVPFL_val(avp->avp_public.avp_flags)), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
995 } else { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
996 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s(%u)[" DUMP_AVPFL_str "]=", |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
997 success ? dictdata.avp_name : "unknown", avp->avp_public.avp_code, DUMP_AVPFL_val(avp->avp_public.avp_flags)), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
998 } |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
999 |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1000 |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1001 if (success && (dictdata.avp_basetype == AVP_TYPE_GROUPED)) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1002 if (level) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1003 struct avp * inavp = NULL; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1004 int first = 1; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1005 CHECK_FCT_DO( fd_msg_browse ( avp, MSG_BRW_FIRST_CHILD, &inavp, NULL ), inavp = NULL ); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1006 while (inavp) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1007 struct avp * nextavp = NULL; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1008 CHECK_FCT_DO( fd_msg_browse ( inavp, MSG_BRW_NEXT, &nextavp, NULL ), inavp = NULL ); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1009 CHECK_MALLOC_DO( avp_format_full(FD_DUMP_STD_PARAMS, inavp, level + 1, first, nextavp ? 0 : 1), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1010 inavp = nextavp; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1011 first = 0; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1012 }; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1013 } |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1014 } else { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1015 if (avp->avp_public.avp_value) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1016 CHECK_MALLOC_DO( fd_dict_dump_avp_value(FD_DUMP_STD_PARAMS, avp->avp_public.avp_value, avp->avp_model, 0, 0), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1017 } else if (avp->avp_rawdata) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1018 CHECK_MALLOC_DO( fd_dump_extend_hexdump(FD_DUMP_STD_PARAMS, avp->avp_rawdata, avp->avp_rawlen, 0, 0), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1019 } else { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1020 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(not set)"), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1021 } |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1022 } |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1023 |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1024 end: |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1025 if (level) { |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1026 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " }"), return NULL); |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1027 } |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1028 |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1029 return *buf; |
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1030 } |
1096
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1031 |
1085
7d7266115a34
Cleaning of the traces in progress
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1084
diff
changeset
|
1032 /* one-line dump with all the contents of the message */ |
7d7266115a34
Cleaning of the traces in progress
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1084
diff
changeset
|
1033 DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_full, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ) |
7d7266115a34
Cleaning of the traces in progress
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1084
diff
changeset
|
1034 { |
1095
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1035 return msg_dump_process(FD_DUMP_STD_PARAMS, msg_format_full, avp_format_full, obj, dict, force_parsing, recurse); |
1085
7d7266115a34
Cleaning of the traces in progress
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1084
diff
changeset
|
1036 } |
1093
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
1037 |
1096
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1038 |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1039 |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1040 /* |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1041 * One-line dumper for compact but complete traces |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1042 */ |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1043 static DECLARE_FD_DUMP_PROTOTYPE( msg_format_summary, struct msg * msg ) |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1044 { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1045 if (!CHECK_MSG(msg)) { |
1125
98d1ad9bf85a
Fix initialization of random number; Cleanup the dump message display
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1121
diff
changeset
|
1046 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID MESSAGE"), return NULL); |
1096
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1047 return *buf; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1048 } |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1049 |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1050 if (!msg->msg_model) { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1051 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(no model)"), return NULL); |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1052 } else { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1053 enum dict_object_type dicttype; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1054 struct dict_cmd_data dictdata; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1055 if (fd_dict_gettype(msg->msg_model, &dicttype) || (dicttype != DICT_COMMAND) || (fd_dict_getval(msg->msg_model, &dictdata))) { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1056 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(model error)"), return NULL); |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1057 } else { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1058 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'", dictdata.cmd_name), return NULL); |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1059 } |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1060 } |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1061 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%u/%u f:" DUMP_CMDFL_str " src:'%s' len:%d", |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1062 msg->msg_public.msg_appl, msg->msg_public.msg_code, DUMP_CMDFL_val(msg->msg_public.msg_flags), msg->msg_src_id?:"(nil)", msg->msg_public.msg_length), return NULL); |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1063 |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1064 return *buf; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1065 } |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1066 |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1067 static DECLARE_FD_DUMP_PROTOTYPE( avp_format_summary, struct avp * avp, int level, int first, int last ) |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1068 { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1069 char * name; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1070 struct dict_avp_data dictdata; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1071 struct dict_avp_data *dictinfo = NULL; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1072 struct dict_vendor_data vendordata; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1073 struct dict_vendor_data *vendorinfo = NULL; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1074 |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1075 if (level) { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1076 if (first) { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1077 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {"), return NULL); |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1078 } else { |
1120
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1079 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, ","), return NULL); |
1096
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1080 } |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1081 } |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1082 |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1083 if (!CHECK_AVP(avp)) { |
1125
98d1ad9bf85a
Fix initialization of random number; Cleanup the dump message display
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1121
diff
changeset
|
1084 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID AVP"), return NULL); |
1096
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1085 goto end; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1086 } |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1087 |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1088 if (!level) { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1089 /* We have been called to explicitely dump this AVP, so we parse its name if available */ |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1090 if (!avp->avp_model) { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1091 name = "(no model)"; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1092 } else { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1093 enum dict_object_type dicttype; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1094 if (fd_dict_gettype(avp->avp_model, &dicttype) || (dicttype != DICT_AVP) || (fd_dict_getval(avp->avp_model, &dictdata))) { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1095 name = "(model error)"; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1096 } else { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1097 name = dictdata.avp_name; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1098 dictinfo = &dictdata; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1099 if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1100 struct dictionary * dict; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1101 struct dict_object * vendor; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1102 if ((!fd_dict_getdict(avp->avp_model, &dict)) |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1103 && (!fd_dict_search(dict, DICT_VENDOR, VENDOR_OF_AVP, avp->avp_model, &vendor, ENOENT)) |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1104 && (!fd_dict_getval(vendor, &vendordata))) { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1105 vendorinfo = &vendordata; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1106 } |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1107 } |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1108 } |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1109 } |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1110 |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1111 if (dictinfo) { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1112 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'(%u)", name, avp->avp_public.avp_code), return NULL); |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1113 } else { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1114 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%u%s", avp->avp_public.avp_code, name), return NULL); |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1115 } |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1116 |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1117 if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1118 if (vendorinfo) { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1119 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " V='%s'(%u)", vendorinfo->vendor_name, avp->avp_public.avp_vendor), return NULL); |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1120 } else { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1121 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " V=%u", avp->avp_public.avp_vendor), return NULL); |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1122 } |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1123 } |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1124 |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1125 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " L=%d F=" DUMP_AVPFL_str " V=", avp->avp_public.avp_len, DUMP_AVPFL_val(avp->avp_public.avp_flags)), return NULL); |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1126 |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1127 if ((!dictinfo) || (dictinfo->avp_basetype != AVP_TYPE_GROUPED)) { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1128 if (avp->avp_public.avp_value) { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1129 CHECK_MALLOC_DO( fd_dict_dump_avp_value(FD_DUMP_STD_PARAMS, avp->avp_public.avp_value, avp->avp_model, 0, 0), return NULL); |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1130 } else if (avp->avp_rawdata) { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1131 CHECK_MALLOC_DO( fd_dump_extend_hexdump(FD_DUMP_STD_PARAMS, avp->avp_rawdata, avp->avp_rawlen, 0, 0), return NULL); |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1132 } else { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1133 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(not set)"), return NULL); |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1134 } |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1135 } |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1136 } else { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1137 /* For embedded AVPs, we only display (vendor,) code & length */ |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1138 if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { |
1120
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1139 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "V:%u/", avp->avp_public.avp_vendor), return NULL); |
1096
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1140 } |
1120
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1141 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "C:%u/l:%d", avp->avp_public.avp_code, avp->avp_public.avp_len), return NULL); |
1096
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1142 } |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1143 |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1144 end: |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1145 if ((level) && (last)) { |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1146 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "}"), return NULL); |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1147 } |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1148 |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1149 return *buf; |
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1150 } |
1095
647c7e7015af
Ported the fd_msg_dump_full function to the new mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1093
diff
changeset
|
1151 |
1093
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
1152 /* This one only prints a short display, does not go into the complete tree */ |
44f3e48dfe27
Align the behavior of all fd_*dump functions wrt final \n
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1092
diff
changeset
|
1153 DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_summary, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ) |
1085
7d7266115a34
Cleaning of the traces in progress
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1084
diff
changeset
|
1154 { |
1096
97a257c80de0
Implemented remaining flavour of message dump function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1095
diff
changeset
|
1155 return msg_dump_process(FD_DUMP_STD_PARAMS, msg_format_summary, avp_format_summary, obj, dict, force_parsing, recurse); |
1085
7d7266115a34
Cleaning of the traces in progress
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1084
diff
changeset
|
1156 } |
7d7266115a34
Cleaning of the traces in progress
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1084
diff
changeset
|
1157 |
0 | 1158 /***************************************************************************************************************/ |
1159 /* Simple meta-data management */ | |
1160 | |
1161 /* Retrieve the model of an object */ | |
1162 int fd_msg_model ( msg_or_avp * reference, struct dict_object ** model ) | |
1163 { | |
1164 TRACE_ENTRY("%p %p", reference, model); | |
1165 | |
1166 /* Check the parameters */ | |
1167 CHECK_PARAMS( model && VALIDATE_OBJ(reference) ); | |
1168 | |
1169 /* copy the model reference */ | |
1170 switch (_C(reference)->type) { | |
1171 case MSG_AVP: | |
1172 *model = _A(reference)->avp_model; | |
1173 break; | |
1174 | |
1175 case MSG_MSG: | |
1176 *model = _M(reference)->msg_model; | |
1177 break; | |
1178 | |
1179 default: | |
1180 CHECK_PARAMS(0); | |
1181 } | |
1182 | |
1183 return 0; | |
1184 } | |
1185 | |
1186 /* Retrieve the address of the msg_public field of a message */ | |
1187 int fd_msg_hdr ( struct msg *msg, struct msg_hdr **pdata ) | |
1188 { | |
1189 TRACE_ENTRY("%p %p", msg, pdata); | |
1190 CHECK_PARAMS( CHECK_MSG(msg) && pdata ); | |
1191 | |
1192 *pdata = &msg->msg_public; | |
1193 return 0; | |
1194 } | |
1195 | |
1196 /* Retrieve the address of the avp_public field of an avp */ | |
1197 int fd_msg_avp_hdr ( struct avp *avp, struct avp_hdr **pdata ) | |
1198 { | |
1199 TRACE_ENTRY("%p %p", avp, pdata); | |
1200 CHECK_PARAMS( CHECK_AVP(avp) && pdata ); | |
1201 | |
1202 *pdata = &avp->avp_public; | |
1203 return 0; | |
1204 } | |
1205 | |
1206 /* Associate answers and queries */ | |
1207 int fd_msg_answ_associate( struct msg * answer, struct msg * query ) | |
1208 { | |
1209 TRACE_ENTRY( "%p %p", answer, query ); | |
1210 | |
1211 CHECK_PARAMS( CHECK_MSG(answer) && CHECK_MSG(query) && (answer->msg_query == NULL ) ); | |
1212 | |
1213 answer->msg_query = query; | |
637
22e8fac3b2d6
Split interface file in modules
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
400
diff
changeset
|
1214 query->msg_associated = 1; |
0 | 1215 |
1216 return 0; | |
1217 } | |
1218 | |
1219 int fd_msg_answ_getq( struct msg * answer, struct msg ** query ) | |
1220 { | |
1221 TRACE_ENTRY( "%p %p", answer, query ); | |
1222 | |
1223 CHECK_PARAMS( CHECK_MSG(answer) && query ); | |
1224 | |
1225 *query = answer->msg_query; | |
1226 | |
1227 return 0; | |
1228 } | |
1229 | |
1230 int fd_msg_answ_detach( struct msg * answer ) | |
1231 { | |
1232 TRACE_ENTRY( "%p", answer ); | |
1233 | |
1234 CHECK_PARAMS( CHECK_MSG(answer) ); | |
1235 | |
637
22e8fac3b2d6
Split interface file in modules
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
400
diff
changeset
|
1236 answer->msg_query->msg_associated = 0; |
0 | 1237 answer->msg_query = NULL; |
1238 | |
1239 return 0; | |
1240 } | |
1241 | |
1242 /* Associate / get answer callbacks */ | |
1014
908ffbb81f60
Added a second callback in fd_msg_send_timeout to handle more easily the timeout situation
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1009
diff
changeset
|
1243 int fd_msg_anscb_associate( struct msg * msg, void ( *anscb)(void *, struct msg **), void * data, void (*expirecb)(void *, DiamId_t, size_t, struct msg **), const struct timespec *timeout ) |
0 | 1244 { |
1014
908ffbb81f60
Added a second callback in fd_msg_send_timeout to handle more easily the timeout situation
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1009
diff
changeset
|
1245 TRACE_ENTRY("%p %p %p %p", msg, anscb, expirecb, data); |
0 | 1246 |
1247 /* Check the parameters */ | |
824
89c5849b0832
Allow retransmission of messages on timeout
Sebastien Decugis <sdecugis@freediameter.net>
parents:
808
diff
changeset
|
1248 CHECK_PARAMS( CHECK_MSG(msg) ); |
893
8187364e39ea
Fix answers sending
Sebastien Decugis <sdecugis@freediameter.net>
parents:
892
diff
changeset
|
1249 |
8187364e39ea
Fix answers sending
Sebastien Decugis <sdecugis@freediameter.net>
parents:
892
diff
changeset
|
1250 if (! (msg->msg_public.msg_flags & CMD_FLAG_REQUEST )) |
1009
e22434c66126
Be more restrictive on fd_msg_send() called with answer messages, the function now rejects the parameters if an answer callback is provided
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1005
diff
changeset
|
1251 return anscb ? EINVAL : 0; /* we associate with requests only */ |
893
8187364e39ea
Fix answers sending
Sebastien Decugis <sdecugis@freediameter.net>
parents:
892
diff
changeset
|
1252 |
1099 | 1253 CHECK_PARAMS( (anscb == NULL) || (msg->msg_cb.anscb == NULL) ); /* We are not overwriting a cb */ |
1254 CHECK_PARAMS( (expirecb == NULL) || (msg->msg_cb.expirecb == NULL) ); /* We are not overwriting a cb */ | |
0 | 1255 |
1256 /* Associate callback and data with the message, if any */ | |
1229
4e52f009861a
Fix setting of answer and expiry callbacks.
Thomas Klausner <tk@giga.or.at>
parents:
1212
diff
changeset
|
1257 if (anscb) { |
4e52f009861a
Fix setting of answer and expiry callbacks.
Thomas Klausner <tk@giga.or.at>
parents:
1212
diff
changeset
|
1258 msg->msg_cb.anscb = anscb; |
4e52f009861a
Fix setting of answer and expiry callbacks.
Thomas Klausner <tk@giga.or.at>
parents:
1212
diff
changeset
|
1259 msg->msg_cb.data = data; |
4e52f009861a
Fix setting of answer and expiry callbacks.
Thomas Klausner <tk@giga.or.at>
parents:
1212
diff
changeset
|
1260 } |
4e52f009861a
Fix setting of answer and expiry callbacks.
Thomas Klausner <tk@giga.or.at>
parents:
1212
diff
changeset
|
1261 if (expirecb) { |
4e52f009861a
Fix setting of answer and expiry callbacks.
Thomas Klausner <tk@giga.or.at>
parents:
1212
diff
changeset
|
1262 msg->msg_cb.expirecb = expirecb; |
1327
82b386714795
Set callback data also when only setting expire callback (and not answer callback as well).
Thomas Klausner <tk@giga.or.at>
parents:
1305
diff
changeset
|
1263 msg->msg_cb.data = data; |
1229
4e52f009861a
Fix setting of answer and expiry callbacks.
Thomas Klausner <tk@giga.or.at>
parents:
1212
diff
changeset
|
1264 if (timeout) { |
4e52f009861a
Fix setting of answer and expiry callbacks.
Thomas Klausner <tk@giga.or.at>
parents:
1212
diff
changeset
|
1265 memcpy(&msg->msg_cb.timeout, timeout, sizeof(struct timespec)); |
4e52f009861a
Fix setting of answer and expiry callbacks.
Thomas Klausner <tk@giga.or.at>
parents:
1212
diff
changeset
|
1266 } |
646
cfc8da9264f4
Prepared first part of the changes for #10
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
638
diff
changeset
|
1267 } |
0 | 1268 |
1269 return 0; | |
1248
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1270 } |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1271 |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1272 /* Remove a callback */ |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1273 int fd_msg_anscb_reset(struct msg * msg, int clear_anscb, int clear_expirecb) |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1274 { |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1275 TRACE_ENTRY("%p %d %d", msg, clear_anscb, clear_expirecb); |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1276 |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1277 /* Check the parameters */ |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1278 CHECK_PARAMS( CHECK_MSG(msg) ); |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1279 |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1280 if (clear_anscb) { |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1281 msg->msg_cb.anscb = NULL; |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1282 msg->msg_cb.data = NULL; |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1283 } |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1284 if (clear_expirecb) { |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1285 msg->msg_cb.expirecb = NULL; |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1286 memset(&msg->msg_cb.timeout, 0, sizeof(struct timespec)); |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1287 } |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1288 |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1289 return 0; |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1290 } |
c9a160b815ea
Fix issue with anscb in the p_sr expiry mechanism. Thanks Guangming for the report.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1230
diff
changeset
|
1291 |
0 | 1292 |
1014
908ffbb81f60
Added a second callback in fd_msg_send_timeout to handle more easily the timeout situation
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1009
diff
changeset
|
1293 int fd_msg_anscb_get( struct msg * msg, void (**anscb)(void *, struct msg **), void (**expirecb)(void *, DiamId_t, size_t, struct msg **), void ** data ) |
0 | 1294 { |
1014
908ffbb81f60
Added a second callback in fd_msg_send_timeout to handle more easily the timeout situation
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1009
diff
changeset
|
1295 TRACE_ENTRY("%p %p %p %p", msg, anscb, expirecb, data); |
0 | 1296 |
1297 /* Check the parameters */ | |
1014
908ffbb81f60
Added a second callback in fd_msg_send_timeout to handle more easily the timeout situation
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1009
diff
changeset
|
1298 CHECK_PARAMS( CHECK_MSG(msg) ); |
0 | 1299 |
1300 /* Copy the result */ | |
1014
908ffbb81f60
Added a second callback in fd_msg_send_timeout to handle more easily the timeout situation
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1009
diff
changeset
|
1301 if (anscb) |
908ffbb81f60
Added a second callback in fd_msg_send_timeout to handle more easily the timeout situation
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1009
diff
changeset
|
1302 *anscb = msg->msg_cb.anscb; |
908ffbb81f60
Added a second callback in fd_msg_send_timeout to handle more easily the timeout situation
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1009
diff
changeset
|
1303 if (data) |
908ffbb81f60
Added a second callback in fd_msg_send_timeout to handle more easily the timeout situation
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1009
diff
changeset
|
1304 *data = msg->msg_cb.data; |
908ffbb81f60
Added a second callback in fd_msg_send_timeout to handle more easily the timeout situation
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1009
diff
changeset
|
1305 if (expirecb) |
908ffbb81f60
Added a second callback in fd_msg_send_timeout to handle more easily the timeout situation
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1009
diff
changeset
|
1306 *expirecb = msg->msg_cb.expirecb; |
0 | 1307 |
1308 return 0; | |
649
5e5d8152c229
Implemented fd_msg_send_timeout to close #10. Not tested yet.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
648
diff
changeset
|
1309 } |
5e5d8152c229
Implemented fd_msg_send_timeout to close #10. Not tested yet.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
648
diff
changeset
|
1310 |
5e5d8152c229
Implemented fd_msg_send_timeout to close #10. Not tested yet.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
648
diff
changeset
|
1311 struct timespec *fd_msg_anscb_gettimeout( struct msg * msg ) |
5e5d8152c229
Implemented fd_msg_send_timeout to close #10. Not tested yet.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
648
diff
changeset
|
1312 { |
5e5d8152c229
Implemented fd_msg_send_timeout to close #10. Not tested yet.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
648
diff
changeset
|
1313 TRACE_ENTRY("%p", msg); |
5e5d8152c229
Implemented fd_msg_send_timeout to close #10. Not tested yet.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
648
diff
changeset
|
1314 |
5e5d8152c229
Implemented fd_msg_send_timeout to close #10. Not tested yet.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
648
diff
changeset
|
1315 /* Check the parameters */ |
5e5d8152c229
Implemented fd_msg_send_timeout to close #10. Not tested yet.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
648
diff
changeset
|
1316 CHECK_PARAMS_DO( CHECK_MSG(msg), return NULL ); |
5e5d8152c229
Implemented fd_msg_send_timeout to close #10. Not tested yet.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
648
diff
changeset
|
1317 |
5e5d8152c229
Implemented fd_msg_send_timeout to close #10. Not tested yet.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
648
diff
changeset
|
1318 if (!msg->msg_cb.timeout.tv_sec) { |
5e5d8152c229
Implemented fd_msg_send_timeout to close #10. Not tested yet.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
648
diff
changeset
|
1319 return NULL; |
5e5d8152c229
Implemented fd_msg_send_timeout to close #10. Not tested yet.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
648
diff
changeset
|
1320 } |
5e5d8152c229
Implemented fd_msg_send_timeout to close #10. Not tested yet.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
648
diff
changeset
|
1321 |
5e5d8152c229
Implemented fd_msg_send_timeout to close #10. Not tested yet.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
648
diff
changeset
|
1322 return &msg->msg_cb.timeout; |
5e5d8152c229
Implemented fd_msg_send_timeout to close #10. Not tested yet.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
648
diff
changeset
|
1323 } |
0 | 1324 |
1325 /* Associate routing lists */ | |
1212
c38bb8b69c43
Fix message rtd handling for extensions based on this data
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1205
diff
changeset
|
1326 int fd_msg_rt_associate( struct msg * msg, struct rt_data * rtd ) |
0 | 1327 { |
83
c662d3eb6ff6
Started support for routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
37
diff
changeset
|
1328 TRACE_ENTRY( "%p %p", msg, rtd ); |
0 | 1329 |
83
c662d3eb6ff6
Started support for routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
37
diff
changeset
|
1330 CHECK_PARAMS( CHECK_MSG(msg) && rtd ); |
0 | 1331 |
1212
c38bb8b69c43
Fix message rtd handling for extensions based on this data
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1205
diff
changeset
|
1332 msg->msg_rtdata = rtd; |
0 | 1333 |
1334 return 0; | |
1335 } | |
1336 | |
83
c662d3eb6ff6
Started support for routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
37
diff
changeset
|
1337 int fd_msg_rt_get( struct msg * msg, struct rt_data ** rtd ) |
0 | 1338 { |
83
c662d3eb6ff6
Started support for routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
37
diff
changeset
|
1339 TRACE_ENTRY( "%p %p", msg, rtd ); |
0 | 1340 |
83
c662d3eb6ff6
Started support for routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
37
diff
changeset
|
1341 CHECK_PARAMS( CHECK_MSG(msg) && rtd ); |
0 | 1342 |
83
c662d3eb6ff6
Started support for routing module
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
37
diff
changeset
|
1343 *rtd = msg->msg_rtdata; |
0 | 1344 |
1345 return 0; | |
1346 } | |
1347 | |
1348 /* Find if a message is routable */ | |
1349 int fd_msg_is_routable ( struct msg * msg ) | |
1350 { | |
1351 TRACE_ENTRY("%p", msg); | |
1352 | |
1353 CHECK_PARAMS_DO( CHECK_MSG(msg), return 0 /* pretend the message is not routable */ ); | |
1354 | |
1355 if ( ! msg->msg_routable ) { | |
37
cc3c59fe98fe
Lot of cleanups in peer structure management
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
35
diff
changeset
|
1356 /* To define if a message is routable, we rely on the "PXY" flag (for application 0). */ |
cc3c59fe98fe
Lot of cleanups in peer structure management
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
35
diff
changeset
|
1357 msg->msg_routable = ((msg->msg_public.msg_appl != 0) || (msg->msg_public.msg_flags & CMD_FLAG_PROXIABLE)) ? 1 : 2; |
0 | 1358 |
1359 /* Note : the 'real' criteria according to the Diameter I-D is that the message is | |
1360 routable if and only if the "Destination-Realm" AVP is required by the command ABNF. | |
1361 We could make a test for this here, but it's more computational work and our test | |
1362 seems accurate (until proven otherwise...) */ | |
1363 } | |
1364 | |
1365 return (msg->msg_routable == 1) ? 1 : 0; | |
1366 } | |
1367 | |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
1368 /* cache the dictionary model for next function to avoid re-searching at every incoming message */ |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
1369 static struct dict_object *cached_avp_rr_model = NULL; |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
1370 static struct dictionary *cached_avp_rr_dict = NULL; |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
1371 static pthread_mutex_t cached_avp_rr_lock = PTHREAD_MUTEX_INITIALIZER; |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
1372 |
0 | 1373 /* Associate source peer */ |
1120
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1374 int fd_msg_source_set( struct msg * msg, DiamId_t diamid, size_t diamidlen ) |
0 | 1375 { |
1120
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1376 TRACE_ENTRY( "%p %p %zd", msg, diamid, diamidlen); |
0 | 1377 |
1378 /* Check we received a valid message */ | |
1120
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1379 CHECK_PARAMS( CHECK_MSG(msg) ); |
0 | 1380 |
1381 /* Cleanup any previous source */ | |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
1382 free(msg->msg_src_id); msg->msg_src_id = NULL; msg->msg_src_id_len = 0; |
0 | 1383 |
1384 /* If the request is to cleanup the source, we are done */ | |
1385 if (diamid == NULL) { | |
1386 return 0; | |
1387 } | |
1388 | |
1389 /* Otherwise save the new informations */ | |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
1390 CHECK_MALLOC( msg->msg_src_id = os0dup(diamid, diamidlen) ); |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
1391 msg->msg_src_id_len = diamidlen; |
1120
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1392 /* done */ |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1393 return 0; |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1394 } |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1395 |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1396 /* Associate source peer */ |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1397 int fd_msg_source_setrr( struct msg * msg, DiamId_t diamid, size_t diamidlen, struct dictionary * dict ) |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1398 { |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1399 struct dict_object *avp_rr_model = NULL; |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1400 avp_code_t code = AC_ROUTE_RECORD; |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1401 struct avp *avp; |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1402 union avp_value val; |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1403 |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1404 TRACE_ENTRY( "%p %p %zd %p", msg, diamid, diamidlen, dict); |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
1405 |
1120
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1406 /* Check we received a valid message */ |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1407 CHECK_PARAMS( CHECK_MSG(msg) && dict ); |
0 | 1408 |
1120
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1409 /* Lock the cached values */ |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1410 CHECK_POSIX( pthread_mutex_lock(&cached_avp_rr_lock) ); |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1411 if (cached_avp_rr_dict == dict) { |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1412 avp_rr_model = cached_avp_rr_model; |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1413 } |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1414 CHECK_POSIX( pthread_mutex_unlock(&cached_avp_rr_lock) ); |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1415 |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1416 /* If it was not cached */ |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1417 if (!avp_rr_model) { |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1418 /* Find the model for Route-Record in the dictionary */ |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1419 CHECK_FCT( fd_dict_search ( dict, DICT_AVP, AVP_BY_CODE, &code, &avp_rr_model, ENOENT) ); |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1420 |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1421 /* Now cache this result */ |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
1422 CHECK_POSIX( pthread_mutex_lock(&cached_avp_rr_lock) ); |
1120
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1423 cached_avp_rr_dict = dict; |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1424 cached_avp_rr_model = avp_rr_model; |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
1425 CHECK_POSIX( pthread_mutex_unlock(&cached_avp_rr_lock) ); |
1120
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1426 } |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1427 |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1428 /* Create the AVP with this model */ |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1429 CHECK_FCT( fd_msg_avp_new ( avp_rr_model, 0, &avp ) ); |
0 | 1430 |
1120
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1431 /* Set the AVP value with the diameter id */ |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1432 memset(&val, 0, sizeof(val)); |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1433 val.os.data = (uint8_t *)diamid; |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1434 val.os.len = diamidlen; |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1435 CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) ); |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1436 |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1437 /* Add the AVP in the message */ |
c473581adff2
Cleanup some traces
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1119
diff
changeset
|
1438 CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp ) ); |
0 | 1439 |
1440 /* done */ | |
1441 return 0; | |
1442 } | |
1443 | |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
1444 int fd_msg_source_get( struct msg * msg, DiamId_t* diamid, size_t * diamidlen ) |
0 | 1445 { |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
1446 TRACE_ENTRY( "%p %p %p", msg, diamid, diamidlen); |
0 | 1447 |
1448 /* Check we received valid parameters */ | |
1449 CHECK_PARAMS( CHECK_MSG(msg) ); | |
1450 CHECK_PARAMS( diamid ); | |
1451 | |
1452 /* Copy the informations */ | |
1453 *diamid = msg->msg_src_id; | |
1454 | |
706
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
1455 if (diamidlen) |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
1456 *diamidlen = msg->msg_src_id_len; |
4ffbc9f1e922
Large UNTESTED commit with the following changes:
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
704
diff
changeset
|
1457 |
0 | 1458 /* done */ |
1459 return 0; | |
1460 } | |
1461 | |
924
877592751fee
Fix (tentative) for invalid handling of sessions fast creation/destruction as pointed by Yusuke Okura -- http://lists.freediameter.net/pipermail/help/2013-February/000584.html and http://lists.freediameter.net/pipermail/help/2013-February/000589.html -- Thank you very much
Sebastien Decugis <sdecugis@freediameter.net>
parents:
920
diff
changeset
|
1462 /* Associate a session with a message, use only when the session was just created */ |
877592751fee
Fix (tentative) for invalid handling of sessions fast creation/destruction as pointed by Yusuke Okura -- http://lists.freediameter.net/pipermail/help/2013-February/000584.html and http://lists.freediameter.net/pipermail/help/2013-February/000589.html -- Thank you very much
Sebastien Decugis <sdecugis@freediameter.net>
parents:
920
diff
changeset
|
1463 int fd_msg_sess_set(struct msg * msg, struct session * session) |
877592751fee
Fix (tentative) for invalid handling of sessions fast creation/destruction as pointed by Yusuke Okura -- http://lists.freediameter.net/pipermail/help/2013-February/000584.html and http://lists.freediameter.net/pipermail/help/2013-February/000589.html -- Thank you very much
Sebastien Decugis <sdecugis@freediameter.net>
parents:
920
diff
changeset
|
1464 { |
877592751fee
Fix (tentative) for invalid handling of sessions fast creation/destruction as pointed by Yusuke Okura -- http://lists.freediameter.net/pipermail/help/2013-February/000584.html and http://lists.freediameter.net/pipermail/help/2013-February/000589.html -- Thank you very much
Sebastien Decugis <sdecugis@freediameter.net>
parents:
920
diff
changeset
|
1465 TRACE_ENTRY("%p %p", msg, session); |
877592751fee
Fix (tentative) for invalid handling of sessions fast creation/destruction as pointed by Yusuke Okura -- http://lists.freediameter.net/pipermail/help/2013-February/000584.html and http://lists.freediameter.net/pipermail/help/2013-February/000589.html -- Thank you very much
Sebastien Decugis <sdecugis@freediameter.net>
parents:
920
diff
changeset
|
1466 |
877592751fee
Fix (tentative) for invalid handling of sessions fast creation/destruction as pointed by Yusuke Okura -- http://lists.freediameter.net/pipermail/help/2013-February/000584.html and http://lists.freediameter.net/pipermail/help/2013-February/000589.html -- Thank you very much
Sebastien Decugis <sdecugis@freediameter.net>
parents:
920
diff
changeset
|
1467 /* Check we received valid parameters */ |
877592751fee
Fix (tentative) for invalid handling of sessions fast creation/destruction as pointed by Yusuke Okura -- http://lists.freediameter.net/pipermail/help/2013-February/000584.html and http://lists.freediameter.net/pipermail/help/2013-February/000589.html -- Thank you very much
Sebastien Decugis <sdecugis@freediameter.net>
parents:
920
diff
changeset
|
1468 CHECK_PARAMS( CHECK_MSG(msg) ); |
877592751fee
Fix (tentative) for invalid handling of sessions fast creation/destruction as pointed by Yusuke Okura -- http://lists.freediameter.net/pipermail/help/2013-February/000584.html and http://lists.freediameter.net/pipermail/help/2013-February/000589.html -- Thank you very much
Sebastien Decugis <sdecugis@freediameter.net>
parents:
920
diff
changeset
|
1469 CHECK_PARAMS( session ); |
877592751fee
Fix (tentative) for invalid handling of sessions fast creation/destruction as pointed by Yusuke Okura -- http://lists.freediameter.net/pipermail/help/2013-February/000584.html and http://lists.freediameter.net/pipermail/help/2013-February/000589.html -- Thank you very much
Sebastien Decugis <sdecugis@freediameter.net>
parents:
920
diff
changeset
|
1470 CHECK_PARAMS( msg->msg_sess == NULL ); |
877592751fee
Fix (tentative) for invalid handling of sessions fast creation/destruction as pointed by Yusuke Okura -- http://lists.freediameter.net/pipermail/help/2013-February/000584.html and http://lists.freediameter.net/pipermail/help/2013-February/000589.html -- Thank you very much
Sebastien Decugis <sdecugis@freediameter.net>
parents:
920
diff
changeset
|
1471 |
877592751fee
Fix (tentative) for invalid handling of sessions fast creation/destruction as pointed by Yusuke Okura -- http://lists.freediameter.net/pipermail/help/2013-February/000584.html and http://lists.freediameter.net/pipermail/help/2013-February/000589.html -- Thank you very much
Sebastien Decugis <sdecugis@freediameter.net>
parents:
920
diff
changeset
|
1472 msg->msg_sess = session; |
877592751fee
Fix (tentative) for invalid handling of sessions fast creation/destruction as pointed by Yusuke Okura -- http://lists.freediameter.net/pipermail/help/2013-February/000584.html and http://lists.freediameter.net/pipermail/help/2013-February/000589.html -- Thank you very much
Sebastien Decugis <sdecugis@freediameter.net>
parents:
920
diff
changeset
|
1473 return 0; |
877592751fee
Fix (tentative) for invalid handling of sessions fast creation/destruction as pointed by Yusuke Okura -- http://lists.freediameter.net/pipermail/help/2013-February/000584.html and http://lists.freediameter.net/pipermail/help/2013-February/000589.html -- Thank you very much
Sebastien Decugis <sdecugis@freediameter.net>
parents:
920
diff
changeset
|
1474 } |
877592751fee
Fix (tentative) for invalid handling of sessions fast creation/destruction as pointed by Yusuke Okura -- http://lists.freediameter.net/pipermail/help/2013-February/000584.html and http://lists.freediameter.net/pipermail/help/2013-February/000589.html -- Thank you very much
Sebastien Decugis <sdecugis@freediameter.net>
parents:
920
diff
changeset
|
1475 |
895
fbf77629cb7b
Added received and sent timestamps in the messages; added logs on emission and reception
Sebastien Decugis <sdecugis@freediameter.net>
parents:
894
diff
changeset
|
1476 |
85
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1477 /* Retrieve the session of the message */ |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1478 int fd_msg_sess_get(struct dictionary * dict, struct msg * msg, struct session ** session, int * new) |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1479 { |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1480 struct avp * avp; |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1481 |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1482 TRACE_ENTRY("%p %p %p", msg, session, new); |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1483 |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1484 /* Check we received valid parameters */ |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1485 CHECK_PARAMS( CHECK_MSG(msg) ); |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1486 CHECK_PARAMS( session ); |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1487 |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1488 /* If we already resolved the session, just send it back */ |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1489 if (msg->msg_sess) { |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1490 *session = msg->msg_sess; |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1491 if (new) |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1492 *new = 0; |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1493 return 0; |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1494 } |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1495 |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1496 /* OK, we have to search for Session-Id AVP -- it is usually the first AVP, but let's be permissive here */ |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1497 /* -- note: we accept messages that have not yet been dictionary parsed... */ |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1498 CHECK_FCT( fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, &avp, NULL) ); |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1499 while (avp) { |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1500 if ( (avp->avp_public.avp_code == AC_SESSION_ID) |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1501 && (avp->avp_public.avp_vendor == 0) ) |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1502 break; |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1503 |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1504 /* Otherwise move to next AVP in the message */ |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1505 CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) ); |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1506 } |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1507 |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1508 if (!avp) { |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1509 TRACE_DEBUG(FULL, "No Session-Id AVP found in message %p", msg); |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1510 *session = NULL; |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1511 return 0; |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1512 } |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1513 |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1514 if (!avp->avp_model) { |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
1515 CHECK_FCT( fd_msg_parse_dict ( avp, dict, NULL ) ); |
85
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1516 } |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1517 |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1518 ASSERT( avp->avp_public.avp_value ); |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1519 |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1520 /* Resolve the session and we are done */ |
919
b1776283d69e
Do not kill framework when a message with 0b session-id is dispatched
Sebastien Decugis <sdecugis@freediameter.net>
parents:
916
diff
changeset
|
1521 if (avp->avp_public.avp_value->os.len > 0) { |
b1776283d69e
Do not kill framework when a message with 0b session-id is dispatched
Sebastien Decugis <sdecugis@freediameter.net>
parents:
916
diff
changeset
|
1522 CHECK_FCT( fd_sess_fromsid_msg ( avp->avp_public.avp_value->os.data, avp->avp_public.avp_value->os.len, &msg->msg_sess, new) ); |
b1776283d69e
Do not kill framework when a message with 0b session-id is dispatched
Sebastien Decugis <sdecugis@freediameter.net>
parents:
916
diff
changeset
|
1523 *session = msg->msg_sess; |
b1776283d69e
Do not kill framework when a message with 0b session-id is dispatched
Sebastien Decugis <sdecugis@freediameter.net>
parents:
916
diff
changeset
|
1524 } else { |
b1776283d69e
Do not kill framework when a message with 0b session-id is dispatched
Sebastien Decugis <sdecugis@freediameter.net>
parents:
916
diff
changeset
|
1525 TRACE_DEBUG(FULL, "Session-Id AVP with 0-byte length found in message %p", msg); |
b1776283d69e
Do not kill framework when a message with 0b session-id is dispatched
Sebastien Decugis <sdecugis@freediameter.net>
parents:
916
diff
changeset
|
1526 *session = NULL; |
b1776283d69e
Do not kill framework when a message with 0b session-id is dispatched
Sebastien Decugis <sdecugis@freediameter.net>
parents:
916
diff
changeset
|
1527 } |
85
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1528 |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1529 return 0; |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1530 } |
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1531 |
1098
f38d77f9cfd3
Initial implementation of the hook mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1096
diff
changeset
|
1532 /* Retrieve the location of the pmd list for the message; return NULL if failed */ |
f38d77f9cfd3
Initial implementation of the hook mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1096
diff
changeset
|
1533 struct fd_msg_pmdl * fd_msg_pmdl_get(struct msg * msg) |
f38d77f9cfd3
Initial implementation of the hook mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1096
diff
changeset
|
1534 { |
f38d77f9cfd3
Initial implementation of the hook mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1096
diff
changeset
|
1535 CHECK_PARAMS_DO( CHECK_MSG(msg), return NULL ); |
f38d77f9cfd3
Initial implementation of the hook mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1096
diff
changeset
|
1536 return &msg->msg_pmdl; |
f38d77f9cfd3
Initial implementation of the hook mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1096
diff
changeset
|
1537 } |
f38d77f9cfd3
Initial implementation of the hook mechanism
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1096
diff
changeset
|
1538 |
85
e5fcd672caff
Added new function to retrieve messages sessions easily
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
83
diff
changeset
|
1539 |
0 | 1540 /******************* End-to-end counter *********************/ |
686
f83d9878bf66
Fixed in case of termination of several modules (before initialization completed)
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
658
diff
changeset
|
1541 static uint32_t fd_eteid; |
f83d9878bf66
Fixed in case of termination of several modules (before initialization completed)
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
658
diff
changeset
|
1542 static pthread_mutex_t fd_eteid_lck = PTHREAD_MUTEX_INITIALIZER; |
0 | 1543 |
1544 void fd_msg_eteid_init(void) | |
1545 { | |
1125
98d1ad9bf85a
Fix initialization of random number; Cleanup the dump message display
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1121
diff
changeset
|
1546 uint32_t t = (uint32_t)time(NULL); |
98d1ad9bf85a
Fix initialization of random number; Cleanup the dump message display
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1121
diff
changeset
|
1547 srand48(t); |
98d1ad9bf85a
Fix initialization of random number; Cleanup the dump message display
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1121
diff
changeset
|
1548 fd_eteid = (t << 20) | ((uint32_t)lrand48() & ( (1 << 20) - 1 )); |
0 | 1549 } |
1550 | |
1551 uint32_t fd_msg_eteid_get ( void ) | |
1552 { | |
1553 uint32_t ret; | |
1554 | |
1555 CHECK_POSIX_DO( pthread_mutex_lock(&fd_eteid_lck), /* continue */ ); | |
1556 | |
1557 ret = fd_eteid ++; | |
1558 | |
1559 CHECK_POSIX_DO( pthread_mutex_unlock(&fd_eteid_lck), /* continue */ ); | |
1560 | |
1561 return ret; | |
1562 } | |
1563 | |
1564 /***************************************************************************************************************/ | |
1565 /* Manage AVPs values */ | |
1566 | |
1567 /* Set the value of an AVP */ | |
1568 int fd_msg_avp_setvalue ( struct avp *avp, union avp_value *value ) | |
1569 { | |
1570 enum dict_avp_basetype type = -1; | |
1571 | |
1572 TRACE_ENTRY("%p %p", avp, value); | |
1573 | |
1574 /* Check parameter */ | |
1575 CHECK_PARAMS( CHECK_AVP(avp) && avp->avp_model ); | |
1576 | |
1577 /* Retrieve information from the AVP model */ | |
1578 { | |
1579 enum dict_object_type dicttype; | |
1580 struct dict_avp_data dictdata; | |
1581 | |
1582 CHECK_PARAMS( (fd_dict_gettype(avp->avp_model, &dicttype) == 0) && (dicttype == DICT_AVP) ); | |
1583 CHECK_FCT( fd_dict_getval(avp->avp_model, &dictdata) ); | |
1584 type = dictdata.avp_basetype; | |
1585 CHECK_PARAMS( type != AVP_TYPE_GROUPED ); | |
1586 } | |
1587 | |
1588 /* First, clean any previous value */ | |
1589 if (avp->avp_mustfreeos != 0) { | |
1590 free(avp->avp_storage.os.data); | |
1591 avp->avp_mustfreeos = 0; | |
1592 } | |
1593 | |
1594 memset(&avp->avp_storage, 0, sizeof(union avp_value)); | |
1595 | |
1596 /* If the request was to delete a value: */ | |
1597 if (!value) { | |
1598 avp->avp_public.avp_value = NULL; | |
1599 return 0; | |
1600 } | |
1601 | |
1602 /* Now we have to set the value */ | |
1603 memcpy(&avp->avp_storage, value, sizeof(union avp_value)); | |
1604 | |
730 | 1605 /* Duplicate an octetstring if needed. */ |
387
743195485eec
Additional fixes for empty octet string AVPs
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
386
diff
changeset
|
1606 if (type == AVP_TYPE_OCTETSTRING) { |
753
71833fa5e35f
allow applications to create empty AVP also
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
752
diff
changeset
|
1607 CHECK_MALLOC( avp->avp_storage.os.data = os0dup(value->os.data, value->os.len) ); |
71833fa5e35f
allow applications to create empty AVP also
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
752
diff
changeset
|
1608 avp->avp_mustfreeos = 1; |
0 | 1609 } |
1610 | |
1611 /* Set the data pointer of the public part */ | |
1612 avp->avp_public.avp_value = &avp->avp_storage; | |
1613 | |
1614 return 0; | |
1615 } | |
1616 | |
1617 /* Set the value of an AVP, using formatted data */ | |
1618 int fd_msg_avp_value_encode ( void *data, struct avp *avp ) | |
1619 { | |
1620 enum dict_avp_basetype type = -1; | |
1621 struct dict_type_data type_data; | |
1622 | |
1623 TRACE_ENTRY("%p %p", data, avp); | |
1624 | |
1625 /* Check parameter */ | |
1626 CHECK_PARAMS( CHECK_AVP(avp) && avp->avp_model ); | |
1627 | |
1628 /* Retrieve information from the AVP model and it's parent type */ | |
1629 { | |
1630 enum dict_object_type dicttype; | |
1631 struct dict_avp_data dictdata; | |
1632 struct dictionary * dict; | |
1633 struct dict_object * parenttype = NULL; | |
1634 | |
1635 /* First check the base type of the AVP */ | |
1636 CHECK_PARAMS( (fd_dict_gettype(avp->avp_model, &dicttype) == 0) && (dicttype == DICT_AVP) ); | |
1637 CHECK_FCT( fd_dict_getval(avp->avp_model, &dictdata) ); | |
1638 type = dictdata.avp_basetype; | |
1639 CHECK_PARAMS( type != AVP_TYPE_GROUPED ); | |
1640 | |
1641 /* Then retrieve information about the parent's type (= derived type) */ | |
1642 CHECK_FCT( fd_dict_getdict( avp->avp_model, &dict ) ); | |
1643 CHECK_FCT( fd_dict_search( dict, DICT_TYPE, TYPE_OF_AVP, avp->avp_model, &parenttype, EINVAL) ); | |
1644 CHECK_FCT( fd_dict_getval(parenttype, &type_data) ); | |
1645 if (type_data.type_encode == NULL) { | |
1646 TRACE_DEBUG(INFO, "This AVP type does not provide a callback to encode formatted data. ENOTSUP."); | |
1647 return ENOTSUP; | |
1648 } | |
1649 } | |
1650 | |
1651 /* Ok, now we can encode the value */ | |
1652 | |
1653 /* First, clean any previous value */ | |
1654 if (avp->avp_mustfreeos != 0) { | |
1655 free(avp->avp_storage.os.data); | |
1656 avp->avp_mustfreeos = 0; | |
1657 } | |
1658 avp->avp_public.avp_value = NULL; | |
1659 memset(&avp->avp_storage, 0, sizeof(union avp_value)); | |
1660 | |
1661 /* Now call the type's callback to encode the data */ | |
1662 CHECK_FCT( (*type_data.type_encode)(data, &avp->avp_storage) ); | |
1663 | |
1664 /* If an octetstring has been allocated, let's mark it to be freed */ | |
1665 if (type == AVP_TYPE_OCTETSTRING) | |
1666 avp->avp_mustfreeos = 1; | |
1667 | |
1668 /* Set the data pointer of the public part */ | |
1669 avp->avp_public.avp_value = &avp->avp_storage; | |
1670 | |
1671 return 0; | |
1672 } | |
1673 | |
1674 /* Interpret the value of an AVP into formatted data */ | |
1675 int fd_msg_avp_value_interpret ( struct avp *avp, void *data ) | |
1676 { | |
1677 struct dict_type_data type_data; | |
1678 | |
1679 TRACE_ENTRY("%p %p", avp, data); | |
1680 | |
1681 /* Check parameter */ | |
1682 CHECK_PARAMS( CHECK_AVP(avp) && avp->avp_model && avp->avp_public.avp_value ); | |
1683 | |
1684 /* Retrieve information about the AVP parent type */ | |
1685 { | |
1686 struct dictionary * dict; | |
1687 struct dict_object * parenttype = NULL; | |
1688 | |
1689 CHECK_FCT( fd_dict_getdict( avp->avp_model, &dict ) ); | |
1690 CHECK_FCT( fd_dict_search( dict, DICT_TYPE, TYPE_OF_AVP, avp->avp_model, &parenttype, EINVAL) ); | |
1691 CHECK_FCT( fd_dict_getval(parenttype, &type_data) ); | |
1692 if (type_data.type_interpret == NULL) { | |
1693 TRACE_DEBUG(INFO, "This AVP type does not provide a callback to interpret value in formatted data. ENOTSUP."); | |
1694 return ENOTSUP; | |
1695 } | |
1696 } | |
1697 | |
1698 /* Ok, now we can interpret the value */ | |
1699 | |
1700 CHECK_FCT( (*type_data.type_interpret)(avp->avp_public.avp_value, data) ); | |
1701 | |
1702 return 0; | |
1703 } | |
1704 | |
1705 /***************************************************************************************************************/ | |
1706 /* Creating a buffer from memory objects (bufferize a struct msg) */ | |
1707 | |
1708 /* Following macros are used to store 32 and 64 bit fields into a buffer in network byte order */ | |
1709 #define PUT_in_buf_32( _u32data, _bufptr ) { \ | |
1710 *(uint32_t *)(_bufptr) = htonl((uint32_t)(_u32data)); \ | |
1711 } | |
791
42fa209a8cc4
Attempt at fixing unaligned 64b direct memory access (sigbus on sparc)
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
765
diff
changeset
|
1712 |
42fa209a8cc4
Attempt at fixing unaligned 64b direct memory access (sigbus on sparc)
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
765
diff
changeset
|
1713 /* The location is not on 64b boundary, so we split the writing in two operations to avoid sigbus */ |
0 | 1714 #define PUT_in_buf_64( _u64data, _bufptr ) { \ |
791
42fa209a8cc4
Attempt at fixing unaligned 64b direct memory access (sigbus on sparc)
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
765
diff
changeset
|
1715 uint64_t __v = htonll((uint64_t)(_u64data)); \ |
792
0f566e550813
improved the previous fix... not sure it was correct
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
791
diff
changeset
|
1716 memcpy(_bufptr, &__v, sizeof(__v)); \ |
0 | 1717 } |
1718 | |
1719 /* Write a message header in the buffer */ | |
1720 static int bufferize_msg(unsigned char * buffer, size_t buflen, size_t * offset, struct msg * msg) | |
1721 { | |
1027
0117a7746b21
Fix a number of errors and warnings introduced/highlighted by recent commits
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1014
diff
changeset
|
1722 TRACE_ENTRY("%p %zd %p %p", buffer, buflen, offset, msg); |
0 | 1723 |
1724 if ((buflen - *offset) < GETMSGHDRSZ()) | |
1725 return ENOSPC; | |
1726 | |
1727 if (*offset & 0x3) | |
1728 return EFAULT; /* We are supposed to start on 32 bit boundaries */ | |
1729 | |
1730 PUT_in_buf_32(msg->msg_public.msg_length, buffer + *offset); | |
1731 buffer[*offset] = msg->msg_public.msg_version; | |
1732 *offset += 4; | |
1733 | |
1734 PUT_in_buf_32(msg->msg_public.msg_code, buffer + *offset); | |
1735 buffer[*offset] = msg->msg_public.msg_flags; | |
1736 *offset += 4; | |
1737 | |
1738 PUT_in_buf_32(msg->msg_public.msg_appl, buffer + *offset); | |
1739 *offset += 4; | |
1740 | |
1741 PUT_in_buf_32(msg->msg_public.msg_hbhid, buffer + *offset); | |
1742 *offset += 4; | |
1743 | |
1744 PUT_in_buf_32(msg->msg_public.msg_eteid, buffer + *offset); | |
1745 *offset += 4; | |
1746 | |
1747 return 0; | |
1748 } | |
1749 | |
1750 static int bufferize_chain(unsigned char * buffer, size_t buflen, size_t * offset, struct fd_list * list); | |
1751 | |
1752 /* Write an AVP in the buffer */ | |
1753 static int bufferize_avp(unsigned char * buffer, size_t buflen, size_t * offset, struct avp * avp) | |
1754 { | |
1755 struct dict_avp_data dictdata; | |
1756 | |
1027
0117a7746b21
Fix a number of errors and warnings introduced/highlighted by recent commits
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1014
diff
changeset
|
1757 TRACE_ENTRY("%p %zd %p %p", buffer, buflen, offset, avp); |
0 | 1758 |
1759 if ((buflen - *offset) < avp->avp_public.avp_len) | |
1760 return ENOSPC; | |
1761 | |
1762 /* Write the header */ | |
1763 PUT_in_buf_32(avp->avp_public.avp_code, buffer + *offset); | |
1764 *offset += 4; | |
1765 | |
1766 PUT_in_buf_32(avp->avp_public.avp_len, buffer + *offset); | |
1767 buffer[*offset] = avp->avp_public.avp_flags; | |
1768 *offset += 4; | |
1769 | |
1770 if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { | |
1771 PUT_in_buf_32(avp->avp_public.avp_vendor, buffer + *offset); | |
1772 *offset += 4; | |
1773 } | |
1774 | |
1775 /* Then we must write the AVP value */ | |
1776 | |
1777 if (avp->avp_model == NULL) { | |
1778 /* In the case where we don't know the type of AVP, just copy the raw data or source */ | |
1779 CHECK_PARAMS( avp->avp_source || avp->avp_rawdata ); | |
1780 | |
1001
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
1781 if ( avp->avp_rawdata != NULL ) { |
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
1782 /* the content was stored in rawdata */ |
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
1783 memcpy(&buffer[*offset], avp->avp_rawdata, avp->avp_rawlen); |
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
1784 *offset += PAD4(avp->avp_rawlen); |
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
1785 } else { |
0 | 1786 /* the message was not parsed completely */ |
1787 size_t datalen = avp->avp_public.avp_len - GETAVPHDRSZ(avp->avp_public.avp_flags); | |
1788 memcpy(&buffer[*offset], avp->avp_source, datalen); | |
1789 *offset += PAD4(datalen); | |
1790 } | |
1791 | |
1792 } else { | |
1793 /* The AVP is defined in the dictionary */ | |
1794 CHECK_FCT( fd_dict_getval(avp->avp_model, &dictdata) ); | |
1795 | |
1796 CHECK_PARAMS( ( dictdata.avp_basetype == AVP_TYPE_GROUPED ) || avp->avp_public.avp_value ); | |
1797 | |
1798 switch (dictdata.avp_basetype) { | |
1799 case AVP_TYPE_GROUPED: | |
1800 return bufferize_chain(buffer, buflen, offset, &avp->avp_chain.children); | |
1801 | |
1802 case AVP_TYPE_OCTETSTRING: | |
387
743195485eec
Additional fixes for empty octet string AVPs
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
386
diff
changeset
|
1803 if (avp->avp_public.avp_value->os.len) |
743195485eec
Additional fixes for empty octet string AVPs
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
386
diff
changeset
|
1804 memcpy(&buffer[*offset], avp->avp_public.avp_value->os.data, avp->avp_public.avp_value->os.len); |
0 | 1805 *offset += PAD4(avp->avp_public.avp_value->os.len); |
1806 break; | |
1807 | |
1808 case AVP_TYPE_INTEGER32: | |
1809 PUT_in_buf_32(avp->avp_public.avp_value->i32, buffer + *offset); | |
1810 *offset += 4; | |
1811 break; | |
1812 | |
1813 case AVP_TYPE_INTEGER64: | |
1814 PUT_in_buf_64(avp->avp_public.avp_value->i64, buffer + *offset); | |
1815 *offset += 8; | |
1816 break; | |
1817 | |
1818 case AVP_TYPE_UNSIGNED32: | |
1819 PUT_in_buf_32(avp->avp_public.avp_value->u32, buffer + *offset); | |
1820 *offset += 4; | |
1821 break; | |
1822 | |
1823 case AVP_TYPE_UNSIGNED64: | |
1824 PUT_in_buf_64(avp->avp_public.avp_value->u64, buffer + *offset); | |
1825 *offset += 8; | |
1826 break; | |
1827 | |
1828 case AVP_TYPE_FLOAT32: | |
1829 /* We read the f32 as "u32" here to avoid casting to uint make decimals go away. | |
1830 The alternative would be something like "*(uint32_t *)(& f32)" but | |
1831 then the compiler complains about strict-aliasing rules. */ | |
1832 PUT_in_buf_32(avp->avp_public.avp_value->u32, buffer + *offset); | |
1833 *offset += 4; | |
1834 break; | |
1835 | |
1836 case AVP_TYPE_FLOAT64: | |
1837 /* Same remark as previously */ | |
1838 PUT_in_buf_64(avp->avp_public.avp_value->u64, buffer + *offset); | |
1839 *offset += 8; | |
1840 break; | |
1841 | |
1842 default: | |
1843 ASSERT(0); | |
1844 } | |
1845 } | |
1846 return 0; | |
1847 } | |
1848 | |
1849 /* Write a chain of AVPs in the buffer */ | |
1850 static int bufferize_chain(unsigned char * buffer, size_t buflen, size_t * offset, struct fd_list * list) | |
1851 { | |
1852 struct fd_list * avpch; | |
1853 | |
1027
0117a7746b21
Fix a number of errors and warnings introduced/highlighted by recent commits
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1014
diff
changeset
|
1854 TRACE_ENTRY("%p %zd %p %p", buffer, buflen, offset, list); |
0 | 1855 |
1856 for (avpch = list->next; avpch != list; avpch = avpch->next) { | |
1857 /* Bufferize the AVP */ | |
1858 CHECK_FCT( bufferize_avp(buffer, buflen, offset, _A(avpch->o)) ); | |
1859 } | |
1860 return 0; | |
1861 } | |
1862 | |
1863 /* Create the message buffer, in network-byte order. We browse the tree twice, this could be probably improved if needed */ | |
1864 int fd_msg_bufferize ( struct msg * msg, unsigned char ** buffer, size_t * len ) | |
1865 { | |
1866 int ret = 0; | |
1867 unsigned char * buf = NULL; | |
1868 size_t offset = 0; | |
1869 | |
1870 TRACE_ENTRY("%p %p %p", msg, buffer, len); | |
1871 | |
1872 /* Check the parameters */ | |
1873 CHECK_PARAMS( buffer && CHECK_MSG(msg) ); | |
1874 | |
1875 /* Update the length. This also checks that all AVP have their values set */ | |
1876 CHECK_FCT( fd_msg_update_length(msg) ); | |
1877 | |
1878 /* Now allocate a buffer to store the message */ | |
1879 CHECK_MALLOC( buf = malloc(msg->msg_public.msg_length) ); | |
1880 | |
1881 /* Clear the memory, so that the padding is always 0 (should not matter) */ | |
1882 memset(buf, 0, msg->msg_public.msg_length); | |
1883 | |
1884 /* Write the message header in the buffer */ | |
1885 CHECK_FCT_DO( ret = bufferize_msg(buf, msg->msg_public.msg_length, &offset, msg), | |
1886 { | |
1887 free(buf); | |
1888 return ret; | |
1889 } ); | |
1890 | |
1891 /* Write the list of AVPs */ | |
1892 CHECK_FCT_DO( ret = bufferize_chain(buf, msg->msg_public.msg_length, &offset, &msg->msg_chain.children), | |
1893 { | |
1894 free(buf); | |
1895 return ret; | |
1896 } ); | |
1897 | |
1898 ASSERT(offset == msg->msg_public.msg_length); /* or the msg_update_length is buggy */ | |
1899 | |
1900 if (len) { | |
1901 *len = offset; | |
1902 } | |
1903 | |
1904 *buffer = buf; | |
1905 return 0; | |
1906 } | |
1907 | |
1908 | |
1909 /***************************************************************************************************************/ | |
1910 /* Parsing buffers and building AVP objects lists (not parsing the AVP values which requires dictionary knowledge) */ | |
1911 | |
1912 /* Parse a buffer containing a supposed list of AVPs */ | |
1913 static int parsebuf_list(unsigned char * buf, size_t buflen, struct fd_list * head) | |
1914 { | |
1915 size_t offset = 0; | |
1916 | |
1027
0117a7746b21
Fix a number of errors and warnings introduced/highlighted by recent commits
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1014
diff
changeset
|
1917 TRACE_ENTRY("%p %zd %p", buf, buflen, head); |
0 | 1918 |
1919 while (offset < buflen) { | |
1920 struct avp * avp; | |
1921 | |
920
cb439d57d0c5
Fix parsing of incoming AVPs with 0-byte length at the end of the message
Sebastien Decugis <sdecugis@freediameter.net>
parents:
919
diff
changeset
|
1922 if (buflen - offset < AVPHDRSZ_NOVEND) { |
1027
0117a7746b21
Fix a number of errors and warnings introduced/highlighted by recent commits
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1014
diff
changeset
|
1923 TRACE_DEBUG(INFO, "truncated buffer: remaining only %zd bytes", buflen - offset); |
0 | 1924 return EBADMSG; |
1925 } | |
1926 | |
1927 /* Create a new AVP object */ | |
1928 CHECK_MALLOC( avp = malloc (sizeof(struct avp)) ); | |
1929 | |
1930 init_avp(avp); | |
1931 | |
1932 /* Initialize the header */ | |
1933 avp->avp_public.avp_code = ntohl(*(uint32_t *)(buf + offset)); | |
1934 avp->avp_public.avp_flags = buf[offset + 4]; | |
1935 avp->avp_public.avp_len = ((uint32_t)buf[offset+5]) << 16 | ((uint32_t)buf[offset+6]) << 8 | ((uint32_t)buf[offset+7]) ; | |
1936 | |
1937 offset += 8; | |
1938 | |
1939 if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { | |
920
cb439d57d0c5
Fix parsing of incoming AVPs with 0-byte length at the end of the message
Sebastien Decugis <sdecugis@freediameter.net>
parents:
919
diff
changeset
|
1940 if (buflen - offset < 4) { |
1027
0117a7746b21
Fix a number of errors and warnings introduced/highlighted by recent commits
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1014
diff
changeset
|
1941 TRACE_DEBUG(INFO, "truncated buffer: remaining only %zd bytes for vendor and data", buflen - offset); |
0 | 1942 free(avp); |
1943 return EBADMSG; | |
1944 } | |
1945 avp->avp_public.avp_vendor = ntohl(*(uint32_t *)(buf + offset)); | |
1946 offset += 4; | |
1947 } | |
1948 | |
1949 /* Check there is enough remaining data in the buffer */ | |
920
cb439d57d0c5
Fix parsing of incoming AVPs with 0-byte length at the end of the message
Sebastien Decugis <sdecugis@freediameter.net>
parents:
919
diff
changeset
|
1950 if ( (avp->avp_public.avp_len > GETAVPHDRSZ(avp->avp_public.avp_flags)) |
cb439d57d0c5
Fix parsing of incoming AVPs with 0-byte length at the end of the message
Sebastien Decugis <sdecugis@freediameter.net>
parents:
919
diff
changeset
|
1951 && (buflen - offset < avp->avp_public.avp_len - GETAVPHDRSZ(avp->avp_public.avp_flags))) { |
1027
0117a7746b21
Fix a number of errors and warnings introduced/highlighted by recent commits
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1014
diff
changeset
|
1952 TRACE_DEBUG(INFO, "truncated buffer: remaining only %zd bytes for data, and avp data size is %d", |
0 | 1953 buflen - offset, |
1954 avp->avp_public.avp_len - GETAVPHDRSZ(avp->avp_public.avp_flags)); | |
1955 free(avp); | |
1956 return EBADMSG; | |
1957 } | |
1958 | |
1959 /* buf[offset] is now the beginning of the data */ | |
1960 avp->avp_source = &buf[offset]; | |
1961 | |
1962 /* Now eat the data and eventual padding */ | |
1963 offset += PAD4(avp->avp_public.avp_len - GETAVPHDRSZ(avp->avp_public.avp_flags)); | |
1964 | |
1965 /* And insert this avp in the list, at the end */ | |
1966 fd_list_insert_before( head, &avp->avp_chain.chaining ); | |
1967 } | |
1968 | |
1969 return 0; | |
1970 } | |
1971 | |
1972 /* Create a message object from a buffer. Dictionary objects are not resolved, AVP contents are not interpreted, buffer is saved in msg */ | |
1973 int fd_msg_parse_buffer ( unsigned char ** buffer, size_t buflen, struct msg ** msg ) | |
1974 { | |
1975 struct msg * new = NULL; | |
1976 int ret = 0; | |
1977 uint32_t msglen = 0; | |
1978 unsigned char * buf; | |
1979 | |
1027
0117a7746b21
Fix a number of errors and warnings introduced/highlighted by recent commits
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1014
diff
changeset
|
1980 TRACE_ENTRY("%p %zd %p", buffer, buflen, msg); |
0 | 1981 |
1982 CHECK_PARAMS( buffer && *buffer && msg && (buflen >= GETMSGHDRSZ()) ); | |
1983 buf = *buffer; | |
1984 | |
1985 if ( buf[0] != DIAMETER_VERSION) { | |
1986 TRACE_DEBUG(INFO, "Invalid version in message: %d (supported: %d)", buf[0], DIAMETER_VERSION); | |
1987 return EBADMSG; | |
1988 } | |
1989 | |
1990 msglen = ntohl(*(uint32_t *)buf) & 0x00ffffff; | |
1991 if ( buflen < msglen ) { | |
1027
0117a7746b21
Fix a number of errors and warnings introduced/highlighted by recent commits
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1014
diff
changeset
|
1992 TRACE_DEBUG(INFO, "Truncated message (%zd / %d)", buflen, msglen ); |
0 | 1993 return EBADMSG; |
1994 } | |
1995 | |
1996 /* Create a new object */ | |
1103
d8591b1c56cd
Implemented a few hooks
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1101
diff
changeset
|
1997 CHECK_MALLOC( new = malloc (sizeof(struct msg)) ); |
0 | 1998 |
1999 /* Initialize the fields */ | |
2000 init_msg(new); | |
2001 | |
2002 /* Now read from the buffer */ | |
2003 new->msg_public.msg_version = buf[0]; | |
2004 new->msg_public.msg_length = msglen; | |
2005 | |
2006 new->msg_public.msg_flags = buf[4]; | |
2007 new->msg_public.msg_code = ntohl(*(uint32_t *)(buf+4)) & 0x00ffffff; | |
2008 | |
2009 new->msg_public.msg_appl = ntohl(*(uint32_t *)(buf+8)); | |
2010 new->msg_public.msg_hbhid = ntohl(*(uint32_t *)(buf+12)); | |
2011 new->msg_public.msg_eteid = ntohl(*(uint32_t *)(buf+16)); | |
2012 | |
2013 /* Parse the AVP list */ | |
2014 CHECK_FCT_DO( ret = parsebuf_list(buf + GETMSGHDRSZ(), buflen - GETMSGHDRSZ(), &new->msg_chain.children), { destroy_tree(_C(new)); return ret; } ); | |
2015 | |
1103
d8591b1c56cd
Implemented a few hooks
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1101
diff
changeset
|
2016 /* Parsing successful */ |
d8591b1c56cd
Implemented a few hooks
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1101
diff
changeset
|
2017 new->msg_rawbuffer = buf; |
d8591b1c56cd
Implemented a few hooks
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1101
diff
changeset
|
2018 *buffer = NULL; |
0 | 2019 *msg = new; |
2020 return 0; | |
2021 } | |
2022 | |
2023 | |
2024 /***************************************************************************************************************/ | |
2025 /* Parsing messages and AVP with dictionary information */ | |
2026 | |
2027 /* Resolve dictionary objects of the cmd and avp instances, from their headers. | |
2028 * When the model is found, the data is interpreted from the avp_source buffer and copied to avp_storage. | |
2029 * When the model is not found, the data is copied as rawdata and saved (in case we FW the message). | |
2030 * Therefore, after this function has been called, the source buffer can be freed. | |
2031 * For command, if the dictionary model is not found, an error is returned. | |
2032 */ | |
2033 | |
889
4a299daed8b2
Add information about parsing errors
Sebastien Decugis <sdecugis@freediameter.net>
parents:
871
diff
changeset
|
2034 static char error_message[256]; |
4a299daed8b2
Add information about parsing errors
Sebastien Decugis <sdecugis@freediameter.net>
parents:
871
diff
changeset
|
2035 |
0 | 2036 /* Process an AVP. If we are not in recheck, the avp_source must be set. */ |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2037 static int parsedict_do_avp(struct dictionary * dict, struct avp * avp, int mandatory, struct fd_pei *error_info) |
0 | 2038 { |
2039 struct dict_avp_data dictdata; | |
1300
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2040 struct dict_type_data derivedtypedata; |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2041 struct dict_object * avp_derived_type = NULL; |
1001
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
2042 uint8_t * source; |
0 | 2043 |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2044 TRACE_ENTRY("%p %p %d %p", dict, avp, mandatory, error_info); |
0 | 2045 |
2046 /* First check we received an AVP as input */ | |
2047 CHECK_PARAMS( CHECK_AVP(avp) ); | |
2048 | |
2049 if (avp->avp_model != NULL) { | |
2050 /* the model has already been resolved. we do check it is still valid */ | |
2051 | |
2052 CHECK_FCT( fd_dict_getval(avp->avp_model, &dictdata) ); | |
2053 | |
2054 if ( avp->avp_public.avp_code == dictdata.avp_code ) { | |
2055 /* Ok then just process the children if any */ | |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2056 return parsedict_do_chain(dict, &avp->avp_chain.children, mandatory && (avp->avp_public.avp_flags & AVP_FLAG_MANDATORY), error_info); |
0 | 2057 } else { |
2058 /* We just erase the old model */ | |
2059 avp->avp_model = NULL; | |
2060 } | |
2061 } | |
2062 | |
1092
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2063 /* Check if we already searched for this model without success */ |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2064 if ((avp->avp_model_not_found.mnf_code != avp->avp_public.avp_code) |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2065 || (avp->avp_model_not_found.mnf_vendor != avp->avp_public.avp_vendor)) { |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2066 |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2067 /* Now try and resolve the model from the avp code and vendor */ |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2068 if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2069 struct dict_avp_request_ex avpreq; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2070 memset(&avpreq, 0, sizeof(avpreq)); |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2071 avpreq.avp_vendor.vendor_id = avp->avp_public.avp_vendor; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2072 avpreq.avp_data.avp_code = avp->avp_public.avp_code; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2073 CHECK_FCT( fd_dict_search ( dict, DICT_AVP, AVP_BY_STRUCT, &avpreq, &avp->avp_model, 0)); |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2074 } else { |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2075 /* no vendor */ |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2076 CHECK_FCT( fd_dict_search ( dict, DICT_AVP, AVP_BY_CODE, &avp->avp_public.avp_code, &avp->avp_model, 0)); |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2077 } |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2078 |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2079 if (!avp->avp_model) { |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2080 avp->avp_model_not_found.mnf_code = avp->avp_public.avp_code; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2081 avp->avp_model_not_found.mnf_vendor = avp->avp_public.avp_vendor; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2082 } |
0 | 2083 } |
2084 | |
2085 /* First handle the case where we have not found this AVP in the dictionary */ | |
2086 if (!avp->avp_model) { | |
2087 | |
2088 if (mandatory && (avp->avp_public.avp_flags & AVP_FLAG_MANDATORY)) { | |
1119
79dd22145f52
Fix a number of compilation warnings
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1113
diff
changeset
|
2089 TRACE_DEBUG(INFO, "Unsupported mandatory AVP found"); |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2090 if (error_info) { |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2091 error_info->pei_errcode = "DIAMETER_AVP_UNSUPPORTED"; |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2092 error_info->pei_avp = avp; |
1119
79dd22145f52
Fix a number of compilation warnings
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1113
diff
changeset
|
2093 } else { |
79dd22145f52
Fix a number of compilation warnings
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1113
diff
changeset
|
2094 char * buf = NULL; |
79dd22145f52
Fix a number of compilation warnings
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1113
diff
changeset
|
2095 size_t buflen; |
79dd22145f52
Fix a number of compilation warnings
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1113
diff
changeset
|
2096 CHECK_MALLOC(fd_msg_dump_treeview(&buf, &buflen, NULL, avp, NULL, 0, 0)); |
79dd22145f52
Fix a number of compilation warnings
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1113
diff
changeset
|
2097 LOG_E("Unsupported AVP: %s", buf); |
79dd22145f52
Fix a number of compilation warnings
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1113
diff
changeset
|
2098 free(buf); |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2099 } |
0 | 2100 return ENOTSUP; |
2101 } | |
2102 | |
2103 if (avp->avp_source) { | |
2104 /* we must copy the data from the source to the internal buffer area */ | |
2105 CHECK_PARAMS( !avp->avp_rawdata ); | |
2106 | |
2107 avp->avp_rawlen = avp->avp_public.avp_len - GETAVPHDRSZ( avp->avp_public.avp_flags ); | |
2108 | |
387
743195485eec
Additional fixes for empty octet string AVPs
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
386
diff
changeset
|
2109 if (avp->avp_rawlen) { |
743195485eec
Additional fixes for empty octet string AVPs
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
386
diff
changeset
|
2110 CHECK_MALLOC( avp->avp_rawdata = malloc(avp->avp_rawlen) ); |
0 | 2111 |
387
743195485eec
Additional fixes for empty octet string AVPs
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
386
diff
changeset
|
2112 memcpy(avp->avp_rawdata, avp->avp_source, avp->avp_rawlen); |
743195485eec
Additional fixes for empty octet string AVPs
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
386
diff
changeset
|
2113 } |
743195485eec
Additional fixes for empty octet string AVPs
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
386
diff
changeset
|
2114 |
0 | 2115 avp->avp_source = NULL; |
2116 | |
2117 TRACE_DEBUG(FULL, "Unsupported optional AVP found, raw source data saved in avp_rawdata."); | |
2118 } | |
2119 | |
2120 return 0; | |
2121 } | |
2122 | |
2123 /* Ok we have resolved the object. Now we need to interpret its content. */ | |
2124 | |
2125 CHECK_FCT( fd_dict_getval(avp->avp_model, &dictdata) ); | |
2126 | |
2127 if (avp->avp_rawdata) { | |
2128 /* This happens if the dictionary object was defined after the first check */ | |
2129 avp->avp_source = avp->avp_rawdata; | |
2130 } | |
2131 | |
2132 /* A bit of sanity here... */ | |
2133 ASSERT(CHECK_BASETYPE(dictdata.avp_basetype)); | |
2134 | |
2135 /* Check the size is valid */ | |
2136 if ((avp_value_sizes[dictdata.avp_basetype] != 0) && | |
2137 (avp->avp_public.avp_len - GETAVPHDRSZ( avp->avp_public.avp_flags ) != avp_value_sizes[dictdata.avp_basetype])) { | |
1119
79dd22145f52
Fix a number of compilation warnings
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1113
diff
changeset
|
2138 TRACE_DEBUG(INFO, "The AVP size is not suitable for the type"); |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2139 if (error_info) { |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2140 error_info->pei_errcode = "DIAMETER_INVALID_AVP_LENGTH"; |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2141 error_info->pei_avp = avp; |
889
4a299daed8b2
Add information about parsing errors
Sebastien Decugis <sdecugis@freediameter.net>
parents:
871
diff
changeset
|
2142 snprintf(error_message, sizeof(error_message), "I expected a size of %d for this AVP according to my dictionary", avp_value_sizes[dictdata.avp_basetype]); |
4a299daed8b2
Add information about parsing errors
Sebastien Decugis <sdecugis@freediameter.net>
parents:
871
diff
changeset
|
2143 error_info->pei_message = error_message; |
1119
79dd22145f52
Fix a number of compilation warnings
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1113
diff
changeset
|
2144 } else { |
79dd22145f52
Fix a number of compilation warnings
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1113
diff
changeset
|
2145 char * buf = NULL; |
79dd22145f52
Fix a number of compilation warnings
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1113
diff
changeset
|
2146 size_t buflen; |
79dd22145f52
Fix a number of compilation warnings
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1113
diff
changeset
|
2147 CHECK_MALLOC(fd_msg_dump_treeview(&buf, &buflen, NULL, avp, NULL, 0, 0)); |
79dd22145f52
Fix a number of compilation warnings
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1113
diff
changeset
|
2148 LOG_E("Invalid length AVP: %s", buf); |
79dd22145f52
Fix a number of compilation warnings
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1113
diff
changeset
|
2149 free(buf); |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2150 } |
891
9432ac55823c
Tentative fix for the parse_or_error function
Sebastien Decugis <sdecugis@freediameter.net>
parents:
889
diff
changeset
|
2151 avp->avp_model = NULL; |
0 | 2152 return EBADMSG; |
2153 } | |
2154 | |
1001
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
2155 source = avp->avp_source; |
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
2156 avp->avp_source = NULL; |
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
2157 |
0 | 2158 /* Now get the value inside */ |
2159 switch (dictdata.avp_basetype) { | |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2160 case AVP_TYPE_GROUPED: { |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2161 int ret; |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2162 |
0 | 2163 /* This is a grouped AVP, so let's parse the list of AVPs inside */ |
1001
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
2164 CHECK_FCT_DO( ret = parsebuf_list(source, avp->avp_public.avp_len - GETAVPHDRSZ( avp->avp_public.avp_flags ), &avp->avp_chain.children), |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2165 { |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2166 if ((ret == EBADMSG) && (error_info)) { |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2167 error_info->pei_errcode = "DIAMETER_INVALID_AVP_VALUE"; |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2168 error_info->pei_avp = avp; |
889
4a299daed8b2
Add information about parsing errors
Sebastien Decugis <sdecugis@freediameter.net>
parents:
871
diff
changeset
|
2169 snprintf(error_message, sizeof(error_message), "I cannot parse this AVP as a Grouped AVP"); |
4a299daed8b2
Add information about parsing errors
Sebastien Decugis <sdecugis@freediameter.net>
parents:
871
diff
changeset
|
2170 error_info->pei_message = error_message; |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2171 } |
1001
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
2172 avp->avp_source = source; |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2173 return ret; |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2174 } ); |
0 | 2175 |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2176 return parsedict_do_chain(dict, &avp->avp_chain.children, mandatory && (avp->avp_public.avp_flags & AVP_FLAG_MANDATORY), error_info); |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2177 } |
0 | 2178 |
2179 case AVP_TYPE_OCTETSTRING: | |
2180 /* We just have to copy the string into the storage area */ | |
387
743195485eec
Additional fixes for empty octet string AVPs
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
386
diff
changeset
|
2181 CHECK_PARAMS_DO( avp->avp_public.avp_len >= GETAVPHDRSZ( avp->avp_public.avp_flags ), |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2182 { |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2183 if (error_info) { |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2184 error_info->pei_errcode = "DIAMETER_INVALID_AVP_LENGTH"; |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2185 error_info->pei_avp = avp; |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2186 } |
1001
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
2187 avp->avp_source = source; |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2188 return EBADMSG; |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2189 } ); |
0 | 2190 avp->avp_storage.os.len = avp->avp_public.avp_len - GETAVPHDRSZ( avp->avp_public.avp_flags ); |
1001
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
2191 CHECK_MALLOC( avp->avp_storage.os.data = os0dup(source, avp->avp_storage.os.len) ); |
752
9e9840ccf059
Attempt to handle more gracefully (invalid) AVPs that contain an empty octetstring
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
740
diff
changeset
|
2192 avp->avp_mustfreeos = 1; |
0 | 2193 break; |
2194 | |
2195 case AVP_TYPE_INTEGER32: | |
1001
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
2196 avp->avp_storage.i32 = (int32_t)ntohl(*(uint32_t *)source); |
0 | 2197 break; |
2198 | |
2199 case AVP_TYPE_INTEGER64: | |
791
42fa209a8cc4
Attempt at fixing unaligned 64b direct memory access (sigbus on sparc)
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
765
diff
changeset
|
2200 /* the storage might not be aligned on 64b boundary, so no direct indirection here is possible */ |
42fa209a8cc4
Attempt at fixing unaligned 64b direct memory access (sigbus on sparc)
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
765
diff
changeset
|
2201 { |
42fa209a8cc4
Attempt at fixing unaligned 64b direct memory access (sigbus on sparc)
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
765
diff
changeset
|
2202 uint64_t __stor; |
1001
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
2203 memcpy(&__stor, source, sizeof(__stor)); |
791
42fa209a8cc4
Attempt at fixing unaligned 64b direct memory access (sigbus on sparc)
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
765
diff
changeset
|
2204 avp->avp_storage.i64 = (int64_t)ntohll(__stor); |
42fa209a8cc4
Attempt at fixing unaligned 64b direct memory access (sigbus on sparc)
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
765
diff
changeset
|
2205 } |
0 | 2206 break; |
2207 | |
2208 case AVP_TYPE_UNSIGNED32: | |
2209 case AVP_TYPE_FLOAT32: /* For float, we must not cast, or the value is changed. Instead we use implicit cast by changing the member of the union */ | |
1001
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
2210 avp->avp_storage.u32 = (uint32_t)ntohl(*(uint32_t *)source); |
0 | 2211 break; |
2212 | |
2213 case AVP_TYPE_UNSIGNED64: | |
2214 case AVP_TYPE_FLOAT64: /* same as 32 bits */ | |
791
42fa209a8cc4
Attempt at fixing unaligned 64b direct memory access (sigbus on sparc)
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
765
diff
changeset
|
2215 { |
42fa209a8cc4
Attempt at fixing unaligned 64b direct memory access (sigbus on sparc)
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
765
diff
changeset
|
2216 uint64_t __stor; |
1001
d03f7e3805ad
Fix generation of the Proxy-Info AVP in fd_msg_new_answer_from_req
Sebastien Decugis <sdecugis@freediameter.net>
parents:
995
diff
changeset
|
2217 memcpy(&__stor, source, sizeof(__stor)); |
791
42fa209a8cc4
Attempt at fixing unaligned 64b direct memory access (sigbus on sparc)
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
765
diff
changeset
|
2218 avp->avp_storage.u64 = (uint64_t)ntohll(__stor); |
42fa209a8cc4
Attempt at fixing unaligned 64b direct memory access (sigbus on sparc)
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
765
diff
changeset
|
2219 } |
0 | 2220 break; |
2221 | |
2222 } | |
2223 | |
1300
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2224 /* Is there a derived type check function ? */ |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2225 CHECK_FCT ( fd_dict_search ( dict, DICT_TYPE, TYPE_OF_AVP, avp->avp_model, &avp_derived_type, 0) ); |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2226 if (avp_derived_type) { |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2227 CHECK_FCT( fd_dict_getval(avp_derived_type, &derivedtypedata) ); |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2228 if (derivedtypedata.type_check != NULL) { |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2229 char * err; |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2230 int ret = (*derivedtypedata.type_check)( derivedtypedata.type_check_param, &avp->avp_storage, &err ); |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2231 |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2232 if (ret != 0) { |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2233 TRACE_DEBUG(INFO, "The AVP failed to pass the dictionary validation"); |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2234 if (error_info) { |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2235 error_info->pei_errcode = "DIAMETER_INVALID_AVP_VALUE"; |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2236 error_info->pei_avp = avp; |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2237 strncpy(error_message, err, sizeof(error_message)); |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2238 error_info->pei_message = error_message; |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2239 } else { |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2240 char * buf = NULL; |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2241 size_t buflen; |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2242 CHECK_MALLOC(fd_msg_dump_treeview(&buf, &buflen, NULL, avp, NULL, 0, 0)); |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2243 LOG_E("Invalid AVP: %s", buf); |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2244 free(buf); |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2245 } |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2246 return ret; /* should we just return EBADMSG? */ |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2247 } |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2248 } |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2249 } |
3f1e79e1273e
Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1298
diff
changeset
|
2250 |
0 | 2251 /* The value is now set, so set the data pointer and return 0 */ |
2252 avp->avp_public.avp_value = &avp->avp_storage; | |
2253 return 0; | |
2254 } | |
2255 | |
2256 /* Process a list of AVPs */ | |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2257 static int parsedict_do_chain(struct dictionary * dict, struct fd_list * head, int mandatory, struct fd_pei *error_info) |
0 | 2258 { |
2259 struct fd_list * avpch; | |
2260 | |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2261 TRACE_ENTRY("%p %p %d %p", dict, head, mandatory, error_info); |
0 | 2262 |
2263 /* Sanity check */ | |
2264 ASSERT ( head == head->head ); | |
2265 | |
2266 /* Now process the list */ | |
2267 for (avpch=head->next; avpch != head; avpch = avpch->next) { | |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2268 CHECK_FCT( parsedict_do_avp(dict, _A(avpch->o), mandatory, error_info) ); |
0 | 2269 } |
2270 | |
2271 /* Done */ | |
2272 return 0; | |
2273 } | |
2274 | |
2275 /* Process a msg header. */ | |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2276 static int parsedict_do_msg(struct dictionary * dict, struct msg * msg, int only_hdr, struct fd_pei *error_info) |
0 | 2277 { |
2278 int ret = 0; | |
2279 | |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2280 TRACE_ENTRY("%p %p %d %p", dict, msg, only_hdr, error_info); |
0 | 2281 |
2282 CHECK_PARAMS( CHECK_MSG(msg) ); | |
2283 | |
1092
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2284 /* First, check if we already have a model. */ |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2285 if (msg->msg_model != NULL) { |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2286 /* Check if this model is still valid for the message data */ |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2287 enum dict_object_type dicttype; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2288 struct dict_cmd_data data; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2289 ASSERT(((fd_dict_gettype(msg->msg_model, &dicttype) == 0) && (dicttype == DICT_COMMAND))); |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2290 (void)fd_dict_getval( msg->msg_model, &data); |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2291 if ((data.cmd_code != msg->msg_public.msg_code) |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2292 || ((data.cmd_flag_val & data.cmd_flag_mask) != (msg->msg_public.msg_flags && data.cmd_flag_mask))) { |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2293 msg->msg_model = NULL; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2294 } else { |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2295 goto chain; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2296 } |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2297 } |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2298 |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2299 /* Check if we already searched for this model without success */ |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2300 if ((msg->msg_model_not_found.mnf_code == msg->msg_public.msg_code) |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2301 && (msg->msg_model_not_found.mnf_flags == msg->msg_public.msg_flags)) { |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2302 goto no_model; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2303 } else { |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2304 msg->msg_model_not_found.mnf_code = 0; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2305 } |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2306 |
0 | 2307 /* Look for the model from the header */ |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2308 CHECK_FCT_DO( ret = fd_dict_search ( dict, DICT_COMMAND, |
0 | 2309 (msg->msg_public.msg_flags & CMD_FLAG_REQUEST) ? CMD_BY_CODE_R : CMD_BY_CODE_A, |
2310 &msg->msg_public.msg_code, | |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2311 &msg->msg_model, ENOTSUP), |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2312 { |
1092
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2313 if (ret == ENOTSUP) { |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2314 /* update the model not found info */ |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2315 msg->msg_model_not_found.mnf_code = msg->msg_public.msg_code; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2316 msg->msg_model_not_found.mnf_flags = msg->msg_public.msg_flags; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2317 goto no_model; |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2318 } |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2319 return ret; |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2320 } ); |
1092
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2321 chain: |
0 | 2322 if (!only_hdr) { |
2323 /* Then process the children */ | |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2324 ret = parsedict_do_chain(dict, &msg->msg_chain.children, 1, error_info); |
0 | 2325 |
2326 /* Free the raw buffer if any */ | |
2327 if ((ret == 0) && (msg->msg_rawbuffer != NULL)) { | |
2328 free(msg->msg_rawbuffer); | |
2329 msg->msg_rawbuffer=NULL; | |
2330 } | |
2331 } | |
2332 | |
2333 return ret; | |
1092
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2334 no_model: |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2335 if (error_info) { |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2336 error_info->pei_errcode = "DIAMETER_COMMAND_UNSUPPORTED"; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2337 error_info->pei_protoerr = 1; |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2338 } |
e40374ddfeef
Optimization: do not attempt resolving dictionary objects again when it already failed during message parsing
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1085
diff
changeset
|
2339 return ENOTSUP; |
0 | 2340 } |
2341 | |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2342 int fd_msg_parse_dict ( msg_or_avp * object, struct dictionary * dict, struct fd_pei *error_info ) |
0 | 2343 { |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2344 TRACE_ENTRY("%p %p %p", dict, object, error_info); |
0 | 2345 |
2346 CHECK_PARAMS( VALIDATE_OBJ(object) ); | |
2347 | |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2348 if (error_info) |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2349 memset(error_info, 0, sizeof(struct fd_pei)); |
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2350 |
0 | 2351 switch (_C(object)->type) { |
2352 case MSG_MSG: | |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2353 return parsedict_do_msg(dict, _M(object), 0, error_info); |
0 | 2354 |
2355 case MSG_AVP: | |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2356 return parsedict_do_avp(dict, _A(object), 0, error_info); |
0 | 2357 |
2358 default: | |
2359 ASSERT(0); | |
2360 } | |
2361 return EINVAL; | |
2362 } | |
2363 | |
2364 /***************************************************************************************************************/ | |
2365 /* Parsing messages and AVP for rules (ABNF) compliance */ | |
2366 | |
2367 /* This function is used to get stats (first occurence position, last occurence position, number of occurences) | |
2368 of AVP instances of a given model in a chain of AVP */ | |
2369 static void parserules_stat_avps( struct dict_object * model_avp, struct fd_list *list, int * count, int * firstpos, int * lastpos) | |
2370 { | |
2371 struct fd_list * li; | |
2372 int curpos = 0; /* The current position in the list */ | |
2373 | |
2374 TRACE_ENTRY("%p %p %p %p %p", model_avp, list, count, firstpos, lastpos); | |
2375 | |
2376 *count = 0; /* number of instances found */ | |
2377 *firstpos = 0; /* position of the first instance */ | |
2378 *lastpos = 0; /* position of the last instance, starting from the end */ | |
2379 | |
2380 for (li = list->next; li != list; li = li->next) { | |
2381 /* Increment the current position counter */ | |
2382 curpos++; | |
2383 | |
2384 /* If we previously saved a "lastpos" information, increment it */ | |
2385 if (*lastpos != 0) | |
2386 (*lastpos)++; | |
2387 | |
2388 /* Check the type of the next AVP. We can compare the references directly, it is safe. */ | |
2389 if (_A(li->o)->avp_model == model_avp) { | |
2390 | |
2391 /* This AVP is of the type we are searching */ | |
2392 (*count)++; | |
2393 | |
2394 /* If we don't have yet a "firstpos", save it */ | |
2395 if (*firstpos == 0) | |
2396 *firstpos = curpos; | |
2397 | |
2398 /* Reset the lastpos */ | |
2399 (*lastpos) = 1; | |
2400 } | |
2401 } | |
2402 } | |
2403 | |
2404 /* We use this structure as parameter for the next function */ | |
2405 struct parserules_data { | |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2406 struct fd_list * sentinel; /* Sentinel of the list of children AVP */ |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2407 struct fd_pei * pei; /* If the rule conflicts, save the error here */ |
0 | 2408 }; |
2409 | |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2410 /* Create an empty AVP of a given model (to use in Failed-AVP) */ |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2411 static struct avp * empty_avp(struct dict_object * model_avp) |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2412 { |
35
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2413 struct avp * avp = NULL; |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2414 struct dict_avp_data avp_info; |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2415 union avp_value val; |
400
bb8a4fa301b3
Fix compilation warning
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
387
diff
changeset
|
2416 unsigned char os[1] = { '\0' }; |
35
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2417 |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2418 /* Create an instance */ |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2419 CHECK_FCT_DO( fd_msg_avp_new(model_avp, 0, &avp ), return NULL ); |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2420 |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2421 /* Type of the AVP */ |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2422 CHECK_FCT_DO( fd_dict_getval(model_avp, &avp_info), return NULL ); |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2423 |
1230
e72c9dad62ac
Fix issue with generating Failed-AVP when the error is DIAMETER_MISSING_AVP. Also fix a memory leak in that case
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1229
diff
changeset
|
2424 /* Set an initial size */ |
e72c9dad62ac
Fix issue with generating Failed-AVP when the error is DIAMETER_MISSING_AVP. Also fix a memory leak in that case
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1229
diff
changeset
|
2425 avp->avp_public.avp_len = GETAVPHDRSZ( avp->avp_public.avp_flags ) + avp_value_sizes[avp_info.avp_basetype]; |
e72c9dad62ac
Fix issue with generating Failed-AVP when the error is DIAMETER_MISSING_AVP. Also fix a memory leak in that case
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1229
diff
changeset
|
2426 |
35
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2427 /* Prepare the empty value */ |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2428 memset(&val, 0, sizeof(val)); |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2429 switch (avp_info.avp_basetype) { |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2430 case AVP_TYPE_OCTETSTRING: |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2431 val.os.data = os; |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2432 val.os.len = sizeof(os); |
1230
e72c9dad62ac
Fix issue with generating Failed-AVP when the error is DIAMETER_MISSING_AVP. Also fix a memory leak in that case
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1229
diff
changeset
|
2433 avp->avp_public.avp_len += val.os.len; |
35
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2434 case AVP_TYPE_INTEGER32: |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2435 case AVP_TYPE_INTEGER64: |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2436 case AVP_TYPE_UNSIGNED32: |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2437 case AVP_TYPE_UNSIGNED64: |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2438 case AVP_TYPE_FLOAT32: |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2439 case AVP_TYPE_FLOAT64: |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2440 CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), return NULL ); |
400
bb8a4fa301b3
Fix compilation warning
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
387
diff
changeset
|
2441 case AVP_TYPE_GROUPED: |
bb8a4fa301b3
Fix compilation warning
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
387
diff
changeset
|
2442 /* For AVP_TYPE_GROUPED we don't do anything */ |
bb8a4fa301b3
Fix compilation warning
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
387
diff
changeset
|
2443 break; |
bb8a4fa301b3
Fix compilation warning
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
387
diff
changeset
|
2444 default: |
bb8a4fa301b3
Fix compilation warning
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
387
diff
changeset
|
2445 ASSERT(0); /* not handled */ |
35
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2446 } |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2447 |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2448 return avp; |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2449 } |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2450 |
0 | 2451 /* Check that a list of AVPs is compliant with a given rule -- will be iterated on the list of rules */ |
2452 static int parserules_check_one_rule(void * data, struct dict_rule_data *rule) | |
2453 { | |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2454 int count, first, last, min; |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2455 struct parserules_data * pr_data = data; |
280
3019f6220122
Provide more useful debug information for non-ABNF-compliant messages
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
258
diff
changeset
|
2456 char * avp_name = "<unresolved name>"; |
0 | 2457 |
2458 TRACE_ENTRY("%p %p", data, rule); | |
2459 | |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2460 /* Get statistics of the AVP concerned by this rule in the parent instance */ |
0 | 2461 parserules_stat_avps( rule->rule_avp, pr_data->sentinel, &count, &first, &last); |
2462 | |
280
3019f6220122
Provide more useful debug information for non-ABNF-compliant messages
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
258
diff
changeset
|
2463 if (TRACE_BOOL(INFO)) |
0 | 2464 { |
2465 struct dict_avp_data avpdata; | |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2466 int ret; |
0 | 2467 ret = fd_dict_getval(rule->rule_avp, &avpdata); |
280
3019f6220122
Provide more useful debug information for non-ABNF-compliant messages
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
258
diff
changeset
|
2468 if (ret == 0) |
3019f6220122
Provide more useful debug information for non-ABNF-compliant messages
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
258
diff
changeset
|
2469 avp_name = avpdata.avp_name; |
0 | 2470 |
2471 TRACE_DEBUG(ANNOYING, "Checking rule: p:%d(%d) m/M:%2d/%2d. Counted %d (first: %d, last:%d) of AVP '%s'", | |
2472 rule->rule_position, | |
2473 rule->rule_order, | |
2474 rule->rule_min, | |
2475 rule->rule_max, | |
2476 count, | |
2477 first, | |
2478 last, | |
280
3019f6220122
Provide more useful debug information for non-ABNF-compliant messages
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
258
diff
changeset
|
2479 avp_name |
0 | 2480 ); |
2481 } | |
2482 | |
2483 /* Now check the rule is not conflicting */ | |
2484 | |
2485 /* Check the "min" value */ | |
2486 if ((min = rule->rule_min) == -1) { | |
2487 if (rule->rule_position == RULE_OPTIONAL) | |
2488 min = 0; | |
2489 else | |
2490 min = 1; | |
2491 } | |
2492 if (count < min) { | |
1062
56bf0377e2ff
Raise "Conflicting rules" to error level since it causes validation
Thomas Klausner <tk@giga.or.at>
parents:
1036
diff
changeset
|
2493 fd_log_error("Conflicting rule: the number of occurences (%d) is < the rule min (%d) for '%s'.", count, min, avp_name); |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2494 if (pr_data->pei) { |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2495 pr_data->pei->pei_errcode = "DIAMETER_MISSING_AVP"; |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2496 pr_data->pei->pei_avp = empty_avp(rule->rule_avp); |
1230
e72c9dad62ac
Fix issue with generating Failed-AVP when the error is DIAMETER_MISSING_AVP. Also fix a memory leak in that case
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1229
diff
changeset
|
2497 pr_data->pei->pei_avp_free = 1; |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2498 } |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2499 return EBADMSG; |
0 | 2500 } |
2501 | |
2502 /* Check the "max" value */ | |
2503 if ((rule->rule_max != -1) && (count > rule->rule_max)) { | |
1062
56bf0377e2ff
Raise "Conflicting rules" to error level since it causes validation
Thomas Klausner <tk@giga.or.at>
parents:
1036
diff
changeset
|
2504 fd_log_error("Conflicting rule: the number of occurences (%d) is > the rule max (%d) for '%s'.", count, rule->rule_max, avp_name); |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2505 if (pr_data->pei) { |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2506 if (rule->rule_max == 0) |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2507 pr_data->pei->pei_errcode = "DIAMETER_AVP_NOT_ALLOWED"; |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2508 else |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2509 pr_data->pei->pei_errcode = "DIAMETER_AVP_OCCURS_TOO_MANY_TIMES"; |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2510 pr_data->pei->pei_avp = empty_avp(rule->rule_avp); /* Well we are supposed to return the (max + 1)th instance of the AVP instead... Pfff... */ TODO("Improve..."); |
1230
e72c9dad62ac
Fix issue with generating Failed-AVP when the error is DIAMETER_MISSING_AVP. Also fix a memory leak in that case
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1229
diff
changeset
|
2511 pr_data->pei->pei_avp_free = 1; |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2512 } |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2513 return EBADMSG; |
0 | 2514 } |
2515 | |
2516 /* Check the position and order (if relevant) */ | |
2517 switch (rule->rule_position) { | |
2518 case RULE_OPTIONAL: | |
2519 case RULE_REQUIRED: | |
2520 /* No special position constraints */ | |
2521 break; | |
2522 | |
2523 case RULE_FIXED_HEAD: | |
2524 /* Since "0*1<fixed>" is a valid rule specifier, we only reject cases where the AVP appears *after* its fixed position */ | |
2525 if (first > rule->rule_order) { | |
1062
56bf0377e2ff
Raise "Conflicting rules" to error level since it causes validation
Thomas Klausner <tk@giga.or.at>
parents:
1036
diff
changeset
|
2526 fd_log_error("Conflicting rule: the FIXED_HEAD AVP appears first in (%d) position, the rule requires (%d) for '%s'.", first, rule->rule_order, avp_name); |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2527 if (pr_data->pei) { |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2528 pr_data->pei->pei_errcode = "DIAMETER_MISSING_AVP"; |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2529 pr_data->pei->pei_message = "AVP was not in its fixed position"; |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2530 pr_data->pei->pei_avp = empty_avp(rule->rule_avp); |
1230
e72c9dad62ac
Fix issue with generating Failed-AVP when the error is DIAMETER_MISSING_AVP. Also fix a memory leak in that case
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1229
diff
changeset
|
2531 pr_data->pei->pei_avp_free = 1; |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2532 } |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2533 return EBADMSG; |
0 | 2534 } |
2535 break; | |
2536 | |
2537 case RULE_FIXED_TAIL: | |
2538 /* Since "0*1<fixed>" is a valid rule specifier, we only reject cases where the AVP appears *before* its fixed position */ | |
2539 if (last > rule->rule_order) { /* We have a ">" here because we count in reverse order (i.e. from the end) */ | |
1062
56bf0377e2ff
Raise "Conflicting rules" to error level since it causes validation
Thomas Klausner <tk@giga.or.at>
parents:
1036
diff
changeset
|
2540 fd_log_error("Conflicting rule: the FIXED_TAIL AVP appears last in (%d) position, the rule requires (%d) for '%s'.", last, rule->rule_order, avp_name); |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2541 if (pr_data->pei) { |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2542 pr_data->pei->pei_errcode = "DIAMETER_MISSING_AVP"; |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2543 pr_data->pei->pei_message = "AVP was not in its fixed position"; |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2544 pr_data->pei->pei_avp = empty_avp(rule->rule_avp); |
1230
e72c9dad62ac
Fix issue with generating Failed-AVP when the error is DIAMETER_MISSING_AVP. Also fix a memory leak in that case
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1229
diff
changeset
|
2545 pr_data->pei->pei_avp_free = 1; |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2546 } |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2547 return EBADMSG; |
0 | 2548 } |
2549 break; | |
2550 | |
2551 default: | |
2552 /* What is this position ??? */ | |
2553 ASSERT(0); | |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2554 return ENOTSUP; |
0 | 2555 } |
2556 | |
2557 /* We've checked all the parameters */ | |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2558 return 0; |
0 | 2559 } |
2560 | |
2561 /* Check the rules recursively */ | |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2562 static int parserules_do ( struct dictionary * dict, msg_or_avp * object, struct fd_pei *error_info, int mandatory) |
0 | 2563 { |
2564 struct parserules_data data; | |
2565 struct dict_object * model = NULL; | |
2566 | |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2567 TRACE_ENTRY("%p %p %p %d", dict, object, error_info, mandatory); |
0 | 2568 |
2569 /* object has already been checked and dict-parsed when we are called. */ | |
2570 | |
2571 /* First, handle the cases where there is no model */ | |
2572 { | |
2573 if (CHECK_MSG(object)) { | |
2574 if ( _M(object)->msg_public.msg_flags & CMD_FLAG_ERROR ) { | |
2575 /* The case of error messages: the ABNF is different */ | |
2576 CHECK_FCT( fd_dict_get_error_cmd(dict, &model) ); | |
2577 } else { | |
2578 model = _M(object)->msg_model; | |
2579 } | |
2580 /* Commands MUST be supported in the dictionary */ | |
2581 if (model == NULL) { | |
2582 TRACE_DEBUG(INFO, "Message with no dictionary model. EBADMSG"); | |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2583 if (error_info) { |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2584 error_info->pei_errcode = "DIAMETER_COMMAND_UNSUPPORTED"; |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2585 error_info->pei_protoerr = 1; |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2586 } |
0 | 2587 return EBADMSG; |
2588 } | |
2589 } | |
2590 | |
2591 /* AVP with the 'M' flag must also be recognized in the dictionary -- except inside an optional grouped AVP */ | |
2592 if (CHECK_AVP(object) && ((model = _A(object)->avp_model) == NULL)) { | |
2593 if ( mandatory && (_A(object)->avp_public.avp_flags & AVP_FLAG_MANDATORY)) { | |
2594 /* Return an error in this case */ | |
2595 TRACE_DEBUG(INFO, "Mandatory AVP with no dictionary model. EBADMSG"); | |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2596 if (error_info) { |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2597 error_info->pei_errcode = "DIAMETER_AVP_UNSUPPORTED"; |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2598 error_info->pei_avp = object; |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2599 } |
0 | 2600 return EBADMSG; |
2601 } else { | |
2602 /* We don't know any rule for this object, so assume OK */ | |
2603 TRACE_DEBUG(FULL, "Unknown informational AVP, ignoring..."); | |
2604 return 0; | |
2605 } | |
2606 } | |
2607 } | |
2608 | |
2609 /* At this point we know "model" is set and points to the object's model */ | |
2610 | |
2611 /* If we are an AVP with no children, just return OK */ | |
2612 if (CHECK_AVP(object)) { | |
2613 struct dict_avp_data dictdata; | |
2614 CHECK_FCT( fd_dict_getval(model, &dictdata) ); | |
2615 if (dictdata.avp_basetype != AVP_TYPE_GROUPED) { | |
2616 /* This object has no children and no rules */ | |
2617 return 0; | |
2618 } | |
2619 } | |
2620 | |
2621 /* If this object has children, first check the rules for all its children */ | |
2622 { | |
2623 int is_child_mand = 0; | |
2624 struct fd_list * ch = NULL; | |
2625 if ( CHECK_MSG(object) | |
2626 || (mandatory && (_A(object)->avp_public.avp_flags & AVP_FLAG_MANDATORY)) ) | |
2627 is_child_mand = 1; | |
2628 for (ch = _C(object)->children.next; ch != &_C(object)->children; ch = ch->next) { | |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2629 CHECK_FCT( parserules_do ( dict, _C(ch->o), error_info, is_child_mand ) ); |
0 | 2630 } |
2631 } | |
2632 | |
2633 /* Now check all rules of this object */ | |
2634 data.sentinel = &_C(object)->children; | |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2635 data.pei = error_info; |
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2636 CHECK_FCT( fd_dict_iterate_rules ( model, &data, parserules_check_one_rule ) ); |
0 | 2637 |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2638 return 0; |
0 | 2639 } |
2640 | |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2641 int fd_msg_parse_rules ( msg_or_avp * object, struct dictionary * dict, struct fd_pei *error_info) |
0 | 2642 { |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2643 TRACE_ENTRY("%p %p %p", object, dict, error_info); |
0 | 2644 |
35
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2645 if (error_info) |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2646 memset(error_info, 0, sizeof(struct fd_pei)); |
6486e97f56ae
Added test for modified message parsing
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
34
diff
changeset
|
2647 |
0 | 2648 /* Resolve the dictionary objects when missing. This also validates the object. */ |
114
5b3868944e2b
Reporting errors in parse_dict function
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
112
diff
changeset
|
2649 CHECK_FCT( fd_msg_parse_dict ( object, dict, error_info ) ); |
0 | 2650 |
2651 /* Call the recursive function */ | |
34
0e2b57789361
Backup for the WE, some warnings remaining
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
7
diff
changeset
|
2652 return parserules_do ( dict, object, error_info, 1 ) ; |
0 | 2653 } |
2654 | |
2655 /***************************************************************************************************************/ | |
2656 | |
2657 /* Compute the lengh of an object and its subtree. */ | |
2658 int fd_msg_update_length ( msg_or_avp * object ) | |
2659 { | |
2660 size_t sz = 0; | |
2661 struct dict_object * model; | |
2662 union { | |
2663 struct dict_cmd_data cmddata; | |
2664 struct dict_avp_data avpdata; | |
2665 } dictdata; | |
2666 | |
2667 TRACE_ENTRY("%p", object); | |
2668 | |
2669 /* Get the model of the object. This also validates the object */ | |
2670 CHECK_FCT( fd_msg_model ( object, &model ) ); | |
2671 | |
2672 /* Get the information of the model */ | |
2673 if (model) { | |
2674 CHECK_FCT( fd_dict_getval(model, &dictdata) ); | |
2675 } else { | |
2676 /* For unknown AVP, just don't change the size */ | |
2677 if (_C(object)->type == MSG_AVP) | |
2678 return 0; | |
2679 } | |
2680 | |
2681 /* Deal with easy cases: AVPs without children */ | |
2682 if ((_C(object)->type == MSG_AVP) && (dictdata.avpdata.avp_basetype != AVP_TYPE_GROUPED)) { | |
2683 /* Sanity check */ | |
2684 ASSERT(FD_IS_LIST_EMPTY(&_A(object)->avp_chain.children)); | |
2685 | |
2686 /* Now check that the data is set in the AVP */ | |
2687 CHECK_PARAMS( _A(object)->avp_public.avp_value ); | |
2688 | |
2689 sz = GETAVPHDRSZ( _A(object)->avp_public.avp_flags ); | |
2690 | |
2691 switch (dictdata.avpdata.avp_basetype) { | |
2692 case AVP_TYPE_OCTETSTRING: | |
2693 sz += _A(object)->avp_public.avp_value->os.len; | |
2694 break; | |
2695 | |
2696 case AVP_TYPE_INTEGER32: | |
2697 case AVP_TYPE_INTEGER64: | |
2698 case AVP_TYPE_UNSIGNED32: | |
2699 case AVP_TYPE_UNSIGNED64: | |
2700 case AVP_TYPE_FLOAT32: | |
2701 case AVP_TYPE_FLOAT64: | |
2702 sz += avp_value_sizes[dictdata.avpdata.avp_basetype]; | |
2703 break; | |
2704 | |
2705 default: | |
2706 /* Something went wrong... */ | |
2707 ASSERT(0); | |
2708 } | |
2709 } | |
2710 else /* message or grouped AVP */ | |
2711 { | |
2712 struct fd_list * ch = NULL; | |
2713 | |
2714 /* First, compute the header size */ | |
2715 if (_C(object)->type == MSG_AVP) { | |
2716 sz = GETAVPHDRSZ( _A(object)->avp_public.avp_flags ); | |
2717 } else { | |
2718 sz = GETMSGHDRSZ( ); | |
2719 } | |
2720 | |
2721 /* Recurse in all children and update the sz information */ | |
2722 for (ch = _C(object)->children.next; ch != &_C(object)->children; ch = ch->next) { | |
2723 CHECK_FCT( fd_msg_update_length ( ch->o ) ); | |
2724 | |
2725 /* Add the padded size to the parent */ | |
2726 sz += PAD4( _A(ch->o)->avp_public.avp_len ); | |
2727 } | |
2728 } | |
2729 | |
2730 /* When we arrive here, the "sz" variable contains the size to write in the object */ | |
2731 if (_C(object)->type == MSG_AVP) | |
2732 _A(object)->avp_public.avp_len = sz; | |
2733 else | |
2734 _M(object)->msg_public.msg_length = sz; | |
2735 | |
2736 return 0; | |
2737 } | |
2738 | |
2739 /***************************************************************************************************************/ | |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2740 /* Macro to check if further callbacks must be called */ |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2741 #define TEST_ACTION_STOP() \ |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2742 if ((*msg == NULL) || (*action != DISP_ACT_CONT)) \ |
690
a29e4201d511
It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
689
diff
changeset
|
2743 goto out; |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2744 |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2745 /* Call all dispatch callbacks for a given message */ |
1113
eb4ce68b6e5c
Added calls to remaining hooks
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1103
diff
changeset
|
2746 int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_action *action, char ** error_code, char ** drop_reason, struct msg ** drop_msg) |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2747 { |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2748 struct dictionary * dict; |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2749 struct dict_object * app; |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2750 struct dict_object * cmd; |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2751 struct avp * avp; |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2752 struct fd_list * cb_list; |
690
a29e4201d511
It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
689
diff
changeset
|
2753 int ret = 0, r2; |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2754 |
90
2c9444152e4b
Added the dispatch thread code
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
85
diff
changeset
|
2755 TRACE_ENTRY("%p %p %p %p", msg, session, action, error_code); |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2756 CHECK_PARAMS( msg && CHECK_MSG(*msg) && action); |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2757 |
90
2c9444152e4b
Added the dispatch thread code
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
85
diff
changeset
|
2758 if (error_code) |
2c9444152e4b
Added the dispatch thread code
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
85
diff
changeset
|
2759 *error_code = NULL; |
1113
eb4ce68b6e5c
Added calls to remaining hooks
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1103
diff
changeset
|
2760 if (drop_reason) |
eb4ce68b6e5c
Added calls to remaining hooks
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1103
diff
changeset
|
2761 *drop_reason = NULL; |
132 | 2762 *action = DISP_ACT_CONT; |
90
2c9444152e4b
Added the dispatch thread code
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
85
diff
changeset
|
2763 |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2764 /* Take the dispatch lock */ |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2765 CHECK_FCT( pthread_rwlock_rdlock(&fd_disp_lock) ); |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2766 pthread_cleanup_push( fd_cleanup_rwlock, &fd_disp_lock ); |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2767 |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2768 /* First, call the DISP_HOW_ANY callbacks */ |
1113
eb4ce68b6e5c
Added calls to remaining hooks
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1103
diff
changeset
|
2769 CHECK_FCT_DO( ret = fd_disp_call_cb_int( NULL, msg, NULL, session, action, NULL, NULL, NULL, NULL, drop_reason, drop_msg ), goto out ); |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2770 |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2771 TEST_ACTION_STOP(); |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2772 |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2773 /* If we don't know the model at this point, we stop cause we cannot get the dictionary. It's invalid: an error should already have been trigged by ANY callbacks */ |
690
a29e4201d511
It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
689
diff
changeset
|
2774 CHECK_PARAMS_DO(cmd = (*msg)->msg_model, { ret = EINVAL; goto out; } ); |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2775 |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2776 /* Now resolve message application */ |
690
a29e4201d511
It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
689
diff
changeset
|
2777 CHECK_FCT_DO( ret = fd_dict_getdict( cmd, &dict ), goto out ); |
a29e4201d511
It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
689
diff
changeset
|
2778 CHECK_FCT_DO( ret = fd_dict_search( dict, DICT_APPLICATION, APPLICATION_BY_ID, &(*msg)->msg_public.msg_appl, &app, 0 ), goto out ); |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2779 |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2780 if (app == NULL) { |
90
2c9444152e4b
Added the dispatch thread code
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
85
diff
changeset
|
2781 if ((*msg)->msg_public.msg_flags & CMD_FLAG_REQUEST) { |
2c9444152e4b
Added the dispatch thread code
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
85
diff
changeset
|
2782 if (error_code) |
2c9444152e4b
Added the dispatch thread code
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
85
diff
changeset
|
2783 *error_code = "DIAMETER_APPLICATION_UNSUPPORTED"; |
2c9444152e4b
Added the dispatch thread code
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
85
diff
changeset
|
2784 *action = DISP_ACT_ERROR; |
2c9444152e4b
Added the dispatch thread code
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
85
diff
changeset
|
2785 } else { |
1113
eb4ce68b6e5c
Added calls to remaining hooks
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1103
diff
changeset
|
2786 *drop_reason = "Internal error: Received this answer to a local query with an unsupported application"; |
eb4ce68b6e5c
Added calls to remaining hooks
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1103
diff
changeset
|
2787 *drop_msg = *msg; |
90
2c9444152e4b
Added the dispatch thread code
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
85
diff
changeset
|
2788 *msg = NULL; |
2c9444152e4b
Added the dispatch thread code
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
85
diff
changeset
|
2789 } |
690
a29e4201d511
It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
689
diff
changeset
|
2790 goto out; |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2791 } |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2792 |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2793 /* So start browsing the message */ |
690
a29e4201d511
It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
689
diff
changeset
|
2794 CHECK_FCT_DO( ret = fd_msg_browse( *msg, MSG_BRW_FIRST_CHILD, &avp, NULL ), goto out ); |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2795 while (avp != NULL) { |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2796 /* For unknown AVP, we don't have a callback registered, so just skip */ |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2797 if (avp->avp_model) { |
330
e283e18b2673
Removed incorrect ASSERT -- thanks to Alexandre for the bug finding.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
291
diff
changeset
|
2798 struct dict_object * enumval = NULL; |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2799 |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2800 /* Get the list of callback for this AVP */ |
690
a29e4201d511
It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
689
diff
changeset
|
2801 CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_AVP, avp->avp_model, &cb_list), goto out ); |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2802 |
330
e283e18b2673
Removed incorrect ASSERT -- thanks to Alexandre for the bug finding.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
291
diff
changeset
|
2803 /* We search enumerated values only in case of non-grouped AVP */ |
e283e18b2673
Removed incorrect ASSERT -- thanks to Alexandre for the bug finding.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
291
diff
changeset
|
2804 if ( avp->avp_public.avp_value ) { |
e283e18b2673
Removed incorrect ASSERT -- thanks to Alexandre for the bug finding.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
291
diff
changeset
|
2805 struct dict_object * type; |
e283e18b2673
Removed incorrect ASSERT -- thanks to Alexandre for the bug finding.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
291
diff
changeset
|
2806 /* Check if the AVP has a constant value */ |
690
a29e4201d511
It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
689
diff
changeset
|
2807 CHECK_FCT_DO( ret = fd_dict_search(dict, DICT_TYPE, TYPE_OF_AVP, avp->avp_model, &type, 0), goto out ); |
330
e283e18b2673
Removed incorrect ASSERT -- thanks to Alexandre for the bug finding.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
291
diff
changeset
|
2808 if (type) { |
e283e18b2673
Removed incorrect ASSERT -- thanks to Alexandre for the bug finding.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
291
diff
changeset
|
2809 struct dict_enumval_request req; |
e283e18b2673
Removed incorrect ASSERT -- thanks to Alexandre for the bug finding.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
291
diff
changeset
|
2810 memset(&req, 0, sizeof(struct dict_enumval_request)); |
e283e18b2673
Removed incorrect ASSERT -- thanks to Alexandre for the bug finding.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
291
diff
changeset
|
2811 req.type_obj = type; |
e283e18b2673
Removed incorrect ASSERT -- thanks to Alexandre for the bug finding.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
291
diff
changeset
|
2812 memcpy( &req.search.enum_value, avp->avp_public.avp_value, sizeof(union avp_value) ); |
690
a29e4201d511
It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
689
diff
changeset
|
2813 CHECK_FCT_DO( ret = fd_dict_search(dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &req, &enumval, 0), goto out ); |
330
e283e18b2673
Removed incorrect ASSERT -- thanks to Alexandre for the bug finding.
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
291
diff
changeset
|
2814 } |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2815 } |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2816 |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2817 /* Call the callbacks */ |
1113
eb4ce68b6e5c
Added calls to remaining hooks
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1103
diff
changeset
|
2818 CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, avp, session, action, app, cmd, avp->avp_model, enumval, drop_reason, drop_msg ), goto out ); |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2819 TEST_ACTION_STOP(); |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2820 } |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2821 /* Go to next AVP */ |
690
a29e4201d511
It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
689
diff
changeset
|
2822 CHECK_FCT_DO( ret = fd_msg_browse( avp, MSG_BRW_WALK, &avp, NULL ), goto out ); |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2823 } |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2824 |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2825 /* Now call command and application callbacks */ |
690
a29e4201d511
It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
689
diff
changeset
|
2826 CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_COMMAND, cmd, &cb_list), goto out ); |
1113
eb4ce68b6e5c
Added calls to remaining hooks
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1103
diff
changeset
|
2827 CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, NULL, session, action, app, cmd, NULL, NULL, drop_reason, drop_msg ), goto out ); |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2828 TEST_ACTION_STOP(); |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2829 |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2830 if (app) { |
690
a29e4201d511
It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
689
diff
changeset
|
2831 CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_APPLICATION, app, &cb_list), goto out ); |
1113
eb4ce68b6e5c
Added calls to remaining hooks
Sebastien Decugis <sdecugis@freediameter.net>
parents:
1103
diff
changeset
|
2832 CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, NULL, session, action, app, cmd, NULL, NULL, drop_reason, drop_msg ), goto out ); |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2833 TEST_ACTION_STOP(); |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2834 } |
690
a29e4201d511
It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
689
diff
changeset
|
2835 out: |
a29e4201d511
It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
689
diff
changeset
|
2836 ; /* some systems would complain without this */ |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2837 pthread_cleanup_pop(0); |
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2838 |
690
a29e4201d511
It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
689
diff
changeset
|
2839 CHECK_POSIX_DO(r2 = pthread_rwlock_unlock(&fd_disp_lock), /* ignore */ ); |
a29e4201d511
It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
689
diff
changeset
|
2840 return ret ?: r2; |
7
e5af94b04946
Added dispatch module and tests
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
4
diff
changeset
|
2841 } |
687
026802543f57
Prepare for new message log facility
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
686
diff
changeset
|
2842 |
026802543f57
Prepare for new message log facility
Sebastien Decugis <sdecugis@nict.go.jp>
parents:
686
diff
changeset
|
2843 |