Add verbosity to STUN monitor requests jkister 2011062301 * adds DEBUG for STUN UDP packet misses * adds NOTICE for STUN failure * adds CLI command "stun show status" # patch -p0 -d asterisk-1.8.4.2/ < stun-verbose-v2.patch ##################################################################### --- res/res_stun_monitor.c.orig 2011-06-23 07:56:56.000000000 -0400 +++ res/res_stun_monitor.c 2011-06-23 09:26:19.000000000 -0400 @@ -34,12 +34,15 @@ #include "asterisk/stun.h" #include "asterisk/netsock2.h" #include "asterisk/lock.h" +#include "asterisk/cli.h" #include static const int DEFAULT_MONITOR_REFRESH = 30; +static int xres = -1; /* initializing */ static const char stun_conf_file[] = "res_stun_monitor.conf"; static struct ast_sched_thread *sched; +static char *_stun_show_status(int fd, int argc, const char *argv[]); static struct { struct sockaddr_in stunaddr; /*!< The stun address we send requests to*/ @@ -49,6 +52,7 @@ int stunsock; unsigned int monitor_enabled:1; unsigned int externaladdr_known:1; + char stunserver[255]; /*!< raw value in res_stun_monitor.conf */ } args; static inline void stun_close_sock(void) @@ -99,7 +103,11 @@ stun_purge_socket(); - if (!(ast_stun_request(args.stunsock, &args.stunaddr, NULL, &answer)) && + xres = ast_stun_request(args.stunsock, &args.stunaddr, NULL, &answer); + if( xres == 1 ){ + ast_log(LOG_WARNING, "STUN monitor: query failed\n"); + } + if ( (xres != -1) && (memcmp(&args.externaladdr, &answer, sizeof(args.externaladdr)))) { const char *newaddr = ast_strdupa(ast_inet_ntoa(answer.sin_addr)); int newport = ntohs(answer.sin_port); @@ -236,7 +244,8 @@ if (ast_parse_arg(v->value, PARSE_INADDR, &args.stunaddr)) { ast_log(LOG_WARNING, "Invalid STUN server address: %s\n", v->value); } else { - ast_log(LOG_NOTICE, "STUN monitor enabled: %s\n", v->value); + strcpy(args.stunserver, v->value); + ast_log(LOG_NOTICE, "STUN monitor enabled: %s\n", args.stunserver); args.monitor_enabled = 1; } } else if (!strcasecmp(v->name, "stunrefresh")) { @@ -274,6 +283,60 @@ return res; } +static char *handle_cli_stun_show_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) +{ + switch (cmd) { + case CLI_INIT: + e->command = "stun show status"; + e->usage = + "Usage: stun show status\n" + " List all known STUN servers and statuses.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + return _stun_show_status(a->fd, a->argc, (const char **) a->argv); +} + +/*! \brief Execute stun show status command */ +static char *_stun_show_status(int fd, int argc, const char *argv[]) +{ + const char *status; + +#define DATALN "%-25s %-5d %-7d %-8d %-7s %-16s %-d\n" +#define HEADER "%-25s %-5s %-7s %-8s %-7s %-16s %-s\n" + + /* we only have one stun server, but start to play well with more */ + ast_cli(fd, HEADER, "Hostname", "Port", "Period", "Retries", "Status", "ExternAddr", "ExternPort"); + + if( xres == -1 ){ + status = "INIT"; + }else if( xres == 0 ){ + status = "OK"; + }else{ + status = "FAIL"; + } + ast_cli( fd, DATALN, + args.stunserver, + 3478, /* port - static for now */ + args.refresh, + 3, /* retries - static for now too */ + status, + ast_inet_ntoa(args.externaladdr.sin_addr), + ntohs(args.externaladdr.sin_port) + ); + +#undef HEADER +#undef DATALN + + return CLI_SUCCESS; +} + +static struct ast_cli_entry cli_stun[] = { + AST_CLI_DEFINE(handle_cli_stun_show_status, "Show STUN servers and statuses"), +}; + static int reload(void) { return __reload(0); @@ -283,6 +346,10 @@ { stun_stop_monitor(); ast_mutex_destroy(&args.lock); + + /* Unregister CLI commands */ + ast_cli_unregister_multiple(cli_stun, ARRAY_LEN(cli_stun)); + return 0; } @@ -299,6 +366,8 @@ return AST_MODULE_LOAD_DECLINE; } + ast_cli_register_multiple(cli_stun, sizeof(cli_stun) / sizeof(struct ast_cli_entry)); + return AST_MODULE_LOAD_SUCCESS; } --- main/stun.c.orig 2011-06-22 22:35:16.000000000 -0400 +++ main/stun.c 2011-06-23 06:18:02.000000000 -0400 @@ -380,7 +380,7 @@ unsigned char reqdata[1024]; int reqlen, reqleft; struct stun_attr *attr; - int res = 0; + int res = -1; int retry; req = (struct stun_header *)reqdata; @@ -410,8 +410,12 @@ if (answer == NULL) break; res = ast_poll(&pfds, 1, 3000); - if (res <= 0) /* timeout or error */ + if (res <= 0){ /* timeout or error */ + /* DEBUG because UDP is inheritly unreliable */ + ast_log(LOG_DEBUG, "ast_stun_request ast_poll #%d failed error %d, retry\n", + retry, res); continue; + } memset(&src, 0, sizeof(src)); srclen = sizeof(src); /* XXX pass -1 in the size, because stun_handle_packet might @@ -427,9 +431,15 @@ memset(answer, 0, sizeof(struct sockaddr_in)); ast_stun_handle_packet(s, &src, reply_buf, res, stun_get_mapped, answer); - res = 0; /* signal regular exit */ + break; } + + if( res > 0 ){ + res = 0; /* signal regular exit */ + }else if( res == 0 ){ + res = 1; /* something went wrong in flight */ + } return res; }