Skip to content

Commit

Permalink
debugger: add a new dbg_sip_msg() config function
Browse files Browse the repository at this point in the history
Added a config function which prints how the sip message would look like
if it were to be sent out at that point in config. Displays how the message
looks after apllying all the lumps; but it is just printing, not actual
lump application. Updated doku.
  • Loading branch information
Stefan Mititelu committed Jun 10, 2015
1 parent 57e05de commit 363027e
Show file tree
Hide file tree
Showing 5 changed files with 300 additions and 23 deletions.
3 changes: 3 additions & 0 deletions dprint.h
Expand Up @@ -98,6 +98,9 @@
#define L_INFO 2
#define L_DBG 3
#define L_MAX 3
#define L_OFFSET 42 /* needs to be added and then substracted
because L_WARN may be confused with NULL pointer
(e.g. fixup_dbg_sip_msg) */

/** @brief This is the facility value used to indicate that the caller of the macro
* did not override the facility. Value 0 (the defaul) is LOG_KERN on Linux
Expand Down
171 changes: 170 additions & 1 deletion modules/debugger/debugger_mod.c
Expand Up @@ -34,13 +34,14 @@
#include "../../parser/parse_param.h"
#include "../../shm_init.h"
#include "../../script_cb.h"
#include "../../msg_translator.h"

#include "debugger_api.h"
#include "debugger_config.h"

MODULE_VERSION

static int mod_init(void);
static int mod_init(void);
static int child_init(int rank);
static void mod_destroy(void);

Expand All @@ -52,6 +53,12 @@ static int dbg_mod_facility_param(modparam_t type, void *val);
static int fixup_dbg_pv_dump(void** param, int param_no);
static int w_dbg_dump(struct sip_msg* msg, char* mask, char* level);

static struct action *dbg_fixup_get_action(void **param, int param_no);
static int fixup_dbg_sip_msg(void** param, int param_no);
static int w_dbg_sip_msg(struct sip_msg* msg, char *level, char *facility);

extern char* dump_lump_list(struct lump *list, int s_offset, char *s_buf);

/* parameters */
extern int _dbg_cfgtrace;
extern int _dbg_cfgpkgcheck;
Expand All @@ -64,6 +71,7 @@ extern int _dbg_step_usleep;
extern int _dbg_step_loops;
extern int _dbg_reset_msgid;

static int _dbg_sip_msg_cline;
static char * _dbg_cfgtrace_facility_str = 0;
static int _dbg_log_assign = 0;

Expand All @@ -76,6 +84,12 @@ static cmd_export_t cmds[]={
fixup_dbg_pv_dump, 0, ANY_ROUTE},
{"dbg_pv_dump", (cmd_function)w_dbg_dump, 2,
fixup_dbg_pv_dump, 0, ANY_ROUTE},
{"dbg_sip_msg", (cmd_function)w_dbg_sip_msg, 0,
fixup_dbg_sip_msg, 0, REQUEST_ROUTE},
{"dbg_sip_msg", (cmd_function)w_dbg_sip_msg, 1,
fixup_dbg_sip_msg, 0, REQUEST_ROUTE},
{"dbg_sip_msg", (cmd_function)w_dbg_sip_msg, 2,
fixup_dbg_sip_msg, 0, REQUEST_ROUTE},
{0, 0, 0, 0, 0, 0}
};

Expand Down Expand Up @@ -370,6 +384,161 @@ static int dbg_mod_facility_param(modparam_t type, void *val)
return -1;
}
return 0;
}

