diff options
author | Luke Bratch <luke@bratch.co.uk> | 2019-06-12 21:29:28 +0100 |
---|---|---|
committer | Luke Bratch <luke@bratch.co.uk> | 2019-06-12 21:29:28 +0100 |
commit | 0bea530df3f718b34a1022a871f4f78a41c2bee6 (patch) | |
tree | 74ec32052bfc81a9218896eb7675be7e87193a2f /blabouncer.c | |
parent | 0ea06b9c632af2fe09cdea8be0baa9ae6e538aeb (diff) |
Handle failing to reconnect to the server upon timeout or disconnection by looping the reconnection and keeping clients informed.
Diffstat (limited to 'blabouncer.c')
-rw-r--r-- | blabouncer.c | 75 |
1 files changed, 49 insertions, 26 deletions
diff --git a/blabouncer.c b/blabouncer.c index c416c3e..bbb22cd 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -492,6 +492,8 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { snprintf(outgoingmsg, MAXDATASIZE, "PING timeouttest"); } sendtoserver(server_ssl, outgoingmsg, strlen(outgoingmsg), 0, clients, settings); + // Back to top of loop + continue; } else { // ...and we've already PINGed the server and haven't heard back yet, so let's assume we've timed out // TODO - Code duplication, make a function and share with socket error code below @@ -502,23 +504,34 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { sendtoallclients(clients, alertmsg, 0, settings); if (settings->servertls) { // Finish up with OpenSSL if using server TLS - SSL_free(server_ssl); + if (server_ssl != NULL) SSL_free(server_ssl); + // Set to NULL so we can check if we already free()d this on a previous attempt + server_ssl = NULL; } // Close the socket close(*serversockfd); - // Make a new one - *serversockfd = createserversocket(settings->ircserver, settings->ircserverport); - - // Set reconnection marker for other functions to know we're reconnecting - 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); + // Make a new one and reconnect + if ((*serversockfd = createserversocket(settings->ircserver, settings->ircserverport)) == -1) { + // We failed + debugprint(DEBUG_CRIT, "dochat(): Couldn't reconnect to server, will try again.\n"); + // Tell clients + char alertmsg[MAXDATASIZE]; + snprintf(alertmsg, MAXDATASIZE, "NOTICE %s :Couldn't reconnect to server, will try again.", ircdstate.ircnick); + sendtoallclients(clients, alertmsg, 0, settings); + // Don't go back to the top of the loop yet, perhaps some clients are waiting to tell us something - TODO - Could this ever happen in this state? + } else { + // We succeeded + // Set reconnection marker for other functions to know we're reconnecting + 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); + // Back to top of loop + continue; + } } - // Back to top of loop - continue; } else { - // No timeout is occuring, back to the top of the loop + // No timeout is occuring, the pselect() just timed out (which is fine and expected), back to the top of the loop continue; } } @@ -543,28 +556,38 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) { // If there was a socket error (receive error or socket closed) // TODO - Code duplication, make a function and share with timeout code above if (servernumbytes < 1) { - printf("Server socket had an error (sockread return code %d), reconnecting!\n", servernumbytes); - // Tell all clients if we timed out + debugprint(DEBUG_CRIT, "Server socket had an error (sockread return code %d), reconnecting!\n", servernumbytes); + // Tell all clients if we had an error char alertmsg[MAXDATASIZE]; snprintf(alertmsg, MAXDATASIZE, "NOTICE %s :Server socket had an error (sockread return code %d), reconnecting!", ircdstate.ircnick, servernumbytes); sendtoallclients(clients, alertmsg, 0, settings); if (settings->servertls) { // Finish up with OpenSSL if using server TLS - SSL_free(server_ssl); + if (server_ssl != NULL) SSL_free(server_ssl); + // Set to NULL so we can check if we already free()d this on a previous attempt + server_ssl = NULL; } // Close the socket close(*serversockfd); - // Make a new one - *serversockfd = createserversocket(settings->ircserver, settings->ircserverport); - - // Set reconnection marker for other functions to know we're reconnecting - 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); - - // Back to top of loop - continue; + // Make a new one and reconnect + if ((*serversockfd = createserversocket(settings->ircserver, settings->ircserverport)) == -1) { + // We failed + debugprint(DEBUG_CRIT, "dochat(): Couldn't reconnect to server, will try again.\n"); + // Tell clients + char alertmsg[MAXDATASIZE]; + snprintf(alertmsg, MAXDATASIZE, "NOTICE %s :Couldn't reconnect to server, will try again.", ircdstate.ircnick); + sendtoallclients(clients, alertmsg, 0, settings); + // Don't go back to the top of the loop yet, perhaps some clients are waiting to tell us something - TODO - Could this ever happen in this state? + } else { + // We succeeded + // Set reconnection marker for other functions to know we're reconnecting + 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); + // Back to top of loop + continue; + } } serverbuf[servernumbytes] = '\0'; |