]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
tcptls.c: Cleanup TCP/TLS listener thread on abnormal exit.
authorRichard Mudgett <rmudgett@digium.com>
Mon, 10 Apr 2017 22:45:35 +0000 (17:45 -0500)
committerRichard Mudgett <rmudgett@digium.com>
Tue, 11 Apr 2017 16:13:53 +0000 (11:13 -0500)
Temporarily running out of file descriptors should not terminate the
listener thread.  Otherwise, when there becomes more file descriptors
available, nothing is listening.

* Added EMFILE exception to abnormal thread exit.

* Added an abnormal TCP/TLS listener exit error message.

* Closed the TCP/TLS listener socket on abnormal exit so Asterisk does not
appear dead if something tries to connect to the socket.

ASTERISK-26903 #close

Change-Id: I10f2f784065136277f271159f0925927194581b5

main/tcptls.c

index c46b8df43dacfbd3b326d832f0e453db32d1e890..3fd3c531227cc9da6164fd885f87e77ef31cd31f 100644 (file)
@@ -761,14 +761,23 @@ void *ast_tcptls_server_root(void *data)
                }
                i = ast_wait_for_input(desc->accept_fd, desc->poll_timeout);
                if (i <= 0) {
+                       /* Prevent tight loop from hogging CPU */
+                       usleep(1);
                        continue;
                }
                fd = ast_accept(desc->accept_fd, &addr);
                if (fd < 0) {
-                       if ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINTR) && (errno != ECONNABORTED)) {
-                               ast_log(LOG_ERROR, "Accept failed: %s\n", strerror(errno));
-                               break;
+                       if (errno != EAGAIN
+                               && errno != EWOULDBLOCK
+                               && errno != EINTR
+                               && errno != ECONNABORTED) {
+                               ast_log(LOG_ERROR, "TCP/TLS accept failed: %s\n", strerror(errno));
+                               if (errno != EMFILE) {
+                                       break;
+                               }
                        }
+                       /* Prevent tight loop from hogging CPU */
+                       usleep(1);
                        continue;
                }
                tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor);
@@ -793,11 +802,21 @@ void *ast_tcptls_server_root(void *data)
 
                /* This thread is now the only place that controls the single ref to tcptls_session */
                if (ast_pthread_create_detached_background(&launched, NULL, handle_tcptls_connection, tcptls_session)) {
-                       ast_log(LOG_ERROR, "Unable to launch helper thread: %s\n", strerror(errno));
+                       ast_log(LOG_ERROR, "TCP/TLS unable to launch helper thread: %s\n",
+                               strerror(errno));
                        ast_tcptls_close_session_file(tcptls_session);
                        ao2_ref(tcptls_session, -1);
                }
        }
+
+       ast_log(LOG_ERROR, "TCP/TLS listener thread ended abnormally\n");
+
+       /* Close the listener socket so Asterisk doesn't appear dead. */
+       fd = desc->accept_fd;
+       desc->accept_fd = -1;
+       if (0 <= fd) {
+               close(fd);
+       }
        return NULL;
 }