Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 103824) +++ 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; @@ -2170,13 +2169,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; @@ -2198,12 +2190,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); @@ -2212,12 +2204,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); @@ -2229,6 +2221,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); @@ -2236,9 +2231,8 @@ ast_free(me); cleanup2: fclose(ser->f); - ast_free(ser); - ast_free(req.socket.lock); - + ser->fd = -1; + return NULL; } @@ -2512,8 +2506,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)); @@ -2524,8 +2518,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) { @@ -4281,6 +4275,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; } /* Clear history */ @@ -5827,6 +5822,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 @@ -7445,7 +7443,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; @@ -17942,7 +17939,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); @@ -17977,13 +17973,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; } @@ -17995,7 +17993,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); } @@ -18027,7 +18026,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; } @@ -18050,7 +18050,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; } @@ -18313,7 +18313,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 */ @@ -21377,6 +21378,7 @@ AST_LIST_UNLOCK(&threadl); pthread_kill(thread, SIGURG); pthread_join(thread, NULL); + usleep(100); AST_LIST_LOCK(&threadl); } AST_LIST_TRAVERSE_SAFE_END; Index: include/asterisk/tcptls.h =================================================================== --- include/asterisk/tcptls.h (revision 103824) +++ 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 103824) +++ main/tcptls.c (working copy) @@ -83,6 +83,10 @@ HOOK_T server_read(struct server_instance *ser, void *buf, size_t count) { + if (ser->fd == -1) { + errno = EIO; + return -1; + } #ifdef DO_SSL if (ser->ssl) return ssl_read(ser->ssl, buf, count); @@ -92,6 +96,10 @@ HOOK_T server_write(struct server_instance *ser, void *buf, size_t count) { + if (ser->fd == -1) { + errno = EIO; + return -1; + } #ifdef DO_SSL if (ser->ssl) return ssl_write(ser->ssl, buf, count); @@ -136,6 +144,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 +261,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;