This is the Asterisk 1.8.8.0-rc2 stabilize patch combined by Jeremy Kister on 2011.10.19 http://jeremy.kister.net/code/asterisk/ * includes sip fromuser fix in options messages https://issues.asterisk.org/jira/browse/ASTERISK-17616 * adds stun verbosity fixes and status display https://issues.asterisk.org/jira/browse/ASTERISK-18046 * includes compile fail on debian/sparc64 https://issues.asterisk.org/jira/browse/ASTERISK-18651 * includes invalid sip dial peer error fix https://issues.asterisk.org/jira/browse/ASTERISK-17146 wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-1.8.8.0-rc2.tar.gz tar zxf asterisk-1.8.8.0-rc2.tar.gz patch -p1 -d asterisk-1.8.8.0-rc2 < ast1880-rc2+stabilize.patch ####################################################################### diff -ruBN asterisk-1.8.8.0-rc2/.version asterisk-1.8.8.0-rc2+stabilize.20111019/.version --- asterisk-1.8.8.0-rc2/.version 2011-10-18 15:49:23.000000000 -0400 +++ asterisk-1.8.8.0-rc2+stabilize.20111019/.version 2011-10-19 18:18:10.000000000 -0400 @@ -1 +1 @@ -1.8.8.0-rc2 +1.8.8.0-rc2+stabilize.2011101901 diff -ruBN asterisk-1.8.8.0-rc2/Makefile asterisk-1.8.8.0-rc2+stabilize.20111019/Makefile --- asterisk-1.8.8.0-rc2/Makefile 2011-10-04 18:54:15.000000000 -0400 +++ asterisk-1.8.8.0-rc2+stabilize.20111019/Makefile 2011-10-19 18:17:42.000000000 -0400 @@ -176,7 +176,13 @@ #the default as we now have a better instruction set to work with. - Belgarath PROC=ultrasparc OPTIONS+=$(shell if $(CC) -mtune=$(PROC) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-mtune=$(PROC)"; fi) - OPTIONS+=$(shell if $(CC) -mcpu=v8 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-mcpu=v8"; fi) + OPTIONS+=$(shell \ + if $(CC) -mcpu=v9 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then\ + echo "-mcpu=v9";\ + elif $(CC) -mcpu=v8 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then\ + echo "-mcpu=v8";\ + fi) + OPTIONS+=-fomit-frame-pointer endif @@ -896,7 +902,7 @@ -@menuselect/nmenuselect menuselect.makeopts && (echo "menuselect changes saved!"; rm -f channels/h323/Makefile.ast main/asterisk) || echo "menuselect changes NOT saved!" # options for make in menuselect/ -MAKE_MENUSELECT=CC="$(BUILD_CC)" CXX="" LD="" AR="" RANLIB="" CFLAGS="" $(MAKE) -C menuselect CONFIGURE_SILENT="--silent" +MAKE_MENUSELECT=CC="$(BUILD_CC)" CXX="" OPTIONS="$(OPTIONS)" LD="" AR="" RANLIB="" CFLAGS="" $(MAKE) -C menuselect CONFIGURE_SILENT="--silent" menuselect/menuselect: menuselect/makeopts +$(MAKE_MENUSELECT) menuselect diff -ruBN asterisk-1.8.8.0-rc2/channels/chan_sip.c asterisk-1.8.8.0-rc2+stabilize.20111019/channels/chan_sip.c --- asterisk-1.8.8.0-rc2/channels/chan_sip.c 2011-10-18 17:44:37.000000000 -0400 +++ asterisk-1.8.8.0-rc2+stabilize.20111019/channels/chan_sip.c 2011-10-19 18:17:47.000000000 -0400 @@ -5279,6 +5279,12 @@ dialog->relatedpeer = ref_peer(peer, "create_addr: setting dialog's relatedpeer pointer"); unref_peer(peer, "create_addr: unref peer from find_peer hashtab lookup"); return res; + } else if (ast_check_digits(peername)) { + /* Although an IPv4 hostname *could* be represented as a 32-bit integer, it is uncommon and + * it makes dialing SIP/${EXTEN} for a peer that isn't defined resolve to an IP that is + * almost certainly not intended. It is much better to just reject purely numeric hostnames */ + ast_log(LOG_WARNING, "Purely numeric hostname (%s), and not a peer--rejecting!\n", peername); + return -1; } else { dialog->rtptimeout = global_rtptimeout; dialog->rtpholdtimeout = global_rtpholdtimeout; @@ -5320,6 +5326,7 @@ if (ast_sockaddr_resolve_first(&dialog->sa, hostn, 0)) { ast_log(LOG_WARNING, "No such host: %s\n", peername); + return -1; } if (srv_ret > 0) { @@ -25646,6 +25653,9 @@ if (!ast_strlen_zero(peer->fullcontact)) ast_string_field_set(p, fullcontact, peer->fullcontact); + if (!ast_strlen_zero(peer->fromuser)) + ast_string_field_set(p, fromuser, peer->fromuser); + if (!ast_strlen_zero(peer->tohost)) ast_string_field_set(p, tohost, peer->tohost); else diff -ruBN asterisk-1.8.8.0-rc2/include/asterisk/strings.h asterisk-1.8.8.0-rc2+stabilize.20111019/include/asterisk/strings.h --- asterisk-1.8.8.0-rc2/include/asterisk/strings.h 2010-06-22 08:58:28.000000000 -0400 +++ asterisk-1.8.8.0-rc2+stabilize.20111019/include/asterisk/strings.h 2011-10-19 18:17:47.000000000 -0400 @@ -872,6 +872,25 @@ ) /*! + * \brief Check if a string is only digits + * + * \retval 1 The string contains only digits + * \retval 0 The string contains non-digit characters + */ +AST_INLINE_API( +int ast_check_digits(char *arg), +{ + char *s; + for (s=arg; *s; s++) { + if (*s < '0' || *s > '9') { + return 0; + } + } + return 1; +} +) + +/*! * \brief Compute a hash value on a string * * This famous hash algorithm was written by Dan Bernstein and is diff -ruBN asterisk-1.8.8.0-rc2/main/stun.c asterisk-1.8.8.0-rc2+stabilize.20111019/main/stun.c --- asterisk-1.8.8.0-rc2/main/stun.c 2010-09-02 01:00:34.000000000 -0400 +++ asterisk-1.8.8.0-rc2+stabilize.20111019/main/stun.c 2011-10-19 18:17:20.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; } diff -ruBN asterisk-1.8.8.0-rc2/res/res_stun_monitor.c asterisk-1.8.8.0-rc2+stabilize.20111019/res/res_stun_monitor.c --- asterisk-1.8.8.0-rc2/res/res_stun_monitor.c 2011-07-14 16:13:06.000000000 -0400 +++ asterisk-1.8.8.0-rc2+stabilize.20111019/res/res_stun_monitor.c 2011-10-19 18:17:20.000000000 -0400 @@ -38,12 +38,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*/ @@ -53,6 +56,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) @@ -103,7 +107,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); @@ -240,7 +248,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")) { @@ -278,6 +287,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); @@ -287,6 +350,10 @@ { stun_stop_monitor(); ast_mutex_destroy(&args.lock); + + /* Unregister CLI commands */ + ast_cli_unregister_multiple(cli_stun, ARRAY_LEN(cli_stun)); + return 0; } @@ -303,6 +370,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; }