Commit 496e59f2 authored by Sebastien Decugis's avatar Sebastien Decugis
Browse files

Log message dumps in one call to the dump function to avoid fragmentation in...

Log message dumps in one call to the dump function to avoid fragmentation in the log files, as per Zack comment
parent 632b6f1b
......@@ -1114,7 +1114,7 @@ struct dict_type_data {
char * type_name; /* The name of this type */
dict_avpdata_interpret type_interpret;/* cb to convert the AVP value in more comprehensive format (or NULL) */
dict_avpdata_encode type_encode; /* cb to convert formatted data into an AVP value (or NULL) */
void (*type_dump)(union avp_value * val, FILE * fstr); /* cb called by fd_msg_dump_one for this type of data (if != NULL), to dump the AVP value in fstr */
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. */
};
/* The criteria for searching a type object in the dictionary */
......
......@@ -144,8 +144,10 @@ static int Address_interpret(union avp_value * avp_value, void * interpreted)
}
/* Dump the content of an Address AVP */
static void Address_dump(union avp_value * avp_value, FILE * fstr)
static char * Address_dump(union avp_value * avp_value)
{
char * ret;
#define STR_LEN 1024
union {
sSA sa;
sSS ss;
......@@ -156,10 +158,12 @@ static void Address_dump(union avp_value * avp_value, FILE * fstr)
memset(&s, 0, sizeof(s));
CHECK_MALLOC_DO( ret = malloc(STR_LEN), return NULL );
/* The first two octets represent the address family, http://www.iana.org/assignments/address-family-numbers/ */
if (avp_value->os.len < 2) {
fd_log_debug_fstr(fstr, "[invalid length: %d]", avp_value->os.len);
return;
snprintf(ret, STR_LEN, "[invalid length: %d]", avp_value->os.len);
return ret;
}
/* Following octets are the address in network byte order already */
......@@ -169,8 +173,8 @@ static void Address_dump(union avp_value * avp_value, FILE * fstr)
/* IP */
s.sa.sa_family = AF_INET;
if (avp_value->os.len != 6) {
fd_log_debug_fstr(fstr, "[invalid IP length: %d]", avp_value->os.len);
return;
snprintf(ret, STR_LEN, "[invalid IP length: %d]", avp_value->os.len);
return ret;
}
memcpy(&s.sin.sin_addr.s_addr, avp_value->os.data + 2, 4);
break;
......@@ -178,33 +182,28 @@ static void Address_dump(union avp_value * avp_value, FILE * fstr)
/* IP6 */
s.sa.sa_family = AF_INET6;
if (avp_value->os.len != 18) {
fd_log_debug_fstr(fstr, "[invalid IP6 length: %d]", avp_value->os.len);
return;
snprintf(ret, STR_LEN, "[invalid IP6 length: %d]", avp_value->os.len);
return ret;
}
memcpy(&s.sin6.sin6_addr.s6_addr, avp_value->os.data + 2, 16);
break;
default:
fd_log_debug_fstr(fstr, "[unsupported family: 0x%hx]", fam);
return;
snprintf(ret, STR_LEN, "[unsupported family: 0x%hx]", fam);
return ret;
}
{
char addrbuf[INET6_ADDRSTRLEN];
int rc = getnameinfo(&s.sa, sSAlen(&s.sa), addrbuf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
int rc = getnameinfo(&s.sa, sSAlen(&s.sa), ret, STR_LEN, NULL, 0, NI_NUMERICHOST);
if (rc)
fd_log_debug_fstr(fstr, "%s", (char *)gai_strerror(rc));
else
fd_log_debug_fstr(fstr, "%s", addrbuf);
snprintf(ret, STR_LEN, "%s", (char *)gai_strerror(rc));
}
return ret;
}
static void UTF8String_dump(union avp_value * avp_value, FILE * fstr)
static char * UTF8String_dump(union avp_value * avp_value)
{
size_t len = avp_value->os.len;
if (len > 42)
len = 42; /* avoid very long strings */
fd_log_debug_fstr(fstr, "%.*s", len, avp_value->os.data);
return strndup((char *)avp_value->os.data, 42); /* avoid very long strings */
}
......
......@@ -1304,50 +1304,57 @@ void fd_dict_dump(struct dictionary * dict)
/**************************** Dump AVP values ********************************/
/* Default dump functions */
static void dump_val_os(union avp_value * value, FILE * fstr)
static int dump_val_os(union avp_value * value, char **outstr, size_t *offset, size_t *outlen)
{
int i;
for (i = 0; i < value->os.len; i++) {
if (i == 24) { /* Dump only up to 24 bytes of the buffer */
fd_log_debug_fstr(fstr, "[...] (len=%zd)", value->os.len);
CHECK_FCT( dump_add_str(outstr, offset, outlen, "[...] (len=%zd)", value->os.len) );
break;
}
fd_log_debug_fstr(fstr, "%02.2X ", value->os.data[i]);
CHECK_FCT( dump_add_str(outstr, offset, outlen, "%02.2X ", value->os.data[i]) );
}
return 0;
}
static void dump_val_i32(union avp_value * value, FILE * fstr)
static int dump_val_i32(union avp_value * value, char **outstr, size_t *offset, size_t *outlen)
{
fd_log_debug_fstr(fstr, "%i (0x%x)", value->i32, value->i32);
CHECK_FCT( dump_add_str(outstr, offset, outlen, "%i (0x%x)", value->i32, value->i32) );
return 0;
}
static void dump_val_i64(union avp_value * value, FILE * fstr)
static int dump_val_i64(union avp_value * value, char **outstr, size_t *offset, size_t *outlen)
{
fd_log_debug_fstr(fstr, "%lli (0x%llx)", value->i64, value->i64);
CHECK_FCT( dump_add_str(outstr, offset, outlen, "%lli (0x%llx)", value->i64, value->i64) );
return 0;
}
static void dump_val_u32(union avp_value * value, FILE * fstr)
static int dump_val_u32(union avp_value * value, char **outstr, size_t *offset, size_t *outlen)
{
fd_log_debug_fstr(fstr, "%u (0x%x)", value->u32, value->u32);
CHECK_FCT( dump_add_str(outstr, offset, outlen, "%u (0x%x)", value->u32, value->u32) );
return 0;
}
static void dump_val_u64(union avp_value * value, FILE * fstr)
static int dump_val_u64(union avp_value * value, char **outstr, size_t *offset, size_t *outlen)
{
fd_log_debug_fstr(fstr, "%llu (0x%llx)", value->u64, value->u64);
CHECK_FCT( dump_add_str(outstr, offset, outlen, "%llu (0x%llx)", value->u64, value->u64) );
return 0;
}
static void dump_val_f32(union avp_value * value, FILE * fstr)
static int dump_val_f32(union avp_value * value, char **outstr, size_t *offset, size_t *outlen)
{
fd_log_debug_fstr(fstr, "%f", value->f32);
CHECK_FCT( dump_add_str(outstr, offset, outlen, "%f", value->f32) );
return 0;
}
static void dump_val_f64(union avp_value * value, FILE * fstr)
static int dump_val_f64(union avp_value * value, char **outstr, size_t *offset, size_t *outlen)
{
fd_log_debug_fstr(fstr, "%g", value->f64);
CHECK_FCT( dump_add_str(outstr, offset, outlen, "%g", value->f64) );
return 0;
}
/* Get the dump function for basic dict_avp_basetype */
static void (*get_default_dump_val_cb(enum dict_avp_basetype datatype))(union avp_value *, FILE *)
static int (*get_default_dump_val_cb(enum dict_avp_basetype datatype))(union avp_value *, char **, size_t *, size_t *)
{
switch (datatype) {
case AVP_TYPE_OCTETSTRING:
......@@ -1382,43 +1389,60 @@ static void (*get_default_dump_val_cb(enum dict_avp_basetype datatype))(union av
#define INOBJHDRVAL indent<0 ? 1 : indent, indent<0 ? "-" : "|"
/* Formater for the AVP value dump line */
static void dump_avp_val(union avp_value *avp_value, void (*dump_val_cb)(union avp_value *, FILE *), enum dict_avp_basetype datatype, char * type_name, char * const_name, int indent, FILE * fstr)
static int dump_avp_val(union avp_value *avp_value,
int (*def_dump_val_cb)(union avp_value *, char **, size_t *, size_t *),
char * (*dump_val_cb)(union avp_value *),
enum dict_avp_basetype datatype,
char * type_name,
char * const_name,
int indent,
char **outstr,
size_t *offset,
size_t *outlen)
{
/* Header for all AVP values dumps: */
fd_log_debug_fstr(fstr, INOBJHDR "value ", INOBJHDRVAL);
CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "value ", INOBJHDRVAL) );
/* If the type is provided, write it */
if (type_name)
fd_log_debug_fstr(fstr, "t: '%s' ", type_name);
if (type_name) {
CHECK_FCT( dump_add_str(outstr, offset, outlen, "t: '%s' ", type_name) );
}
/* Always give the base datatype anyway */
fd_log_debug_fstr(fstr, "(%s) ", type_base_name[datatype]);
CHECK_FCT( dump_add_str(outstr, offset, outlen, "(%s) ", type_base_name[datatype]) );
/* Now, the value */
fd_log_debug_fstr(fstr, "v: ");
if (const_name)
fd_log_debug_fstr(fstr, "'%s' (", const_name);
(*dump_val_cb)(avp_value, fstr);
if (const_name)
fd_log_debug_fstr(fstr, ")");
CHECK_FCT( dump_add_str(outstr, offset, outlen, "v: ") );
if (const_name) {
CHECK_FCT( dump_add_str(outstr, offset, outlen, "'%s' (", const_name) );
}
if (dump_val_cb) {
char * str;
CHECK_MALLOC_DO( str = (*dump_val_cb)(avp_value), dump_add_str(outstr, offset, outlen, "(dump failed)") );
CHECK_FCT( dump_add_str(outstr, offset, outlen, "%s", str) );
free(str);
} else {
CHECK_FCT( (*def_dump_val_cb)(avp_value, outstr, offset, outlen) );
}
if (const_name) {
CHECK_FCT( dump_add_str(outstr, offset, outlen, ")") );
}
/* Done! */
fd_log_debug_fstr(fstr, "\n");
CHECK_FCT( dump_add_str(outstr, offset, outlen, "\n") );
return 0;
}
/* Dump the value of an AVP of known type */
void fd_dict_dump_avp_value(union avp_value *avp_value, struct dict_object * model, int indent, FILE * fstr)
/* Dump the value of an AVP of known type into the returned str */
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)
{
void (*dump_val_cb)(union avp_value *avp_value, FILE * fstr);
char * (*dump_val_cb)(union avp_value *avp_value) = NULL;
struct dict_object * type = NULL;
char * type_name = NULL;
char * const_name = NULL;
/* Check the parameters are correct */
CHECK_PARAMS_DO( avp_value && verify_object(model) && (model->type == DICT_AVP), return );
/* Default: display the value with the formatter for the AVP datatype */
CHECK_PARAMS_DO( dump_val_cb = get_default_dump_val_cb(model->data.avp.avp_basetype), return );
CHECK_PARAMS( avp_value && verify_object(model) && (model->type == DICT_AVP) );
/* Get the type definition of this AVP */
type = model->parent;
......@@ -1444,7 +1468,8 @@ void fd_dict_dump_avp_value(union avp_value *avp_value, struct dict_object * mod
}
/* And finally, dump the value */
dump_avp_val(avp_value, dump_val_cb, model->data.avp.avp_basetype, type_name, const_name, indent, fstr);
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) );
return 0;
}
/*******************************************************************************************************/
......
......@@ -59,7 +59,7 @@ int fd_dict_iterate_rules ( struct dict_object *parent, void * data, int (*cb)(v
/* Dispatch / messages / dictionary API */
int fd_dict_disp_cb(enum dict_object_type type, struct dict_object *obj, struct fd_list ** cb_list);
void fd_dict_dump_avp_value(union avp_value *avp_value, struct dict_object * model, int indent, FILE * fstr);
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 fd_disp_call_cb_int( struct fd_list * cb_list, struct msg ** msg, struct avp *avp, struct session *sess, enum disp_action *action,
struct dict_object * obj_app, struct dict_object * obj_cmd, struct dict_object * obj_avp, struct dict_object * obj_enu);
extern pthread_rwlock_t fd_disp_lock;
......@@ -69,4 +69,40 @@ int fd_sess_fromsid_msg ( uint8_t * sid, size_t len, struct session ** session,
int fd_sess_ref_msg ( struct session * session );
int fd_sess_reclaim_msg ( struct session ** session );
/* For dump routines into string buffers */
#include <stdarg.h>
static __inline__ int dump_init_str(char **outstr, size_t *offset, size_t *outlen)
{
*outlen = 1<<12;
CHECK_MALLOC( *outstr = malloc(*outlen) );
*offset = 0;
(*outstr)[0] = 0;
return 0;
}
static __inline__ int dump_add_str(char **outstr, size_t *offset, size_t *outlen, char * fmt, ...)
{
va_list argp;
int len;
va_start(argp, fmt);
len = vsnprintf(*outstr + *offset, *outlen - *offset, fmt, argp);
va_end(argp);
if ((len + *offset) >= *outlen) {
char * newstr;
/* buffer was too short, extend */
size_t newsize = ((len + *offset) + (1<<12)) & ~((1<<12) - 1); /* next multiple of 4k */
CHECK_MALLOC( newstr = realloc(*outstr, newsize) );
/* redo */
*outstr = newstr;
*outlen = newsize;
va_start(argp, fmt);
len = vsnprintf(*outstr + *offset, *outlen - *offset, fmt, argp);
va_end(argp);
}
*offset += len;
return 0;
}
#endif /* _LIBFDPROTO_INTERNAL_H */
......@@ -661,21 +661,23 @@ int fd_msg_free ( msg_or_avp * object )
#define INOBJHDR "%*s "
#define INOBJHDRVAL indent<0 ? 1 : indent, indent<0 ? "-" : "|"
/* Write some debug data in a buffer */
/* Dump a msg_t object */
static void obj_dump_msg (struct msg * msg, int indent, FILE * fstr )
static int obj_dump_msg (struct msg * msg, int indent, char **outstr, size_t *offset, size_t *outlen )
{
int ret = 0;
fd_log_debug_fstr(fstr, "%*sMSG: %p\n", INOBJHDRVAL, msg);
CHECK_FCT( dump_add_str(outstr, offset, outlen, "%*sMSG: %p\n", INOBJHDRVAL, msg) );
if (!CHECK_MSG(msg)) {
fd_log_debug_fstr(fstr, INOBJHDR "INVALID!\n", INOBJHDRVAL);
return;
CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "INVALID!\n", INOBJHDRVAL) );
return 0;
}
if (!msg->msg_model) {
fd_log_debug_fstr(fstr, INOBJHDR "(no model)\n", INOBJHDRVAL);
CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "(no model)\n", INOBJHDRVAL) );
} else {
......@@ -683,19 +685,19 @@ static void obj_dump_msg (struct msg * msg, int indent, FILE * fstr )
struct dict_cmd_data dictdata;
ret = fd_dict_gettype(msg->msg_model, &dicttype);
if (ret || (dicttype != DICT_COMMAND)) {
fd_log_debug_fstr(fstr, INOBJHDR "(invalid model: %d %d)\n", INOBJHDRVAL, ret, dicttype);
CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "(invalid model: %d %d)\n", INOBJHDRVAL, ret, dicttype) );
goto public;
}
ret = fd_dict_getval(msg->msg_model, &dictdata);
if (ret != 0) {
fd_log_debug_fstr(fstr, INOBJHDR "(error getting model data: %s)\n", INOBJHDRVAL, strerror(ret));
CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "(error getting model data: %s)\n", INOBJHDRVAL, strerror(ret)) );
goto public;
}
fd_log_debug_fstr(fstr, INOBJHDR "model : v/m:" DUMP_CMDFL_str "/" DUMP_CMDFL_str ", %u \"%s\"\n", INOBJHDRVAL,
DUMP_CMDFL_val(dictdata.cmd_flag_val), DUMP_CMDFL_val(dictdata.cmd_flag_mask), dictdata.cmd_code, dictdata.cmd_name);
CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "model : v/m:" DUMP_CMDFL_str "/" DUMP_CMDFL_str ", %u \"%s\"\n", INOBJHDRVAL,
DUMP_CMDFL_val(dictdata.cmd_flag_val), DUMP_CMDFL_val(dictdata.cmd_flag_mask), dictdata.cmd_code, dictdata.cmd_name) );
}
public:
fd_log_debug_fstr(fstr, INOBJHDR "public: V:%d L:%d fl:" DUMP_CMDFL_str " CC:%u A:%d hi:%x ei:%x\n", INOBJHDRVAL,
CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "public: V:%d L:%d fl:" DUMP_CMDFL_str " CC:%u A:%d hi:%x ei:%x\n", INOBJHDRVAL,
msg->msg_public.msg_version,
msg->msg_public.msg_length,
DUMP_CMDFL_val(msg->msg_public.msg_flags),
......@@ -703,24 +705,25 @@ public:
msg->msg_public.msg_appl,
msg->msg_public.msg_hbhid,
msg->msg_public.msg_eteid
);
fd_log_debug_fstr(fstr, INOBJHDR "intern: rwb:%p rt:%d cb:%p(%p) qry:%p asso:%d sess:%p src:%s(%zd)\n",
INOBJHDRVAL, msg->msg_rawbuffer, msg->msg_routable, msg->msg_cb.fct, msg->msg_cb.data, msg->msg_query, msg->msg_associated, msg->msg_sess, msg->msg_src_id?:"(nil)", msg->msg_src_id_len);
) );
CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "intern: rwb:%p rt:%d cb:%p(%p) qry:%p asso:%d sess:%p src:%s(%zd)\n",
INOBJHDRVAL, msg->msg_rawbuffer, msg->msg_routable, msg->msg_cb.fct, msg->msg_cb.data, msg->msg_query, msg->msg_associated, msg->msg_sess, msg->msg_src_id?:"(nil)", msg->msg_src_id_len) );
return 0;
}
/* Dump an avp object */
static void obj_dump_avp ( struct avp * avp, int indent, FILE * fstr )
static int obj_dump_avp ( struct avp * avp, int indent, char **outstr, size_t *offset, size_t *outlen )
{
int ret = 0;
if (!CHECK_AVP(avp)) {
fd_log_debug_fstr(fstr, INOBJHDR "INVALID!\n", INOBJHDRVAL);
return;
CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "INVALID!\n", INOBJHDRVAL) );
return 0;
}
if (!avp->avp_model) {
fd_log_debug_fstr(fstr, INOBJHDR "(no model)\n", INOBJHDRVAL);
CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "(no model)\n", INOBJHDRVAL) );
} else {
......@@ -728,67 +731,69 @@ static void obj_dump_avp ( struct avp * avp, int indent, FILE * fstr )
struct dict_avp_data dictdata;
ret = fd_dict_gettype(avp->avp_model, &dicttype);
if (ret || (dicttype != DICT_AVP)) {
fd_log_debug_fstr(fstr, INOBJHDR "(invalid model: %d %d)\n", INOBJHDRVAL, ret, dicttype);
CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "(invalid model: %d %d)\n", INOBJHDRVAL, ret, dicttype) );
goto public;
}
ret = fd_dict_getval(avp->avp_model, &dictdata);
if (ret != 0) {
fd_log_debug_fstr(fstr, INOBJHDR "(error getting model data: %s)\n", INOBJHDRVAL, strerror(ret));
CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "(error getting model data: %s)\n", INOBJHDRVAL, strerror(ret)) );
goto public;
}
fd_log_debug_fstr(fstr, INOBJHDR "model : v/m:" DUMP_AVPFL_str "/" DUMP_AVPFL_str ", %12s, %u \"%s\"\n", INOBJHDRVAL,
CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "model : v/m:" DUMP_AVPFL_str "/" DUMP_AVPFL_str ", %12s, %u \"%s\"\n", INOBJHDRVAL,
DUMP_AVPFL_val(dictdata.avp_flag_val),
DUMP_AVPFL_val(dictdata.avp_flag_mask),
type_base_name[dictdata.avp_basetype],
dictdata.avp_code,
dictdata.avp_name );
dictdata.avp_name ) );
}
public:
fd_log_debug_fstr(fstr, INOBJHDR "public: C:%u fl:" DUMP_AVPFL_str " L:%d V:%u data:@%p\n", INOBJHDRVAL,
CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "public: C:%u fl:" DUMP_AVPFL_str " L:%d V:%u data:@%p\n", INOBJHDRVAL,
avp->avp_public.avp_code,
DUMP_AVPFL_val(avp->avp_public.avp_flags),
avp->avp_public.avp_len,
avp->avp_public.avp_vendor,
avp->avp_public.avp_value
);
) );
/* Dump the value if set */
if (avp->avp_public.avp_value) {
if (!avp->avp_model) {
fd_log_debug_fstr(fstr, INOBJHDR "(data set but no model: ERROR)\n", INOBJHDRVAL);
CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "(data set but no model: ERROR)\n", INOBJHDRVAL) );
} else {
fd_dict_dump_avp_value(avp->avp_public.avp_value, avp->avp_model, indent, fstr);
CHECK_FCT( fd_dict_dump_avp_value(avp->avp_public.avp_value, avp->avp_model, indent, outstr, offset, outlen) );
}
}
fd_log_debug_fstr(fstr, INOBJHDR "intern: src:%p mf:%d raw:%p(%d)\n", INOBJHDRVAL, avp->avp_source, avp->avp_mustfreeos, avp->avp_rawdata, avp->avp_rawlen);
CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "intern: src:%p mf:%d raw:%p(%d)\n", INOBJHDRVAL, avp->avp_source, avp->avp_mustfreeos, avp->avp_rawdata, avp->avp_rawlen) );
return 0;
}
/* Dump a single object content */
static void msg_dump_intern ( int level, msg_or_avp * obj, int indent, FILE * fstr )
/* Dump a single object content into out string, realloc if needed */
static int msg_dump_intern ( int level, msg_or_avp * obj, int indent, char **outstr, size_t *offset, size_t *outlen )
{
/* Log only if we are at least at level */
if ( ! TRACE_BOOL(level) )
return;
return 0;
/* Check the object */
if (!VALIDATE_OBJ(obj)) {
fd_log_debug_fstr(fstr, ">>> invalid object (%p)!.\n", obj);
return;
CHECK_FCT( dump_add_str(outstr, offset, outlen, ">>> invalid object (%p)!.\n", obj) );
return 0;
}
/* Dump the object */
switch (_C(obj)->type) {
case MSG_AVP:
obj_dump_avp ( _A(obj), indent, fstr );
CHECK_FCT( obj_dump_avp ( _A(obj), indent, outstr, offset, outlen ));
break;
case MSG_MSG:
obj_dump_msg ( _M(obj), indent, fstr );
CHECK_FCT( obj_dump_msg ( _M(obj), indent, outstr, offset, outlen ) );
break;
default:
ASSERT(0);
}
return 0;
}
/* Dump a message to a specified file stream */
......@@ -796,18 +801,35 @@ void fd_msg_dump_fstr ( struct msg * msg, FILE * fstr )
{
msg_or_avp * ref = msg;
int indent = 2;
char *outstr;
size_t offset, outlen;
CHECK_FCT_DO( dump_init_str(&outstr, &offset, &outlen), { fd_log_debug_fstr(fstr, "Error initializing string for dumping %p\n", msg); return; } );
do {
msg_dump_intern ( NONE, ref, indent, fstr );
CHECK_FCT_DO( msg_dump_intern ( NONE, ref, indent, &outstr, &offset, &outlen ),
fd_log_debug_fstr(fstr, "Error while dumping %p\n", ref) );
/* Now find the next object */
CHECK_FCT_DO( fd_msg_browse ( ref, MSG_BRW_WALK, &ref, &indent ), break );
/* dump next object */
} while (ref);
/* now really output this in one shot, so it is not interrupted */
fd_log_debug_fstr(fstr, "%s", outstr);
free(outstr);
}
void fd_msg_dump_fstr_one ( struct msg * msg, FILE * fstr ) /* just the header */
{
msg_dump_intern ( NONE, msg, 2, fstr );
char *outstr;
size_t offset, outlen;
CHECK_FCT_DO( dump_init_str(&outstr, &offset, &outlen), { fd_log_debug_fstr(fstr, "Error initializing string for dumping %p\n", msg); return; } );
CHECK_FCT_DO( msg_dump_intern ( NONE, msg, 2, &outstr, &offset, &outlen ),
fd_log_debug_fstr(fstr, "Error while dumping %p\n", msg) );
/* now really output this in one shot, so it is not interrupted */
fd_log_debug_fstr(fstr, "%s", outstr);
free(outstr);
}
/* Dump a message content -- for debug mostly */
......@@ -815,10 +837,14 @@ void fd_msg_dump_walk ( int level, msg_or_avp *obj )
{
msg_or_avp * ref = obj;
int indent = 1;
TRACE_DEBUG(level, "------ Dumping object %p (w)-------", obj);
char *outstr;
size_t offset, outlen;
CHECK_FCT_DO( dump_init_str(&outstr, &offset, &outlen),
{ fd_log_debug_fstr(fd_g_debug_fstr, "Error initializing string for dumping %p\n", obj); return; } );
do {
msg_dump_intern ( level, ref, indent, fd_g_debug_fstr );
CHECK_FCT_DO( msg_dump_intern ( level, ref, indent, &outstr, &offset, &outlen ),
fd_log_debug_fstr(fd_g_debug_fstr, "Error while dumping %p\n", ref) );
/* Now find the next object */
CHECK_FCT_DO( fd_msg_browse ( ref, MSG_BRW_WALK, &ref, &indent ), break );
......@@ -826,15 +852,27 @@ void fd_msg_dump_walk ( int level, msg_or_avp *obj )
/* dump next object */
} while (ref);
/* now really output this in one shot, so it is not interrupted */
TRACE_DEBUG(level, "------ Dumping object %p (w)-------", obj);
fd_log_debug_fstr(fd_g_debug_fstr, "%s", outstr);
TRACE_DEBUG(level, "------ /end of object %p -------", obj);
free(outstr);
}
/* Dump a single object content -- for debug mostly */
void fd_msg_dump_one ( int level, msg_or_avp * obj )
{
char *outstr;
size_t offset, outlen;
CHECK_FCT_DO( dump_init_str(&outstr, &offset, &outlen),
{ fd_log_debug_fstr(fd_g_debug_fstr, "Error initializing string for dumping %p\n", obj); return; } );
CHECK_FCT_DO( msg_dump_intern ( level, obj, 1, &outstr, &offset, &outlen ),
fd_log_debug_fstr(fd_g_debug_fstr, "Error while dumping %p\n", obj) );
TRACE_DEBUG(level, "------ Dumping object %p (s)-------", obj);
msg_dump_intern ( level, obj, 1, fd_g_debug_fstr );
fd_log_debug_fstr(fd_g_debug_fstr, "%s", outstr);
TRACE_DEBUG(level, "------ /end of object %p -------", obj);
free(outstr);
}
......@@ -1687,7 +1725,7 @@ static int parsedict_do_avp(struct dictionary * dict, struct avp * avp, int mand
if (mandatory && (avp->avp_public.avp_flags & AVP_FLAG_MANDATORY)) {
TRACE_DEBUG(INFO, "Unsupported mandatory AVP found:");
msg_dump_intern(INFO, avp, 2, fd_g_debug_fstr);
fd_msg_dump_one(INFO, avp);
if (error_info) {
error_info->pei_errcode = "DIAMETER_AVP_UNSUPPORTED";
error_info->pei_avp = avp;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment