@ -1507,7 +1507,7 @@ static int get_domain(const char *str, char *domain, int len);
static void get_realm ( struct sip_pvt * p , const struct sip_request * req ) ;
/*-- TCP connection handling ---*/
static void * _sip_tcp_helper_thread ( struct sip_pvt * pvt , struct ast_tcptls_session_instance * tcptls_session ) ;
static void * _sip_tcp_helper_thread ( struct ast_tcptls_session_instance * tcptls_session ) ;
static void * sip_tcp_worker_fn ( void * ) ;
/*--- Constructing requests and responses */
@ -2485,7 +2485,7 @@ static void *sip_tcp_worker_fn(void *data)
{
struct ast_tcptls_session_instance * tcptls_session = data ;
return _sip_tcp_helper_thread ( NULL , tcptls_session ) ;
return _sip_tcp_helper_thread ( tcptls_session ) ;
}
/*! \brief Check if the authtimeout has expired.
@ -2516,7 +2516,7 @@ static int sip_check_authtimeout(time_t start)
/*! \brief SIP TCP thread management function
This function reads from the socket , parses the packet into a request
*/
static void * _sip_tcp_helper_thread ( struct sip_pvt * pvt , struct ast_tcptls_session_instance * tcptls_session )
static void * _sip_tcp_helper_thread ( struct ast_tcptls_session_instance * tcptls_session )
{
int res , cl , timeout = - 1 , authenticated = 0 , flags , after_poll = 0 , need_poll = 1 ;
time_t start ;
@ -26269,6 +26269,7 @@ static int sip_prepare_socket(struct sip_pvt *p)
struct ast_tcptls_session_instance * tcptls_session ;
struct ast_tcptls_session_args * ca ;
struct ast_sockaddr sa_tmp ;
pthread_t launched ;
/* check to see if a socket is already active */
if ( ( s - > fd ! = - 1 ) & & ( s - > type = = SIP_TRANSPORT_UDP ) ) {
@ -26293,7 +26294,7 @@ static int sip_prepare_socket(struct sip_pvt *p)
}
/* At this point we are dealing with a TCP/TLS connection
* 1. We need to check to see if a connecti n thread exists
* 1. We need to check to see if a connecti o n thread exists
* for this address , if so use that .
* 2. If a thread does not exist for this address , but the tcptls_session
* exists on the socket , the connection was closed .
@ -26364,7 +26365,7 @@ static int sip_prepare_socket(struct sip_pvt *p)
/* Give the new thread a reference to the tcptls_session */
ao2_ref ( s - > tcptls_session , + 1 ) ;
if ( ast_pthread_create_ background( & ca - > master , NULL , sip_tcp_worker_fn , s - > tcptls_session ) ) {
if ( ast_pthread_create_ detached_background( & launched , NULL , sip_tcp_worker_fn , s - > tcptls_session ) ) {
ast_debug ( 1 , " Unable to launch '%s'. " , ca - > name ) ;
ao2_ref ( s - > tcptls_session , - 1 ) ; /* take away the thread ref we just gave it */
goto create_tcptls_session_fail ;
@ -31309,6 +31310,7 @@ static int unload_module(void)
struct sip_threadinfo * th ;
struct ast_context * con ;
struct ao2_iterator i ;
int wait_count ;
network_change_event_unsubscribe ( ) ;
@ -31367,7 +31369,6 @@ static int unload_module(void)
pthread_t thread = th - > threadid ;
th - > stop = 1 ;
pthread_kill ( thread , SIGURG ) ;
pthread_join ( thread , NULL ) ;
ao2_t_ref ( th , - 1 , " decrement ref from iterator " ) ;
}
ao2_iterator_destroy ( & i ) ;
@ -31413,21 +31414,11 @@ static int unload_module(void)
sip_epa_unregister_all ( ) ;
destroy_escs ( ) ;
if ( default_tls_cfg . certfile ) {
ast_free ( default_tls_cfg . certfile ) ;
}
if ( default_tls_cfg . pvtfile ) {
ast_free ( default_tls_cfg . pvtfile ) ;
}
if ( default_tls_cfg . cipher ) {
ast_free ( default_tls_cfg . cipher ) ;
}
if ( default_tls_cfg . cafile ) {
ast_free ( default_tls_cfg . cafile ) ;
}
if ( default_tls_cfg . capath ) {
ast_free ( default_tls_cfg . capath ) ;
}
ast_free ( default_tls_cfg . certfile ) ;
ast_free ( default_tls_cfg . pvtfile ) ;
ast_free ( default_tls_cfg . cipher ) ;
ast_free ( default_tls_cfg . cafile ) ;
ast_free ( default_tls_cfg . capath ) ;
cleanup_all_regs ( ) ;
ASTOBJ_CONTAINER_DESTROYALL ( & regl , sip_registry_destroy ) ;
@ -31445,6 +31436,21 @@ static int unload_module(void)
ASTOBJ_CONTAINER_DESTROYALL ( & submwil , sip_subscribe_mwi_destroy ) ;
ASTOBJ_CONTAINER_DESTROY ( & submwil ) ;
/*
* Wait awhile for the TCP / TLS thread container to become empty .
*
* XXX This is a hack , but the worker threads cannot be created
* joinable . They can die on their own and remove themselves
* from the container thus resulting in a huge memory leak .
*/
wait_count = 1000 ;
while ( ao2_container_count ( threadt ) & & - - wait_count ) {
sched_yield ( ) ;
}
if ( ! wait_count ) {
ast_debug ( 2 , " TCP/TLS thread container did not become empty :( \n " ) ;
}
ao2_t_ref ( peers , - 1 , " unref the peers table " ) ;
ao2_t_ref ( peers_by_ip , - 1 , " unref the peers_by_ip table " ) ;
ao2_t_ref ( dialogs , - 1 , " unref the dialogs table " ) ;