]> jfr.im git - solanum.git/commitdiff
ircd: support restarting ssld processes
authorSimon Arlott <sa.me.uk>
Wed, 10 Feb 2016 22:57:16 +0000 (22:57 +0000)
committerWilliam Pitcock <redacted>
Thu, 11 Feb 2016 01:03:30 +0000 (19:03 -0600)
Add REHASH SSLD (admins only) that starts new sslds and marks the
existing ones as inactive until all their clients disconnect.

Very useful whenever the SSL library has a vulnerability because
new connections can use a new version of the library without
disconnecting existing clients/servers.

Add STATS S (admins only) to list ssld processes, status, and client
count.

help/opers/rehash
help/opers/stats
include/sslproc.h
ircd/sslproc.c
modules/m_rehash.c
modules/m_stats.c

index 2226499dde518b182986eb210147f4813b5fecce..a8c062a463b4357a924a12f3fe96ccb63fbf2571 100644 (file)
@@ -11,6 +11,7 @@ ircd.conf file.
   NICKDELAY - Clears delayed nicks
   OMOTD    - Re-reads Oper MOTD file
   REJECTCACHE - Clears the reject cache
+  SSLD     - Restarts the ssld processes
   TDLINES  - Clears temporary D Lines
   THROTTLES - Clears throttled IP addresses
   TKLINES  - Clears temporary K Lines
index fb7bb347f6db8b1c8f4ff06901c91b8ac88dde15..c109b9daa530afe0c53c782c0dd0b3c034c8bfdb 100644 (file)
@@ -32,6 +32,7 @@ X f - Shows File Descriptors
 * q - Shows temporary and global resv'd nicks and channels
 * Q - Shows resv'd nicks and channels
 * r - Shows resource usage by ircd
+X S - Shows ssld processes
 * t - Shows generic server stats
 * U - Shows shared blocks (Old U: lines)
   u - Shows server uptime
index 838bff75079dbad0bea567958cbee633d3ce9909..b152d7eb77bbd4edd642337fb5b9c26a65866d95 100644 (file)
 struct _ssl_ctl;
 typedef struct _ssl_ctl ssl_ctl_t;
 
+enum ssld_status {
+       SSLD_ACTIVE,
+       SSLD_SHUTDOWN,
+       SSLD_DEAD,
+};
+
 void init_ssld(void);
+void restart_ssld(void);
 int start_ssldaemon(int count, const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params, const char *ssl_cipher_list);
 ssl_ctl_t *start_ssld_accept(rb_fde_t *sslF, rb_fde_t *plainF, uint32_t id);
 ssl_ctl_t *start_ssld_connect(rb_fde_t *sslF, rb_fde_t *plainF, uint32_t id);
@@ -35,6 +42,7 @@ void start_zlib_session(void *data);
 void send_new_ssl_certs(const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params, const char *ssl_cipher_list);
 void ssld_decrement_clicount(ssl_ctl_t *ctl);
 int get_ssld_count(void);
+void ssld_foreach_info(void (*func)(void *data, pid_t pid, int cli_count, enum ssld_status status), void *data);
 
 #endif
 
index 3b4be1a8e0e1928413267d6f3b298c0adb840607..4fad6dc47c1efd58b015edafcb5792783133aa58 100644 (file)
@@ -66,6 +66,7 @@ struct _ssl_ctl
        pid_t pid;
        rb_dlink_list readq;
        rb_dlink_list writeq;
+       uint8_t shutdown;
        uint8_t dead;
 };
 
@@ -150,6 +151,31 @@ static time_t last_spin;
 static int ssld_wait = 0;
 
 
+void
+restart_ssld(void)
+{
+       rb_dlink_node *ptr, *next;
+       ssl_ctl_t *ctl;
+
+       RB_DLINK_FOREACH_SAFE(ptr, next, ssl_daemons.head)
+       {
+               ctl = ptr->data;
+               if(ctl->dead)
+                       continue;
+               if(ctl->shutdown)
+                       continue;
+               ctl->shutdown = 1;
+               ssld_count--;
+               if(!ctl->cli_count)
+               {
+                       rb_kill(ctl->pid, SIGKILL);
+                       free_ssl_daemon(ctl);
+               }
+       }
+
+       start_ssldaemon(ServerInfo.ssld_count, ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list);
+}
+
 static void
 ssl_killall(void)
 {
@@ -161,8 +187,11 @@ ssl_killall(void)
                if(ctl->dead)
                        continue;
                ctl->dead = 1;
-               ssld_count--;
+               if(!ctl->shutdown)
+                       ssld_count--;
                rb_kill(ctl->pid, SIGKILL);
+               if(!ctl->cli_count)
+                       free_ssl_daemon(ctl);
        }
 }
 
