implement successor listener, fix webserver_reconfig

Sat, 26 Nov 2022 19:15:33 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 26 Nov 2022 19:15:33 +0100
changeset 440
d77b8f3e14e2
parent 439
255e316db762
child 441
797aeb31a2c6

implement successor listener, fix webserver_reconfig

src/server/daemon/config.c file | annotate | diff | comparison | revisions
src/server/daemon/config.h file | annotate | diff | comparison | revisions
src/server/daemon/configmanager.c file | annotate | diff | comparison | revisions
src/server/daemon/event.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
src/server/daemon/webserver.c file | annotate | diff | comparison | revisions
--- a/src/server/daemon/config.c	Sat Nov 26 19:14:29 2022 +0100
+++ b/src/server/daemon/config.c	Sat Nov 26 19:15:33 2022 +0100
@@ -349,6 +349,27 @@
     return serverconfig;
 }
 
+int migrate_server_conf(ServerConfiguration *old_cfg, ServerConfiguration *new_cfg) {
+    // compare old/new listeners and set next listener, if they are using
+    // the same socket
+    CxIterator old_listeners = cxListIterator(old_cfg->listeners, 0);
+    cx_foreach(HttpListener*, oldls, old_listeners) {
+        if(oldls->next) {
+            continue;
+        }
+        
+        CxIterator new_listeners = cxListIterator(new_cfg->listeners, 0);
+        cx_foreach(HttpListener*, newls, new_listeners) {
+            if(http_listener_socket_eq(oldls, newls)) {
+                oldls->next = newls;
+                break;
+            }
+        }
+    }
+    
+    return 0;
+}
+
 void cfg_ref(ServerConfiguration *cfg) {
     ws_atomic_inc32(&cfg->ref);
 }
--- a/src/server/daemon/config.h	Sat Nov 26 19:14:29 2022 +0100
+++ b/src/server/daemon/config.h	Sat Nov 26 19:15:33 2022 +0100
@@ -132,6 +132,8 @@
 
 ServerConfiguration* load_server_conf(CfgManager *mgr, char *file);
 ServerConfiguration* apply_server_conf(CfgManager *mgr);
+int migrate_server_conf(ServerConfiguration *old_cfg, ServerConfiguration *new_cfg);
+
 void cfg_ref(ServerConfiguration *cfg);
 void cfg_unref(ServerConfiguration *cfg);
 
--- a/src/server/daemon/configmanager.c	Sat Nov 26 19:14:29 2022 +0100
+++ b/src/server/daemon/configmanager.c	Sat Nov 26 19:15:33 2022 +0100
@@ -65,17 +65,23 @@
 }
 
 int cfgmgr_apply_config(CfgManager *mgr) {
-    int err = 0;
-    if(apply_server_conf(mgr)) {
-        if(current_config) {
-            cfg_unref(current_config);
-        }
-        current_config = mgr->cfg;
-    } else {
-        err = 1;
+    // stage 2 config loading
+    if(!apply_server_conf(mgr)) {
+        return 1;
     }
     
-    return err;
+    // some extra steps required if there is already a configuration loaded
+    if(current_config) {
+        if(migrate_server_conf(current_config, mgr->cfg)) {
+            return 1;
+        }
+        
+        cfg_unref(current_config);
+    }
+    
+    current_config = mgr->cfg;
+    
+    return 0;
 }
 
 ServerConfiguration *cfgmgr_get_server_config() {
--- a/src/server/daemon/event.c	Sat Nov 26 19:14:29 2022 +0100
+++ b/src/server/daemon/event.c	Sat Nov 26 19:15:33 2022 +0100
@@ -49,7 +49,7 @@
     if(cxMapGet(event_handler_map, key)) {
         /* TODO: log message */
         /* TODO: set reload status */
-        return 1;
+        return 0;
     }
     
     /* create new handler */
--- a/src/server/daemon/httplistener.c	Sat Nov 26 19:14:29 2022 +0100
+++ b/src/server/daemon/httplistener.c	Sat Nov 26 19:15:33 2022 +0100
@@ -465,6 +465,24 @@
     }
 }
 
