From fa1b052f8bbd556e188aea52e7b29e352fd91d92 Mon Sep 17 00:00:00 2001 From: Luke Bratch Date: Sun, 16 Jun 2019 20:03:24 +0100 Subject: Handle failing to connect to the real IRC even after the socket has been created. --- blabouncer.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/blabouncer.c b/blabouncer.c index ff8667a..22252d7 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -83,11 +83,13 @@ void sighandler(int sig) { signum = sig; } +// Connect to the real IRC server. +// Returns 1 on success or 0 on failure. int connecttoircserver(SSL_CTX **serverctx, SSL **server_ssl, int *serversockfd, struct ircdstate *ircdstate, struct settings *settings, struct client *clients) { char outgoingmsg[MAXDATASIZE]; // String to send to server if (settings->servertls) { - debugprint(DEBUG_FULL, "server openssl start.\n"); + debugprint(DEBUG_FULL, "Server OpenSSL start.\n"); *serverctx = create_openssl_context(SOURCE_SERVER); configure_openssl_context(*serverctx, NULL, NULL); *server_ssl = SSL_new(*serverctx); @@ -96,11 +98,12 @@ int connecttoircserver(SSL_CTX **serverctx, SSL **server_ssl, int *serversockfd, char* errstr = openssl_error_string(); debugprint(DEBUG_CRIT, "SSL_connect failed - %s", errstr); if (errstr != NULL) free(errstr); + return 0; } else { debugprint(DEBUG_FULL, "SSL_connect() success.\n"); } - debugprint(DEBUG_FULL, "server openssl complete.\n"); + debugprint(DEBUG_FULL, "Server OpenSSL complete.\n"); } else { // If not using TLS then just slap the serversockfd into server_ssl by casting it *server_ssl = (SSL*)(long int)*serversockfd; @@ -155,7 +158,7 @@ int connecttoircserver(SSL_CTX **serverctx, SSL **server_ssl, int *serversockfd, // =============================================> - return 1; // TODO - Return 0 if this fails and make callers do something with that + return 1; } // Figure out what to do with each CRLF-split IRC message (if anything) @@ -407,7 +410,11 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { // Set reconnection things to null/zero for now (not used unless reconnecting to server) ircdstate.oldnick[0] = '\0'; ircdstate.reconnecting = 0; - connecttoircserver(&serverctx, &server_ssl, serversockfd, &ircdstate, settings, clients); + if (!connecttoircserver(&serverctx, &server_ssl, serversockfd, &ircdstate, settings, clients)) { + fprintf(stderr, "Failed to connect to IRC server, exiting.\n"); + debugprint(DEBUG_CRIT, "Failed to connect to IRC server, exiting.\n"); + exit(EXIT_FAILURE); + } // OpenSSL context for client side (that clients connect to) (need to create this whether or not using TLS as it is referenced later) SSL_CTX *ctx; @@ -550,7 +557,15 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { ircdstate.reconnecting = 1; // Set oldnick in case we change nick when reconnecting so we can inform existing clients strcpy(ircdstate.oldnick, ircdstate.ircnick); - connecttoircserver(&serverctx, &server_ssl, serversockfd, &ircdstate, settings, clients); + if (!connecttoircserver(&serverctx, &server_ssl, serversockfd, &ircdstate, settings, clients)) { + // Let clients know if we failed + char alertmsg[MAXDATASIZE]; + snprintf(alertmsg, MAXDATASIZE, "NOTICE %s :Failed to reconnect to server, will try again.", ircdstate.ircnick); + sendtoallclients(clients, alertmsg, 0, settings); + // Then wait a few seconds and try again + sleep(5); + connecttoircserver(&serverctx, &server_ssl, serversockfd, &ircdstate, settings, clients); + } // Back to top of loop continue; } @@ -605,7 +620,15 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { ircdstate.reconnecting = 1; // Set oldnick in case we change nick when reconnecting so we can inform existing clients strcpy(ircdstate.oldnick, ircdstate.ircnick); - connecttoircserver(&serverctx, &server_ssl, serversockfd, &ircdstate, settings, clients); + if (!connecttoircserver(&serverctx, &server_ssl, serversockfd, &ircdstate, settings, clients)) { + // Let clients know if we failed + char alertmsg[MAXDATASIZE]; + snprintf(alertmsg, MAXDATASIZE, "NOTICE %s :Failed to reconnect to server, will try again.", ircdstate.ircnick); + sendtoallclients(clients, alertmsg, 0, settings); + // Then wait a few seconds and try again + sleep(5); + connecttoircserver(&serverctx, &server_ssl, serversockfd, &ircdstate, settings, clients); + } // Back to top of loop continue; } -- cgit v1.2.3