improve acceptor error handling

Sat, 03 Dec 2022 12:27:00 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 03 Dec 2022 12:27:00 +0100
changeset 445
834351da593b
parent 444
96d2ba2f28db
child 446
240ed6f945ca

improve acceptor error handling

src/server/daemon/config.c file | annotate | diff | comparison | revisions
src/server/daemon/httplistener.c file | annotate | diff | comparison | revisions
src/server/daemon/httplistener.h file | annotate | diff | comparison | revisions
--- a/src/server/daemon/config.c	Sun Nov 27 15:58:37 2022 +0100
+++ b/src/server/daemon/config.c	Sat Dec 03 12:27:00 2022 +0100
@@ -361,6 +361,8 @@
     CxIterator old_listeners = cxListIterator(old_cfg->listeners, 0);
     cx_foreach(HttpListener*, oldls, old_listeners) {
         if(oldls->next) {
+            // maybe we can remove this check
+            log_ereport(LOG_WARN, "migrate_server_conf: oldls->next not NULL");
             continue;
         }
                
@@ -371,6 +373,7 @@
                 break;
             }
         }
+        http_listener_shutdown_acceptors(oldls);
     }
     
     return 0;
--- a/src/server/daemon/httplistener.c	Sun Nov 27 15:58:37 2022 +0100
+++ b/src/server/daemon/httplistener.c	Sat Dec 03 12:27:00 2022 +0100
@@ -45,6 +45,7 @@
 #include <unistd.h>
 #include <strings.h>
 #include <stdbool.h>
+#include <signal.h>
 #include <pthread.h>
 
 #include <arpa/inet.h>
@@ -476,10 +477,17 @@
 }
 
 
+
+void http_listener_shutdown_acceptors(HttpListener *listener) {
+    // not implemented yet
+}
+
+
 Acceptor* acceptor_new(HttpListener *listener) {
     Acceptor *acceptor = malloc(sizeof(Acceptor));
     acceptor->listener = listener;
     acceptor->ipv6 = WS_FALSE;
+    acceptor->exit = WS_FALSE;
     return acceptor;
 }
 
@@ -491,7 +499,7 @@
             (void*(*)(void*))acceptor_thread,
             a) != 0)
     {
-        log_ereport(LOG_FAILURE, "Listener %s: acceptor_start: %s", a->listener->name.ptr, strerror(errno));
+        log_ereport(LOG_FAILURE, "Listener %s: acceptor_start: %s acceptor", a->listener->name.ptr, strerror(errno));
         cfg_unref(a->listener->cfg);
     }
 }
@@ -503,6 +511,7 @@
     WS_ASSERT(acceptor->listener->session_handler);
     WS_ASSERT(acceptor->listener->session_handler->enqueue_connection);
     
+    acceptor->running = TRUE;
     HttpListener *listener = acceptor->listener;
     
     int server_socket;
@@ -523,6 +532,7 @@
         addr_type = CONN_ADDR_IPV4;
     }
     
+    log_ereport(LOG_DEBUG, "acceptor: %p listener: %p start", acceptor, acceptor->listener);
     
     for (;;) {
         // accept connections
@@ -563,17 +573,26 @@
                 flags = 0;
             }
             if(fcntl(conn->fd, F_SETFL, flags | O_NONBLOCK)) {
-                perror("Error: acceptor_thread: fcntl");
-                // TODO: error
+                log_ereport(LOG_FAILURE, "acceptor: fcntl failed: %s", strerror(errno));
+                close(clientfd);
+                free(conn);
+                conn = NULL;
+            } else {
+                SSL *ssl = SSL_new(ls->ssl->sslctx);
+                if(ssl) {
+                    SSL_set_fd(ssl, clientfd);
+
+                    conn->ssl = ssl;
+                    conn->read = connection_ssl_read;
+                    conn->write = connection_ssl_write;
+                    conn->close = connection_ssl_close;
+                } else {
+                    log_ereport(LOG_FAILURE, "acceptor: %p listener: %p SSL_new() failed", acceptor, acceptor->listener);
+                    free(conn);
+                    close(clientfd);
+                    conn = NULL;
+                }
             }
-            
-            SSL *ssl = SSL_new(ls->ssl->sslctx);
-            SSL_set_fd(ssl, clientfd);
-            
-            conn->ssl = ssl;
-            conn->read = connection_ssl_read;
-            conn->write = connection_ssl_write;
-            conn->close = connection_ssl_close;
         } else {
             conn->ssl = NULL;
             conn->read = connection_read;
@@ -592,13 +611,16 @@
 
         // ready for new connection
         
-        if(acceptor_exit) {
+        if(acceptor_exit || acceptor->exit) {
             // this acceptor is outdated
             log_ereport(LOG_VERBOSE, "acceptor thread %p: exit", (void*)acceptor->tid);
             break;
         }
     }
     
+    acceptor->running = FALSE;
+    log_ereport(LOG_DEBUG, "acceptor: %p listener %p exit thread", acceptor, acceptor->listener);
+    
     cfg_unref(acceptor->listener->cfg);
     
     return NULL;
--- a/src/server/daemon/httplistener.h	Sun Nov 27 15:58:37 2022 +0100
+++ b/src/server/daemon/httplistener.h	Sat Dec 03 12:27:00 2022 +0100
@@ -76,6 +76,8 @@
     pthread_t      tid;
     HttpListener   *listener;
     WSBool         ipv6;
+    WSBool         exit;
+    WSBool         running;
 };
 
 struct _http_listener {
@@ -140,12 +142,15 @@
  */
 void http_listener_set_next(HttpListener *listener, HttpListener *next);
 
+/*
+ * shutdown all acceptor threads
+ */
+void http_listener_shutdown_acceptors(HttpListener *listener);
+
 Acceptor* acceptor_new(HttpListener *listener);
 
 void acceptor_start(Acceptor *a);
 
-void acceptor_shutdown(Acceptor *a);
-
 void* acceptor_thread(Acceptor *a);
 
 void wssocket_ref(WSSocket *ws);

mercurial