static int fixup_dbg_sip_msg(void** param, int param_no)
{
int facility;
int level;
struct action *dbg_sip_msg_action;

switch(param_no)
{
case 2:
facility = str2facility((char*)*(param));
if (facility == -1) {
LM_ERR("invalid log facility configured");
return E_UNSPEC;
}

*param = (void*)(long)facility;
break;
case 1:
switch(((char*)(*param))[2])
{
/* add L_OFFSET because L_WARN is consdered null pointer */
case 'A': level = L_ALERT + L_OFFSET; break;
case 'B': level = L_BUG + L_OFFSET; break;
case 'C': level = L_CRIT2 + L_OFFSET; break;
case 'E': level = L_ERR + L_OFFSET; break;
case 'W': level = L_WARN + L_OFFSET; break;
case 'N': level = L_NOTICE + L_OFFSET; break;
case 'I': level = L_INFO + L_OFFSET; break;
case 'D': level = L_DBG + L_OFFSET; break;
default:
LM_ERR("unknown log level\n");
return E_UNSPEC;
}

*param = (void*)(long)level;
break;
}

/* save the config line where this config function was called */
dbg_sip_msg_action = dbg_fixup_get_action(param, param_no);
_dbg_sip_msg_cline = dbg_sip_msg_action->cline;

return 0;
}

/**
* dump current SIP message and a diff lump list
* part of the code taken from msg_apply_changes_f
*/
static int w_dbg_sip_msg(struct sip_msg* msg, char *level, char *facility)
{
int ilevel = cfg_get(core, core_cfg, debug);
int ifacility= cfg_get(core, core_cfg, log_facility);
int flag = FLAG_MSG_LUMPS_ONLY; // copy lumps only, not the whole message
unsigned int new_buf_offs=0, orig_offs = 0;
char *hdr_lumps = NULL;
char *bdy_lumps = NULL;
const char *start_txt = "------------------------- START OF SIP message debug --------------------------\n";
const char *hdr_txt = "------------------------------ SIP header diffs -------------------------------\n";
const char *bdy_txt = "------------------------------- SIP body diffs --------------------------------\n";
const char *end_txt = "-------------------------- END OF SIP message debug ---------------------------\n\n";
struct dest_info send_info;
str obuf;

if (level != NULL) {
/* substract L_OFFSET previously added */
ilevel = (int)(long)level - L_OFFSET;
}

if (facility != NULL) {
ifacility = (int)(long)facility;
}

/* msg_apply_changes_f code needed to get the current msg */
init_dest_info(&send_info);
send_info.proto = PROTO_UDP;
if(msg->first_line.type == SIP_REPLY) {
obuf.s = generate_res_buf_from_sip_res(msg,
(unsigned int*)&obuf.len, BUILD_NO_VIA1_UPDATE);
} else {
obuf.s = build_req_buf_from_sip_req(msg,
(unsigned int*)&obuf.len, &send_info,
BUILD_NO_PATH|BUILD_NO_LOCAL_VIA|BUILD_NO_VIA1_UPDATE);
}

if(obuf.s == NULL)
{
LM_ERR("couldn't update msg buffer content\n");
return -1;
}

if(obuf.len >= BUF_SIZE)
{
LM_ERR("new buffer overflow (%d)\n", obuf.len);
pkg_free(obuf.s);
return -1;
}

/* skip original uri */
if (msg->new_uri.s){
orig_offs=msg->first_line.u.request.uri.s - msg->buf;
orig_offs=msg->first_line.u.request.uri.len;
}

/* alloc private mem and copy lumps */
hdr_lumps = pkg_malloc(BUF_SIZE);
bdy_lumps = pkg_malloc(BUF_SIZE);

new_buf_offs = 0;
process_lumps(msg, msg->add_rm, hdr_lumps, &new_buf_offs, &orig_offs, &send_info, flag);

new_buf_offs = 0;
process_lumps(msg, msg->body_lumps, bdy_lumps, &new_buf_offs, &orig_offs, &send_info, flag);

/* do the print */
if (hdr_lumps != NULL && bdy_lumps != NULL) {
LOG_FC(ifacility, ilevel, "CONFIG LINE %d\n%s%.*s%s%s%s%s%s",
_dbg_sip_msg_cline,
start_txt,
obuf.len, obuf.s,
hdr_txt, hdr_lumps,
bdy_txt, bdy_lumps,
end_txt);
} else if (hdr_lumps != NULL) {
LOG_FC(ifacility, ilevel, "CONFIG LINE %d\n%s%.*s%s%s%s",
_dbg_sip_msg_cline,
start_txt,
obuf.len, obuf.s,
hdr_txt, hdr_lumps,
end_txt);
} else if (bdy_lumps != NULL) {
LOG_FC(ifacility, ilevel, "CONFIG LINE %d\n%s%.*s%s%s%s",
_dbg_sip_msg_cline,
start_txt,
obuf.len, obuf.s,
bdy_txt, bdy_lumps,
end_txt);
} else {
LOG_FC(ifacility, ilevel, "CONFIG LINE %d\n%s%.*s%s",
_dbg_sip_msg_cline,
start_txt,
obuf.len, obuf.s,
end_txt);
}

/* free lumps */
if (hdr_lumps) {
pkg_free(hdr_lumps);
}

if (bdy_lumps) {
pkg_free(bdy_lumps);
}

return 1;
}
63 changes: 62 additions & 1 deletion modules/debugger/doc/debugger_admin.xml
Expand Up @@ -531,8 +531,69 @@ dbg_pv_dump(30, "L_DBG");
</example>
</section>

