]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/conn.c
ngIRCd Release 27
[ngircd-alex.git] / src / ngircd / conn.c
index 3882899f4406b85829d0f5e0ce04f0008aff093a..68a901d05e6a066aee87cadeb9e1f51d21873a5d 100644 (file)
@@ -66,6 +66,7 @@
 #include "ng_ipaddr.h"
 #include "parse.h"
 #include "resolve.h"
+#include "sighandlers.h"
 
 #define SERVER_WAIT (NONE - 1)         /** "Wait for outgoing connection" flag */
 
@@ -668,11 +669,13 @@ Conn_Handler(void)
        int i;
        size_t wdatalen;
        struct timeval tv;
-       time_t t;
+       time_t t, notify_t = 0;
        bool command_available;
+       char status[200];
 
        Log(LOG_NOTICE, "Server \"%s\" (on \"%s\") ready.",
            Client_ID(Client_ThisServer()), Client_Hostname(Client_ThisServer()));
+       Signal_NotifySvcMgr("READY=1\n");
 
        while (!NGIRCd_SignalQuit && !NGIRCd_SignalRestart) {
                t = time(NULL);
@@ -781,20 +784,34 @@ Conn_Handler(void)
                        exit(1);
                }
 
-               /* Should ngIRCd timeout when idle? */
+               t = time(NULL);
                if (Conf_IdleTimeout > 0 && NumConnectionsAccepted > 0
-                   && idle_t > 0 && time(NULL) - idle_t >= Conf_IdleTimeout) {
+                   && idle_t > 0 && t - idle_t >= Conf_IdleTimeout) {
+                       /* Should ngIRCd timeout when idle? */
                        LogDebug("Server idle timeout reached: %d second%s. Initiating shutdown ...",
                                 Conf_IdleTimeout,
                                 Conf_IdleTimeout == 1 ? "" : "s");
                        NGIRCd_SignalQuit = true;
+               } else if (Signal_NotifySvcMgr_Possible() && t - notify_t > 3) {
+                       /* Send the current status to the service manager. */
+                       snprintf(status, sizeof(status),
+                                "WATCHDOG=1\nSTATUS=%ld connection%s established (%ld user%s, %ld server%s), %ld maximum. %ld accepted in total.\n",
+                                (long)NumConnections, NumConnections == 1 ? "" : "s",
+                                Client_MyUserCount(), Client_MyUserCount() == 1 ? "" : "s",
+                                Client_MyServerCount(), Client_MyServerCount() == 1 ? "" : "s",
+                                (long)NumConnectionsMax, (long)NumConnectionsAccepted);
+                       Signal_NotifySvcMgr(status);
+                       notify_t = t;
                }
        }
 
-       if (NGIRCd_SignalQuit)
+       if (NGIRCd_SignalQuit) {
                Log(LOG_NOTICE | LOG_snotice, "Server going down NOW!");
-       else if (NGIRCd_SignalRestart)
+               Signal_NotifySvcMgr("STOPPING=1\n");
+       } else if (NGIRCd_SignalRestart) {
                Log(LOG_NOTICE | LOG_snotice, "Server restarting NOW!");
+               Signal_NotifySvcMgr("RELOADING=1\n");
+       }
 } /* Conn_Handler */
 
 /**
@@ -2556,6 +2573,13 @@ cb_listen_ssl(int sock, short irrelevant)
 /**
  * IO callback for new outgoing SSL-enabled server connections.
  *
+ * IMPORTANT: The SSL session has been validated before, but all errors have
+ * been ignored so far! The reason for this is that the generic SSL code has no
+ * idea if the new session actually belongs to a server, as this only becomes
+ * clear when the remote peer sends its PASS command (and we have to handle
+ * invalid client certificates!). Therefore, it is important to check the
+ * status of the SSL session first before continuing the server handshake here!
+ *
  * @param sock         Socket descriptor.
  * @param unused       (ignored IO specification)
  */
@@ -2584,28 +2608,25 @@ cb_connserver_login_ssl(int sock, short unused)
 
        serveridx = Conf_GetServer(idx);
        assert(serveridx >= 0);
-       if (serveridx < 0)
-               goto err;
-
-       Log( LOG_INFO, "SSL connection %d with \"%s:%d\" established.", idx,
-           My_Connections[idx].host, Conf_Server[Conf_GetServer( idx )].port );
 
+       /* The SSL handshake is done, but validation results were ignored so
+        * far, so let's see where we are: */
+       LogDebug("SSL handshake on socket %d done.", idx);
        if (!Conn_OPTION_ISSET(&My_Connections[idx], CONN_SSL_PEERCERT_OK)) {
                if (Conf_Server[serveridx].SSLVerify) {
                        Log(LOG_ERR,
-                               "SSLVerify enabled for %d, but peer certificate check failed",
-                               idx);
-                       goto err;
+                               "Peer certificate check failed for \"%s\" on connection %d!",
+                               My_Connections[idx].host, idx);
+                       Conn_Close(idx, "Valid certificate required",
+                                  NULL, false);
+                       return;
                }
                Log(LOG_WARNING,
-                       "Peer certificate check failed for %d, but SSLVerify is disabled, continuing",
-                       idx);
+                       "Peer certificate check failed for \"%s\" on connection %d, but \"SSLVerify\" is disabled. Continuing ...",
+                       My_Connections[idx].host, idx);
        }
+       LogDebug("Server certificate accepted, continuing server login ...");
        server_login(idx);
-       return;
-      err:
-       Log(LOG_ERR, "SSL connection on socket %d failed!", sock);
-       Conn_Close(idx, "Can't connect!", NULL, false);
 }