Changeset 1085:7d7266115a34 in freeDiameter
- Timestamp:
- May 3, 2013, 8:20:56 PM (11 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
include/freeDiameter/libfdcore.h
r1077 r1085 58 58 59 59 /* Check the return value of a GNUTLS function, log and propagate */ 60 #define CHECK_GNUTLS_DO( __call__, __fallback__ ) { \ 61 int __ret__; \ 62 TRACE_DEBUG(GNUTLS_DBG_LEVEL, "GNUTLS call: %s", #__call__ ); \ 63 __ret__ = (__call__); \ 64 if (__ret__ < 0) { \ 65 TRACE_DEBUG(INFO, "Error in '%s':\t%s", #__call__ , gnutls_strerror(__ret__)); \ 66 __fallback__; \ 67 } \ 60 #define CHECK_GNUTLS_GEN( faillevel, __call__, __fallback__ ) { \ 61 CHECK_PRELUDE(__call__); \ 62 if (__ret__ < 0) { \ 63 __ret__ = errno; \ 64 LOG(faillevel, "ERROR: in '%s' :\t%s", #__call__ , gnutls_strerror(__ret__)); \ 65 __fallback__; \ 66 } \ 68 67 } 69 68 70 /* For GNUTLS routines that do not return a value*/69 /* we use this macro to help debugging gnutls usage issues -- just change the content to display what you need */ 71 70 #define GNUTLS_TRACE( __call__) { \ 72 TRACE_ DEBUG(GNUTLS_DBG_LEVEL, "GNUTLS call: " #__call__ );\71 TRACE_CALL("Check: %s", #__call__ ); \ 73 72 (__call__); \ 74 73 } 74 75 76 #ifndef EXCLUDE_DEPRECATED 77 /* Macro for transition, replace with CHECK_GNUTLS_GEN */ 78 #define CHECK_GNUTLS_DO( __call__, __fallback__ ) { \ 79 CHECK_PRELUDE(__call__); \ 80 if (__ret__ < 0) { \ 81 __ret__ = errno; \ 82 TRACE_ERROR("ERROR: in '%s' :\t%s", #__call__ , gnutls_strerror(__ret__)); \ 83 __fallback__; \ 84 } \ 85 } 86 87 #endif /* EXCLUDE_DEPRECATED */ 75 88 76 89 … … 778 791 enum { 779 792 FDEV_TERMINATE = 1000 /* request to terminate */ 780 ,FDEV_DUMP_DICT /* Dump the content of the dictionary */781 ,FDEV_DUMP_EXT /* Dump state of extensions */782 ,FDEV_DUMP_SERV /* Dump the server socket status */783 ,FDEV_DUMP_QUEUES /* Dump the message queues */784 ,FDEV_DUMP_CONFIG /* Dump the configuration */785 ,FDEV_DUMP_PEERS /* Dump the list of peers */786 793 ,FDEV_TRIGGER /* Trigger available for extensions. size is sizeof(int), data is int * */ 787 794 }; … … 795 802 /* for extensions */ 796 803 int fd_event_trig_regcb(int trigger_val, const char * module, void (*cb)(void)); 797 void fd_event_trig_dump(); 798 804 805 DECLARE_FD_DUMP_PROTOTYPE(fd_event_trig_dump); 806 807 /* The "old" FD_EV_DUMP_* events are replaced with direct calls to the following dump functions */ 808 DECLARE_FD_DUMP_PROTOTYPE(fd_conf_dump); 809 DECLARE_FD_DUMP_PROTOTYPE(fd_ext_dump); 810 DECLARE_FD_DUMP_PROTOTYPE(fd_peer_dump_list, int details); 811 DECLARE_FD_DUMP_PROTOTYPE(fd_peer_dump, struct peer_hdr * p, int details); 812 DECLARE_FD_DUMP_PROTOTYPE(fd_servers_dump); 799 813 800 814 /*============================================================*/ … … 832 846 int fd_ep_filter_list( struct fd_list * list, struct fd_list * exclude_list ); 833 847 int fd_ep_clearflags( struct fd_list * list, uint32_t flags ); 834 void fd_ep_dump_one( char * prefix, struct fd_endpoint * ep );835 void fd_ep_dump( int indent, struct fd_list * eps);848 DECLARE_FD_DUMP_PROTOTYPE(fd_ep_dump_one, struct fd_endpoint * ep ); 849 DECLARE_FD_DUMP_PROTOTYPE(fd_ep_dump, int indent, struct fd_list * eps ); 836 850 837 851 -
include/freeDiameter/libfdproto.h
r1082 r1085 133 133 /* 134 134 * FUNCTION: fd_log 135 * MACRO: fd_log_debug 136 * MACRO: fd_log_notice 137 * MACRO: fd_log_error 138 * 139 * PARAMETERS: 140 * loglevel : Integer, how important the message is 135 * 136 * PARAMETERS: 137 * loglevel : Integer, how important the message is. Valid values are macros FD_LOG_* 141 138 * format : Same format string as in the printf function 142 139 * ... : Same list as printf … … 151 148 */ 152 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) 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 *, ... ); 150 void fd_log_va( int, const char *, va_list args ); 158 151 159 152 /* these are internal objects of the debug facility, … … 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 244 /* DEBUG MACROS */ … … 237 249 #endif /* ASSERT */ 238 250 239 /* log levels definitions */ 240 #define FD_LOG_DEBUG 0 /* Verbose information for developers use */ 241 #define FD_LOG_NOTICE 3 /* Normal execution states worth noting */ 242 #define FD_LOG_ERROR 5 /* Error conditions, both recoverable or not */ 243 244 /* print level definitions */ 245 #define NONE 0 /* Display no debug message */ 246 #define INFO 1 /* Display errors only */ 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). */ 251 /* log levels definitions, that are passed to the logger */ 252 #define FD_LOG_ANNOYING 0 /* very verbose loops and such "overkill" traces. Only active when the framework is compiled in DEBUG mode. */ 253 #define FD_LOG_DEBUG 1 /* Get a detailed sense of what is going on in the framework. Use this level for normal debug */ 254 #define FD_LOG_NOTICE 3 /* Normal execution states worth noting */ 255 #define FD_LOG_ERROR 5 /* Recoverable or expected error conditions */ 256 #define FD_LOG_FATAL 6 /* Unrecoverable error, e.g. malloc fail, etc. that requires the framework to shutdown */ 257 258 /* The level used by the default logger, can be changed by command-line arguments. Ignored for other loggers. */ 253 259 extern int fd_g_debug_lvl; 254 260 … … 265 271 #endif /* __PRETTY_FUNCTION__ */ 266 272 267 #ifdef DEBUG268 273 /* A version of __FILE__ without the full path */ 269 274 static char * file_bname = NULL; … … 271 276 #define __STRIPPED_FILE__ (file_bname ?: file_bname_init((char *)__FILE__)) 272 277 273 /* Boolean for tracing at a certain level */ 274 #define TRACE_BOOL(_level_) ( ((_level_) <= fd_g_debug_lvl) \ 275 || (fd_debug_one_function && !strcmp(fd_debug_one_function, __PRETTY_FUNCTION__)) \ 276 || (fd_debug_one_file && !strcmp(fd_debug_one_file, __STRIPPED_FILE__) ) ) 278 279 280 /* In DEBUG mode, we add meta-information along each trace. This makes multi-threading problems easier to debug. */ 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 284 #else /* DEBUG */ 278 # define TRACE_BOOL(_level_) ((_level_) <= fd_g_debug_lvl)279 # define __STRIPPED_FILE__ __FILE__285 # define STD_TRACE_FMT_STRING "" 286 # define STD_TRACE_FMT_ARGS 280 287 #endif /* DEBUG */ 281 288 282 283 #define STD_TRACE_FMT_STRING "pid:%s in %s@%s:%d: " 289 /************************* 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) 286 *************/ 287 #ifdef DEBUG 288 /* In DEBUG mode, we add (a lot of) meta-information along each trace. This makes multi-threading problems easier to debug. */ 289 #define TRACE(printlevel,level,format,args... ) { \ 290 if ( TRACE_BOOL(level) ) { \ 291 const char * __thn = ((char *)pthread_getspecific(fd_log_thname) ?: "unnamed"); \ 292 fd_log((printlevel), STD_TRACE_FMT_STRING format, \ 293 __thn, __PRETTY_FUNCTION__, __STRIPPED_FILE__, __LINE__, ## args); \ 294 } \ 323 Derivatives 324 ************/ 325 /* Trace a binary buffer content */ 326 #define LOG_BUFFER(printlevel, prefix, buf, bufsz, suffix ) { \ 327 int __i; \ 328 size_t __sz = (size_t)(bufsz); \ 329 uint8_t * __buf = (uint8_t *)(buf); \ 330 char __strbuf[1024+1]; \ 331 for (__i = 0; (__i < __sz) && (__i<(sizeof(__strbuf)/2)); __i++) { \ 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 */ 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 ************/ 337 328 338 /* Helper for function entry -- for very detailed trace of the execution */ 329 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 342 /* Helper for debugging by adding traces -- for debuging a specific location of the code */ 333 343 #define TRACE_HERE() \ 334 TRACE_DEBUG(NONE," -- debug checkpoint %d -- ", fd_breakhere());344 LOG_F(" -- debug checkpoint %d -- ", fd_breakhere()); 335 345 int fd_breakhere(void); 336 346 337 347 /* Helper for tracing the CHECK_* macros below -- very very verbose code execution! */ 338 #define TRACE_DEBUG_ALL( str... ) \ 339 TRACE_DEBUG(CALL, str ); 348 #define TRACE_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 354 /* For development only, to keep track of TODO locations in the code */ 342 355 #ifndef ERRORS_ON_TODO 343 # define TODO( _msg, _args... ) \344 TRACE_DEBUG(NONE,"TODO: " _msg , ##_args);356 # define TODO( _msg, _args... ) \ 357 LOG_F( "TODO: " _msg , ##_args); 345 358 #else /* ERRORS_ON_TODO */ 346 # define TODO( _msg, _args... ) \347 "TODO" = _msg ## _args; /* just a stupid compilation error to spot the todo */359 # define TODO( _msg, _args... ) \ 360 "TODO" = _msg ## _args; /* just a stupid compilation error to spot the todo */ 348 361 #endif /* ERRORS_ON_TODO */ 349 362 350 /* Trace a binary buffer content */ 351 #ifdef DEBUG 352 /* In DEBUG mode, we add (a lot of) meta-information along each trace. This makes multi-threading problems easier to debug. */ 353 #define TRACE_BUFFER(printlevel, level, prefix, buf, bufsz, suffix ) { \ 354 if ( TRACE_BOOL(level) ) { \ 355 int __i; \ 356 size_t __sz = (size_t)(bufsz); \ 357 uint8_t * __buf = (uint8_t *)(buf); \ 358 char __strbuf[1024+1]; \ 359 char * __thn = ((char *)pthread_getspecific(fd_log_thname) ?: "unnamed"); \ 360 for (__i = 0; (__i < __sz) && (__i<(sizeof(__strbuf)/2)); __i++) { \ 361 sprintf(__strbuf + (2 * __i), "%2.2hhx", __buf[__i]); \ 362 } \ 363 fd_log(printlevel, STD_TRACE_FMT_STRING "%s%s%s", \ 364 __thn, __PRETTY_FUNCTION__, __STRIPPED_FILE__, __LINE__, (prefix), __strbuf, (suffix)); \ 365 } \ 363 364 /*============================================================*/ 365 /* ERROR CHECKING MACRO */ 366 /*============================================================*/ 367 368 /* Macros to check a return value and branch out in case of error. 369 * These macro additionally provide the logging information. 370 * 371 * The name "__ret__" is always available in the __fallback__ parameter and contains the error code. 372 */ 373 374 #define CHECK_PRELUDE(__call__) \ 375 int __ret__; \ 376 TRACE_CALL("Check: %s", #__call__ ); \ 377 __ret__ = (__call__) 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 */ 368 /* Do not print thread, function, ... only the message itself in this case */ 369 #define TRACE_BUFFER(printlevel, level, prefix, buf, bufsz, suffix ) { \ 370 if ( TRACE_BOOL(level) ) {\371 int __i;\372 size_t __sz = (size_t)(bufsz);\373 uint8_t * __buf = (uint8_t *)(buf);\374 char __strbuf[1024+1];\375 for (__i = 0; (__i < __sz) && (__i<(sizeof(__strbuf)/2)); __i++) {\376 sprintf(__strbuf + (2 * __i), "%2.2hhx", __buf[__i]);\377 }\378 fd_log(printlevel, "%s%s%s", (prefix), __strbuf, (suffix));\379 }\390 391 392 /* Check the return value of a function and execute fallback in case of error or special value */ 393 #define CHECK_FCT_GEN2( faillevel, __call__, __speval__, __fallback1__, __fallback2__ ) { \ 394 CHECK_PRELUDE(__call__); \ 395 if (__ret__ != 0) { \ 396 if (__ret__ == (__speval__)) { \ 397 __fallback1__; \ 398 } else { \ 399 LOG(faillevel, "ERROR: in '%s' :\t%s", #__call__ , strerror(__ret__)); \ 400 __fallback2__; \ 401 } \ 402 } \ 380 403 } 381 #endif /* DEBUG */ 382 383 /* Some aliases to socket addresses structures */ 384 #define sSS struct sockaddr_storage 385 #define sSA struct sockaddr 386 #define sSA4 struct sockaddr_in 387 #define sSA6 struct sockaddr_in6 388 389 /* The sockaddr length of a sSS structure */ 390 #define sSAlen( _sa_ ) \ 391 ( (socklen_t) ( (((sSA *)_sa_)->sa_family == AF_INET) ? (sizeof(sSA4)) : \ 392 ((((sSA *)_sa_)->sa_family == AF_INET6) ? (sizeof(sSA6)) : \ 393 0 ) ) ) 394 395 /* Dump one sockaddr Node information */ 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 } \ 404 405 /* Check the return value of a function and execute fallback in case of error (return value different from 0) */ 406 #define CHECK_FCT_GEN( faillevel, __call__, __fallback__) \ 407 CHECK_FCT_GEN2( faillevel, (__call__), 0, , (__fallback__) ) 408 409 /* Check that a memory allocator did not return NULL, otherwise log an error and execute fallback */ 410 #define CHECK_MALLOC_GEN( faillevel, __call__, __fallback__ ) { \ 411 void * __ptr__; \ 412 TRACE_CALL("Check: %s", #__call__ ); \ 413 __ptr__ = (void *)(__call__); \ 414 if (__ptr__ == NULL) { \ 415 int __ret__ = errno; \ 416 LOG(faillevel, "ERROR: in '%s' :\t%s", #__call__ , strerror(__ret__)); \ 417 __fallback__; \ 418 } \ 414 419 } 415 /* Same but with the port (service) also */ 416 #define sSA_DUMP_NODE_SERV( buf, bufsize, sa, flag ) { \ 417 sSA * __sa = (sSA *)(sa); \ 418 char __addrbuf[INET6_ADDRSTRLEN]; \ 419 char __servbuf[32]; \ 420 if (__sa) { \ 421 int __rc = getnameinfo(__sa, \ 422 sSAlen(__sa), \ 423 __addrbuf, \ 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 } \ 420 421 /* Check parameters at function entry, execute fallback on error */ 422 #define CHECK_PARAMS_GEN( faillevel, __bool__, __fallback__ ) { \ 423 TRACE_CALL("Check: %s", #__bool__ ); \ 424 if ( ! (__bool__) ) { \ 425 int __ret__ = EINVAL; \ 426 LOG(faillevel, "ERROR: invalid parameter '%s'", #__bool__ ); \ 427 __fallback__; \ 428 } \ 435 429 } 436 430 437 #ifdef DEBUG 438 /* In DEBUG mode, we add (a lot of) meta-information along each trace. This makes multi-threading problems easier to debug. */ 439 #define TRACE_sSA(printlevel, level, prefix, sa, flags, suffix ) { \ 440 if ( TRACE_BOOL(level) ) { \ 441 char __buf[1024]; \ 442 char * __thn = ((char *)pthread_getspecific(fd_log_thname) ?: "unnamed"); \ 443 sSA_DUMP_NODE_SERV(__buf, sizeof(__buf), sa, flags ); \ 444 fd_log(printlevel, STD_TRACE_FMT_STRING "%s%s%s" , \ 445 __thn, __PRETTY_FUNCTION__, __STRIPPED_FILE__, __LINE__, (prefix), __buf, (suffix)); \ 446 } \ 431 432 /*============================================================*/ 433 /* COMPATIBILITY MACROS, TO BE REMOVED */ 434 /*============================================================*/ 435 /* Redefine the old macros for transition of the code */ 436 #ifndef EXCLUDE_DEPRECATED 437 438 #define MARK_DEPRECATED /* __attribute__ ((deprecated)) */ 439 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 */ 449 /* Do not print thread, function, ... only the message itself in this case */ 450 #define TRACE_sSA(printlevel, level, prefix, sa, flags, suffix ) { \ 451 if ( TRACE_BOOL(level) ) { \ 452 char __buf[1024]; \ 453 sSA_DUMP_NODE_SERV(__buf, sizeof(__buf), sa, flags ); \ 454 fd_log(printlevel, "%s%s%s" , (prefix), __buf, (suffix)); \ 455 } \ 455 456 static __inline__ void fd_log_deprecated( int level, const char *format, ... ) MARK_DEPRECATED 457 { 458 va_list ap; 459 va_start(ap, format); 460 fd_log_va(level, format, ap); 461 va_end(ap); 456 462 } 457 #endif /* DEBUG */ 458 459 /****************** 460 Optimized code: remove all debugging code 461 **/ 463 static __inline__ void replace_me() MARK_DEPRECATED { } 464 465 #define TRACE_sSA(...) replace_me(); 466 #define sSA_DUMP_NODE_SERV(...) replace_me(); 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 556 #ifdef STRIP_DEBUG_CODE 463 #undef TRACE_DEBUG 464 #undef TRACE_NOTICE 465 #undef TRACE_ERROR 466 #undef TRACE_BOOL 467 #undef TRACE_BUFFER 468 #undef TRACE_sSA 469 470 #define TRACE_DEBUG(level,format,args... ) /* noop */ 471 #define TRACE_BOOL(_level_) (0) /* always false */ 472 #define TRACE_NOTICE fd_log_notice 473 #define TRACE_ERROR fd_log_error 474 #define TRACE_BUFFER(printlevel, level, prefix, buf, bufsz, suffix ) { \ 557 #undef LOG_D 558 #undef LOG_N 559 #undef LOG_E 560 #undef LOG_F 561 #undef LOG_BUFFER 562 563 #define LOG_D(format,args... ) /* noop */ 564 #define LOG_N(format,args...) fd_log(FD_LOG_NOTICE, format, ## args) 565 #define LOG_E(format,args...) fd_log(FD_LOG_ERROR, format, ## args) 566 #define LOG_F(format,args...) fd_log(FD_LOG_FATAL, format, ## args) 567 #define LOG_BUFFER(printlevel, level, prefix, buf, bufsz, suffix ) { \ 475 568 if (printlevel > FD_LOG_DEBUG) { \ 476 569 int __i; \ … … 483 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 578 #endif /* STRIP_DEBUG_CODE */ 492 579 493 494 /*============================================================*/ 495 /* ERROR CHECKING MACRO */ 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 580 /*============================================================*/ 581 /* OTHER MACROS */ 582 /*============================================================*/ 601 583 /* helper macros (pre-processor hacks to allow macro arguments) */ 602 584 #define __tostr( arg ) #arg … … 604 586 #define __agr( arg1, arg2 ) arg1 ## arg2 605 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 … … 984 981 985 982 /* Debug functions */ 986 void fd_dict_dump_object(struct dict_object * obj);987 void fd_dict_dump(struct dictionary * dict);983 DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump_object, struct dict_object * obj); 984 DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump, struct dictionary * dict); 988 985 989 986 /* Function to access full contents of the dictionary, see doc in dictionary.c */ … … 1223 1220 dict_avpdata_interpret type_interpret;/* cb to convert the AVP value in more comprehensive format (or NULL) */ 1224 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 … … 1240 1237 int fd_dictfct_Address_encode(void * data, union avp_value * avp_value); 1241 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 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 1244 /* For Time AVPs, map with time_t value directly */ 1248 1245 int fd_dictfct_Time_encode(void * data, union avp_value * avp_value); 1249 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 … … 1822 1819 typedef void session_state; 1823 1820 1821 typedef DECLARE_FD_DUMP_PROTOTYPE(session_state_dump, session_state * st); 1822 1824 1823 /* The following function must be called to activate the session expiry mechanism */ 1825 1824 int fd_sess_start(void); … … 1831 1830 * handler : location where the new handler must be stored. 1832 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 1833 * opaque : A pointer that is passed to the cleanup callback -- the content is never examined by the framework. 1834 1834 * … … 1843 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 1846 /* Macro to avoid casting everywhere */ 1847 #define fd_sess_handler_create( _handler, _cleanup, _ opaque ) \1848 fd_sess_handler_create_internal( (_handler), (void (*)(session_state *, os0_t, void *))(_cleanup), (void *)(_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), _dumper, (void *)(_opaque) ) 1849 1849 1850 1850 … … 2046 2046 2047 2047 /* For debug */ 2048 void fd_sess_dump(int level, struct session * session);2049 void fd_sess_dump_hdl(int level, struct session_handler * handler);2048 DECLARE_FD_DUMP_PROTOTYPE(fd_sess_dump, struct session * session, int with_states); 2049 DECLARE_FD_DUMP_PROTOTYPE(fd_sess_dump_hdl, struct session_handler * handler); 2050 2050 2051 2051 /* For statistics / monitoring: get the number of struct session in memory */ … … 2328 2328 * 2329 2329 * PARAMETERS: 2330 * level : the log level (INFO, FULL, ...) at which the object is dumped 2331 * obj : A msg or avp object. 2332 * 2333 * DESCRIPTION: 2334 * These functions dump the content of a message to the debug log 2330 * see definition of DECLARE_FD_DUMP_PROTOTYPE, 2331 * obj : A msg or avp object to dump. 2332 * dict : the dictionary to use if parsing is requested (optional) 2333 * force_parsing: by default these functions do not parse the object but dump hexa values in that case. 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 2339 * either recursively or only the object itself. 2336 2340 * 2337 2341 * RETURN VALUE: 2338 * - 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. 2342 * - see DECLARE_FD_DUMP_PROTOTYPE, 2350 2343 */ 2351 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 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 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 … … 3141 3134 3142 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 3139 #ifdef __cplusplus -
libfdcore/config.c
r1034 r1085 81 81 } 82 82 83 void fd_conf_dump()83 DECLARE_FD_DUMP_PROTOTYPE(fd_conf_dump) 84 84 { 85 if (!TRACE_BOOL(INFO)) 86 return; 87 88 fd_log_debug("-- Configuration :"); 89 fd_log_debug(" Debug trace level ...... : %+d", fd_g_debug_lvl); 90 fd_log_debug(" Configuration file ..... : %s", fd_g_config->cnf_file); 91 fd_log_debug(" Diameter Identity ...... : %s (l:%Zi)", fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len); 92 fd_log_debug(" Diameter Realm ......... : %s (l:%Zi)", fd_g_config->cnf_diamrlm, fd_g_config->cnf_diamrlm_len); 93 fd_log_debug(" Tc Timer ............... : %u", fd_g_config->cnf_timer_tc); 94 fd_log_debug(" Tw Timer ............... : %u", fd_g_config->cnf_timer_tw); 95 fd_log_debug(" Local port ............. : %hu", fd_g_config->cnf_port); 96 fd_log_debug(" Local secure port ...... : %hu", fd_g_config->cnf_port_tls); 97 fd_log_debug(" Number of SCTP streams . : %hu", fd_g_config->cnf_sctp_str); 98 fd_log_debug(" Number of server threads : %hu", fd_g_config->cnf_dispthr); 85 size_t o=0; 86 if (!offset) 87 offset = &o; 88 89 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{freeDiameter configuration}(@%p): \n", fd_g_config), return NULL); 90 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Default trace level .... : %+d\n", fd_g_debug_lvl), return NULL); 91 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Configuration file ..... : %s\n", fd_g_config->cnf_file), return NULL); 92 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Diameter Identity ...... : %s (l:%Zi)\n", fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len), return NULL); 93 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Diameter Realm ......... : %s (l:%Zi)\n", fd_g_config->cnf_diamrlm, fd_g_config->cnf_diamrlm_len), return NULL); 94 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Tc Timer ............... : %u\n", fd_g_config->cnf_timer_tc), return NULL); 95 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Tw Timer ............... : %u\n", fd_g_config->cnf_timer_tw), return NULL); 96 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local port ............. : %hu\n", fd_g_config->cnf_port), return NULL); 97 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local secure port ...... : %hu\n", fd_g_config->cnf_port_tls), return NULL); 98 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Number of SCTP streams . : %hu\n", fd_g_config->cnf_sctp_str), return NULL); 99 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Number of server threads : %hu\n", fd_g_config->cnf_dispthr), return NULL); 99 100 if (FD_IS_LIST_EMPTY(&fd_g_config->cnf_endpoints)) { 100 fd_log_debug(" Local endpoints ........ : Default (use all available)");101 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local endpoints ........ : Default (use all available)\n"), return NULL); 101 102 } else { 102 fd_log_debug(" Local endpoints ........ : ");103 fd_ep_dump( 29, &fd_g_config->cnf_endpoints);103 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local endpoints ........ : \n"), return NULL); 104 CHECK_MALLOC_DO( fd_ep_dump( FD_DUMP_STD_PARAMS, 29, &fd_g_config->cnf_endpoints ), return NULL); 104 105 } 105 106 if (FD_IS_LIST_EMPTY(&fd_g_config->cnf_apps)) { 106 fd_log_debug(" Local applications ..... : (none)");107 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local applications ..... : (none)\n"), return NULL); 107 108 } else { 108 109 struct fd_list * li = fd_g_config->cnf_apps.next; 109 fd_log_debug(" Local applications ..... : ");110 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Local applications ..... : \n"), return NULL); 110 111 while (li != &fd_g_config->cnf_apps) { 111 112 struct fd_app * app = (struct fd_app *)li; 112 if (li != fd_g_config->cnf_apps.next) fd_log_debug(" "); 113 fd_log_debug("App: %u\t%s%s\tVnd: %u", 113 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " App: %u\t%s%s\tVnd: %u\n", 114 114 app->appid, 115 115 app->flags.auth ? "Au" : "--", 116 116 app->flags.acct ? "Ac" : "--", 117 app->vndid) ;117 app->vndid), return NULL); 118 118 li = li->next; 119 119 } 120 120 } 121 121 122 fd_log_debug(" Flags : - IP ........... : %s", fd_g_config->cnf_flags.no_ip4 ? "DISABLED" : "Enabled");123 fd_log_debug(" - IPv6 ......... : %s", fd_g_config->cnf_flags.no_ip6 ? "DISABLED" : "Enabled");124 fd_log_debug(" - Relay app .... : %s", fd_g_config->cnf_flags.no_fwd ? "DISABLED" : "Enabled");125 fd_log_debug(" - TCP .......... : %s", fd_g_config->cnf_flags.no_tcp ? "DISABLED" : "Enabled");122 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Flags : - IP ........... : %s\n", fd_g_config->cnf_flags.no_ip4 ? "DISABLED" : "Enabled"), return NULL); 123 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - IPv6 ......... : %s\n", fd_g_config->cnf_flags.no_ip6 ? "DISABLED" : "Enabled"), return NULL); 124 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - Relay app .... : %s\n", fd_g_config->cnf_flags.no_fwd ? "DISABLED" : "Enabled"), return NULL); 125 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - TCP .......... : %s\n", fd_g_config->cnf_flags.no_tcp ? "DISABLED" : "Enabled"), return NULL); 126 126 #ifdef DISABLE_SCTP 127 fd_log_debug(" - SCTP ......... : DISABLED (at compilation)");127 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - SCTP ......... : DISABLED (at compilation)\n"), return NULL); 128 128 #else /* DISABLE_SCTP */ 129 fd_log_debug(" - SCTP ......... : %s", fd_g_config->cnf_flags.no_sctp ? "DISABLED" : "Enabled");129 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - SCTP ......... : %s\n", fd_g_config->cnf_flags.no_sctp ? "DISABLED" : "Enabled"), return NULL); 130 130 #endif /* DISABLE_SCTP */ 131 fd_log_debug(" - Pref. proto .. : %s", fd_g_config->cnf_flags.pr_tcp ? "TCP" : "SCTP"); 132 fd_log_debug(" - TLS method ... : %s", fd_g_config->cnf_flags.tls_alg ? "INBAND" : "Separate port"); 133 134 fd_log_debug(" TLS : - Certificate .. : %s", fd_g_config->cnf_sec_data.cert_file ?: "(NONE)"); 135 fd_log_debug(" - Private key .. : %s", fd_g_config->cnf_sec_data.key_file ?: "(NONE)"); 136 fd_log_debug(" - CA (trust) ... : %s (%d certs)", fd_g_config->cnf_sec_data.ca_file ?: "(none)", fd_g_config->cnf_sec_data.ca_file_nr); 137 fd_log_debug(" - CRL .......... : %s", fd_g_config->cnf_sec_data.crl_file ?: "(none)"); 138 fd_log_debug(" - Priority ..... : %s", fd_g_config->cnf_sec_data.prio_string ?: "(default: '" GNUTLS_DEFAULT_PRIORITY "')"); 139 if (fd_g_config->cnf_sec_data.dh_file) 140 fd_log_debug(" - DH file ...... : %s", fd_g_config->cnf_sec_data.dh_file); 141 else 142 fd_log_debug(" - DH bits ...... : %d", fd_g_config->cnf_sec_data.dh_bits ?: GNUTLS_DEFAULT_DHBITS); 143 144 fd_log_debug(" Origin-State-Id ........ : %u", fd_g_config->cnf_orstateid); 131 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - Pref. proto .. : %s\n", fd_g_config->cnf_flags.pr_tcp ? "TCP" : "SCTP"), return NULL); 132 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - TLS method ... : %s\n", fd_g_config->cnf_flags.tls_alg ? "INBAND" : "Separate port"), return NULL); 133 134 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " TLS : - Certificate .. : %s\n", fd_g_config->cnf_sec_data.cert_file ?: "(NONE)"), return NULL); 135 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - Private key .. : %s\n", fd_g_config->cnf_sec_data.key_file ?: "(NONE)"), return NULL); 136 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - CA (trust) ... : %s (%d certs)\n", fd_g_config->cnf_sec_data.ca_file ?: "(none)", fd_g_config->cnf_sec_data.ca_file_nr), return NULL); 137 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - CRL .......... : %s\n", fd_g_config->cnf_sec_data.crl_file ?: "(none)"), return NULL); 138 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - Priority ..... : %s\n", fd_g_config->cnf_sec_data.prio_string ?: "(default: '" GNUTLS_DEFAULT_PRIORITY "')"), return NULL); 139 if (fd_g_config->cnf_sec_data.dh_file) { 140 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - DH file ...... : %s\n", fd_g_config->cnf_sec_data.dh_file), return NULL); 141 } else { 142 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " - DH bits ...... : %d\n", fd_g_config->cnf_sec_data.dh_bits ?: GNUTLS_DEFAULT_DHBITS), return NULL); 143 } 144 145 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " Origin-State-Id ........ : %u", fd_g_config->cnf_orstateid), return NULL); 146 147 return *buf; 145 148 } 146 149 -
libfdcore/core.c
r1079 r1085 85 85 CHECK_FCT_DO( fd_event_get(fd_g_config->cnf_main_ev, &code, &sz, &data), break ); 86 86 switch (code) { 87 case FDEV_DUMP_DICT:88 fd_dict_dump(fd_g_config->cnf_dict);89 break;90 91 case FDEV_DUMP_EXT:92 fd_ext_dump();93 break;94 95 case FDEV_DUMP_SERV:96 fd_servers_dump();97 break;98 99 case FDEV_DUMP_QUEUES:100 fd_fifo_dump(0, "Incoming messages", fd_g_incoming, fd_msg_dump_walk);101 fd_fifo_dump(0, "Outgoing messages", fd_g_outgoing, fd_msg_dump_walk);102 fd_fifo_dump(0, "Local messages", fd_g_local, fd_msg_dump_walk);103 break;104 105 case FDEV_DUMP_CONFIG:106 fd_conf_dump();107 break;108 109 case FDEV_DUMP_PEERS:110 fd_peer_dump_list(FULL);111 break;112 113 87 case FDEV_TRIGGER: 114 88 { … … 182 156 } 183 157 184 TRACE_DEBUG(INFO,"libfdproto initialized.");158 LOG_D("libfdproto initialized."); 185 159 186 160 /* Name this thread */ … … 225 199 int fd_core_parseconf(const char * conffile) 226 200 { 201 char * buf = NULL, *b; 202 size_t len = 0, offset=0; 203 204 227 205 TRACE_ENTRY("%p", conffile); 228 206 … … 240 218 241 219 /* Display configuration */ 242 fd_conf_dump(); 220 b = fd_conf_dump(&buf, &len, NULL); 221 LOG_N("%s\n", b ?: "Error during configuration dump..."); 243 222 244 223 /* Display registered triggers for FDEV_TRIGGER */ 245 fd_event_trig_dump(); 246 224 b = fd_event_trig_dump(&buf, &len, &offset); 225 if (!b || offset) { 226 LOG_N("%s\n", b ?: "Error during triggers dump..."); 227 } 228 229 free(buf); 230 247 231 return 0; 248 232 } -
libfdcore/endpoints.c
r1033 r1085 58 58 } 59 59 60 if (TRACE_BOOL(ANNOYING + 1)) {61 char buf[1024];62 sSA_DUMP_NODE_SERV( buf, sizeof(buf), sa, NI_NUMERICHOST | NI_NUMERICSERV );63 TRACE_DEBUG(ANNOYING, " DEBUG:fd_ep_add_merge Current list:");64 fd_ep_dump( 4, list );65 TRACE_DEBUG(ANNOYING, " DEBUG:fd_ep_add_merge Adding:");66 fd_log_debug(" %s {%s%s%s%s%s}", buf,67 (flags & EP_FL_CONF) ? "C" : "-",68 (flags & EP_FL_DISC) ? "D" : "-",69 (flags & EP_FL_ADV) ? "A" : "-",70 (flags & EP_FL_LL) ? "L" : "-",71 (flags & EP_FL_PRIMARY) ? "P" : "-");72 }73 60 ptr.sa = sa; 74 61 … … 82 69 || ((ntohl(ptr.sin->sin_addr.s_addr) & 0xe0000000) == 0xe0000000) 83 70 || (ptr.sin->sin_addr.s_addr == INADDR_BROADCAST)) { 84 if (TRACE_BOOL(ANNOYING + 1)) { 85 TRACE_DEBUG(ANNOYING, " DEBUG:fd_ep_add_merge Address was ignored, not added."); 86 } 71 LOG_A(" DEBUG:fd_ep_add_merge Address was ignored, not added."); 87 72 return 0; 88 73 } … … 98 83 || IN6_IS_ADDR_LINKLOCAL(&ptr.sin6->sin6_addr) 99 84 || IN6_IS_ADDR_SITELOCAL(&ptr.sin6->sin6_addr)) { 100 if (TRACE_BOOL(ANNOYING + 1)) { 101 TRACE_DEBUG(ANNOYING, " DEBUG:fd_ep_add_merge Address was ignored, not added."); 102 } 85 LOG_A(" DEBUG:fd_ep_add_merge Address was ignored, not added."); 103 86 return 0; 104 87 } … … 108 91 109 92 default: 110 if (TRACE_BOOL(ANNOYING + 1)) { 111 TRACE_DEBUG(ANNOYING, " DEBUG:fd_ep_add_merge Address family was unknown, not added."); 112 } 93 LOG_A(" DEBUG:fd_ep_add_merge Address family was unknown, not added."); 113 94 return 0; 114 95 } … … 175 156 ep->flags |= flags; 176 157 177 if (TRACE_BOOL(ANNOYING + 1)) {178 TRACE_DEBUG(ANNOYING, " DEBUG:fd_ep_add_merge New list:");179 fd_ep_dump( 4, list );180 }181 158 return 0; 182 159 } … … 190 167 CHECK_PARAMS(list); 191 168 192 if (TRACE_BOOL(ANNOYING + 1)) {193 TRACE_DEBUG(ANNOYING, " DEBUG:fd_ep_filter Filter this list for flags %x:", flags);194 fd_ep_dump( 4, list );195 }196 169 for (li = list->next; li != list; li = li->next) { 197 170 struct fd_endpoint * ep = (struct fd_endpoint *)li; … … 204 177 } 205 178 206 if (TRACE_BOOL(ANNOYING + 1)) {207 TRACE_DEBUG(ANNOYING, " DEBUG:fd_ep_filter Resulting list:");208 fd_ep_dump( 4, list );209 }210 179 return 0; 211 180 } … … 219 188 CHECK_PARAMS(list); 220 189 221 if (TRACE_BOOL(ANNOYING + 1)) {222 TRACE_DEBUG(ANNOYING, " DEBUG:fd_ep_filter_family Filter this list for family %d:", af);223 fd_ep_dump( 4, list );224 }225 190 for (li = list->next; li != list; li = li->next) { 226 191 struct fd_endpoint * ep = (struct fd_endpoint *)li; … … 233 198 } 234 199 235 if (TRACE_BOOL(ANNOYING + 1)) {236 TRACE_DEBUG(ANNOYING, " DEBUG:fd_ep_filter_family Resulting list:");237 fd_ep_dump( 4, list );238 }239 200 return 0; 240 201 } … … 253 214 li_ex = exclude_list->next; 254 215 255 if (TRACE_BOOL(ANNOYING + 1)) {256 TRACE_DEBUG(ANNOYING, " DEBUG:fd_ep_filter_list Filter this list ");257 fd_ep_dump( 4, list );258 TRACE_DEBUG(ANNOYING, " DEBUG:fd_ep_filter_list Removing from list");259 fd_ep_dump( 6, exclude_list );260 }261 216 /* Now browse both lists in parallel */ 262 217 while ((li_out != list) && (li_ex != exclude_list)) { … … 304 259 } 305 260 306 if (TRACE_BOOL(ANNOYING + 1)) {307 TRACE_DEBUG(ANNOYING, " DEBUG:fd_ep_filter_list Resulting list:");308 fd_ep_dump( 4, list );309 }310 261 return 0; 311 262 … … 334 285 } 335 286 336 void fd_ep_dump_one( char * prefix, struct fd_endpoint * ep ) 337 { 338 char buf[1024]; 339 340 sSA_DUMP_NODE_SERV( buf, sizeof(buf), &ep->sa, NI_NUMERICHOST | NI_NUMERICSERV ); 341 fd_log_debug("%s%s {%s%s%s%s}%s", prefix ?: "", buf, 287 DECLARE_FD_DUMP_PROTOTYPE(fd_ep_dump_one, struct fd_endpoint * ep ) 288 { 289 size_t o = 0; 290 if (!offset) 291 offset=&o; 292 293 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{ep}(@%p): ", ep), return NULL); 294 295 if (!ep) { 296 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL\n"), return NULL); 297 return *buf; 298 } 299 300 CHECK_MALLOC_DO( fd_sa_dump_node_serv( FD_DUMP_STD_PARAMS, &ep->sa, NI_NUMERICHOST | NI_NUMERICSERV ), return NULL); 301 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {%s%s%s%s%s}", 342 302 (ep->flags & EP_FL_CONF) ? "C" : "-", 343 303 (ep->flags & EP_FL_DISC) ? "D" : "-", 344 304 (ep->flags & EP_FL_ADV) ? "A" : "-", 345 305 (ep->flags & EP_FL_LL) ? "L" : "-", 346 (ep->flags & EP_FL_PRIMARY) ? "P" : "-"); 347 } 348 349 void fd_ep_dump( int indent, struct fd_list * eps ) 350 { 351 struct fd_list * li; 352 for (li = eps->next; li != eps; li = li->next) { 353 struct fd_endpoint * ep = (struct fd_endpoint *)li; 354 fd_log_debug("%*s", indent, ""); 355 fd_ep_dump_one( NULL, ep ); 356 } 357 } 358 306 (ep->flags & EP_FL_PRIMARY) ? "P" : "-"), return NULL); 307 return *buf; 308 } 309 310 DECLARE_FD_DUMP_PROTOTYPE(fd_ep_dump, int indent, struct fd_list * eps ) 311 { 312 struct fd_list * li; 313 size_t o = 0; 314 if (!offset) 315 offset=&o; 316 317 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*s{eps}(@%p):\n", indent, "", eps), return NULL); 318 if (eps) { 319 for (li = eps->next; li != eps; li = li->next) { 320 struct fd_endpoint * ep = (struct fd_endpoint *)li; 321 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*s", indent+1, ""), return NULL); 322 CHECK_MALLOC_DO( fd_ep_dump_one( FD_DUMP_STD_PARAMS, ep ), return NULL); 323 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n"), return NULL); 324 } 325 } 326 } 327 -
libfdcore/events.c
r974 r1085 106 106 case _val : return #_val 107 107 case_str(FDEV_TERMINATE); 108 case_str(FDEV_DUMP_DICT);109 case_str(FDEV_DUMP_EXT);110 case_str(FDEV_DUMP_SERV);111 case_str(FDEV_DUMP_QUEUES);112 case_str(FDEV_DUMP_CONFIG);113 case_str(FDEV_DUMP_PEERS);114 108 case_str(FDEV_TRIGGER); 115 109 … … 168 162 } 169 163 170 void fd_event_trig_dump()164 DECLARE_FD_DUMP_PROTOTYPE(fd_event_trig_dump) 171 165 { 172 166 struct fd_list * li; 173 if (!TRACE_BOOL(FULL)) 174 return; 167 size_t o=0; 168 if (!offset) 169 offset=&o; 175 170 176 171 CHECK_POSIX_DO( pthread_rwlock_rdlock(&trig_rwl), ); … … 178 173 for (li = trig_list.next; li != &trig_list; li = li->next) { 179 174 struct trig_item *t = li->o; 180 fd_log_debug(" Trigger %d, module '%s': %p", t->trig_value, t->trig_module, t->cb);175 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{trigger sig:%d}'%s'->%p ", t->trig_value, t->trig_module, t->cb), break); 181 176 } 182 177 183 178 CHECK_POSIX_DO( pthread_rwlock_unlock(&trig_rwl), ); 179 return *buf; 184 180 } 185 181 -
libfdcore/extensions.c
r1006 r1085 78 78 79 79 /* Dump the list */ 80 void fd_ext_dump(void)80 DECLARE_FD_DUMP_PROTOTYPE(fd_ext_dump) 81 81 { 82 82 struct fd_list * li; 83 84 fd_log_debug("Dumping extensions list :"); 83 size_t o=0; 84 if (!offset) 85 offset = &o; 85 86 86 87 for (li = ext_list.next; li != &ext_list; li = li->next) 87 88 { 88 89 struct fd_ext_info * ext = (struct fd_ext_info *)li; 89 fd_log_debug(" - '%s'[%s] is %sloaded", ext->filename, ext->conffile?:"no conf", ext->handler ? "" : "not "); 90 } 90 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{extension}(@%p): '%s'[%s], %sloaded\n", ext, ext->filename, ext->conffile?:"no conf", ext->handler ? "" : "not "), return NULL); 91 } 92 return *buf; 91 93 } 92 94 -
libfdcore/fdcore-internal.h
r1016 r1085 86 86 int fd_conf_init(); 87 87 int fd_conf_deinit(); 88 void fd_conf_dump();89 88 int fd_conf_parse(); 90 89 int fddparse(struct fd_config * conf); /* yacc generated */ … … 95 94 int fd_ext_add( char * filename, char * conffile ); 96 95 int fd_ext_load(); 97 void fd_ext_dump(void);98 96 int fd_ext_term(void); 99 97 … … 218 216 /* Events codespace for struct fd_peer->p_events */ 219 217 enum { 220 /* Dump all info about this peer in the debug log */221 FDEVP_DUMP_ALL = 1500222 223 218 /* request to terminate this peer : disconnect, requeue all messages */ 224 ,FDEVP_TERMINATE219 FDEVP_TERMINATE = 1500 225 220 226 221 /* A connection object has received a message. (data contains the buffer + struct timespec piggytailed -- unaligned) */ … … 250 245 }; 251 246 #define CHECK_PEVENT( _e ) \ 252 (((int)(_e) >= FDEVP_ DUMP_ALL) && ((int)(_e) <= FDEVP_PSM_TIMEOUT))247 (((int)(_e) >= FDEVP_TERMINATE) && ((int)(_e) <= FDEVP_PSM_TIMEOUT)) 253 248 /* The following macro is actually called in p_psm.c -- another solution would be to declare it static inline */ 254 249 #define DECLARE_PEV_STR() \ … … 256 251 { \ 257 252 switch (event) { \ 258 case_str(FDEVP_DUMP_ALL); \259 253 case_str(FDEVP_TERMINATE); \ 260 254 case_str(FDEVP_CNX_MSG_RECV); \ … … 281 275 /* Functions */ 282 276 int fd_peer_fini(); 283 void fd_peer_dump_list(int details);284 void fd_peer_dump(struct fd_peer * peer, int details);285 277 int fd_peer_alloc(struct fd_peer ** ptr); 286 278 int fd_peer_free(struct fd_peer ** ptr); … … 339 331 340 332 /* Server sockets */ 341 void fd_servers_dump();342 333 int fd_servers_start(); 343 334 int fd_servers_stop(); -
libfdcore/p_psm.c
r1078 r1085 454 454 } 455 455 456 /* Handle the (easy) debug event now */457 if (event == FDEVP_DUMP_ALL) {458 fd_peer_dump(peer, ANNOYING);459 goto psm_loop;460 }461 462 456 /* Requests to terminate the peer object */ 463 457 if (event == FDEVP_TERMINATE) { … … 712 706 CHECK_FCT_DO( fd_cnx_getremoteeps(peer->p_cnxctx, &peer->p_hdr.info.pi_endpoints), /* ignore the error */); 713 707 714 /* We do not support local endpoints change currently, but it could be added here if needed (refresh fd_g_config->cnf_endpoints)*/ 715 716 if (TRACE_BOOL(ANNOYING)) { 717 TRACE_DEBUG(ANNOYING, "New remote endpoint(s):" ); 718 fd_ep_dump(6, &peer->p_hdr.info.pi_endpoints); 708 /* We do not support local endpoints change currently, but it could be added here if needed (refresh fd_g_config->cnf_endpoints) */ 709 { 710 char * buf = NULL; 711 size_t len = 0; 712 LOG_D("New remote endpoint(s): %s", fd_ep_dump(&buf, &len, NULL, 6, &peer->p_hdr.info.pi_endpoints) ?: "error"); 713 free(buf); 719 714 } 720 715 -
libfdcore/peers.c
r1078 r1085 410 410 411 411 /* Dump info of one peer */ 412 void fd_peer_dump(struct fd_peer * peer, int details) 413 { 414 char buf[1024]; 415 if (peer->p_eyec != EYEC_PEER) { 416 fd_log_debug(" Invalid peer @ %p !", peer); 417 return; 418 } 419 420 snprintf(buf, sizeof(buf), "> %s\t%s\t[%ldsr,%ldpa]", STATE_STR(fd_peer_getstate(peer)), peer->p_hdr.info.pi_diamid, peer->p_sr.cnt, peer->p_reqin_count); 421 if (details > INFO) { 422 snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "\t(rlm:%s)", peer->p_hdr.info.runtime.pir_realm ?: "<unknown>"); 423 if (peer->p_hdr.info.runtime.pir_prodname) 424 snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "\t['%s' %u]", peer->p_hdr.info.runtime.pir_prodname, peer->p_hdr.info.runtime.pir_firmrev); 425 } 426 fd_log_debug("%s", buf); 427 if (details > FULL) { 428 /* Dump all info */ 429 fd_log_debug("\tEntry origin : %s", peer->p_dbgorig?: "not set"); 430 fd_log_debug("\tConfig flags : %s%s%s - %s%s - %s%s", 431 peer->p_hdr.info.config.pic_flags.pro3 == PI_P3_DEFAULT ? "." : 432 (peer->p_hdr.info.config.pic_flags.pro3 == PI_P3_IP ? "IP" : "IPv6"), 433 peer->p_hdr.info.config.pic_flags.pro4 == PI_P4_DEFAULT ? "." : 434 (peer->p_hdr.info.config.pic_flags.pro4 == PI_P4_TCP ? "TCP" : "SCTP"), 435 peer->p_hdr.info.config.pic_flags.alg ? "PrefTCP" : ".", 436 peer->p_hdr.info.config.pic_flags.sec & PI_SEC_NONE ? "NoTLSok" :".", 437 peer->p_hdr.info.config.pic_flags.sec & PI_SEC_TLS_OLD ? "OldTLS" :".", 438 peer->p_hdr.info.config.pic_flags.exp ? "Expire" : ".", 439 peer->p_hdr.info.config.pic_flags.persist ? "Persist" : "." 440 ); 441 fd_log_debug("\tLifetime : %d sec", peer->p_hdr.info.config.pic_lft); 442 } 412 DECLARE_FD_DUMP_PROTOTYPE(fd_peer_dump, struct peer_hdr * p, int details) 413 { 414 size_t o=0; 415 if (!offset) 416 offset = &o; 417 418 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{peer}(@%p): ", p), return NULL); 419 420 if (!CHECK_PEER(p)) { 421 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL"), return NULL); 422 } else { 423 struct fd_peer * peer = (struct fd_peer *)p; 424 425 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s [%s, cnt:%ldsr,%ldpa]", peer->p_hdr.info.pi_diamid, STATE_STR(fd_peer_getstate(peer)), peer->p_sr.cnt, peer->p_reqin_count), return NULL); 426 if (details > 0) { 427 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " rlm:%s", peer->p_hdr.info.runtime.pir_realm ?: "<unknown>"), return NULL); 428 if (peer->p_hdr.info.runtime.pir_prodname) { 429 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " ['%s' %u]", peer->p_hdr.info.runtime.pir_prodname, peer->p_hdr.info.runtime.pir_firmrev), return NULL); 430 } 431 } 432 if (details > 1) { 433 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " [from:%s] flags:%s%s%s%s%s%s%s lft:%ds", 434 peer->p_dbgorig ?: "unset", 435 peer->p_hdr.info.config.pic_flags.pro3 == PI_P3_DEFAULT ? "-" : 436 (peer->p_hdr.info.config.pic_flags.pro3 == PI_P3_IP ? "4" : "6"), 437 peer->p_hdr.info.config.pic_flags.pro4 == PI_P4_DEFAULT ? "-" : 438 (peer->p_hdr.info.config.pic_flags.pro4 == PI_P4_TCP ? "T" : "S"), 439 peer->p_hdr.info.config.pic_flags.alg ? "P" : "-", 440 peer->p_hdr.info.config.pic_flags.sec & PI_SEC_NONE ? "N" :"-", 441 peer->p_hdr.info.config.pic_flags.sec & PI_SEC_TLS_OLD ? "O" :"-", 442 peer->p_hdr.info.config.pic_flags.exp ? "E" : "-", 443 peer->p_hdr.info.config.pic_flags.persist ? "P" : "-", 444 peer->p_hdr.info.config.pic_lft), return NULL); 445 } 446 447 } 448 449 return *buf; 443 450 } 444 451 445 452 /* Dump the list of peers */ 446 void fd_peer_dump_list(int details)453 DECLARE_FD_DUMP_PROTOTYPE(fd_peer_dump_list, int details) 447 454 { 448 455 struct fd_list * li; 449 450 fd_log_debug("Dumping list of peers :"); 456 size_t o=0; 457 if (!offset) 458 offset = &o; 459 451 460 CHECK_FCT_DO( pthread_rwlock_rdlock(&fd_g_peers_rw), /* continue */ ); 452 461 453 462 for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { 454 struct fd_peer * np = (struct fd_peer *)li->o;455 fd_peer_dump(np, details);463 CHECK_MALLOC_DO( fd_peer_dump(FD_DUMP_STD_PARAMS, (struct peer_hdr *)li->o, details), break); 464 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n"), break); 456 465 } 457 466 458 467 CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), /* continue */ ); 468 return *buf; 459 469 } 460 470 -
libfdcore/server.c
r1078 r1085 94 94 95 95 /* Dump all servers information */ 96 void fd_servers_dump()96 DECLARE_FD_DUMP_PROTOTYPE(fd_servers_dump) 97 97 { 98 98 struct fd_list * li, *cli; 99 100 fd_log_debug("Dumping servers list :"); 99 size_t o=0; 100 if (!offset) 101 offset = &o; 102 101 103 for (li = FD_SERVERS.next; li != &FD_SERVERS; li = li->next) { 102 104 struct server * s = (struct server *)li; 103 105 enum s_state st = get_status(s); 104 fd_log_debug(" Serv %p '%s': %s, %s, %s",105 106 107 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{server}(@%p)'%s': %s, %s, %s\n", s, fd_cnx_getid(s->conn), 106 108 IPPROTO_NAME( s->proto ), 107 109 s->secur ? "Secur" : "NotSecur", … … 109 111 ((st == RUNNING) ? "Thread running" : 110 112 ((st == TERMINATED) ? "Thread terminated" : 111 "Thread status unknown"))) ;113 "Thread status unknown"))), return NULL); 112 114 /* Dump the client list of this server */ 113 115 CHECK_POSIX_DO( pthread_mutex_lock(&s->clients_mtx), ); … … 115 117 struct client * c = (struct client *)cli; 116 118 char bufts[128]; 117 fd_log_debug(" Connected: '%s' (timeout: %s)", 118 fd_cnx_getid(c->conn), 119 fd_log_time(&c->ts, bufts, sizeof(bufts))); 119 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {client}(@%p)'%s': to:%s\n", c, fd_cnx_getid(c->conn), fd_log_time(&c->ts, bufts, sizeof(bufts))), break); 120 120 } 121 121 CHECK_POSIX_DO( pthread_mutex_unlock(&s->clients_mtx), ); 122 122 } 123 124 return *buf; 123 125 } 124 126 … … 393 395 } 394 396 } 395 if (TRACE_BOOL(FULL)){ 396 fd_log_debug(" Local server address(es) :"); 397 fd_ep_dump( 5, &fd_g_config->cnf_endpoints ); 397 398 { 399 char * buf = NULL; 400 size_t len = 0, offset = 0; 401 CHECK_MALLOC_DO( fd_dump_extend( &buf, &len, &offset , "Local server address(es): "), ); 402 CHECK_MALLOC_DO( fd_ep_dump( &buf, &len, &offset, 5, &fd_g_config->cnf_endpoints ), ); 403 LOG_N("%s", buf ?: "Error dumping addresses"); 404 free(buf); 398 405 } 399 406 return 0; -
libfdcore/tcp.c
r965 r1085 124 124 int ret = 0; 125 125 int s; 126 char * buf = NULL; size_t len = 0; 126 127 127 128 TRACE_ENTRY("%p %p %d", sock, sa, salen); … … 137 138 pthread_cleanup_push(fd_cleanup_socket, &s); 138 139 139 TRACE_sSA(FD_LOG_DEBUG, FULL, "Attempting TCP connection with peer: ", sa, NI_NUMERICHOST | NI_NUMERICSERV, "..." ); 140 LOG_D( "Attempting TCP connection to %s...", fd_sa_dump_node(&buf, &len, NULL, sa, NI_NUMERICHOST | NI_NUMERICSERV)?:"<error>" ); 141 free(buf); 140 142 141 143 /* Try connecting to the remote address */ -
libfdproto/dictionary.c
r1052 r1085 148 148 149 149 /* Forward declarations of dump functions */ 150 static void dump_vendor_data (void * data );151 static void dump_application_data (void * data );152 static void dump_type_data (void * data );150 static DECLARE_FD_DUMP_PROTOTYPE(dump_vendor_data, void * data ); 151 static DECLARE_FD_DUMP_PROTOTYPE(dump_application_data, void * data ); 152 static DECLARE_FD_DUMP_PROTOTYPE(dump_type_data, void * data ); 153 153 /* the dump function for enum has a different prototype since it need the datatype */ 154 static void dump_avp_data (void * data );155 static void dump_command_data (void * data );156 static void dump_rule_data (void * data );154 static DECLARE_FD_DUMP_PROTOTYPE(dump_avp_data, void * data ); 155 static DECLARE_FD_DUMP_PROTOTYPE(dump_command_data, void * data ); 156 static DECLARE_FD_DUMP_PROTOTYPE(dump_rule_data, void * data ); 157 157 158 158 /* Forward declarations of search functions */ … … 173 173 enum dict_object_type parenttype; /* The type of the parent, when relevant */ 174 174 int eyecatcher; /* A kind of signature for this object */ 175 void (*dump_data)(void * data ); /* The function to dump the data section */175 DECLARE_FD_DUMP_PROTOTYPE( (*dump_data), void * data ); /* The function to dump the data section */ 176 176 int (*search_fct)(struct dictionary * dict, int criteria, const void * what, struct dict_object **result );; /* The function to search an object of this type */ 177 177 int haslist[NB_LISTS_PER_OBJ]; /* Tell if this list is used */ … … 1150 1150 /*******************************************************************************************************/ 1151 1151 /* The following functions are used to debug the module, and allow to print out the content of the dictionary */ 1152 static void dump_vendor_data (void * data )1152 static DECLARE_FD_DUMP_PROTOTYPE(dump_vendor_data, void * data ) 1153 1153 { 1154 1154 struct dict_vendor_data * vendor = (struct dict_vendor_data *)data; 1155 1155 1156 fd_log_debug("data: %-6u \"%s\"", vendor->vendor_id, vendor->vendor_name);1157 } 1158 static void dump_application_data (void * data )1156 return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: %-6u \"%s\"", vendor->vendor_id, vendor->vendor_name); 1157 } 1158 static DECLARE_FD_DUMP_PROTOTYPE(dump_application_data, void * data ) 1159 1159 { 1160 1160 struct dict_application_data * appli = (struct dict_application_data *) data; 1161 fd_log_debug("data: %-6u \"%s\"", appli->application_id, appli->application_name);1162 } 1163 static void dump_type_data (void * data )1161 return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: %-6u \"%s\"", appli->application_id, appli->application_name); 1162 } 1163 static DECLARE_FD_DUMP_PROTOTYPE(dump_type_data, void * data ) 1164 1164 { 1165 1165 struct dict_type_data * type = ( struct dict_type_data * ) data; 1166 1166 1167 fd_log_debug("data: %-12s \"%s\"",1167 return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: %-12s \"%s\"", 1168 1168 type_base_name[type->type_base], 1169 1169 type->type_name); 1170 1170 } 1171 static void dump_enumval_data (struct dict_enumval_data * enumval, enum dict_avp_basetype type )1171 static DECLARE_FD_DUMP_PROTOTYPE(dump_enumval_data, struct dict_enumval_data * enumval, enum dict_avp_basetype type ) 1172 1172 { 1173 1173 const int LEN_MAX = 20; 1174 fd_log_debug("data: (%-12s) \"%s\" -> ", type_base_name[type], enumval->enum_name);1174 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "data: (%-12s) \"%s\" -> ", type_base_name[type], enumval->enum_name), return NULL); 1175 1175 switch (type) { 1176 1176 case AVP_TYPE_OCTETSTRING: … … 1180 1180 n = enumval->enum_value.os.len; 1181 1181 for (i=0; i < n; i++) 1182 fd_log_debug("0x%2hhX/'%c' ", enumval->enum_value.os.data[i], ASCII(enumval->enum_value.os.data[i]));1182 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "0x%2hhX/'%c' ", enumval->enum_value.os.data[i], ASCII(enumval->enum_value.os.data[i])), return NULL); 1183 1183 if (n == LEN_MAX) 1184 fd_log_debug("...");1184 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "..."), return NULL); 1185 1185 } 1186 1186 break; 1187 1187 1188 1188 case AVP_TYPE_INTEGER32: 1189 fd_log_debug("%i", enumval->enum_value.i32);1189 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%i", enumval->enum_value.i32), return NULL); 1190 1190 break; 1191 1191 1192 1192 case AVP_TYPE_INTEGER64: 1193 fd_log_debug("%"PRId64, enumval->enum_value.i64);1193 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%"PRId64, enumval->enum_value.i64), return NULL); 1194 1194 break; 1195 1195 1196 1196 case AVP_TYPE_UNSIGNED32: 1197 fd_log_debug("%u", enumval->enum_value.u32);1197 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%u", enumval->enum_value.u32), return NULL); 1198 1198 break; 1199 1199 1200 1200 case AVP_TYPE_UNSIGNED64: 1201 fd_log_debug("%"PRIu64, enumval->enum_value.u64);1201 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%"PRIu64, enumval->enum_value.u64), return NULL); 1202 1202 break; 1203 1203 1204 1204 case AVP_TYPE_FLOAT32: 1205 fd_log_debug("%f", enumval->enum_value.f32);1205 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%f", enumval->enum_value.f32), return NULL); 1206 1206 break; 1207 1207 1208 1208 case AVP_TYPE_FLOAT64: 1209 fd_log_debug("%g", enumval->enum_value.f64);1209 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%g", enumval->enum_value.f64), return NULL); 1210 1210 break; 1211 1211 1212 1212 default: 1213 fd_log_debug("??? (ERROR unknown type %d)", type); 1214 } 1215 } 1216 static void dump_avp_data ( void * data ) 1213 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "??? (ERROR unknown type %d)", type), return NULL); 1214 } 1215 return *buf; 1216 } 1217 static DECLARE_FD_DUMP_PROTOTYPE(dump_avp_data, void * data ) 1217 1218 { 1218 1219 struct dict_avp_data * avp = (struct dict_avp_data * ) data; 1219 fd_log_debug("data: v/m:" DUMP_AVPFL_str "/" DUMP_AVPFL_str ", %12s, %-6u \"%s\"",1220 return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: v/m:" DUMP_AVPFL_str "/" DUMP_AVPFL_str ", %12s, %-6u \"%s\"", 1220 1221 DUMP_AVPFL_val(avp->avp_flag_val), 1221 1222 DUMP_AVPFL_val(avp->avp_flag_mask), … … 1224 1225 avp->avp_name ); 1225 1226 } 1226 static void dump_command_data (void * data )1227 static DECLARE_FD_DUMP_PROTOTYPE(dump_command_data, void * data ) 1227 1228 { 1228 1229 struct dict_cmd_data * cmd = (struct dict_cmd_data *) data; 1229 fd_log_debug("data: v/m:" DUMP_CMDFL_str "/" DUMP_CMDFL_str ", %-6u \"%s\"",1230 return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: v/m:" DUMP_CMDFL_str "/" DUMP_CMDFL_str ", %-6u \"%s\"", 1230 1231 DUMP_CMDFL_val(cmd->cmd_flag_val), DUMP_CMDFL_val(cmd->cmd_flag_mask), cmd->cmd_code, cmd->cmd_name); 1231 1232 } 1232 static void dump_rule_data (void * data )1233 static DECLARE_FD_DUMP_PROTOTYPE(dump_rule_data, void * data ) 1233 1234 { 1234 1235 struct dict_rule_data * rule = (struct dict_rule_data * )data; 1235 fd_log_debug("data: pos:%d ord:%d m/M:%2d/%2d avp:\"%s\"",1236 return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: pos:%d ord:%d m/M:%2d/%2d avp:\"%s\"", 1236 1237 rule->rule_position, 1237 1238 rule->rule_order, … … 1241 1242 } 1242 1243 1243 static void dump_object (struct dict_object * obj, int parents, int depth, int indent );1244 1245 static void dump_list (struct fd_list * sentinel, int parents, int depth, int indent )1244 static DECLARE_FD_DUMP_PROTOTYPE(dump_object, struct dict_object * obj, int parents, int depth, int indent ); 1245 1246 static DECLARE_FD_DUMP_PROTOTYPE(dump_list, struct fd_list * sentinel, int parents, int depth, int indent ) 1246 1247 { 1247 1248 struct fd_list * li = sentinel; … … 1250 1251 { 1251 1252 li = li->next; 1252 dump_object( _O(li->o), parents, depth, indent ); 1253 } 1254 } 1255 1256 static void dump_object ( struct dict_object * obj, int parents, int depth, int indent ) 1257 { 1258 if (obj == NULL) 1259 return; 1260 1261 if (parents) 1262 dump_object (obj->parent, parents-1, 0, indent + 1 ); 1263 1264 fd_log_debug("%*s@%p: %s%s (p:%-9p) ", 1265 indent, 1266 "", 1267 obj, 1268 verify_object(obj) ? "" : "INVALID ", 1269 _OBINFO(obj).name, 1270 obj->parent); 1271 1272 if (obj->type == DICT_ENUMVAL) 1273 dump_enumval_data ( &obj->data.enumval, obj->parent->data.type.type_base ); 1274 else 1275 _OBINFO(obj).dump_data(&obj->data); 1253 CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, _O(li->o), parents, depth, indent ), return NULL); 1254 } 1255 } 1256 1257 static DECLARE_FD_DUMP_PROTOTYPE(dump_object, struct dict_object * obj, int parents, int depth, int indent ) 1258 { 1259 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*s{dictobj}(@%p): ", indent, "", obj), return NULL); 1260 1261 if (!verify_object(obj)) { 1262 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL\n"), return NULL); 1263 return *buf; 1264 } 1265 1266 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s p:%p ", 1267 _OBINFO(obj).name, 1268 obj->parent), return NULL); 1269 1270 if (obj->type == DICT_ENUMVAL) { 1271 CHECK_MALLOC_DO( dump_enumval_data ( FD_DUMP_STD_PARAMS, &obj->data.enumval, obj->parent->data.type.type_base ), return NULL); 1272 } else { 1273 CHECK_MALLOC_DO( _OBINFO(obj).dump_data(FD_DUMP_STD_PARAMS, &obj->data), return NULL); 1274 } 1275 1276 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n"), return NULL); 1277 1278 if (parents) { 1279 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*sparent:", indent + 1, ""), return NULL); 1280 CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, obj->parent, parents-1, 0, 0 ), return NULL); 1281 } 1276 1282 1277 1283 if (depth) { … … 1279 1285 for (i=0; i<NB_LISTS_PER_OBJ; i++) { 1280 1286 if ((obj->list[i].o == NULL) && (obj->list[i].next != &obj->list[i])) { 1281 fd_log_debug("%*s>%p: list[%d]:", indent, "", obj, i);1282 dump_list(&obj->list[i], parents, depth - 1, indent + 2);1287 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*slist[%d]:\n", indent + 1, "", i), return NULL); 1288 CHECK_MALLOC_DO( dump_list(FD_DUMP_STD_PARAMS, &obj->list[i], 0, depth - 1, indent + 2), return NULL); 1283 1289 } 1284 1290 } 1285 1291 } 1286 } 1287 1288 void fd_dict_dump_object(struct dict_object * obj) 1289 { 1290 fd_log_debug("Dictionary object %p dump:", obj); 1291 dump_object( obj, 1, 2, 2 ); 1292 } 1293 1294 void fd_dict_dump(struct dictionary * dict) 1292 1293 return *buf; 1294 } 1295 1296 DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump_object, struct dict_object * obj) 1297 { 1298 size_t o = 0; 1299 1300 if (!offset) 1301 offset = &o; 1302 1303 CHECK_MALLOC_DO( dump_object(FD_DUMP_STD_PARAMS, obj, 1, 2, 0), return NULL); 1304 1305 return *buf; 1306 } 1307 1308 DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump, struct dictionary * dict) 1295 1309 { 1296 1310 int i; 1297 1311 struct fd_list * li; 1298 1299 CHECK_PARAMS_DO(dict && (dict->dict_eyec == DICT_EYECATCHER), return); 1312 size_t o = 0; 1313 1314 if (!offset) 1315 offset = &o; 1316 1317 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{dictionary}(@%p): ", dict), return NULL); 1318 1319 if ((dict == NULL) || (dict->dict_eyec != DICT_EYECATCHER)) { 1320 return fd_dump_extend(FD_DUMP_STD_PARAMS, "INVALID/NULL\n"); 1321 } 1300 1322 1301 1323 CHECK_POSIX_DO( pthread_rwlock_rdlock( &dict->dict_lock ), /* ignore */ ); 1302 1324 1303 fd_log_debug("######################################################"); 1304 fd_log_debug("###### Dumping vendors, AVPs and related rules #######"); 1305 1306 dump_object( &dict->dict_vendors, 0, 3, 0 ); 1325 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {dict:%p > vendors, AVPs and related rules}\n", dict), goto error); 1326 CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, &dict->dict_vendors, 0, 3, 3 ), goto error); 1307 1327 for (li = dict->dict_vendors.list[0].next; li != &dict->dict_vendors.list[0]; li = li->next) 1308 dump_object( li->o, 0, 3, 0 ); 1309 1310 fd_log_debug("###### Dumping applications #######"); 1311 1312 dump_object( &dict->dict_applications, 0, 1, 0 ); 1328 CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, li->o, 0, 3, 3 ), goto error); 1329 1330 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {dict:%p > applications}\n", dict), goto error); 1331 CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, &dict->dict_applications, 0, 1, 3 ), goto error); 1313 1332 for (li = dict->dict_applications.list[0].next; li != &dict->dict_applications.list[0]; li = li->next) 1314 dump_object( li->o, 0, 1, 0 ); 1315 1316 fd_log_debug("###### Dumping types #######"); 1317 1318 dump_list( &dict->dict_types, 0, 2, 0 ); 1319 1320 fd_log_debug("###### Dumping commands per name #######"); 1321 1322 dump_list( &dict->dict_cmd_name, 0, 2, 0 ); 1323 1324 fd_log_debug("###### Dumping commands per code and flags #######"); 1325 1326 dump_list( &dict->dict_cmd_code, 0, 0, 0 ); 1327 1328 fd_log_debug("###### Statistics #######"); 1329 1333 CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, li->o, 0, 1, 3 ), goto error); 1334 1335 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {dict:%p > types}\n", dict), goto error); 1336 CHECK_MALLOC_DO( dump_list(FD_DUMP_STD_PARAMS, &dict->dict_types, 0, 2, 3 ), goto error); 1337 1338 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {dict:%p > commands}\n", dict), goto error); 1339 CHECK_MALLOC_DO( dump_list(FD_DUMP_STD_PARAMS, &dict->dict_cmd_code, 0, 0, 3 ), goto error); 1340 1341 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {dict:%p > statistics}\n", dict), goto error); 1330 1342 for (i=1; i<=DICT_TYPE_MAX; i++) 1331 fd_log_debug(" %5d objects of type %s", dict->dict_count[i], dict_obj_info[i].name); 1332 1333 fd_log_debug("######################################################"); 1334 1343 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " %5d: %s\n", dict->dict_count[i], dict_obj_info[i].name), goto error); 1344 1345 CHECK_POSIX_DO( pthread_rwlock_unlock( &dict->dict_lock ), /* ignore */ ); 1346 return *buf; 1347 error: 1335 1348 /* Free the rwlock */ 1336 1349 CHECK_POSIX_DO( pthread_rwlock_unlock( &dict->dict_lock ), /* ignore */ ); 1350 return NULL; 1337 1351 } 1338 1352 … … 1340 1354 1341 1355 /* Default dump functions */ 1342 static int dump_val_os(union avp_value * value, char **outstr, size_t *offset, size_t *outlen)1356 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_os, union avp_value * value) 1343 1357 { 1344 1358 int i; 1345 CHECK_FCT( dump_add_str(outstr, offset, outlen, "<") ); 1359 1360 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "<"), return NULL); 1346 1361 for (i = 0; i < value->os.len; i++) { 1347 1362 if (i == 1024) { /* Dump only up to 1024 bytes of the buffer */ 1348 CHECK_ FCT( dump_add_str(outstr, offset, outlen, "[...] (len=%zd)", value->os.len));1363 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "[...] (len=%zd)", value->os.len), return NULL); 1349 1364 break; 1350 1365 } 1351 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%s%02.2X", (i==0 ? "" : " "), value->os.data[i]) ); 1352 } 1353 CHECK_FCT( dump_add_str(outstr, offset, outlen, ">") ); 1354 return 0; 1355 } 1356 1357 static int dump_val_i32(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) 1358 { 1359 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%i (0x%x)", value->i32, value->i32) ); 1360 return 0; 1361 } 1362 1363 static int dump_val_i64(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) 1364 { 1365 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%lli (0x%llx)", value->i64, value->i64) ); 1366 return 0; 1367 } 1368 1369 static int dump_val_u32(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) 1370 { 1371 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%u (0x%x)", value->u32, value->u32) ); 1372 return 0; 1373 } 1374 1375 static int dump_val_u64(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) 1376 { 1377 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%llu (0x%llx)", value->u64, value->u64) ); 1378 return 0; 1379 } 1380 1381 static int dump_val_f32(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) 1382 { 1383 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%f", value->f32) ); 1384 return 0; 1385 } 1386 1387 static int dump_val_f64(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) 1388 { 1389 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%g", value->f64) ); 1390 return 0; 1366 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s%02hhX", (i==0 ? "" : " "), value->os.data[i]), return NULL); 1367 } 1368 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, ">"), return NULL); 1369 return *buf; 1370 } 1371 1372 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_i32, union avp_value * value) 1373 { 1374 return fd_dump_extend( FD_DUMP_STD_PARAMS, "%i (0x%x)", value->i32, value->i32); 1375 } 1376 1377 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_i64, union avp_value * value) 1378 { 1379 return fd_dump_extend( FD_DUMP_STD_PARAMS, "%" PRId64 " (0x%" PRIx64 ")", value->i64, value->i64); 1380 } 1381 1382 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_u32, union avp_value * value) 1383 { 1384 return fd_dump_extend( FD_DUMP_STD_PARAMS, "%u (0x%x)", value->u32, value->u32); 1385 } 1386 1387 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_u64, union avp_value * value) 1388 { 1389 return fd_dump_extend( FD_DUMP_STD_PARAMS, "%" PRIu64 " (0x%" PRIx64 ")", value->u64, value->u64); 1390 } 1391 1392 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_f32, union avp_value * value) 1393 { 1394 return fd_dump_extend( FD_DUMP_STD_PARAMS, "%f", value->f32); 1395 } 1396 1397 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_f64, union avp_value * value) 1398 { 1399 return fd_dump_extend( FD_DUMP_STD_PARAMS, "%g", value->f64); 1391 1400 } 1392 1401 1393 1402 /* Get the dump function for basic dict_avp_basetype */ 1394 static int (*get_default_dump_val_cb(enum dict_avp_basetype datatype))(union avp_value *, char **, size_t *, size_t*)1403 static DECLARE_FD_DUMP_PROTOTYPE((*get_default_dump_val_cb(enum dict_avp_basetype datatype)), union avp_value *) 1395 1404 { 1396 1405 switch (datatype) { … … 1426 1435 #define INOBJHDRVAL indent<0 ? 1 : indent, indent<0 ? "-" : "|" 1427 1436 1437 typedef DECLARE_FD_DUMP_PROTOTYPE((*dump_val_cb_t), union avp_value *); 1438 1428 1439 /* Formatter for the AVP value dump line */ 1429 static int dump_avp_val(union avp_value *avp_value,1430 int (*def_dump_val_cb)(union avp_value *, char **, size_t *, size_t *),1431 char * (*dump_val_cb)(union avp_value *),1440 static DECLARE_FD_DUMP_PROTOTYPE(dump_avp_val, union avp_value *avp_value, 1441 dump_val_cb_t def_dump_val_cb, 1442 dump_val_cb_t dump_val_cb, 1432 1443 enum dict_avp_basetype datatype, 1433 1444 char * type_name, 1434 1445 char * const_name, 1435 1446 int indent, 1436 char **outstr,1437 size_t *offset,1438 size_t *outlen,1439 1447 int header) 1440 1448 { 1441 1449 if (header) { 1442 1450 /* Header for all AVP values dumps: */ 1443 CHECK_ FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "value ", INOBJHDRVAL));1451 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, INOBJHDR "value ", INOBJHDRVAL), return NULL); 1444 1452 1445 1453 /* If the type is provided, write it */ 1446 1454 if (type_name) { 1447 CHECK_ FCT( dump_add_str(outstr, offset, outlen, "t: '%s' ", type_name));1455 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "t: '%s' ", type_name), return NULL); 1448 1456 } 1449 1457 1450 1458 /* Always give the base datatype anyway */ 1451 CHECK_ FCT( dump_add_str(outstr, offset, outlen, "(%s) ", type_base_name[datatype]));1459 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(%s) ", type_base_name[datatype]), return NULL); 1452 1460 1453 1461 /* Now, the value */ 1454 CHECK_ FCT( dump_add_str(outstr, offset, outlen, "v: "));1462 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "v: "), return NULL); 1455 1463 } 1456 1464 if (const_name) { 1457 CHECK_ FCT( dump_add_str(outstr, offset, outlen, "'%s' (", const_name));1465 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s' (", const_name), return NULL); 1458 1466 } 1459 1467 if (dump_val_cb) { 1460 char * str; 1461 CHECK_MALLOC_DO( str = (*dump_val_cb)(avp_value), dump_add_str(outstr, offset, outlen, "(dump failed)") ); 1462 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%s", str) ); 1463 free(str); 1468 CHECK_MALLOC_DO( (*dump_val_cb)( FD_DUMP_STD_PARAMS, avp_value), fd_dump_extend( FD_DUMP_STD_PARAMS, "(dump failed)")); 1464 1469 } else { 1465 CHECK_ FCT( (*def_dump_val_cb)(avp_value, outstr, offset, outlen));1470 CHECK_MALLOC_DO( (*def_dump_val_cb)( FD_DUMP_STD_PARAMS, avp_value), return NULL); 1466 1471 } 1467 1472 if (const_name) { 1468 CHECK_ FCT( dump_add_str(outstr, offset, outlen, ")"));1473 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, ")"), return NULL); 1469 1474 } 1470 1475 1471 1476 /* Done! */ 1472 return 0;1477 return *buf; 1473 1478 } 1474 1479 1475 1480 /* Dump the value of an AVP of known type into the returned str */ 1476 int fd_dict_dump_avp_value(union avp_value *avp_value, struct dict_object * model, int indent, char **outstr, size_t *offset, size_t *outlen, int header)1477 { 1478 char * (*dump_val_cb)(union avp_value *avp_value) = NULL;1481 DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump_avp_value, union avp_value *avp_value, struct dict_object * model, int indent, int header) 1482 { 1483 DECLARE_FD_DUMP_PROTOTYPE((*dump_val_cb), union avp_value *avp_value) = NULL; 1479 1484 struct dict_object * type = NULL; 1480 1485 char * type_name = NULL; 1481 1486 char * const_name = NULL; 1487 size_t o = 0; 1488 1489 if (!offset) 1490 offset = &o; 1482 1491 1483 1492 /* Check the parameters are correct */ 1484 CHECK_PARAMS ( avp_value && verify_object(model) && (model->type == DICT_AVP));1493 CHECK_PARAMS_DO( avp_value && verify_object(model) && (model->type == DICT_AVP), return NULL ); 1485 1494 1486 1495 /* Get the type definition of this AVP */ … … 1502 1511 /* bypass checks */ 1503 1512 if ((search_enumval( type->dico, ENUMVAL_BY_STRUCT, &request, &enumval ) == 0) && (enumval)) { 1504 /* We found a co sntant, get its name */1513 /* We found a constant, get its name */ 1505 1514 const_name = enumval->data.enumval.enum_name; 1506 1515 } … … 1508 1517 1509 1518 /* And finally, dump the value */ 1510 CHECK_ FCT( dump_avp_val(avp_value, get_default_dump_val_cb(model->data.avp.avp_basetype), dump_val_cb, model->data.avp.avp_basetype, type_name, const_name, indent, outstr, offset, outlen, header));1511 return 0;1519 CHECK_MALLOC_DO( dump_avp_val(FD_DUMP_STD_PARAMS, avp_value, get_default_dump_val_cb(model->data.avp.avp_basetype), dump_val_cb, model->data.avp.avp_basetype, type_name, const_name, indent, header), return NULL ); 1520 return *buf; 1512 1521 } 1513 1522 … … 1574 1583 switch (dict_obj_info[type].parent) { 1575 1584 case 0: /* parent is forbidden */ 1576 CHECK_PARAMS ( parent == NULL);1585 CHECK_PARAMS_DO( parent == NULL, goto error_param ); 1577 1586 1578 1587 case 1: /* parent is optional */ … … 1581 1590 1582 1591 case 2: /* parent is mandatory */ 1583 CHECK_PARAMS ( verify_object(parent));1592 CHECK_PARAMS_DO( verify_object(parent), goto error_param ); 1584 1593 1585 1594 if (type == DICT_RULE ) { /* Special case : grouped AVP or Command parents are allowed */ 1586 CHECK_PARAMS ( (parent->type == DICT_COMMAND )1587 || ( (parent->type == DICT_AVP) && (parent->data.avp.avp_basetype == AVP_TYPE_GROUPED ) ) );1595 CHECK_PARAMS_DO( (parent->type == DICT_COMMAND ) 1596 || ( (parent->type == DICT_AVP) && (parent->data.avp.avp_basetype == AVP_TYPE_GROUPED ) ), goto error_param ); 1588 1597 } else { 1589 CHECK_PARAMS ( parent->type == dict_obj_info[type].parenttype);1598 CHECK_PARAMS_DO( parent->type == dict_obj_info[type].parenttype, goto error_param ); 1590 1599 } 1591 1600 } … … 1594 1603 if (type == DICT_AVP) { 1595 1604 CHECK_FCT_DO( fd_dict_search( dict, DICT_VENDOR, VENDOR_BY_ID, &(((struct dict_avp_data *)data)->avp_vendor), (void*)&vendor, ENOENT ), 1596 { TRACE_DEBUG(INFO, "Unable to find vendor '%d' referenced in the AVP data", ((struct dict_avp_data *)data)->avp_vendor); return EINVAL; } );1605 { TRACE_DEBUG(INFO, "Unable to find vendor '%d' referenced in the AVP data", ((struct dict_avp_data *)data)->avp_vendor); goto error_param; } ); 1597 1606 1598 1607 /* Also check if a parent is provided, that the type are the same */ 1599 1608 if (parent) { 1600 CHECK_PARAMS ( parent->data.type.type_base == ((struct dict_avp_data *)data)->avp_basetype);1609 CHECK_PARAMS_DO( parent->data.type.type_base == ((struct dict_avp_data *)data)->avp_basetype, goto error_param ); 1601 1610 } 1602 1611 } … … 1604 1613 /* For RULE object, we must also check that the "avp" referenced exists */ 1605 1614 if (type == DICT_RULE) { 1606 CHECK_PARAMS ( verify_object(((struct dict_rule_data *)data)->rule_avp));1607 CHECK_PARAMS ( ((struct dict_rule_data *)data)->rule_avp->type == DICT_AVP);1615 CHECK_PARAMS_DO( verify_object(((struct dict_rule_data *)data)->rule_avp), goto error_param ); 1616 CHECK_PARAMS_DO( ((struct dict_rule_data *)data)->rule_avp->type == DICT_AVP, goto error_param ); 1608 1617 } 1609 1618 1610 1619 /* For COMMAND object, check that the 'R' flag is fixed */ 1611 1620 if (type == DICT_COMMAND) { 1612 CHECK_PARAMS ( ((struct dict_cmd_data *)data)->cmd_flag_mask & CMD_FLAG_REQUEST);1621 CHECK_PARAMS_DO( ((struct dict_cmd_data *)data)->cmd_flag_mask & CMD_FLAG_REQUEST, goto error_param ); 1613 1622 } 1614 1623 1615 1624 /* We have to check that the new values are not equal to the sentinels */ 1616 1625 if (type == DICT_VENDOR) { 1617 CHECK_PARAMS ( ((struct dict_vendor_data *)data)->vendor_id != 0);1626 CHECK_PARAMS_DO( ((struct dict_vendor_data *)data)->vendor_id != 0, goto error_param ); 1618 1627 } 1619 1628 if (type == DICT_APPLICATION) { 1620 CHECK_PARAMS ( ((struct dict_application_data *)data)->application_id != 0);1629 CHECK_PARAMS_DO( ((struct dict_application_data *)data)->application_id != 0, goto error_param ); 1621 1630 } 1622 1631 … … 1718 1727 return 0; 1719 1728 1729 error_param: 1730 ret = EINVAL; 1731 goto all_errors; 1732 1720 1733 error_unlock: 1721 1734 CHECK_POSIX_DO( pthread_rwlock_unlock(&dict->dict_lock), /* continue */ ); … … 1728 1741 if (fd_os_cmp(locref->data.vendor.vendor_name, locref->datastr_len, 1729 1742 new->data.vendor.vendor_name, new->datastr_len)) { 1730 TRACE_DEBUG( FULL, "Conflicting vendor name");1743 TRACE_DEBUG(INFO, "Conflicting vendor name: %s", new->data.vendor.vendor_name); 1731 1744 break; 1732 1745 } … … 1866 1879 break; 1867 1880 } 1868 if (ret) { 1869 TRACE_DEBUG(INFO, "An existing object with different non-key data was found: EEXIST"); 1870 if (TRACE_BOOL(INFO)) { 1871 fd_log_debug("New object to insert:"); 1872 dump_object(new, 0, 0, 3); 1873 fd_log_debug("Object already in dictionary:"); 1874 dump_object(locref, 0, 0 , 3); 1875 } 1876 } else { 1881 if (!ret) { 1877 1882 TRACE_DEBUG(FULL, "An existing object with the same data was found, ignoring the error..."); 1878 1883 } 1879 1884 if (ref) 1880 1885 *ref = locref; 1881 } else { 1882 CHECK_FCT_DO( ret, ); /* log the error */ 1883 } 1884 1886 } 1887 all_errors: 1888 if (ret != 0) { 1889 char * buf = NULL; 1890 size_t len = 0; 1891 1892 CHECK_MALLOC( dict_obj_info[CHECK_TYPE(type) ? type : 0].dump_data(&buf, &len, NULL, data) ); 1893 TRACE_DEBUG(INFO, "An error occurred while adding the following data in the dictionary: %s", buf); 1894 1895 if (ret == EEXIST) { 1896 CHECK_MALLOC( dump_object(&buf, &len, NULL, locref, 0, 0, 0) ); 1897 TRACE_DEBUG(INFO, "Conflicting entry in the dictionary: %s", buf); 1898 } 1899 free(buf); 1900 } 1885 1901 error_free: 1886 1902 free(new); -
libfdproto/dictionary_functions.c
r1052 r1085 153 153 154 154 /* Dump the content of an Address AVP */ 155 char * fd_dictfct_Address_dump(union avp_value * avp_value) 156 { 157 char * ret; 158 #define STR_LEN 1024 155 DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_Address_dump, union avp_value * avp_value) 156 { 159 157 union { 160 158 sSA sa; … … 164 162 } s; 165 163 uint16_t fam; 164 size_t o = 0; 165 166 if (!offset) 167 offset = &o; 166 168 167 169 memset(&s, 0, sizeof(s)); 168 169 CHECK_MALLOC_DO( ret = malloc(STR_LEN), return NULL );170 170 171 171 /* The first two octets represent the address family, http://www.iana.org/assignments/address-family-numbers/ */ 172 172 if (avp_value->os.len < 2) { 173 snprintf(ret, STR_LEN, "[invalid length: %zd]", avp_value->os.len);174 return ret;173 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid length: %zd]", avp_value->os.len), return NULL); 174 return *buf; 175 175 } 176 176 … … 182 182 s.sa.sa_family = AF_INET; 183 183 if (avp_value->os.len != 6) { 184 snprintf(ret, STR_LEN, "[invalid IP length: %zd]", avp_value->os.len);185 return ret;184 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid IP length: %zd]", avp_value->os.len), return NULL); 185 return *buf; 186 186 } 187 187 memcpy(&s.sin.sin_addr.s_addr, avp_value->os.data + 2, 4); … … 191 191 s.sa.sa_family = AF_INET6; 192 192 if (avp_value->os.len != 18) { 193 snprintf(ret, STR_LEN, "[invalid IP6 length: %zd]", avp_value->os.len);194 return ret;193 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid IP6 length: %zd]", avp_value->os.len), return NULL); 194 return *buf; 195 195 } 196 196 memcpy(&s.sin6.sin6_addr.s6_addr, avp_value->os.data + 2, 16); 197 197 break; 198 198 default: 199 snprintf(ret, STR_LEN, "[unsupported family: 0x%hx]", fam); 200 return ret; 201 } 202 203 { 204 int rc = getnameinfo(&s.sa, sSAlen(&s.sa), ret, STR_LEN, NULL, 0, NI_NUMERICHOST); 205 if (rc) 206 snprintf(ret, STR_LEN, "%s", (char *)gai_strerror(rc)); 207 } 208 209 return ret; 199 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[unsupported family: 0x%hx]", fam), return NULL); 200 return *buf; 201 } 202 203 return fd_sa_dump_node(FD_DUMP_STD_PARAMS, &s.sa, NI_NUMERICHOST); 210 204 } 211 205 … … 216 210 /*******************************/ 217 211 218 /* Dump the AVP in a natural human-readable format */ 219 char * fd_dictfct_UTF8String_dump(union avp_value * avp_value) 220 { 221 #define TRUNC_LEN 1024 /* avoid very long strings */ 222 char * ret; 223 CHECK_MALLOC_DO( ret = malloc(TRUNC_LEN+2+3+1), return NULL ); 224 *ret = '"'; 225 strncpy(ret+1, (char *)avp_value->os.data, TRUNC_LEN); 226 /* be sure to have a nul-terminated string */ 227 ret[TRUNC_LEN+1] = '\0'; 228 if (ret[1] != '\0') { 229 /* We sanitize the returned string to avoid UTF8 boundary problem. 230 We do this whether the string is trucated at TRUNC_LEN or not, to avoid potential problem 231 with malformed AVP */ 232 233 char * end = strchr(ret, '\0'); 234 while (end > ret) { 235 end--; 236 char b = *end; 237 /* after the position pointed by end, we have only \0s */ 238 if ((b & 0x80) == 0) { 239 break; /* this is a single byte char, no problem */ 240 } else { 241 /* this byte is start or cont. of multibyte sequence, as we do not know the next byte we need to delete it. */ 242 *end = '\0'; 243 if (b & 0x40) 244 break; /* This was a start byte, we can stop the loop */ 245 } 246 } 247 if (strlen((char *)avp_value->os.data) > strlen(ret+1)) 248 strcat(end, "..."); 249 strcat(end, "\""); 250 } else { 251 *ret = '\0'; 252 } 253 return ret; 212 /* Dump the AVP in a natural human-readable format. This dumps the complete length of the AVP, it is up to the caller to truncate if needed */ 213 DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_UTF8String_dump, union avp_value * avp_value) 214 { 215 size_t o = 0, l; 216 if (!offset) 217 offset = &o; 218 219 l = avp_value->os.len; 220 /* Just in case the string ends in invalid UTF-8 chars, we shorten it */ 221 while ((l > 0) && (avp_value->os.data[l - 1] & 0x80)) { 222 /* this byte is start or cont. of multibyte sequence, as we do not know the next byte we need to delete it. */ 223 l--; 224 if (avp_value->os.data[l] & 0x40) 225 break; /* This was a start byte, we can stop the loop */ 226 } 227 228 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "\"%.*s\"", (int)l, (char *)avp_value->os.data), return NULL); 229 230 return *buf; 254 231 } 255 232 … … 326 303 } 327 304 328 char * fd_dictfct_Time_dump(union avp_value * avp_value)329 { 330 char * ret;305 DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_Time_dump, union avp_value * avp_value) 306 { 307 size_t o = 0; 331 308 time_t val; 332 309 struct tm conv; 333 CHECK_MALLOC_DO( ret = malloc(STR_LEN), return NULL ); 310 311 if (!offset) 312 offset = &o; 313 334 314 if (avp_value->os.len != 4) { 335 snprintf(ret, STR_LEN, "[invalid length: %zd]", avp_value->os.len); 336 return ret; 337 } 315 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid length: %zd]", avp_value->os.len), return NULL); 316 return *buf; 317 } 318 338 319 if (diameter_string_to_time_t((char *)avp_value->os.data, avp_value->os.len, &val) != 0) { 339 snprintf(ret, STR_LEN, "[time conversion error]");340 return ret;341 } 342 gmtime_r(&val, &conv);343 snprintf(ret, STR_LEN, "%d%02d%02dT%02d%02d%02d+00", conv.tm_year+1900, conv.tm_mon+1, conv.tm_mday, conv.tm_hour, conv.tm_min, conv.tm_sec);344 return ret;345 } 346 320 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[time conversion error]"), return NULL); 321 return *buf; 322 } 323 324 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "%d%02d%02dT%02d%02d%02d+00", conv.tm_year+1900, conv.tm_mon+1, conv.tm_mday, conv.tm_hour, conv.tm_min, conv.tm_sec), return NULL); 325 return *buf; 326 } 327 -
libfdproto/fdproto-internal.h
r1052 r1085 51 51 extern FILE * fd_g_debug_fstr; 52 52 53 /* Special message dump function */54 void fd_msg_dump_fstr_one ( struct msg * msg, FILE * fstr );55 void fd_msg_dump_fstr ( struct msg * msg, FILE * fstr );56 57 53 /* Iterator on the rules of a parent object */ 58 54 int fd_dict_iterate_rules ( struct dict_object *parent, void * data, int (*cb)(void *, struct dict_rule_data *) ); … … 60 56 /* Dispatch / messages / dictionary API */ 61 57 int fd_dict_disp_cb(enum dict_object_type type, struct dict_object *obj, struct fd_list ** cb_list); 62 int fd_dict_dump_avp_value(union avp_value *avp_value, struct dict_object * model, int indent, char **outstr, size_t *offset, size_t *outlen, int header);58 DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump_avp_value, union avp_value *avp_value, struct dict_object * model, int indent, int header); 63 59 int fd_disp_call_cb_int( struct fd_list * cb_list, struct msg ** msg, struct avp *avp, struct session *sess, enum disp_action *action, 64 60 struct dict_object * obj_app, struct dict_object * obj_cmd, struct dict_object * obj_avp, struct dict_object * obj_enu); … … 69 65 70 66 71 /* For dump routines into string buffers */72 #include <stdarg.h>73 static __inline__ int dump_init_str(char **outstr, size_t *offset, size_t *outlen)74 {75 *outlen = 1<<12;76 CHECK_MALLOC( *outstr = malloc(*outlen) );77 *offset = 0;78 (*outstr)[0] = 0;79 return 0;80 }81 static __inline__ int dump_add_str(char **outstr, size_t *offset, size_t *outlen, char * fmt, ...)82 {83 va_list argp;84 int len;85 va_start(argp, fmt);86 len = vsnprintf(*outstr + *offset, *outlen - *offset, fmt, argp);87 va_end(argp);88 if ((len + *offset) >= *outlen) {89 char * newstr;90 /* buffer was too short, extend */91 size_t newsize = ((len + *offset) + (1<<12)) & ~((1<<12) - 1); /* next multiple of 4k */92 CHECK_MALLOC( newstr = realloc(*outstr, newsize) );93 94 /* redo */95 *outstr = newstr;96 *outlen = newsize;97 va_start(argp, fmt);98 len = vsnprintf(*outstr + *offset, *outlen - *offset, fmt, argp);99 va_end(argp);100 }101 *offset += len;102 return 0;103 }104 105 106 107 67 #endif /* _LIBFDPROTO_INTERNAL_H */ -
libfdproto/fifo.c
r1073 r1085 119 119 120 120 /* Dump the content of a queue */ 121 void fd_fifo_dump(int level, char * name, struct fifo * queue, void (*dump_item)(int level, void * item)) 122 { 123 TRACE_ENTRY("%i %p %p %p", level, name, queue, dump_item); 124 125 if (!TRACE_BOOL(level)) 126 return; 127 128 fd_log_debug("Dumping queue '%s' (%p):", name ?: "?", queue); 121 DECLARE_FD_DUMP_PROTOTYPE(fd_fifo_dump, char * name, struct fifo * queue, fd_fifo_dump_item_cb dump_item) 122 { 123 size_t o = 0; 124 if (!offset) 125 offset = &o; 126 127 if (name) { 128 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'(@%p): ", name, queue), return NULL); 129 } else { 130 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{fifo}(@%p): ", queue), return NULL); 131 } 132 129 133 if (!CHECK_FIFO( queue )) { 130 fd_log_debug(" Queue invalid!"); 131 if (queue) 132 fd_log_debug(" (%x != %x)", queue->eyec, FIFO_EYEC); 133 return; 134 return fd_dump_extend(FD_DUMP_STD_PARAMS, "INVALID/NULL\n"); 134 135 } 135 136 136 137 CHECK_POSIX_DO( pthread_mutex_lock( &queue->mtx ), /* continue */ ); 137 fd_log_debug(" %d elements in queue / %d threads waiting", queue->count, queue->thrs); 138 fd_log_debug(" %d elements max / %d threads waiting to push", queue->max, queue->thrs_push); 139 fd_log_debug(" thresholds: %d / %d (h:%d), cb: %p,%p (%p), highest: %d", 140 queue->high, queue->low, queue->highest, 141 queue->h_cb, queue->l_cb, queue->data, 142 queue->highest_ever); 143 fd_log_debug(" stats: total:%lld in %ld.%06ld, blocking:%ld.%06ld, last:%ld.%06ld", 144 queue->total_items, 145 (long)queue->total_time.tv_sec,(long)(queue->total_time.tv_nsec/1000), 146 (long)queue->blocking_time.tv_sec,(long)(queue->blocking_time.tv_nsec/1000), 147 (long)queue->last_time.tv_sec,(long)(queue->last_time.tv_nsec/1000) ); 138 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "items:%d,%d,%d threads:%d,%d stats:%lld/%ld.%06ld,%ld.%06ld,%ld.%06ld thresholds:%d,%d,%d,%p,%p,%p\n", 139 queue->count, queue->highest_ever, queue->max, 140 queue->thrs, queue->thrs_push, 141 queue->total_items,(long)queue->total_time.tv_sec,(long)(queue->total_time.tv_nsec/1000),(long)queue->blocking_time.tv_sec,(long)(queue->blocking_time.tv_nsec/1000),(long)queue->last_time.tv_sec,(long)(queue->last_time.tv_nsec/1000), 142 queue->high, queue->low, queue->highest, queue->h_cb, queue->l_cb, queue->data), 143 goto error); 148 144 149 145 if (dump_item) { … … 152 148 for (li = queue->list.next; li != &queue->list; li = li->next) { 153 149 struct fifo_item * fi = (struct fifo_item *)li; 154 fd_log_debug(" [%i] item %p in fifo %p, posted:%ld.%06ld", 155 i++, fi->item.o, queue, (long)fi->posted_on.tv_sec,(long)(fi->posted_on.tv_nsec/1000)); 156 (*dump_item)(level, fi->item.o); 150 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " [#%i](@%p)@%ld.%06ld: ", 151 i++, fi->item.o, (long)fi->posted_on.tv_sec,(long)(fi->posted_on.tv_nsec/1000)), 152 goto error); 153 CHECK_MALLOC_DO( (*dump_item)(FD_DUMP_STD_PARAMS, fi->item.o), goto error); 157 154 } 158 155 } 159 156 CHECK_POSIX_DO( pthread_mutex_unlock( &queue->mtx ), /* continue */ ); 160 157 return *buf; 158 error: 159 CHECK_POSIX_DO( pthread_mutex_unlock( &queue->mtx ), /* continue */ ); 160 return NULL; 161 161 } 162 162 -
libfdproto/log.c
r1027 r1085 143 143 } 144 144 145 /* Log debug message to file. */ 146 void fd_log_debug_fstr( FILE * fstr, const char * format, ... ) 147 { 148 va_list ap; 149 150 va_start(ap, format); 151 vfprintf(fstr, format, ap); 152 va_end(ap); 145 /* Log a debug message */ 146 void fd_log_va ( int loglevel, const char * format, va_list args ) 147 { 148 (void)pthread_mutex_lock(&fd_log_lock); 149 150 pthread_cleanup_push(fd_cleanup_mutex_silent, &fd_log_lock); 151 fd_logger(loglevel, format, args); 152 pthread_cleanup_pop(0); 153 154 (void)pthread_mutex_unlock(&fd_log_lock); 153 155 } 154 156 … … 208 210 return buf; 209 211 } 212 213 214 /* Helper function for fd_*_dump. Prints the format string from 'offset' into '*buf', extends if needed. The location of buf can be updated by this function. */ 215 char * fd_dump_extend(char ** buf, size_t *len, size_t *offset, const char * format, ... ) 216 { 217 va_list ap; 218 int to_write; 219 size_t o = 0; 220 static size_t mempagesz = 0; 221 222 if (!mempagesz) { 223 mempagesz = sysconf(_SC_PAGESIZE); /* We alloc buffer by memory pages for efficiency */ 224 if (mempagesz <= 0) 225 mempagesz = 1024; /* default size if above call failed */ 226 } 227 228 /* we do not TRACE_ENTRY this one on purpose */ 229 230 CHECK_PARAMS_DO(buf && len, return NULL); 231 232 if (*buf == NULL) { 233 CHECK_MALLOC_DO(*buf = malloc(mempagesz), return NULL); 234 *len = mempagesz; 235 } 236 237 if (offset) 238 o = *offset; 239 240 va_start(ap, format); 241 to_write = vsnprintf(*buf + o, *len - o, format, ap); 242 va_end(ap); 243 244 if (to_write + o >= *len) { 245 /* There was no room in the buffer, we extend and redo */ 246 size_t new_len = (((to_write + o) / mempagesz) + 1) * mempagesz; 247 CHECK_MALLOC_DO(*buf = realloc(*buf, new_len), return NULL); 248 *len = new_len; 249 250 va_start(ap, format); 251 to_write = vsnprintf(*buf + o, *len - o, format, ap); 252 va_end(ap); 253 } 254 255 if (offset) 256 *offset += to_write; 257 258 return *buf; 259 } -
libfdproto/messages.c
r1084 r1085 711 711 /* Debug functions: dumping */ 712 712 713 #warning "todo" 714 DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_summary, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ) 715 { 716 return NULL; 717 } 718 /* one-line dump with all the contents of the message */ 719 DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_full, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ) 720 { 721 return NULL; 722 } 723 /* multi-line human-readable dump similar to wireshark output */ 724 DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_treeview, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ) 725 { 726 return NULL; 727 } 728 729 #ifndef OLD_CODE_TO_BE_REPLACED 730 void fd_msg_dump_walk ( int level, msg_or_avp *obj ) 731 { 732 LOG_D("fd_msg_dump_walk %d, %p is deprecated", level, obj); 733 } 734 void fd_msg_dump_one ( int level, msg_or_avp * obj ) 735 { 736 LOG_D("fd_msg_dump_one %d, %p is deprecated", level, obj); 737 } 738 #else /* OLD_CODE_TO_BE_REPLACED */ 739 740 713 741 /* indent inside an object */ 714 742 #define INOBJHDR "%*s " … … 1076 1104 } 1077 1105 1078 1106 #endif /* OLD_CODE_TO_BE_REPLACED */ 1079 1107 /***************************************************************************************************************/ 1080 1108 /* Simple meta-data management */ -
libfdproto/sessions.c
r1027 r1085 70 70 int id; /* A unique integer to identify this handler */ 71 71 void (*cleanup)(session_state *, os0_t, void *); /* The cleanup function to be called for cleaning a state */ 72 session_state_dump *state_dump; /* dumper function */ 72 73 void *opaque; /* a value that is passed as is to the cleanup callback */ 73 74 }; … … 273 274 274 275 /* Create a new handler */ 275 int fd_sess_handler_create_internal ( struct session_handler ** handler, void (*cleanup)(session_state *, os0_t, void *), void * opaque )276 int fd_sess_handler_create_internal ( struct session_handler ** handler, void (*cleanup)(session_state *, os0_t, void *), session_state_dump dumper, void * opaque ) 276 277 { 277 278 struct session_handler *new; … … 290 291 new->eyec = SH_EYEC; 291 292 new->cleanup = cleanup; 293 new->state_dump = dumper; 292 294 new->opaque = opaque; 293 295 … … 873 875 874 876 /* Dump functions */ 875 void fd_sess_dump(int level, struct session * session) 876 { 877 struct fd_list * li; 878 char buf[30]; 879 struct tm tm; 880 881 if (!TRACE_BOOL(level)) 882 return; 883 884 fd_log_debug("\t %*s -- Session @%p --", level, "", session); 877 DECLARE_FD_DUMP_PROTOTYPE(fd_sess_dump, struct session * session, int with_states) 878 { 879 size_t o = 0; 880 if (!offset) 881 offset = &o; 882 883 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{session}(@%p): ", session), return NULL); 884 885 885 if (!VALIDATE_SI(session)) { 886 fd_log_debug("\t %*s Invalid session object", level, "");886 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL\n"), return NULL); 887 887 } else { 888 889 fd_log_debug("\t %*s sid '%s'(%zd), hash %x, msg %d, destroyed %d", level, "", session->sid, session->sidlen, session->hash, session->msg_cnt, session->is_destroyed); 890 891 strftime(buf, sizeof(buf), "%D,%T", localtime_r( &session->timeout.tv_sec , &tm )); 892 fd_log_debug("\t %*s timeout %s.%09ld", level, "", buf, session->timeout.tv_nsec); 893 894 CHECK_POSIX_DO( pthread_mutex_lock(&session->stlock), /* ignore */ ); 895 pthread_cleanup_push( fd_cleanup_mutex, &session->stlock ); 896 for (li = session->states.next; li != &session->states; li = li->next) { 897 struct state * st = (struct state *)(li->o); 898 fd_log_debug("\t %*s handler %d registered data %p", level, "", st->hdl->id, st->state); 888 char timebuf[30]; 889 struct tm tm; 890 891 strftime(timebuf, sizeof(timebuf), "%D,%T", localtime_r( &session->timeout.tv_sec , &tm )); 892 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'(%zd) h:%x m:%d d:%d to:%s.%06ld\n", 893 session->sid, session->sidlen, session->hash, session->msg_cnt, session->is_destroyed, 894 timebuf, session->timeout.tv_nsec/1000), 895 return NULL); 896 897 if (with_states) { 898 struct fd_list * li; 899 CHECK_POSIX_DO( pthread_mutex_lock(&session->stlock), /* ignore */ ); 900 pthread_cleanup_push( fd_cleanup_mutex, &session->stlock ); 901 902 for (li = session->states.next; li != &session->states; li = li->next) { 903 struct state * st = (struct state *)(li->o); 904 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {state i:%d}(@%p): \n", st->hdl->id, st), return NULL); 905 if (st->hdl->state_dump) { 906 CHECK_MALLOC_DO( (*st->hdl->state_dump)( FD_DUMP_STD_PARAMS, st->state), 907 fd_dump_extend( FD_DUMP_STD_PARAMS, "[dumper error]\n")); 908 } else { 909 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "<%p>\n", st->state), return NULL); 910 } 911 } 912 913 pthread_cleanup_pop(0); 914 CHECK_POSIX_DO( pthread_mutex_unlock(&session->stlock), /* ignore */ ); 899 915 } 900 pthread_cleanup_pop(0);901 CHECK_POSIX_DO( pthread_mutex_unlock(&session->stlock), /* ignore */ );902 903 fd_log_debug("\t %*s -- end of session @%p --", level, "", session); 904 } 905 906 void fd_sess_dump_hdl(int level, struct session_handler * handler) 907 { 908 if (!TRACE_BOOL(level))909 return;910 911 fd_log_debug("\t %*s -- Handler @%p --", level, "", handler);916 } 917 return *buf; 918 } 919 920 DECLARE_FD_DUMP_PROTOTYPE(fd_sess_dump_hdl, struct session_handler * handler) 921 { 922 size_t o = 0; 923 if (!offset) 924 offset = &o; 925 926 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{sesshdl}(@%p): ", handler), return NULL); 927 912 928 if (!VALIDATE_SH(handler)) { 913 fd_log_debug("\t %*s Invalid session handler object", level, "");929 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL\n"), return NULL); 914 930 } else { 915 fd_log_debug("\t %*s id %d, cleanup %p, opaque %p", level, "", handler->id, handler->cleanup, handler->opaque);916 } 917 fd_log_debug("\t %*s -- end of handler @%p --", level, "", handler);931 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "i:%d cl:%p d:%p o:%p\n", handler->id, handler->cleanup, handler->state_dump, handler->opaque), return NULL); 932 } 933 return *buf; 918 934 } 919 935 -
libfdproto/utils.c
r1084 r1085 36 36 #include "fdproto-internal.h" 37 37 38 char * fd_sa_dump_node(char * buf, size_t bufsize, sSA * sa, int flags) 38 DECLARE_FD_DUMP_PROTOTYPE(fd_sa_dump_node, sSA * sa, int flags) 39 39 { 40 40 char addrbuf[INET6_ADDRSTRLEN]; 41 size_t o = 0; 42 if (!offset) 43 offset = &o; 44 41 45 if (sa) { 42 46 int rc = getnameinfo(sa, sSAlen( sa ), addrbuf, sizeof(addrbuf), NULL, 0, flags); 43 if (rc) 44 snprintf(buf, bufsize, "%s", gai_strerror(rc)); 45 else 46 snprintf(buf, bufsize, "%s", &addrbuf[0]); 47 if (rc) { 48 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s", gai_strerror(rc)), return NULL); 49 } else { 50 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s", &addrbuf[0]), return NULL); 51 } 47 52 } else { 48 snprintf(buf, bufsize, "(NULL / ANY)");53 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(NULL / ANY)"), return NULL); 49 54 } 50 return buf; 55 56 return *buf; 51 57 } 52 58 53 char * fd_sa_dump_node_serv(char * buf, size_t bufsize, sSA * sa, int flags)59 DECLARE_FD_DUMP_PROTOTYPE(fd_sa_dump_node_serv, sSA * sa, int flags) 54 60 { 55 61 char addrbuf[INET6_ADDRSTRLEN]; 56 62 char servbuf[32]; 63 size_t o = 0; 64 if (!offset) 65 offset = &o; 66 57 67 if (sa) { 58 68 int rc = getnameinfo(sa, sSAlen( sa ), addrbuf, sizeof(addrbuf), servbuf, sizeof(servbuf), flags); 59 if (rc) 60 snprintf(buf, bufsize, "%s", gai_strerror(rc)); 61 else 62 snprintf(buf, bufsize, "%s", &addrbuf[0]); 69 if (rc) { 70 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s", gai_strerror(rc)), return NULL); 71 } else { 72 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s", &addrbuf[0]), return NULL); 73 } 63 74 } else { 64 snprintf(buf, bufsize, "(NULL / ANY)");75 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(NULL / ANY)"), return NULL); 65 76 } 66 return buf;77 return *buf; 67 78 }
Note: See TracChangeset
for help on using the changeset viewer.