Added address iteration and graceful TLS failures.

* source/client/main.c (main):
- Added iteration through found addresses from getaddrinfo.
- Added graceful failures for TLS errors.
This commit is contained in:
Barra Ó Catháin 2024-03-18 03:09:32 +00:00
parent 03ea201716
commit 24f8e2688a
1 changed files with 35 additions and 14 deletions

View File

@ -21,23 +21,24 @@
#include "client-drawing.h" #include "client-drawing.h"
#include "receiving-thread.h" #include "receiving-thread.h"
static char serverPort[HOST_NAME_MAX] = "5050";
static char serverHostname[HOST_NAME_MAX] = "127.0.0.1";
static bool hostSpecified = false, portSpecified = false;
int main (int argc, char ** argv) int main (int argc, char ** argv)
{ {
static char serverPort[HOST_NAME_MAX] = "5050";
static char serverHostname[HOST_NAME_MAX] = "127.0.0.1";
struct addrinfo * serverInformation;
// Print a welcome message: // Print a welcome message:
printf("SilverMUD Client - Starting Now.\n" printf("SilverMUD Client - Starting Now.\n"
"================================\n"); "================================\n");
struct addrinfo * serverInformation;
// Configure command-line options: // Configure command-line options:
static struct option longOptions[] = static struct option longOptions[] =
{ {
{"host", required_argument, 0, 'h' }, {"host", required_argument, 0, 'h' },
{"port", required_argument, 0, 'p' } {"port", required_argument, 0, 'p' }
}; };
bool hostSpecified = false, portSpecified = false;
// Parse command-line options: // Parse command-line options:
int selectedOption = 0, optionIndex = 0; int selectedOption = 0, optionIndex = 0;
@ -78,13 +79,22 @@ int main (int argc, char ** argv)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Connect to the server: // Connect to the server, iterating through addresses until we get SilverMUD:
if (connect(serverSocket, serverInformation->ai_addr, serverInformation->ai_addrlen) != 0) struct addrinfo * currentAddress;
for (currentAddress = serverInformation; currentAddress != NULL; currentAddress = currentAddress->ai_next)
{
if (connect(serverSocket, serverInformation->ai_addr, serverInformation->ai_addrlen) != -1)
{
break;
}
}
if (currentAddress == NULL)
{ {
printf("Failed to connect to the server. Aborting.\n"); printf("Failed to connect to the server. Aborting.\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
freeaddrinfo(serverInformation);
// Set up a GnuTLS session and handshake with the server: // Set up a GnuTLS session and handshake with the server:
gnutls_session_t tlsSession = NULL; gnutls_session_t tlsSession = NULL;
if (gnutls_init(&tlsSession, GNUTLS_CLIENT) < 0) if (gnutls_init(&tlsSession, GNUTLS_CLIENT) < 0)
@ -94,20 +104,31 @@ int main (int argc, char ** argv)
gnutls_anon_client_credentials_t clientKey = NULL; gnutls_anon_client_credentials_t clientKey = NULL;
gnutls_anon_allocate_client_credentials(&clientKey); gnutls_anon_allocate_client_credentials(&clientKey);
gnutls_credentials_set(tlsSession, GNUTLS_CRD_ANON, &clientKey);
gnutls_transport_set_int(tlsSession, serverSocket); gnutls_transport_set_int(tlsSession, serverSocket);
gnutls_priority_set_direct(tlsSession, "PERFORMANCE:+ANON-ECDH:+ANON-DH", NULL); gnutls_credentials_set(tlsSession, GNUTLS_CRD_ANON, &clientKey);
gnutls_handshake_set_timeout(tlsSession, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); gnutls_handshake_set_timeout(tlsSession, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
gnutls_priority_set_direct(tlsSession, "PERFORMANCE:+ANON-ECDH:+ANON-DH", NULL);
gnutls_server_name_set(tlsSession, GNUTLS_NAME_DNS, serverHostname, strlen(serverHostname));
int returnValue = -1; int returnValue = -1, connectionAttempts = 0;
do do
{ {
returnValue = gnutls_handshake(tlsSession); returnValue = gnutls_handshake(tlsSession);
connectionAttempts++;
if (connectionAttempts == 50)
{
printf("Failed to establish a TLS session. Aborting.\n");
exit(EXIT_FAILURE);
}
} }
while (returnValue < 0 && gnutls_error_is_fatal(returnValue) == 0); while (returnValue < 0 && gnutls_error_is_fatal(returnValue) == 0);
if (returnValue < 0)
{
printf("Failed to establish a TLS session. Aborting.\n");
exit(EXIT_FAILURE);
}
// Initialize ncurses: // Initialize ncurses:
initscr(); initscr();
keypad(stdscr, TRUE); keypad(stdscr, TRUE);