X-Git-Url: https://jfr.im/git/solanum.git/blobdiff_plain/b9ff4868a9f7d1a63f161dc9272359f1348c38c2..bfc44622c8d3c9b94e89ee169e0e04d61adcc098:/ircd/sslproc.c diff --git a/ircd/sslproc.c b/ircd/sslproc.c index fa3afba7..c6625314 100644 --- a/ircd/sslproc.c +++ b/ircd/sslproc.c @@ -17,11 +17,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA - * - * $Id$ */ -#include +#include #include "stdinc.h" @@ -66,7 +64,9 @@ struct _ssl_ctl pid_t pid; rb_dlink_list readq; rb_dlink_list writeq; + uint8_t shutdown; uint8_t dead; + char version[256]; }; static void send_new_ssl_certs_one(ssl_ctl_t * ctl, const char *ssl_cert, @@ -150,6 +150,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 +186,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 +201,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 @@ -307,7 +339,7 @@ start_ssldaemon(int count, const char *ssl_cert, const char *ssl_private_key, co rb_close(F2); rb_close(P1); ctl = allocate_ssl_daemon(F1, P2, pid); - if(ssl_ok) + if(ircd_ssl_ok) { send_init_prng(ctl, RB_PRNG_DEFAULT, NULL); send_certfp_method(ctl, ConfigFileEntry.certfp_method); @@ -446,15 +478,18 @@ ssl_process_cmd_recv(ssl_ctl_t * ctl) static const char *no_ssl_or_zlib = "ssld has neither SSL/TLS or zlib support killing all sslds"; rb_dlink_node *ptr, *next; ssl_ctl_buf_t *ctl_buf; + int len; + if(ctl->dead) return; + RB_DLINK_FOREACH_SAFE(ptr, next, ctl->readq.head) { ctl_buf = ptr->data; switch (*ctl_buf->buf) { case 'N': - ssl_ok = 0; /* ssld says it can't do ssl/tls */ + ircd_ssl_ok = false; /* ssld says it can't do ssl/tls */ break; case 'D': ssl_process_dead_fd(ctl, ctl_buf); @@ -469,17 +504,22 @@ ssl_process_cmd_recv(ssl_ctl_t * ctl) ssl_process_zipstats(ctl, ctl_buf); break; case 'I': - ssl_ok = 0; + ircd_ssl_ok = false; ilog(L_MAIN, "%s", cannot_setup_ssl); sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s", cannot_setup_ssl); break; case 'U': zlib_ok = 0; - ssl_ok = 0; + ircd_ssl_ok = false; ilog(L_MAIN, "%s", no_ssl_or_zlib); sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s", no_ssl_or_zlib); ssl_killall(); - break; + return; + case 'V': + len = ctl_buf->buflen - 1; + if (len > sizeof(ctl->version) - 1) + len = sizeof(ctl->version) - 1; + strncpy(ctl->version, &ctl_buf->buf[1], len); case 'z': zlib_ok = 0; break; @@ -541,6 +581,8 @@ which_ssld(void) ctl = ptr->data; if(ctl->dead) continue; + if(ctl->shutdown) + continue; if(lowest == NULL) { lowest = ctl; @@ -680,7 +722,7 @@ send_new_ssl_certs(const char *ssl_cert, const char *ssl_private_key, const char rb_dlink_node *ptr; if(ssl_cert == NULL || ssl_private_key == NULL || ssl_dh_params == NULL) { - ssl_ok = 0; + ircd_ssl_ok = false; return; } RB_DLINK_FOREACH(ptr, ssl_daemons.head) @@ -703,6 +745,8 @@ start_ssld_accept(rb_fde_t * sslF, rb_fde_t * plainF, uint32_t id) buf[0] = 'A'; uint32_to_buf(&buf[1], id); ctl = which_ssld(); + if(!ctl) + return NULL; ctl->cli_count++; ssl_cmd_write_queue(ctl, F, 2, buf, sizeof(buf)); return ctl; @@ -721,6 +765,8 @@ start_ssld_connect(rb_fde_t * sslF, rb_fde_t * plainF, uint32_t id) uint32_to_buf(&buf[1], id); ctl = which_ssld(); + if(!ctl) + return NULL; ctl->cli_count++; ssl_cmd_write_queue(ctl, F, 2, buf, sizeof(buf)); return ctl; @@ -733,6 +779,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); @@ -825,13 +876,19 @@ start_zlib_session(void *data) F[0] = server->localClient->F; F[1] = xF1; - del_from_cli_connid_hash(server); + del_from_zconnid_hash(server); server->localClient->F = xF2; /* need to redo as what we did before isn't valid now */ - uint32_to_buf(&buf[1], rb_get_fd(server->localClient->F)); - add_to_cli_connid_hash(server); + uint32_to_buf(&buf[1], server->localClient->zconnid); + add_to_zconnid_hash(server); server->localClient->z_ctl = which_ssld(); + if(!server->localClient->z_ctl) + { + exit_client(server, server, server, "Error finding available ssld"); + rb_free(buf); + return; + } server->localClient->z_ctl->cli_count++; ssl_cmd_write_queue(server->localClient->z_ctl, F, 2, buf, len); rb_free(buf); @@ -887,6 +944,21 @@ get_ssld_count(void) return ssld_count; } +void +ssld_foreach_info(void (*func)(void *data, pid_t pid, int cli_count, enum ssld_status status, const char *version), void *data) +{ + rb_dlink_node *ptr, *next; + ssl_ctl_t *ctl; + RB_DLINK_FOREACH_SAFE(ptr, next, ssl_daemons.head) + { + ctl = ptr->data; + func(data, ctl->pid, ctl->cli_count, + ctl->dead ? SSLD_DEAD : + (ctl->shutdown ? SSLD_SHUTDOWN : SSLD_ACTIVE), + ctl->version); + } +} + void init_ssld(void) {