Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 110639) +++ channels/chan_sip.c (working copy) @@ -780,7 +780,7 @@ ast_mutex_t *lock; enum sip_transport type; int fd; - uint16_t port; + uint16_t port; /* XXX Is this even used anywhere? */ struct ast_tcptls_session_instance *ser; }; @@ -18225,22 +18225,49 @@ struct sip_socket *s = &p->socket; static const char name[] = "SIP socket"; struct ast_tcptls_session_instance *ser; + struct sip_threadinfo *thread; struct server_args ca = { .name = name, .accept_fd = -1, }; + int deadthread = 0; /* boolean used to see if we just killed a TCP helper thread */ - if (s->fd != -1) - return s->fd; + ca.sin = *(sip_real_dst(p)); + if (s->fd != -1) { + if ((s->type & SIP_TRANSPORT_TCP) && s->ser && inaddrcmp(&s->ser->requestor, &ca.sin)) { + /* Let's stop the previously running helper thread associated with this + * socket. + */ + AST_LIST_LOCK(&threadl); + AST_LIST_TRAVERSE(&threadl, thread, list) { + if (thread->ser->fd == s->fd) { /* XXX Specific enough check ? */ + /* This will signal the thread to stop */ + thread->stop = 1; + /* This will wake it from the poll if necessary */ + pthread_kill(thread->threadid, SIGURG); + deadthread = 1; + } + } + AST_LIST_UNLOCK(&threadl); + /* XXX Is this enough? The cleanup section of the tcp helper thread + * closes fd's, but I don't know if it's enough to actually shut down + * the TCP connection + */ + } else { + return s->fd; + } + } + if (s->type & SIP_TRANSPORT_UDP) { s->fd = sipsock; return s->fd; } - ca.sin = *(sip_real_dst(p)); - - if ((ser = sip_tcp_locate(&ca.sin))) { + /* No point searching for the associated tcp helper thread if + * we just killed it + */ + if (!deadthread && (ser = sip_tcp_locate(&ca.sin))) { s->fd = ser->fd; s->ser = ser; return s->fd;