diff --git a/help/opers/rehash b/help/opers/rehash index 2226499dd..a8c062a46 100644 --- a/help/opers/rehash +++ b/help/opers/rehash @@ -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 diff --git a/help/opers/stats b/help/opers/stats index fb7bb347f..c109b9daa 100644 --- a/help/opers/stats +++ b/help/opers/stats @@ -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 diff --git a/include/sslproc.h b/include/sslproc.h index 838bff750..b152d7eb7 100644 --- a/include/sslproc.h +++ b/include/sslproc.h @@ -27,7 +27,14 @@ 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 diff --git a/ircd/sslproc.c b/ircd/sslproc.c index 3b4be1a8e..4fad6dc47 100644 --- a/ircd/sslproc.c +++ b/ircd/sslproc.c @@ -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); diff --git a/modules/m_rehash.c b/modules/m_rehash.c index 005ef3528..dae84c2c8 100644 --- a/modules/m_rehash.c +++ b/modules/m_rehash.c @@ -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 }, diff --git a/modules/m_stats.c b/modules/m_stats.c index 21631e15d..4fccb5e96 100644 --- a/modules/m_stats.c +++ b/modules/m_stats.c @@ -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) {