Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 143269) +++ channels/chan_sip.c (working copy) @@ -2076,6 +2076,9 @@ } } +/* adding this for tracking */ +int hangfix_count = 0; + /*! \brief Kill a SIP dialog (called by scheduler) */ static int __sip_autodestruct(const void *data) { @@ -2092,10 +2095,14 @@ } /* If there are packets still waiting for delivery, delay the destruction */ - if (p->packets) { + if (p->packets && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { if (option_debug > 2) ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : ""); append_history(p, "ReliableXmit", "timeout"); + if (p->method == SIP_CANCEL || p->method == SIP_BYE) { + ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); + hangfix_count++; + } return 10000; } @@ -10028,7 +10035,16 @@ "\r\n", total, idtext); return 0; } +/*! \brief CLI Show Hangfix command; shows how many times a 'software safety valve' + * saved a channel from being hung + * */ +static int sip_show_hangfix(int fd, int argc, char *argv[]) +{ + ast_cli(fd,"The NEEDDESTROY flag has been set on %d channels so far; they probably would have hung otherwise.\n", hangfix_count); + return RESULT_SUCCESS; +} + /*! \brief CLI Show Peers command */ static int sip_show_peers(int fd, int argc, char *argv[]) { @@ -11792,6 +11808,10 @@ "Usage: sip show history \n" " Provides detailed dialog history on a given SIP channel.\n"; +static char show_hangfix_usage[] = +"Usage: sip show hangfix\n" +" Shows how many times a code patch allowed zombie channels to taste sweet death.\n"; + static char show_peers_usage[] = "Usage: sip show peers [like ]\n" " Lists all known SIP peers.\n" @@ -18476,6 +18496,10 @@ sip_show_objects, "List all SIP object allocations", show_objects_usage }, + { { "sip", "show", "hangfix", NULL }, + sip_show_hangfix, "Show how many times a patch allowed a zombie channel to die", + show_hangfix_usage }, + { { "sip", "show", "peers", NULL }, sip_show_peers, "List defined SIP peers", show_peers_usage },