Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 103333) +++ channels/chan_sip.c (working copy) @@ -773,7 +773,6 @@ /*!< The SIP socket definition */ struct sip_socket { - ast_mutex_t *lock; enum sip_transport type; int fd; uint16_t port; @@ -2167,13 +2166,6 @@ AST_LIST_INSERT_TAIL(&threadl, me, list); AST_LIST_UNLOCK(&threadl); - req.socket.lock = ast_calloc(1, sizeof(*req.socket.lock)); - - if (!req.socket.lock) - goto cleanup; - - ast_mutex_init(req.socket.lock); - for (;;) { memset(req.data, 0, sizeof(req.data)); req.len = 0; @@ -2195,12 +2187,12 @@ /* Read in headers one line at a time */ while (req.len < 4 || strncmp((char *)&req.data + req.len - 4, "\r\n\r\n", 4)) { - if (req.socket.lock) - ast_mutex_lock(req.socket.lock); + if (ser->lock) + ast_mutex_lock(ser->lock); if (!fgets(buf, sizeof(buf), ser->f)) - goto cleanup; - if (req.socket.lock) - ast_mutex_unlock(req.socket.lock); + goto cleanupunlock; + if (ser->lock) + ast_mutex_unlock(ser->lock); if (me->stop) goto cleanup; strncat(req.data, buf, sizeof(req.data) - req.len); @@ -2209,12 +2201,12 @@ parse_copy(&reqcpy, &req); if (sscanf(get_header(&reqcpy, "Content-Length"), "%d", &cl)) { while (cl > 0) { - if (req.socket.lock) - ast_mutex_lock(req.socket.lock); + if (ser->lock) + ast_mutex_lock(ser->lock); if (!fread(buf, (cl < sizeof(buf)) ? cl : sizeof(buf), 1, ser->f)) - goto cleanup; - if (req.socket.lock) - ast_mutex_unlock(req.socket.lock); + goto cleanupunlock; + if (ser->lock) + ast_mutex_unlock(ser->lock); if (me->stop) goto cleanup; cl -= strlen(buf); @@ -2226,6 +2218,9 @@ handle_request_do(&req, &ser->requestor); } +cleanupunlock: + if (ser->lock) + ast_mutex_unlock(ser->lock); cleanup: AST_LIST_LOCK(&threadl); AST_LIST_REMOVE(&threadl, me, list); @@ -2233,9 +2228,8 @@ ast_free(me); cleanup2: fclose(ser->f); - ast_free(ser); - ast_free(req.socket.lock); - + ser->fd = -1; + return NULL; } @@ -2509,8 +2503,8 @@ if (sip_prepare_socket(p) < 0) return XMIT_ERROR; - if (p->socket.lock) - ast_mutex_lock(p->socket.lock); + if (p->socket.ser) + ast_mutex_lock(p->socket.ser->lock); if (p->socket.type & SIP_TRANSPORT_UDP) res = sendto(p->socket.fd, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); @@ -2521,8 +2515,8 @@ ast_debug(1, "No p->socket.ser->f len=%d\n", len); } - if (p->socket.lock) - ast_mutex_unlock(p->socket.lock); + if (p->socket.ser) + ast_mutex_unlock(p->socket.ser->lock); if (res == -1) { switch (errno) { @@ -4175,6 +4169,7 @@ if (p->stimer->st_active == TRUE && p->stimer->st_schedid > -1) ast_sched_del(sched, p->stimer->st_schedid); ast_free(p->stimer); + p->stimer = NULL; } /* Unlink us from the owner if we have one */ @@ -5712,6 +5707,9 @@ int found = FALSE; if (ast_strlen_zero(p->callid)) continue; + /* If there is a TCP/TLS server attached and it doesn't have a fd don't consider it */ + if (p->socket.ser && p->socket.ser->fd == -1) + continue; if (req->method == SIP_REGISTER) found = (!strcmp(p->callid, callid)); else @@ -7333,7 +7331,6 @@ build_via(p); ast_string_field_set(p, callid, callid); - p->socket.lock = req->socket.lock; p->socket.type = req->socket.type; p->socket.fd = req->socket.fd; p->socket.port = req->socket.port; @@ -17828,7 +17825,6 @@ req.socket.type = SIP_TRANSPORT_UDP; req.socket.ser = NULL; req.socket.port = bindaddr.sin_port; - req.socket.lock = NULL; handle_request_do(&req, &sin); @@ -17863,13 +17859,15 @@ /* Process request, with netlock held, and with usual deadlock avoidance */ for (lockretry = 100; lockretry > 0; lockretry--) { - ast_mutex_lock(&netlock); + if (req->socket.type & SIP_TRANSPORT_UDP) + ast_mutex_lock(&netlock); /* Find the active SIP dialog or create a new one */ p = find_call(req, sin, req->method); /* returns p locked */ if (p == NULL) { ast_debug(1, "Invalid SIP message - rejected , no callid, len %d\n", req->len); - ast_mutex_unlock(&netlock); + if (req->socket.type & SIP_TRANSPORT_UDP) + ast_mutex_unlock(&netlock); return 1; } @@ -17881,7 +17879,8 @@ break; /* locking succeeded */ ast_debug(1, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid); sip_pvt_unlock(p); - ast_mutex_unlock(&netlock); + if (req->socket.type & SIP_TRANSPORT_UDP) + ast_mutex_unlock(&netlock); /* Sleep for a very short amount of time */ usleep(1); } @@ -17913,7 +17912,8 @@ if (p->owner && !nounlock) ast_channel_unlock(p->owner); sip_pvt_unlock(p); - ast_mutex_unlock(&netlock); + if (req->socket.type & SIP_TRANSPORT_UDP) + ast_mutex_unlock(&netlock); return 1; } @@ -17936,7 +17936,7 @@ AST_LIST_TRAVERSE(&threadl, th, list) { if ((s->sin_family == th->ser->requestor.sin_family) && (s->sin_addr.s_addr == th->ser->requestor.sin_addr.s_addr) && - (s->sin_port == th->ser->requestor.sin_port)) { + (s->sin_port == th->ser->requestor.sin_port)) { AST_LIST_UNLOCK(&threadl); return th->ser; } @@ -18199,7 +18199,8 @@ get back to this point every millisecond or less) */ for (dialog = dialoglist; dialog; dialog = dialog->next) { - sip_pvt_lock(dialog); + if (ast_mutex_trylock(&dialog->pvt_lock)) + break; /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ check_rtp_timeout(dialog, t); /* If we have sessions that needs to be destroyed, do it now */ Index: include/asterisk/tcptls.h =================================================================== --- include/asterisk/tcptls.h (revision 103333) +++ include/asterisk/tcptls.h (working copy) @@ -125,6 +125,7 @@ SSL *ssl; /* ssl state */ /* iint (*ssl_setup)(SSL *); */ int client; + ast_mutex_t *lock; struct sockaddr_in requestor; struct server_args *parent; }; Index: main/tcptls.c =================================================================== --- main/tcptls.c (revision 103333) +++ main/tcptls.c (working copy) @@ -83,6 +83,8 @@ HOOK_T server_read(struct server_instance *ser, void *buf, size_t count) { + if (ser->fd == -1) + return -1; #ifdef DO_SSL if (ser->ssl) return ssl_read(ser->ssl, buf, count); @@ -92,6 +94,8 @@ HOOK_T server_write(struct server_instance *ser, void *buf, size_t count) { + if (ser->fd == -1) + return -1; #ifdef DO_SSL if (ser->ssl) return ssl_write(ser->ssl, buf, count); @@ -136,6 +140,12 @@ memcpy(&ser->requestor, &sin, sizeof(ser->requestor)); ser->client = 0; + ser->lock = ast_calloc(1, sizeof(*ser->lock)); + if (!ser->lock) { + close(fd); + continue; + } + ast_mutex_init(ser->lock); if (ast_pthread_create_detached_background(&launched, NULL, ast_make_file_from_fd, ser)) { ast_log(LOG_WARNING, "Unable to launch helper thread: %s\n", strerror(errno)); @@ -247,6 +257,10 @@ memcpy(&ser->requestor, &desc->sin, sizeof(ser->requestor)); ser->client = 1; + ser->lock = ast_calloc(1, sizeof(*ser->lock)); + if (!ser->lock) + goto error; + ast_mutex_init(ser->lock); if (desc->tls_cfg) { desc->tls_cfg->enabled = 1;