@@ -173,11 +202,15 @@ ssl_dead(ssl_ctl_t * ctl)
                return;
 
        ctl->dead = 1;
-       ssld_count--;
        rb_kill(ctl->pid, SIGKILL);     /* make sure the process is really gone */
-       ilog(L_MAIN, "ssld helper died - attempting to restart");
-       sendto_realops_snomask(SNO_GENERAL, L_ALL, "ssld helper died - attempting to restart");
-       start_ssldaemon(1, ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list);
+
+       if(!ctl->shutdown)
+       {
+               ssld_count--;
+               ilog(L_MAIN, "ssld helper died - attempting to restart");
+               sendto_realops_snomask(SNO_GENERAL, L_ALL, "ssld helper died - attempting to restart");
+               start_ssldaemon(1, ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list);
+       }
 }
 
 static void
@@ -541,6 +574,8 @@ which_ssld(void)
                ctl = ptr->data;
                if(ctl->dead)
                        continue;
+               if(ctl->shutdown)
+                       continue;
                if(lowest == NULL)
                {
                        lowest = ctl;
@@ -737,6 +772,11 @@ ssld_decrement_clicount(ssl_ctl_t * ctl)
                return;
 
        ctl->cli_count--;
+       if(ctl->shutdown && !ctl->cli_count)
+       {
+               ctl->dead = 1;
+               rb_kill(ctl->pid, SIGKILL);
+       }
        if(ctl->dead && !ctl->cli_count)
        {
                free_ssl_daemon(ctl);
index 005ef35282f4deaaf44eb73a47598988e1991883..dae84c2c847f713817435dbd842314cc90bf9625 100644 (file)
@@ -44,6 +44,7 @@
 #include "hash.h"
 #include "cache.h"
 #include "irc_radixtree.h"
+#include "sslproc.h"
 
 static int mo_rehash(struct Client *, struct Client *, int, const char **);
 static int me_rehash(struct Client *, struct Client *, int, const char **);
@@ -85,6 +86,15 @@ rehash_dns(struct Client *source_p)
        restart_authd();
 }
 
+static void
+rehash_ssld(struct Client *source_p)
+{
+       sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s is restarting ssld",
+                               get_oper_name(source_p));
+
+       restart_ssld();
+}
+
 static void
 rehash_motd(struct Client *source_p)
 {
@@ -276,6 +286,7 @@ static struct hash_commands rehash_commands[] =
 {
        {"BANS",        rehash_bans_loc         },
        {"DNS",         rehash_dns              },
+       {"SSLD",        rehash_ssld             },
        {"MOTD",        rehash_motd             },
        {"OMOTD",       rehash_omotd            },
        {"TKLINES",     rehash_tklines          },
index 21631e15d1c2f20576530df23c39468ed1597863..4fccb5e96410f29906979c4b2033cd334036750f 100644 (file)
@@ -49,6 +49,7 @@
 #include "reject.h"
 #include "whowas.h"
 #include "irc_radixtree.h"
+#include "sslproc.h"
 
 static int m_stats (struct Client *, struct Client *, int, const char **);
 
@@ -109,6 +110,7 @@ static void stats_operedup(struct Client *);
 static void stats_ports(struct Client *);
 static void stats_tresv(struct Client *);
 static void stats_resv(struct Client *);
+static void stats_ssld(struct Client *);
 static void stats_usage(struct Client *);
 static void stats_tstats(struct Client *);
 static void stats_uptime(struct Client *);
@@ -162,6 +164,8 @@ static struct StatsStruct stats_cmd_table[] = {
        {'Q', stats_resv,               1, 0, },
        {'r', stats_usage,              1, 0, },
        {'R', stats_usage,              1, 0, },
+       {'s', stats_ssld,               1, 1, },
+       {'S', stats_ssld,               1, 1, },
        {'t', stats_tstats,             1, 0, },
        {'T', stats_tstats,             1, 0, },
        {'u', stats_uptime,             0, 0, },
@@ -884,6 +888,24 @@ stats_resv(struct Client *source_p)
        }
 }
 
+static void
+stats_ssld_foreach(void *data, pid_t pid, int cli_count, enum ssld_status status)
+{
+       struct Client *source_p = data;
+
+       sendto_one_numeric(source_p, RPL_STATSDEBUG,
+                       "S :%u %c %u",
+                       pid,
+                       status == SSLD_DEAD ? 'D' : (status == SSLD_SHUTDOWN ? 'S' : 'A'),
+                       cli_count);
+}
+
+static void
+stats_ssld(struct Client *source_p)
+{
+       ssld_foreach_info(stats_ssld_foreach, source_p);
+}
+
 static void
 stats_usage (struct Client *source_p)
 {