+int http_listener_socket_eq(HttpListener *l1, HttpListener *l2) {
+    if(l1->server_socket && l2->server_socket && l1->server_socket == l2->server_socket) {
+        return TRUE;
+    }
+    if(l1->server_socket6 && l2->server_socket6 && l1->server_socket6 == l2->server_socket6) {
+        return TRUE;
+    }
+    return FALSE;
+}
+
+void http_listener_set_next(HttpListener *listener, HttpListener *next) {
+    while(listener->next) {
+        listener = listener->next;
+    }
+    
+    http_listener_ref(next);
+    listener->next = next;
+}
 
 
 Acceptor* acceptor_new(HttpListener *listener) {
@@ -522,6 +540,7 @@
                 server_socket,
                 ca_ptr,
                 &length);
+        log_ereport(LOG_DEBUG, "acceptor: %p listener: %p: accept(): %d", acceptor, acceptor->listener, clientfd);
         if (clientfd == -1) {
             log_ereport(LOG_FAILURE, "accept %s failed: %s", acceptor->ipv6 ? "ipv6" : "ipv4", strerror(errno));
             continue;
@@ -535,7 +554,7 @@
             acceptor_exit = 1;
         }
         
-        /* create Connection object */
+        // create Connection object
         Connection *conn = malloc(sizeof(Connection));
         conn->address = ca;
         conn->addr_type = addr_type;
@@ -571,13 +590,13 @@
         if(conn) {
             cfg_ref(ls->cfg);
 
-            /* enqueue the connection */
+            // enqueue the connection
             ls->session_handler->enqueue_connection(
                     ls->session_handler,
                     conn);
         }
 
-        /* ready for new connection */
+        // ready for new connection
         
         if(acceptor_exit) {
             // this acceptor is outdated
@@ -586,7 +605,9 @@
         }
     }
     
-    http_listener_unref(listener->next);
+    if(listener->next) {
+        http_listener_unref(listener->next);
+    }
     http_listener_unref(listener);
     
     return NULL;
--- a/src/server/daemon/httplistener.h	Sat Nov 26 19:14:29 2022 +0100
+++ b/src/server/daemon/httplistener.h	Sat Nov 26 19:15:33 2022 +0100
@@ -80,7 +80,7 @@
 
 struct _http_listener {
     ServerConfiguration  *cfg;
-    cxmutstr               name;
+    cxmutstr             name;
     union vs             default_vs;
     int                  port;
     WSSocket             *server_socket;
@@ -128,14 +128,21 @@
 
 HttpListener* http_listener_create(ListenerConfig *conf);
 
-// used by http_listener_create
-HttpListener* http_listener_new(ListenerConfig *conf);
-
 int http_listener_start(HttpListener *listener);
 
 void http_listener_ref(HttpListener *listener);
 void http_listener_unref(HttpListener *listener);
 
+/*
+ * returns true of l1 and l2 share the same socket
+ */
+int http_listener_socket_eq(HttpListener *l1, HttpListener *l2);
+
+/*
+ * set the succeeding listener
+ */
+void http_listener_set_next(HttpListener *listener, HttpListener *next);
+
 Acceptor* acceptor_new(HttpListener *listener);
 
 void acceptor_start(Acceptor *a);
--- a/src/server/daemon/webserver.c	Sat Nov 26 19:14:29 2022 +0100
+++ b/src/server/daemon/webserver.c	Sat Nov 26 19:15:33 2022 +0100
@@ -284,9 +284,17 @@
 }
 
 int webserver_reconfig() {
-    if(cfgmgr_load_config(NULL) != 0) {
-        return -1;
+    CfgManager mgr;
+    if(cfgmgr_load_config(&mgr) != 0) {
+        log_ereport(LOG_FAILURE, "cannot reload server.conf");
+        return 1;
+    } else {
+        if(cfgmgr_apply_config(&mgr)) {
+            log_ereport(LOG_FAILURE, "cannot reload config");
+            return 1;
+        }
     }
+    
     // start newly created listeners
     start_all_listener();
     

mercurial