<section id="dbg.f.dbg_sip_msg">
<title>
<function moreinfo="none">dbg_sip_msg([log_level], [facility])</function>
</title>
<para>
Prints how the sip message <emphasis>would look</emphasis> like if it <emphasis>would be sent</emphasis> out
at that point in the config(i.e. if the current lump lists would
have been applied at that point in the config).

It also prints a diff list for both header and body of sip msg
which contain the lump lists content. The lumps deleted are printed
with "-" sign whereas the lumps added have no sign. The config line
where the function has been called is also printed.
</para>
<para>
NOTE that dbg_sip_msg function does not modify the initially received SIP message.
Just displays how it WOULD look like if it were to send it at that point.
</para>
<para>
NOTE that the lump lists are usually applied only once, just before sending, to spare message reparse processing.
All the changes present in lump list are applied on the <emphasis>initially received</emphasis> SIP message.
One can force the lump application using msg_apply_changes() function from textopsx module.
</para>
<para>
</para>
<example>
<title><function>dbg_sip_msg</function> usage</title>
<programlisting format="linespecific">
...
dbg_sip_msg();
dbg_sip_msg("L_ERR");
dbg_sip_msg("L_ERR", "LOG_LOCAL0");
...
</programlisting>

<para>Output when dbg_sip_msg("L_ERR") is called after <emphasis>append_hf("P-Hint: My hint\r\n"); remove_hf("Contact");</emphasis></para>
<programlisting format="linespecific">
ERROR: debugger [debugger_mod.c:467]: w_dbg_sip_msg(): CONFIG LINE 338
------------------------- START OF SIP message debug --------------------------
OPTIONS sip:nobody@127.0.0.1 SIP/2.0
Via: SIP/2.0/UDP 127.0.1.1:56872;branch=z9hG4bK.6d7c487a;rport;alias
From: sip:sipsak@127.0.1.1:56872;tag=188b7433
To: sip:nobody@127.0.0.1
Call-ID: 411792435@127.0.1.1
CSeq: 1 OPTIONS
Content-Length: 0
Max-Forwards: 70
User-Agent: sipsak 0.9.6
Accept: text/plain
P-Hint: My hintt

------------------------------ SIP header diffs -------------------------------
- Contact: sip:sipsak@127.0.1.1:56872
P-Hint: My hint
------------------------------- SIP body diffs --------------------------------
-------------------------- END OF SIP message debug ---------------------------
</programlisting>
</example>
</section>

</section>



<section>
<title>Exported RPC Functions</title>

Expand Down

0 comments on commit 363027e

Please sign in to comment.