FS-9490: [mod_sofia] add filter to SIP messages that match a regexp.
This commit is contained in:
parent
4dacece6a3
commit
53dbe5d84a
|
@ -4179,6 +4179,10 @@ SWITCH_STANDARD_API(sofia_function)
|
|||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
sofia_command_t func = NULL;
|
||||
int lead = 1;
|
||||
const char *errorptr;
|
||||
int erroffset;
|
||||
const unsigned char *tables = 0;
|
||||
uint32_t flags = 0;
|
||||
static const char usage_string[] = "USAGE:\n"
|
||||
"--------------------------------------------------------------------------------\n"
|
||||
"sofia global siptrace <on|off>\n"
|
||||
|
@ -4221,6 +4225,29 @@ SWITCH_STANDARD_API(sofia_function)
|
|||
func = cmd_status;
|
||||
} else if (!strcasecmp(argv[0], "xmlstatus")) {
|
||||
func = cmd_xml_status;
|
||||
} else if (!strcasecmp(argv[0], "filter")) {
|
||||
if (argc > 1) {
|
||||
if (!strcasecmp(argv[1],"off")) {
|
||||
mod_sofia_globals.filtering = SWITCH_FALSE;
|
||||
switch_regex_free(mod_sofia_globals.filter_re);
|
||||
} else {
|
||||
mod_sofia_globals.filtering = SWITCH_TRUE;
|
||||
strncpy( mod_sofia_globals.filter_expression, argv[1], sizeof(mod_sofia_globals.filter_expression) );
|
||||
mod_sofia_globals.filter_re = switch_regex_compile( argv[1], flags, &errorptr, &erroffset, tables );
|
||||
if (errorptr) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "COMPILE ERROR: %d [%s][%s]\n", erroffset, errorptr, argv[1]);
|
||||
stream->write_function(stream, "Couldn't compile that regex: %s\n", argv[1]);
|
||||
switch_regex_free(mod_sofia_globals.filter_re);
|
||||
goto done;
|
||||
}
|
||||
|
||||
}
|
||||
stream->write_function(stream, "+OK %s filtering sofia log for %s\n", mod_sofia_globals.filtering ? "enabled" : "disabled", mod_sofia_globals.filter_expression );
|
||||
} else {
|
||||
stream->write_function(stream, "%s%s", "sofia filter is ", mod_sofia_globals.filtering ? "enabled. " : "disabled. ", mod_sofia_globals.filter_expression);
|
||||
stream->write_function(stream, "%s", " (sofia filter <filter-regex|off>) - Enable, disable filtering, set 'filter-regex' to use as filter. Set 'filter-expression' to 'off' to stop filtering\n");
|
||||
}
|
||||
goto done;
|
||||
} else if (!strcasecmp(argv[0], "tracelevel")) {
|
||||
if (argv[1]) {
|
||||
mod_sofia_globals.tracelevel = switch_log_str2level(argv[1]);
|
||||
|
@ -6109,7 +6136,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
|
|||
switch_console_set_complete("add sofia ::[help:status");
|
||||
switch_console_set_complete("add sofia status profile ::sofia::list_profiles reg");
|
||||
switch_console_set_complete("add sofia status gateway ::sofia::list_gateways");
|
||||
|
||||
switch_console_set_complete("add sofia filter");
|
||||
switch_console_set_complete("add sofia loglevel ::[all:default:tport:iptsec:nea:nta:nth_client:nth_server:nua:soa:sresolv:stun ::[0:1:2:3:4:5:6:7:8:9");
|
||||
switch_console_set_complete("add sofia tracelevel ::[console:alert:crit:err:warning:notice:info:debug");
|
||||
|
||||
|
|
|
@ -155,6 +155,12 @@ typedef enum {
|
|||
SOFIA_CONFIG_RESPAWN
|
||||
} sofia_config_t;
|
||||
|
||||
typedef enum {
|
||||
FILTER_UNKOWN = 0,
|
||||
FILTER_BEGIN = 1,
|
||||
FILTER_END = 2
|
||||
} filter_packet_state_t;
|
||||
|
||||
typedef struct sofia_dispatch_event_s {
|
||||
nua_saved_event_t event[1];
|
||||
nua_handle_t *nh;
|
||||
|
@ -396,6 +402,9 @@ struct mod_sofia_globals {
|
|||
uint32_t max_reg_threads;
|
||||
time_t presence_epoch;
|
||||
int presence_year;
|
||||
char filter_expression[100];
|
||||
switch_regex_t *filter_re;
|
||||
switch_bool_t filtering;
|
||||
};
|
||||
extern struct mod_sofia_globals mod_sofia_globals;
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
* Emmanuel Schmidbauer <e.schmidbauer@gmail.com>
|
||||
* William King <william.king@quentustech.com>
|
||||
* David Knell <david.knell@telng.com>
|
||||
* David Villasmil <david.villasmil@gmail.com>
|
||||
*
|
||||
* sofia.c -- SOFIA SIP Endpoint (sofia code)
|
||||
*
|
||||
|
@ -3450,13 +3451,65 @@ void launch_sofia_profile_thread(sofia_profile_t *profile)
|
|||
switch_thread_create(&profile->thread, thd_attr, sofia_profile_thread_run, profile, profile->pool);
|
||||
}
|
||||
|
||||
static int is_packet_begin_or_end(char *mybuf)
|
||||
{
|
||||
if (!strncasecmp( mybuf, "recv ", 3) || !strncasecmp( mybuf, "send ", 3) ) {
|
||||
// Buffer starts with "recv" or "send", this means it's a new packet
|
||||
if (strstr(mybuf, "------------------------------------------------------------------------") != NULL) {
|
||||
// Buffer also contains the dahsed line, this is good, the complete "header" so to speak
|
||||
return 1;
|
||||
}
|
||||
} else if (!strcmp(mybuf, " ------------------------------------------------------------------------\n")) {
|
||||
// Buffer only has the dashed line, this means it is the end of a packet
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void logger(void *logarg, char const *fmt, va_list ap)
|
||||
{
|
||||
if (!fmt) return;
|
||||
filter_packet_state_t filter_packet_state;
|
||||
char buf[1024];
|
||||
static switch_stream_handle_t packetstream = { 0 };
|
||||
static switch_bool_t print_this_packet = SWITCH_FALSE;
|
||||
static int ovector[30];
|
||||
|
||||
switch_log_vprintf(SWITCH_CHANNEL_LOG_CLEAN, mod_sofia_globals.tracelevel, fmt, ap);
|
||||
va_list temp_ap;
|
||||
va_copy(temp_ap,ap);
|
||||
|
||||
if (!fmt) return;
|
||||
|
||||
vsnprintf( buf, 1024, fmt, temp_ap);
|
||||
buf[sizeof(buf)-1] = '\0';
|
||||
|
||||
if (mod_sofia_globals.filtering) {
|
||||
if (switch_regex_perform( buf, mod_sofia_globals.filter_expression, &mod_sofia_globals.filter_re, ovector, sizeof(ovector) / sizeof(ovector[0]) ) > 0) {
|
||||
print_this_packet = SWITCH_TRUE;
|
||||
}
|
||||
|
||||
filter_packet_state = is_packet_begin_or_end(buf);
|
||||
|
||||
if ( filter_packet_state == FILTER_BEGIN ) {
|
||||
print_this_packet = SWITCH_FALSE;
|
||||
SWITCH_STANDARD_STREAM(packetstream);
|
||||
packetstream.write_function(&packetstream, "%s", buf);
|
||||
|
||||
} else if ( filter_packet_state == FILTER_END ) {
|
||||
if ( print_this_packet == SWITCH_TRUE ) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, mod_sofia_globals.tracelevel, "\nFILTER REGEX (%s) FOUND IN: \n <<<%s>>>\n", mod_sofia_globals.filter_expression, (char *)packetstream.data );
|
||||
}
|
||||
switch_safe_free(packetstream.data);
|
||||
|
||||
} else {
|
||||
packetstream.write_function(&packetstream, "%s", buf);
|
||||
}
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, mod_sofia_globals.tracelevel, "%s", buf );
|
||||
}
|
||||
buf[0] = '\0';
|
||||
}
|
||||
|
||||
|
||||
static su_log_t *sofia_get_logger(const char *name)
|
||||
{
|
||||
if (!strcasecmp(name, "tport")) {
|
||||
|
|
Loading…
Reference in New Issue