ircd: support restarting ssld processes
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.
This commit is contained in:
parent
dea27a087c
commit
eb1b303d56
6 changed files with 88 additions and 5 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
if(!ctl->shutdown)
|
||||
ssld_count--;
|
||||
rb_kill(ctl->pid, SIGKILL);
|
||||
if(!ctl->cli_count)
|
||||
free_ssl_daemon(ctl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,12 +202,16 @@ ssl_dead(ssl_ctl_t * ctl)
|
|||
return;
|
||||
|
||||
ctl->dead = 1;
|
||||
ssld_count--;
|
||||
rb_kill(ctl->pid, SIGKILL); /* make sure the process is really gone */
|
||||
|
||||
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
|
||||
ssl_do_pipe(rb_fde_t * F, void *data)
|
||||
|
@ -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);
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue