Mercurial > hg > freeDiameter
comparison include/freeDiameter/libfdproto.h @ 1085:7d7266115a34
Cleaning of the traces in progress
author | Sebastien Decugis <sdecugis@freediameter.net> |
---|---|
date | Fri, 03 May 2013 19:20:56 +0800 |
parents | b380c9f3be1e |
children | 1c5d410788cc |
comparison
equal
deleted
inserted
replaced
1084:6b7966ea27fb | 1085:7d7266115a34 |
---|---|
130 /*============================================================*/ | 130 /*============================================================*/ |
131 | 131 |
132 | 132 |
133 /* | 133 /* |
134 * FUNCTION: fd_log | 134 * FUNCTION: fd_log |
135 * MACRO: fd_log_debug | 135 * |
136 * MACRO: fd_log_notice | 136 * PARAMETERS: |
137 * MACRO: fd_log_error | 137 * loglevel : Integer, how important the message is. Valid values are macros FD_LOG_* |
138 * | |
139 * PARAMETERS: | |
140 * loglevel : Integer, how important the message is | |
141 * format : Same format string as in the printf function | 138 * format : Same format string as in the printf function |
142 * ... : Same list as printf | 139 * ... : Same list as printf |
143 * | 140 * |
144 * DESCRIPTION: | 141 * DESCRIPTION: |
145 * Write information to log. | 142 * Write information to log. |
148 * | 145 * |
149 * RETURN VALUE: | 146 * RETURN VALUE: |
150 * None. | 147 * None. |
151 */ | 148 */ |
152 void fd_log ( int, const char *, ... ) _ATTRIBUTE_PRINTFLIKE_(2,3); | 149 void fd_log ( int, const char *, ... ) _ATTRIBUTE_PRINTFLIKE_(2,3); |
153 #define fd_log_debug(format,args...) fd_log(FD_LOG_DEBUG, format, ## args) | 150 void fd_log_va( int, const char *, va_list args ); |
154 #define fd_log_notice(format,args...) fd_log(FD_LOG_NOTICE, format, ## args) | |
155 #define fd_log_error(format,args...) fd_log(FD_LOG_ERROR, format, ## args) | |
156 | |
157 void fd_log_debug_fstr( FILE *, const char *, ... ); | |
158 | 151 |
159 /* these are internal objects of the debug facility, | 152 /* these are internal objects of the debug facility, |
160 might be useful to control the behavior from outside */ | 153 might be useful to control the behavior from outside */ |
161 extern pthread_mutex_t fd_log_lock; | 154 extern pthread_mutex_t fd_log_lock; |
162 extern char * fd_debug_one_function; | 155 extern char * fd_debug_one_function; |
226 * int : Success or failure | 219 * int : Success or failure |
227 */ | 220 */ |
228 int fd_log_handler_unregister ( void ); | 221 int fd_log_handler_unregister ( void ); |
229 | 222 |
230 | 223 |
224 /* Helper function for the *dump functions that add into a buffer */ | |
225 char * fd_dump_extend(char ** buf, size_t *len, size_t *offset, const char * format, ... ) _ATTRIBUTE_PRINTFLIKE_(4,5); | |
226 | |
227 /* All dump functions follow the same prototype: | |
228 * PARAMETERS: | |
229 * buf : *buf can be NULL on entry, it will be malloc'd. Otherwise it can be realloc'd if needed. | |
230 * len : the current size of the buffer (in/out) | |
231 * offset: (optional) if provided, starts writing dump at offset in the buffer, and updated upon exit. if NULL, starts at offset O. | |
232 * | |
233 * RETURN VALUE: | |
234 * *buf upon success, NULL upon failure. | |
235 * After the buffer has been used, it should be freed. | |
236 */ | |
237 #define DECLARE_FD_DUMP_PROTOTYPE( function_name, args... ) \ | |
238 char * function_name(char ** buf, size_t *len, size_t *offset, ##args) | |
239 | |
240 #define FD_DUMP_STD_PARAMS buf, len, offset | |
241 | |
242 | |
231 /*============================================================*/ | 243 /*============================================================*/ |
232 /* DEBUG MACROS */ | 244 /* DEBUG MACROS */ |
233 /*============================================================*/ | 245 /*============================================================*/ |
234 | 246 |
235 #ifndef ASSERT | 247 #ifndef ASSERT |
236 #define ASSERT(x) assert(x) | 248 #define ASSERT(x) assert(x) |
237 #endif /* ASSERT */ | 249 #endif /* ASSERT */ |
238 | 250 |
239 /* log levels definitions */ | 251 /* log levels definitions, that are passed to the logger */ |
240 #define FD_LOG_DEBUG 0 /* Verbose information for developers use */ | 252 #define FD_LOG_ANNOYING 0 /* very verbose loops and such "overkill" traces. Only active when the framework is compiled in DEBUG mode. */ |
241 #define FD_LOG_NOTICE 3 /* Normal execution states worth noting */ | 253 #define FD_LOG_DEBUG 1 /* Get a detailed sense of what is going on in the framework. Use this level for normal debug */ |
242 #define FD_LOG_ERROR 5 /* Error conditions, both recoverable or not */ | 254 #define FD_LOG_NOTICE 3 /* Normal execution states worth noting */ |
243 | 255 #define FD_LOG_ERROR 5 /* Recoverable or expected error conditions */ |
244 /* print level definitions */ | 256 #define FD_LOG_FATAL 6 /* Unrecoverable error, e.g. malloc fail, etc. that requires the framework to shutdown */ |
245 #define NONE 0 /* Display no debug message */ | 257 |
246 #define INFO 1 /* Display errors only */ | 258 /* The level used by the default logger, can be changed by command-line arguments. Ignored for other loggers. */ |
247 #define FULL 2 /* Display additional information to follow code execution */ | |
248 #define ANNOYING 4 /* Very verbose, for example in loops */ | |
249 #define FCTS 6 /* Display entry parameters of most functions */ | |
250 #define CALL 9 /* Display calls to most functions (with CHECK macros) */ | |
251 | |
252 /* A global level, changed by configuration or cmd line for example. Default is INFO (in libfdproto/log.c). */ | |
253 extern int fd_g_debug_lvl; | 259 extern int fd_g_debug_lvl; |
254 | 260 |
255 /* Some portability code to get nice function name in __PRETTY_FUNCTION__ */ | 261 /* Some portability code to get nice function name in __PRETTY_FUNCTION__ */ |
256 #if (!defined( __func__)) && (__STDC_VERSION__ < 199901L) | 262 #if (!defined( __func__)) && (__STDC_VERSION__ < 199901L) |
257 # if __GNUC__ >= 2 | 263 # if __GNUC__ >= 2 |
262 #endif /*(!defined( __func__)) && (__STDC_VERSION__ < 199901L) */ | 268 #endif /*(!defined( __func__)) && (__STDC_VERSION__ < 199901L) */ |
263 #ifndef __PRETTY_FUNCTION__ | 269 #ifndef __PRETTY_FUNCTION__ |
264 #define __PRETTY_FUNCTION__ __func__ | 270 #define __PRETTY_FUNCTION__ __func__ |
265 #endif /* __PRETTY_FUNCTION__ */ | 271 #endif /* __PRETTY_FUNCTION__ */ |
266 | 272 |
267 #ifdef DEBUG | |
268 /* A version of __FILE__ without the full path */ | 273 /* A version of __FILE__ without the full path */ |
269 static char * file_bname = NULL; | 274 static char * file_bname = NULL; |
270 static char * file_bname_init(char * full) { file_bname = basename(full); return file_bname; } | 275 static char * file_bname_init(char * full) { file_bname = basename(full); return file_bname; } |
271 #define __STRIPPED_FILE__ (file_bname ?: file_bname_init((char *)__FILE__)) | 276 #define __STRIPPED_FILE__ (file_bname ?: file_bname_init((char *)__FILE__)) |
272 | 277 |
273 /* Boolean for tracing at a certain level */ | 278 |
274 #define TRACE_BOOL(_level_) ( ((_level_) <= fd_g_debug_lvl) \ | 279 |
275 || (fd_debug_one_function && !strcmp(fd_debug_one_function, __PRETTY_FUNCTION__)) \ | 280 /* In DEBUG mode, we add meta-information along each trace. This makes multi-threading problems easier to debug. */ |
276 || (fd_debug_one_file && !strcmp(fd_debug_one_file, __STRIPPED_FILE__) ) ) | 281 #ifdef DEBUG |
282 # define STD_TRACE_FMT_STRING "pid:%s in %s@%s:%d: " | |
283 # define STD_TRACE_FMT_ARGS , ((char *)pthread_getspecific(fd_log_thname) ?: "unnamed"), __PRETTY_FUNCTION__, __STRIPPED_FILE__, __LINE__ | |
277 #else /* DEBUG */ | 284 #else /* DEBUG */ |
278 #define TRACE_BOOL(_level_) ((_level_) <= fd_g_debug_lvl) | 285 # define STD_TRACE_FMT_STRING "" |
279 #define __STRIPPED_FILE__ __FILE__ | 286 # define STD_TRACE_FMT_ARGS |
280 #endif /* DEBUG */ | 287 #endif /* DEBUG */ |
281 | 288 |
282 | 289 /************************* |
283 #define STD_TRACE_FMT_STRING "pid:%s in %s@%s:%d: " | 290 The general debug macro |
291 *************************/ | |
292 #define LOG(printlevel,format,args... ) \ | |
293 fd_log((printlevel), STD_TRACE_FMT_STRING format STD_TRACE_FMT_ARGS, ## args) | |
294 | |
295 /* | |
296 * Use the following macros in the code to get traces with location & pid in debug mode: | |
297 */ | |
298 #ifdef DEBUG | |
299 # define LOG_A(format,args... ) \ | |
300 LOG(FD_LOG_ANNOYING,format,##args) | |
301 #else /* DEBUG */ | |
302 # define LOG_A(format,args... ) /* not defined in release */ | |
303 #endif /* DEBUG */ | |
304 | |
305 /* Debug information useful to follow in detail what is going on */ | |
306 #define LOG_D(format,args... ) \ | |
307 LOG(FD_LOG_DEBUG, format, ##args) | |
308 | |
309 /* Report a normal message that is useful for normal admin monitoring */ | |
310 #define LOG_N(format,args... ) \ | |
311 LOG(FD_LOG_NOTICE, format,##args) | |
312 | |
313 /* Report an error */ | |
314 #define LOG_E(format,args... ) \ | |
315 LOG(FD_LOG_ERROR, format, ##args) | |
316 | |
317 /* Report a fatal error */ | |
318 #define LOG_F(format,args... ) \ | |
319 LOG(FD_LOG_FATAL, format, ##args) | |
320 | |
321 | |
284 /************* | 322 /************* |
285 The general debug macro, each call results in two lines of debug messages (change the macro for more compact output) | 323 Derivatives |
286 *************/ | 324 ************/ |
287 #ifdef DEBUG | 325 /* Trace a binary buffer content */ |
288 /* In DEBUG mode, we add (a lot of) meta-information along each trace. This makes multi-threading problems easier to debug. */ | 326 #define LOG_BUFFER(printlevel, prefix, buf, bufsz, suffix ) { \ |
289 #define TRACE(printlevel,level,format,args... ) { \ | 327 int __i; \ |
290 if ( TRACE_BOOL(level) ) { \ | 328 size_t __sz = (size_t)(bufsz); \ |
291 const char * __thn = ((char *)pthread_getspecific(fd_log_thname) ?: "unnamed"); \ | 329 uint8_t * __buf = (uint8_t *)(buf); \ |
292 fd_log((printlevel), STD_TRACE_FMT_STRING format, \ | 330 char __strbuf[1024+1]; \ |
293 __thn, __PRETTY_FUNCTION__, __STRIPPED_FILE__, __LINE__, ## args); \ | 331 for (__i = 0; (__i < __sz) && (__i<(sizeof(__strbuf)/2)); __i++) { \ |
294 } \ | 332 sprintf(__strbuf + (2 * __i), "%02hhx", __buf[__i]); \ |
333 } \ | |
334 fd_log(printlevel, STD_TRACE_FMT_STRING "%s%s%s" STD_TRACE_FMT_ARGS, \ | |
335 (prefix), __strbuf, (suffix)); \ | |
295 } | 336 } |
296 #else /* DEBUG */ | 337 |
297 /* Do not print thread, function, ... only the message itself in this case */ | |
298 #define TRACE(printlevel,level,format,args... ) { \ | |
299 if ( TRACE_BOOL(level) ) { \ | |
300 fd_log((printlevel), format, ## args); \ | |
301 } \ | |
302 } | |
303 #endif /* DEBUG */ | |
304 | |
305 /* Report debug information */ | |
306 #define TRACE_DEBUG(level,format,args... ) \ | |
307 TRACE(FD_LOG_DEBUG,(level),format,##args) | |
308 | |
309 /* Report a normal message that is useful for normal admin monitoring */ | |
310 #define TRACE_NOTICE(format,args... ) \ | |
311 TRACE(FD_LOG_NOTICE,INFO,format,##args) | |
312 | |
313 /* Report an error */ | |
314 #define TRACE_ERROR(format,args... ) \ | |
315 TRACE(FD_LOG_ERROR, NONE, format, ##args) | |
316 | |
317 /* | |
318 TRACE_NOTICE(...) and fd_log_notice(...) are equivalent when the code is not compiled in DEBUG mode, | |
319 but there is more contextual information when compiled in DEBUG with the TRACE_NOTICE macro, | |
320 hence it is recommended to use this one except for formatted output (e.g. fd_*_dump function) | |
321 | |
322 resp. TRACE_DEBUG and TRACE_ERROR. | |
323 */ | |
324 | |
325 /************* | |
326 Derivatives for debug | |
327 ************/ | |
328 /* Helper for function entry -- for very detailed trace of the execution */ | 338 /* Helper for function entry -- for very detailed trace of the execution */ |
329 #define TRACE_ENTRY(_format,_args... ) \ | 339 #define TRACE_ENTRY(_format,_args... ) \ |
330 TRACE_DEBUG(FCTS, "[enter] %s(" _format ") {" #_args "}", __PRETTY_FUNCTION__, ##_args ); | 340 LOG_A(FCTS, "[enter] %s(" _format ") {" #_args "}", __PRETTY_FUNCTION__, ##_args ); |
331 | 341 |
332 /* Helper for debugging by adding traces -- for debuging a specific location of the code */ | 342 /* Helper for debugging by adding traces -- for debuging a specific location of the code */ |
333 #define TRACE_HERE() \ | 343 #define TRACE_HERE() \ |
334 TRACE_DEBUG(NONE, " -- debug checkpoint %d -- ", fd_breakhere()); | 344 LOG_F(" -- debug checkpoint %d -- ", fd_breakhere()); |
335 int fd_breakhere(void); | 345 int fd_breakhere(void); |
336 | 346 |
337 /* Helper for tracing the CHECK_* macros below -- very very verbose code execution! */ | 347 /* Helper for tracing the CHECK_* macros below -- very very verbose code execution! */ |
338 #define TRACE_DEBUG_ALL( str... ) \ | 348 #define TRACE_CALL( str... ) \ |
339 TRACE_DEBUG(CALL, str ); | 349 if ((fd_debug_one_function && !strcmp(fd_debug_one_function, __PRETTY_FUNCTION__)) \ |
350 || (fd_debug_one_file && !strcmp(fd_debug_one_file, __STRIPPED_FILE__) ) ) { \ | |
351 LOG_A( str ); \ | |
352 } | |
340 | 353 |
341 /* For development only, to keep track of TODO locations in the code */ | 354 /* For development only, to keep track of TODO locations in the code */ |
342 #ifndef ERRORS_ON_TODO | 355 #ifndef ERRORS_ON_TODO |
343 #define TODO( _msg, _args... ) \ | 356 # define TODO( _msg, _args... ) \ |
344 TRACE_DEBUG(NONE, "TODO: " _msg , ##_args); | 357 LOG_F( "TODO: " _msg , ##_args); |
345 #else /* ERRORS_ON_TODO */ | 358 #else /* ERRORS_ON_TODO */ |
346 #define TODO( _msg, _args... ) \ | 359 # define TODO( _msg, _args... ) \ |
347 "TODO" = _msg ## _args; /* just a stupid compilation error to spot the todo */ | 360 "TODO" = _msg ## _args; /* just a stupid compilation error to spot the todo */ |
348 #endif /* ERRORS_ON_TODO */ | 361 #endif /* ERRORS_ON_TODO */ |
349 | 362 |
350 /* Trace a binary buffer content */ | 363 |
351 #ifdef DEBUG | 364 /*============================================================*/ |
352 /* In DEBUG mode, we add (a lot of) meta-information along each trace. This makes multi-threading problems easier to debug. */ | 365 /* ERROR CHECKING MACRO */ |
353 #define TRACE_BUFFER(printlevel, level, prefix, buf, bufsz, suffix ) { \ | 366 /*============================================================*/ |
354 if ( TRACE_BOOL(level) ) { \ | 367 |
355 int __i; \ | 368 /* Macros to check a return value and branch out in case of error. |
356 size_t __sz = (size_t)(bufsz); \ | 369 * These macro additionally provide the logging information. |
357 uint8_t * __buf = (uint8_t *)(buf); \ | 370 * |
358 char __strbuf[1024+1]; \ | 371 * The name "__ret__" is always available in the __fallback__ parameter and contains the error code. |
359 char * __thn = ((char *)pthread_getspecific(fd_log_thname) ?: "unnamed"); \ | 372 */ |
360 for (__i = 0; (__i < __sz) && (__i<(sizeof(__strbuf)/2)); __i++) { \ | 373 |
361 sprintf(__strbuf + (2 * __i), "%2.2hhx", __buf[__i]); \ | 374 #define CHECK_PRELUDE(__call__) \ |
362 } \ | 375 int __ret__; \ |
363 fd_log(printlevel, STD_TRACE_FMT_STRING "%s%s%s", \ | 376 TRACE_CALL("Check: %s", #__call__ ); \ |
364 __thn, __PRETTY_FUNCTION__, __STRIPPED_FILE__, __LINE__, (prefix), __strbuf, (suffix)); \ | 377 __ret__ = (__call__) |
365 } \ | 378 |
379 #define DEFAULT_FB return __ret__; | |
380 | |
381 /* System check: error case if < 0, error value in errno */ | |
382 #define CHECK_SYS_GEN( faillevel, __call__, __fallback__ ) { \ | |
383 CHECK_PRELUDE(__call__); \ | |
384 if (__ret__ < 0) { \ | |
385 __ret__ = errno; \ | |
386 LOG(faillevel, "ERROR: in '%s' :\t%s", #__call__ , strerror(__ret__)); \ | |
387 __fallback__; \ | |
388 } \ | |
366 } | 389 } |
367 #else /* DEBUG */ | 390 |
368 /* Do not print thread, function, ... only the message itself in this case */ | 391 |
369 #define TRACE_BUFFER(printlevel, level, prefix, buf, bufsz, suffix ) { \ | 392 /* Check the return value of a function and execute fallback in case of error or special value */ |
370 if ( TRACE_BOOL(level) ) { \ | 393 #define CHECK_FCT_GEN2( faillevel, __call__, __speval__, __fallback1__, __fallback2__ ) { \ |
371 int __i; \ | 394 CHECK_PRELUDE(__call__); \ |
372 size_t __sz = (size_t)(bufsz); \ | 395 if (__ret__ != 0) { \ |
373 uint8_t * __buf = (uint8_t *)(buf); \ | 396 if (__ret__ == (__speval__)) { \ |
374 char __strbuf[1024+1]; \ | 397 __fallback1__; \ |
375 for (__i = 0; (__i < __sz) && (__i<(sizeof(__strbuf)/2)); __i++) { \ | 398 } else { \ |
376 sprintf(__strbuf + (2 * __i), "%2.2hhx", __buf[__i]); \ | 399 LOG(faillevel, "ERROR: in '%s' :\t%s", #__call__ , strerror(__ret__)); \ |
377 } \ | 400 __fallback2__; \ |
378 fd_log(printlevel, "%s%s%s", (prefix), __strbuf, (suffix)); \ | 401 } \ |
379 } \ | 402 } \ |
380 } | 403 } |
381 #endif /* DEBUG */ | 404 |
382 | 405 /* Check the return value of a function and execute fallback in case of error (return value different from 0) */ |
383 /* Some aliases to socket addresses structures */ | 406 #define CHECK_FCT_GEN( faillevel, __call__, __fallback__) \ |
384 #define sSS struct sockaddr_storage | 407 CHECK_FCT_GEN2( faillevel, (__call__), 0, , (__fallback__) ) |
385 #define sSA struct sockaddr | 408 |
386 #define sSA4 struct sockaddr_in | 409 /* Check that a memory allocator did not return NULL, otherwise log an error and execute fallback */ |
387 #define sSA6 struct sockaddr_in6 | 410 #define CHECK_MALLOC_GEN( faillevel, __call__, __fallback__ ) { \ |
388 | 411 void * __ptr__; \ |
389 /* The sockaddr length of a sSS structure */ | 412 TRACE_CALL("Check: %s", #__call__ ); \ |
390 #define sSAlen( _sa_ ) \ | 413 __ptr__ = (void *)(__call__); \ |
391 ( (socklen_t) ( (((sSA *)_sa_)->sa_family == AF_INET) ? (sizeof(sSA4)) : \ | 414 if (__ptr__ == NULL) { \ |
392 ((((sSA *)_sa_)->sa_family == AF_INET6) ? (sizeof(sSA6)) : \ | 415 int __ret__ = errno; \ |
393 0 ) ) ) | 416 LOG(faillevel, "ERROR: in '%s' :\t%s", #__call__ , strerror(__ret__)); \ |
394 | 417 __fallback__; \ |
395 /* Dump one sockaddr Node information */ | 418 } \ |
396 #define sSA_DUMP_NODE( buf, bufsize, sa, flag ) { \ | |
397 sSA * __sa = (sSA *)(sa); \ | |
398 char __addrbuf[INET6_ADDRSTRLEN]; \ | |
399 if (__sa) { \ | |
400 int __rc = getnameinfo(__sa, \ | |
401 sSAlen(__sa), \ | |
402 __addrbuf, \ | |
403 sizeof(__addrbuf), \ | |
404 NULL, \ | |
405 0, \ | |
406 (flag)); \ | |
407 if (__rc) \ | |
408 snprintf(buf, bufsize, "%s", gai_strerror(__rc)); \ | |
409 else \ | |
410 snprintf(buf, bufsize, "%s", &__addrbuf[0]); \ | |
411 } else { \ | |
412 snprintf(buf, bufsize, "(NULL / ANY)"); \ | |
413 } \ | |
414 } | 419 } |
415 /* Same but with the port (service) also */ | 420 |
416 #define sSA_DUMP_NODE_SERV( buf, bufsize, sa, flag ) { \ | 421 /* Check parameters at function entry, execute fallback on error */ |
417 sSA * __sa = (sSA *)(sa); \ | 422 #define CHECK_PARAMS_GEN( faillevel, __bool__, __fallback__ ) { \ |
418 char __addrbuf[INET6_ADDRSTRLEN]; \ | 423 TRACE_CALL("Check: %s", #__bool__ ); \ |
419 char __servbuf[32]; \ | 424 if ( ! (__bool__) ) { \ |
420 if (__sa) { \ | 425 int __ret__ = EINVAL; \ |
421 int __rc = getnameinfo(__sa, \ | 426 LOG(faillevel, "ERROR: invalid parameter '%s'", #__bool__ ); \ |
422 sSAlen(__sa), \ | 427 __fallback__; \ |
423 __addrbuf, \ | 428 } \ |
424 sizeof(__addrbuf), \ | |
425 __servbuf, \ | |
426 sizeof(__servbuf), \ | |
427 (flag)); \ | |
428 if (__rc) \ | |
429 snprintf(buf, bufsize, "%s", gai_strerror(__rc)); \ | |
430 else \ | |
431 snprintf(buf, bufsize, "[%s]:%s", &__addrbuf[0],&__servbuf[0]); \ | |
432 } else { \ | |
433 snprintf(buf, bufsize,"(NULL / ANY)"); \ | |
434 } \ | |
435 } | 429 } |
436 | 430 |
437 #ifdef DEBUG | 431 |
438 /* In DEBUG mode, we add (a lot of) meta-information along each trace. This makes multi-threading problems easier to debug. */ | 432 /*============================================================*/ |
439 #define TRACE_sSA(printlevel, level, prefix, sa, flags, suffix ) { \ | 433 /* COMPATIBILITY MACROS, TO BE REMOVED */ |
440 if ( TRACE_BOOL(level) ) { \ | 434 /*============================================================*/ |
441 char __buf[1024]; \ | 435 /* Redefine the old macros for transition of the code */ |
442 char * __thn = ((char *)pthread_getspecific(fd_log_thname) ?: "unnamed"); \ | 436 #ifndef EXCLUDE_DEPRECATED |
443 sSA_DUMP_NODE_SERV(__buf, sizeof(__buf), sa, flags ); \ | 437 |
444 fd_log(printlevel, STD_TRACE_FMT_STRING "%s%s%s" , \ | 438 #define MARK_DEPRECATED /* __attribute__ ((deprecated)) */ |
445 __thn, __PRETTY_FUNCTION__, __STRIPPED_FILE__, __LINE__, (prefix), __buf, (suffix)); \ | 439 |
446 } \ | 440 enum old_levels { |
441 NONE = 0, | |
442 INFO = 1, | |
443 FULL = 2, | |
444 ANNOYING = 4, | |
445 FCTS = 6, | |
446 CALL = 9 | |
447 } MARK_DEPRECATED; | |
448 | |
449 static __inline__ int TRACE_BOOL( enum old_levels level ) MARK_DEPRECATED | |
450 { | |
451 return (level <= fd_g_debug_lvl) | |
452 || (fd_debug_one_function && !strcmp(fd_debug_one_function, __PRETTY_FUNCTION__)) | |
453 || (fd_debug_one_file && !strcmp(fd_debug_one_file, __STRIPPED_FILE__) ); | |
447 } | 454 } |
448 #else /* DEBUG */ | 455 |
449 /* Do not print thread, function, ... only the message itself in this case */ | 456 static __inline__ void fd_log_deprecated( int level, const char *format, ... ) MARK_DEPRECATED |
450 #define TRACE_sSA(printlevel, level, prefix, sa, flags, suffix ) { \ | 457 { |
451 if ( TRACE_BOOL(level) ) { \ | 458 va_list ap; |
452 char __buf[1024]; \ | 459 va_start(ap, format); |
453 sSA_DUMP_NODE_SERV(__buf, sizeof(__buf), sa, flags ); \ | 460 fd_log_va(level, format, ap); |
454 fd_log(printlevel, "%s%s%s" , (prefix), __buf, (suffix)); \ | 461 va_end(ap); |
455 } \ | |
456 } | 462 } |
457 #endif /* DEBUG */ | 463 static __inline__ void replace_me() MARK_DEPRECATED { } |
458 | 464 |
459 /****************** | 465 #define TRACE_sSA(...) replace_me(); |
460 Optimized code: remove all debugging code | 466 #define sSA_DUMP_NODE_SERV(...) replace_me(); |
461 **/ | 467 #define sSA_DUMP_NODE(...) replace_me(); |
468 #define TRACE_BUFFER(...) replace_me(); | |
469 #define TRACE_NOTICE(...) replace_me(); | |
470 | |
471 | |
472 /* Use the LOG_* instead, or use the new *_dump functions when dumping an object */ | |
473 #define fd_log_debug(format,args...) fd_log_deprecated(FD_LOG_DEBUG, format, ## args) | |
474 #define fd_log_notice(format,args...) fd_log_deprecated(FD_LOG_NOTICE, format, ## args) | |
475 #define fd_log_error(format,args...) fd_log_deprecated(FD_LOG_ERROR, format, ## args) | |
476 | |
477 /* old macro for traces. To be replaced by appropriate LOG_* macros. */ | |
478 # define TRACE_DEBUG(oldlevel, format,args... ) { \ | |
479 if (TRACE_BOOL(oldlevel)) { \ | |
480 if (oldlevel == NONE) { LOG_E(format,##args); } \ | |
481 else if (oldlevel == INFO) { LOG_N(format,##args); } \ | |
482 else { LOG_D(format,##args); } \ | |
483 } } | |
484 | |
485 /* the following macro must be replaced with LOG_E or LOG_F */ | |
486 # define TRACE_ERROR fd_log_error | |
487 | |
488 | |
489 /* The following macros are missing the faillevel information, which indicates at what log level the error case should be displayed. */ | |
490 # define CHECK_SYS_DO( __call__, __fallback__ ) { \ | |
491 CHECK_PRELUDE(__call__); \ | |
492 if (__ret__ < 0) { \ | |
493 __ret__ = errno; \ | |
494 TRACE_ERROR("ERROR: in '%s' :\t%s", #__call__ , strerror(__ret__)); \ | |
495 __fallback__; \ | |
496 } \ | |
497 } | |
498 | |
499 # define CHECK_SYS( __call__ ) \ | |
500 CHECK_SYS_DO( (__call__), return __ret__ ) | |
501 | |
502 | |
503 # define CHECK_POSIX_DO2( __call__, __speval__, __fallback1__, __fallback2__ ) { \ | |
504 CHECK_PRELUDE(__call__); \ | |
505 if (__ret__ != 0) { \ | |
506 if (__ret__ == (__speval__)) { \ | |
507 __fallback1__; \ | |
508 } else { \ | |
509 TRACE_ERROR("ERROR: in '%s' :\t%s", #__call__ , strerror(__ret__)); \ | |
510 __fallback2__; \ | |
511 } \ | |
512 } \ | |
513 } | |
514 | |
515 # define CHECK_POSIX_DO( __call__, __fallback__ ) \ | |
516 CHECK_POSIX_DO2( (__call__), 0, , __fallback__ ) | |
517 | |
518 # define CHECK_POSIX( __call__ ) \ | |
519 CHECK_POSIX_DO( (__call__), return __ret__ ) | |
520 | |
521 # define CHECK_MALLOC_DO( __call__, __fallback__ ) { \ | |
522 void * __ptr__; \ | |
523 TRACE_CALL("Check: %s", #__call__ ); \ | |
524 __ptr__ = (void *)(__call__); \ | |
525 if (__ptr__ == NULL) { \ | |
526 int __ret__ = errno; \ | |
527 TRACE_ERROR("ERROR: in '%s' :\t%s", #__call__ , strerror(__ret__)); \ | |
528 __fallback__; \ | |
529 } \ | |
530 } | |
531 | |
532 # define CHECK_MALLOC( __call__ ) \ | |
533 CHECK_MALLOC_DO( (__call__), return __ret__ ) | |
534 | |
535 # define CHECK_PARAMS_DO( __bool__, __fallback__ ) { \ | |
536 TRACE_CALL("Check: %s", #__bool__ ); \ | |
537 if ( ! (__bool__) ) { \ | |
538 int __ret__ = EINVAL; \ | |
539 TRACE_ERROR("ERROR: invalid parameter '%s'", #__bool__ ); \ | |
540 __fallback__; \ | |
541 } \ | |
542 } | |
543 | |
544 # define CHECK_PARAMS( __bool__ ) \ | |
545 CHECK_PARAMS_DO( (__bool__), return __ret__ ) | |
546 | |
547 # define CHECK_FCT_DO CHECK_POSIX_DO | |
548 # define CHECK_FCT CHECK_POSIX | |
549 | |
550 #endif /* EXCLUDE_DEPRECATED */ | |
551 | |
552 | |
553 /*============================================================*/ | |
554 /* Optimized code: remove all debugging code */ | |
555 /*============================================================*/ | |
462 #ifdef STRIP_DEBUG_CODE | 556 #ifdef STRIP_DEBUG_CODE |
463 #undef TRACE_DEBUG | 557 #undef LOG_D |
464 #undef TRACE_NOTICE | 558 #undef LOG_N |
465 #undef TRACE_ERROR | 559 #undef LOG_E |
466 #undef TRACE_BOOL | 560 #undef LOG_F |
467 #undef TRACE_BUFFER | 561 #undef LOG_BUFFER |
468 #undef TRACE_sSA | 562 |
469 | 563 #define LOG_D(format,args... ) /* noop */ |
470 #define TRACE_DEBUG(level,format,args... ) /* noop */ | 564 #define LOG_N(format,args...) fd_log(FD_LOG_NOTICE, format, ## args) |
471 #define TRACE_BOOL(_level_) (0) /* always false */ | 565 #define LOG_E(format,args...) fd_log(FD_LOG_ERROR, format, ## args) |
472 #define TRACE_NOTICE fd_log_notice | 566 #define LOG_F(format,args...) fd_log(FD_LOG_FATAL, format, ## args) |
473 #define TRACE_ERROR fd_log_error | 567 #define LOG_BUFFER(printlevel, level, prefix, buf, bufsz, suffix ) { \ |
474 #define TRACE_BUFFER(printlevel, level, prefix, buf, bufsz, suffix ) { \ | |
475 if (printlevel > FD_LOG_DEBUG) { \ | 568 if (printlevel > FD_LOG_DEBUG) { \ |
476 int __i; \ | 569 int __i; \ |
477 size_t __sz = (size_t)(bufsz); \ | 570 size_t __sz = (size_t)(bufsz); \ |
478 uint8_t * __buf = (uint8_t *)(buf); \ | 571 uint8_t * __buf = (uint8_t *)(buf); \ |
479 char * __strbuf[1024+1]; \ | 572 char * __strbuf[1024+1]; \ |
480 for (__i = 0; (__i < __sz) && (__i<(sizeof(__strbuf)/2); __i++) { \ | 573 for (__i = 0; (__i < __sz) && (__i<(sizeof(__strbuf)/2); __i++) { \ |
481 sprintf(__strbuf + (2 * __i), "%02.2hhx", __buf[__i]); \ | 574 sprintf(__strbuf + (2 * __i), "%02.2hhx", __buf[__i]); \ |
482 } \ | 575 } \ |
483 fd_log(printlevel, prefix"%s"suffix, __strbuf); \ | 576 fd_log(printlevel, prefix"%s"suffix, __strbuf); \ |
484 } | 577 } |
485 #define TRACE_sSA(printlevel, level, prefix, sa, flags, suffix ) { \ | |
486 if (printlevel > FD_LOG_DEBUG) { \ | |
487 char __buf[1024]; \ | |
488 sSA_DUMP_NODE_SERV(__buf, sizeof(__buf), sa, flags ); \ | |
489 fd_log(printlevel, prefix "%s" suffix, __buf); \ | |
490 } | |
491 #endif /* STRIP_DEBUG_CODE */ | 578 #endif /* STRIP_DEBUG_CODE */ |
492 | 579 |
493 | 580 /*============================================================*/ |
494 /*============================================================*/ | 581 /* OTHER MACROS */ |
495 /* ERROR CHECKING MACRO */ | 582 /*============================================================*/ |
496 /*============================================================*/ | |
497 | |
498 /* Macros to check a return value and branch out in case of error. | |
499 * These macro should be used only when errors are improbable, not for expected errors. | |
500 */ | |
501 | |
502 /* Check the return value of a system function and execute fallback in case of error */ | |
503 #define CHECK_SYS_DO( __call__, __fallback__ ) { \ | |
504 int __ret__; \ | |
505 TRACE_DEBUG_ALL( "Check SYS: %s", #__call__ ); \ | |
506 __ret__ = (__call__); \ | |
507 if (__ret__ < 0) { \ | |
508 int __err__ = errno; /* We may handle EINTR here */ \ | |
509 TRACE_ERROR("ERROR: in '%s' :\t%s", #__call__ , strerror(__err__)); \ | |
510 __fallback__; \ | |
511 } \ | |
512 } | |
513 /* Check the return value of a system function, return error code on error */ | |
514 #define CHECK_SYS( __call__ ) { \ | |
515 int __ret__; \ | |
516 TRACE_DEBUG_ALL( "Check SYS: %s", #__call__ ); \ | |
517 __ret__ = (__call__); \ | |
518 if (__ret__ < 0) { \ | |
519 int __err__ = errno; /* We may handle EINTR here */ \ | |
520 TRACE_ERROR("ERROR: in '%s' :\t%s", #__call__ , strerror(__err__)); \ | |
521 return __err__; \ | |
522 } \ | |
523 } | |
524 | |
525 /* Check the return value of a POSIX function and execute fallback in case of error or special value */ | |
526 #define CHECK_POSIX_DO2( __call__, __speval__, __fallback1__, __fallback2__ ) { \ | |
527 int __ret__; \ | |
528 TRACE_DEBUG_ALL( "Check POSIX: %s", #__call__ ); \ | |
529 __ret__ = (__call__); \ | |
530 if (__ret__ != 0) { \ | |
531 if (__ret__ == (__speval__)) { \ | |
532 __fallback1__; \ | |
533 } else { \ | |
534 TRACE_ERROR("ERROR: in '%s':\t%s", #__call__, strerror(__ret__)); \ | |
535 __fallback2__; \ | |
536 } \ | |
537 } \ | |
538 } | |
539 | |
540 /* Check the return value of a POSIX function and execute fallback in case of error */ | |
541 #define CHECK_POSIX_DO( __call__, __fallback__ ) \ | |
542 CHECK_POSIX_DO2( (__call__), 0, , __fallback__ ); | |
543 | |
544 /* Check the return value of a POSIX function and return it if error */ | |
545 #define CHECK_POSIX( __call__ ) { \ | |
546 int __v__; \ | |
547 CHECK_POSIX_DO( __v__ = (__call__), return __v__ ); \ | |
548 } | |
549 | |
550 /* Check that a memory allocator did not return NULL, otherwise log an error and execute fallback */ | |
551 #define CHECK_MALLOC_DO( __call__, __fallback__ ) { \ | |
552 void * __ret__; \ | |
553 TRACE_DEBUG_ALL( "Check MALLOC: %s", #__call__ ); \ | |
554 __ret__ = (void *)( __call__ ); \ | |
555 if (__ret__ == NULL) { \ | |
556 int __err__ = errno; \ | |
557 TRACE_ERROR("ERROR: in '%s':\t%s", #__call__, strerror(__err__)); \ | |
558 __fallback__; \ | |
559 } \ | |
560 } | |
561 | |
562 /* Check that a memory allocator did not return NULL, otherwise return ENOMEM */ | |
563 #define CHECK_MALLOC( __call__ ) \ | |
564 CHECK_MALLOC_DO( __call__, return ENOMEM ); | |
565 | |
566 | |
567 /* Check parameters at function entry, execute fallback on error */ | |
568 #define CHECK_PARAMS_DO( __bool__, __fallback__ ) \ | |
569 TRACE_DEBUG_ALL( "Check PARAMS: %s", #__bool__ ); \ | |
570 if ( ! (__bool__) ) { \ | |
571 TRACE_ERROR("Warning: Invalid parameter received in '%s'", #__bool__); \ | |
572 __fallback__; \ | |
573 } | |
574 /* Check parameters at function entry, return EINVAL if the boolean is false (similar to assert) */ | |
575 #define CHECK_PARAMS( __bool__ ) \ | |
576 CHECK_PARAMS_DO( __bool__, return EINVAL ); | |
577 | |
578 /* Check the return value of an internal function, log and propagate */ | |
579 #define CHECK_FCT_DO( __call__, __fallback__ ) { \ | |
580 int __ret__; \ | |
581 TRACE_DEBUG_ALL( "Check FCT: %s", #__call__ ); \ | |
582 __ret__ = (__call__); \ | |
583 if (__ret__ != 0) { \ | |
584 TRACE_ERROR("ERROR: in '%s':\t%s", #__call__, strerror(__ret__)); \ | |
585 __fallback__; \ | |
586 } \ | |
587 } | |
588 /* Check the return value of a function call, return any error code */ | |
589 #define CHECK_FCT( __call__ ) { \ | |
590 int __v__; \ | |
591 CHECK_FCT_DO( __v__ = (__call__), return __v__ ); \ | |
592 } | |
593 | |
594 | |
595 | |
596 /*============================================================*/ | |
597 /* OTHER MACROS */ | |
598 /*============================================================*/ | |
599 | |
600 | |
601 /* helper macros (pre-processor hacks to allow macro arguments) */ | 583 /* helper macros (pre-processor hacks to allow macro arguments) */ |
602 #define __tostr( arg ) #arg | 584 #define __tostr( arg ) #arg |
603 #define _stringize( arg ) __tostr( arg ) | 585 #define _stringize( arg ) __tostr( arg ) |
604 #define __agr( arg1, arg2 ) arg1 ## arg2 | 586 #define __agr( arg1, arg2 ) arg1 ## arg2 |
605 #define _aggregate( arg1, arg2 ) __agr( arg1, arg2 ) | 587 #define _aggregate( arg1, arg2 ) __agr( arg1, arg2 ) |
588 | |
589 /* Some aliases to socket addresses structures */ | |
590 #define sSS struct sockaddr_storage | |
591 #define sSA struct sockaddr | |
592 #define sSA4 struct sockaddr_in | |
593 #define sSA6 struct sockaddr_in6 | |
594 | |
595 /* The sockaddr length of a sSS structure */ | |
596 #define sSAlen( _sa_ ) \ | |
597 ( (socklen_t) ( (((sSA *)_sa_)->sa_family == AF_INET) ? (sizeof(sSA4)) : \ | |
598 ((((sSA *)_sa_)->sa_family == AF_INET6) ? (sizeof(sSA6)) : \ | |
599 0 ) ) ) | |
600 | |
601 DECLARE_FD_DUMP_PROTOTYPE(fd_sa_dump_node, sSA * sa, int flags); | |
602 DECLARE_FD_DUMP_PROTOTYPE(fd_sa_dump_node_serv, sSA * sa, int flags); | |
606 | 603 |
607 | 604 |
608 /* A l4 protocol name (TCP / SCTP) */ | 605 /* A l4 protocol name (TCP / SCTP) */ |
609 #ifdef DISABLE_SCTP | 606 #ifdef DISABLE_SCTP |
610 #define IPPROTO_NAME( _proto ) \ | 607 #define IPPROTO_NAME( _proto ) \ |
981 int fd_dict_getval ( struct dict_object * object, void * val); | 978 int fd_dict_getval ( struct dict_object * object, void * val); |
982 int fd_dict_gettype ( struct dict_object * object, enum dict_object_type * type); | 979 int fd_dict_gettype ( struct dict_object * object, enum dict_object_type * type); |
983 int fd_dict_getdict ( struct dict_object * object, struct dictionary ** dict); | 980 int fd_dict_getdict ( struct dict_object * object, struct dictionary ** dict); |
984 | 981 |
985 /* Debug functions */ | 982 /* Debug functions */ |
986 void fd_dict_dump_object(struct dict_object * obj); | 983 DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump_object, struct dict_object * obj); |
987 void fd_dict_dump(struct dictionary * dict); | 984 DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump, struct dictionary * dict); |
988 | 985 |
989 /* Function to access full contents of the dictionary, see doc in dictionary.c */ | 986 /* Function to access full contents of the dictionary, see doc in dictionary.c */ |
990 int fd_dict_getlistof(int criteria, void * parent, struct fd_list ** sentinel); | 987 int fd_dict_getlistof(int criteria, void * parent, struct fd_list ** sentinel); |
991 | 988 |
992 /* Function to remove an entry from the dictionary. | 989 /* Function to remove an entry from the dictionary. |
1220 struct dict_type_data { | 1217 struct dict_type_data { |
1221 enum dict_avp_basetype type_base; /* How the data of such AVP must be interpreted */ | 1218 enum dict_avp_basetype type_base; /* How the data of such AVP must be interpreted */ |
1222 char * type_name; /* The name of this type */ | 1219 char * type_name; /* The name of this type */ |
1223 dict_avpdata_interpret type_interpret;/* cb to convert the AVP value in more comprehensive format (or NULL) */ | 1220 dict_avpdata_interpret type_interpret;/* cb to convert the AVP value in more comprehensive format (or NULL) */ |
1224 dict_avpdata_encode type_encode; /* cb to convert formatted data into an AVP value (or NULL) */ | 1221 dict_avpdata_encode type_encode; /* cb to convert formatted data into an AVP value (or NULL) */ |
1225 char * (*type_dump)(union avp_value * val); /* cb called by fd_msg_dump_one for this type of data (if != NULL). Returned string must be freed. */ | 1222 DECLARE_FD_DUMP_PROTOTYPE((*type_dump), union avp_value * val); /* cb called by fd_msg_dump_one for this type of data (if != NULL). Returned string must be freed. */ |
1226 }; | 1223 }; |
1227 | 1224 |
1228 /* The criteria for searching a type object in the dictionary */ | 1225 /* The criteria for searching a type object in the dictionary */ |
1229 enum { | 1226 enum { |
1230 TYPE_BY_NAME = 30, /* "what" points to a char * */ | 1227 TYPE_BY_NAME = 30, /* "what" points to a char * */ |
1237 */ | 1234 */ |
1238 | 1235 |
1239 /* Convert an Address type AVP into a struct sockaddr_storage */ | 1236 /* Convert an Address type AVP into a struct sockaddr_storage */ |
1240 int fd_dictfct_Address_encode(void * data, union avp_value * avp_value); | 1237 int fd_dictfct_Address_encode(void * data, union avp_value * avp_value); |
1241 int fd_dictfct_Address_interpret(union avp_value * avp_value, void * interpreted); | 1238 int fd_dictfct_Address_interpret(union avp_value * avp_value, void * interpreted); |
1242 char * fd_dictfct_Address_dump(union avp_value * avp_value); | 1239 DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_Address_dump, union avp_value * avp_value); |
1243 | 1240 |
1244 /* Display the content of an AVP of type UTF8String in the log file */ | 1241 /* Display the content of an AVP of type UTF8String in the log file */ |
1245 char * fd_dictfct_UTF8String_dump(union avp_value * avp_value); | 1242 DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_UTF8String_dump, union avp_value * avp_value); |
1246 | 1243 |
1247 /* For Time AVPs, map with time_t value directly */ | 1244 /* For Time AVPs, map with time_t value directly */ |
1248 int fd_dictfct_Time_encode(void * data, union avp_value * avp_value); | 1245 int fd_dictfct_Time_encode(void * data, union avp_value * avp_value); |
1249 int fd_dictfct_Time_interpret(union avp_value * avp_value, void * interpreted); | 1246 int fd_dictfct_Time_interpret(union avp_value * avp_value, void * interpreted); |
1250 char * fd_dictfct_Time_dump(union avp_value * avp_value); | 1247 DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_Time_dump, union avp_value * avp_value); |
1251 | 1248 |
1252 | 1249 |
1253 | 1250 |
1254 /****/ | 1251 /****/ |
1255 | 1252 |
1819 struct session; | 1816 struct session; |
1820 | 1817 |
1821 /* The state information that a module associate with a session -- each module defines its own data format */ | 1818 /* The state information that a module associate with a session -- each module defines its own data format */ |
1822 typedef void session_state; | 1819 typedef void session_state; |
1823 | 1820 |
1821 typedef DECLARE_FD_DUMP_PROTOTYPE(session_state_dump, session_state * st); | |
1822 | |
1824 /* The following function must be called to activate the session expiry mechanism */ | 1823 /* The following function must be called to activate the session expiry mechanism */ |
1825 int fd_sess_start(void); | 1824 int fd_sess_start(void); |
1826 | 1825 |
1827 /* | 1826 /* |
1828 * FUNCTION: fd_sess_handler_create | 1827 * FUNCTION: fd_sess_handler_create |
1829 * | 1828 * |
1830 * PARAMETERS: | 1829 * PARAMETERS: |
1831 * handler : location where the new handler must be stored. | 1830 * handler : location where the new handler must be stored. |
1832 * cleanup : a callback function that must be called when the session with associated data is destroyed. | 1831 * cleanup : a callback function that must be called when the session with associated data is destroyed. |
1832 * dumper : if not NULL, will be called during fd_sess_dump to display the data associated with a session. NULL otherwise. | |
1833 * opaque : A pointer that is passed to the cleanup callback -- the content is never examined by the framework. | 1833 * opaque : A pointer that is passed to the cleanup callback -- the content is never examined by the framework. |
1834 * | 1834 * |
1835 * DESCRIPTION: | 1835 * DESCRIPTION: |
1836 * Create a new session handler. This is needed by a module to associate a state with a session object. | 1836 * Create a new session handler. This is needed by a module to associate a state with a session object. |
1837 * The cleanup handler is called when the session timeout expires, or fd_sess_destroy is called. It must free | 1837 * The cleanup handler is called when the session timeout expires, or fd_sess_destroy is called. It must free |
1840 * RETURN VALUE: | 1840 * RETURN VALUE: |
1841 * 0 : The new handler has been created. | 1841 * 0 : The new handler has been created. |
1842 * EINVAL : A parameter is invalid. | 1842 * EINVAL : A parameter is invalid. |
1843 * ENOMEM : Not enough memory to complete the operation | 1843 * ENOMEM : Not enough memory to complete the operation |
1844 */ | 1844 */ |
1845 int fd_sess_handler_create_internal ( struct session_handler ** handler, void (*cleanup)(session_state * state, os0_t sid, void * opaque), void * opaque ); | 1845 int fd_sess_handler_create_internal ( struct session_handler ** handler, void (*cleanup)(session_state * state, os0_t sid, void * opaque), session_state_dump dumper, void * opaque ); |
1846 /* Macro to avoid casting everywhere */ | 1846 /* Macro to avoid casting everywhere */ |
1847 #define fd_sess_handler_create( _handler, _cleanup, _opaque ) \ | 1847 #define fd_sess_handler_create( _handler, _cleanup, _dumper, _opaque ) \ |
1848 fd_sess_handler_create_internal( (_handler), (void (*)(session_state *, os0_t, void *))(_cleanup), (void *)(_opaque) ) | 1848 fd_sess_handler_create_internal( (_handler), (void (*)(session_state *, os0_t, void *))(_cleanup), _dumper, (void *)(_opaque) ) |
1849 | 1849 |
1850 | 1850 |
1851 /* | 1851 /* |
1852 * FUNCTION: fd_sess_handler_destroy | 1852 * FUNCTION: fd_sess_handler_destroy |
1853 * | 1853 * |
2043 #define fd_sess_state_retrieve( _handler, _session, _state ) \ | 2043 #define fd_sess_state_retrieve( _handler, _session, _state ) \ |
2044 fd_sess_state_retrieve_internal( (_handler), (_session), (void *)(_state) ) | 2044 fd_sess_state_retrieve_internal( (_handler), (_session), (void *)(_state) ) |
2045 | 2045 |
2046 | 2046 |
2047 /* For debug */ | 2047 /* For debug */ |
2048 void fd_sess_dump(int level, struct session * session); | 2048 DECLARE_FD_DUMP_PROTOTYPE(fd_sess_dump, struct session * session, int with_states); |
2049 void fd_sess_dump_hdl(int level, struct session_handler * handler); | 2049 DECLARE_FD_DUMP_PROTOTYPE(fd_sess_dump_hdl, struct session_handler * handler); |
2050 | 2050 |
2051 /* For statistics / monitoring: get the number of struct session in memory */ | 2051 /* For statistics / monitoring: get the number of struct session in memory */ |
2052 int fd_sess_getcount(uint32_t *cnt); | 2052 int fd_sess_getcount(uint32_t *cnt); |
2053 | 2053 |
2054 /*============================================================*/ | 2054 /*============================================================*/ |
2325 /***************************************/ | 2325 /***************************************/ |
2326 /* | 2326 /* |
2327 * FUNCTION: fd_msg_dump_* | 2327 * FUNCTION: fd_msg_dump_* |
2328 * | 2328 * |
2329 * PARAMETERS: | 2329 * PARAMETERS: |
2330 * level : the log level (INFO, FULL, ...) at which the object is dumped | 2330 * see definition of DECLARE_FD_DUMP_PROTOTYPE, |
2331 * obj : A msg or avp object. | 2331 * obj : A msg or avp object to dump. |
2332 * | 2332 * dict : the dictionary to use if parsing is requested (optional) |
2333 * DESCRIPTION: | 2333 * force_parsing: by default these functions do not parse the object but dump hexa values in that case. |
2334 * These functions dump the content of a message to the debug log | 2334 * use !0 to force parsing. If parsing fails, the hexa dump is still provided. |
2335 * recurse : allow the function to go through the children objects if any to dump more information. might require parsing. | |
2336 * | |
2337 * DESCRIPTION: | |
2338 * These functions dump the content of a message or avp into a buffer | |
2335 * either recursively or only the object itself. | 2339 * either recursively or only the object itself. |
2336 * | 2340 * |
2337 * RETURN VALUE: | 2341 * RETURN VALUE: |
2338 * - | 2342 * - see DECLARE_FD_DUMP_PROTOTYPE, |
2339 */ | |
2340 void fd_msg_dump_walk ( int level, msg_or_avp *obj ); | |
2341 void fd_msg_dump_one ( int level, msg_or_avp *obj ); | |
2342 | |
2343 /* Helper functions to get a dump of an object in the logs. Several formats are available. | |
2344 * buf : a buffer that can be reallocated if needed. *buf==NULL is also accepted for first allocation | |
2345 * buflen: the length of the buffer buf. | |
2346 * dict : optional, the dictionary to use for resolving objects, if force_parsing != 0 | |
2347 * obj : the message or AVP to dump. | |
2348 * | |
2349 * After use, the buf pointer should be freed. | |
2350 */ | 2343 */ |
2351 /* one-line dump with only short information */ | 2344 /* one-line dump with only short information */ |
2352 void fd_msg_dump_summary( char ** buf, size_t buflen, struct dictionary *dict, msg_or_avp *obj, int force_parsing); | 2345 DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_summary, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ); |
2353 /* one-line dump with all the contents of the message */ | 2346 /* one-line dump with all the contents of the message */ |
2354 void fd_msg_dump_full( char ** buf, size_t buflen, struct dictionary *dict, msg_or_avp *obj, int force_parsing); | 2347 DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_full, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ); |
2355 /* multi-line human-readable dump similar to wireshark output */ | 2348 /* multi-line human-readable dump similar to wireshark output */ |
2356 void fd_msg_dump_treeview( char ** buf, size_t buflen, struct dictionary *dict, msg_or_avp *obj, int force_parsing); | 2349 DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_treeview, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ); |
2357 | 2350 |
2358 | 2351 |
2359 /*********************************************/ | 2352 /*********************************************/ |
2360 /* Message metadata management functions */ | 2353 /* Message metadata management functions */ |
2361 /*********************************************/ | 2354 /*********************************************/ |
3138 int fd_fifo_timedget_int ( struct fifo * queue, void ** item, const struct timespec *abstime ); | 3131 int fd_fifo_timedget_int ( struct fifo * queue, void ** item, const struct timespec *abstime ); |
3139 #define fd_fifo_timedget(queue, item, abstime) \ | 3132 #define fd_fifo_timedget(queue, item, abstime) \ |
3140 fd_fifo_timedget_int((queue), (void *)(item), (abstime)) | 3133 fd_fifo_timedget_int((queue), (void *)(item), (abstime)) |
3141 | 3134 |
3142 /* Dump a fifo list and optionally its inner elements -- beware of deadlocks! */ | 3135 /* Dump a fifo list and optionally its inner elements -- beware of deadlocks! */ |
3143 void fd_fifo_dump(int level, char * name, struct fifo * queue, void (*dump_item)(int level, void * item)); | 3136 typedef DECLARE_FD_DUMP_PROTOTYPE((*fd_fifo_dump_item_cb), void * item); /* This function should be 1 line if possible, or use indent level. Ends with '\n' */ |
3137 DECLARE_FD_DUMP_PROTOTYPE(fd_fifo_dump, char * name, struct fifo * queue, fd_fifo_dump_item_cb dump_item); | |
3144 | 3138 |
3145 #ifdef __cplusplus | 3139 #ifdef __cplusplus |
3146 } | 3140 } |
3147 #endif | 3141 #endif |
3148 | 3142 |