#include "server.h" #include #include #include #include #include #include "log.h" #include "ssl.h" #include "util/thread_queue.h" #define MODULE_NAME "login_server" #define SERVER_PORT 443 static const char message[] = "

Hello World!

"; static SSL_CTX* _ssl_server_ctx = NULL; static struct logger_s _logger; static pthread_t *_server_thread = NULL; static struct threadqueue _server_thread_queue; _Atomic enum server_state _server_state = SERVER_NOT_STARTED; static enum server_start_return _server_thread_func(void* data) { atomic_store(&_server_state, SERVER_STARTING); struct sockaddr_in sockaddr = { .sin_family = AF_INET, .sin_port = htons(SERVER_PORT), .sin_addr = { .s_addr = htonl(INADDR_ANY) } }; int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { log_log(MODULE_NAME, LOG_ERR, "Failed to create socket: %s", strerror(errno)); atomic_store(&_server_state, SERVER_FAILED); return SERVER_FAIL; } if (bind(sock, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0) { log_log(MODULE_NAME, LOG_ERR, "Failed to bind socket: %s", strerror(errno)); atomic_store(&_server_state, SERVER_FAILED); close(sock); return SERVER_FAIL; } if (listen(sock, 1) != 0) { log_log(MODULE_NAME, LOG_ERR, "Failed to start listening on socket: %s", strerror(errno)); atomic_store(&_server_state, SERVER_FAILED); close(sock); return SERVER_FAIL; } log_log(MODULE_NAME, LOG_INFO, "Waiting for incoming connections..."); atomic_store(&_server_state, SERVER_RUNNING); while(1) { struct sockaddr addr; socklen_t addr_len = sizeof(addr); int client_fd = accept(sock, &addr, &addr_len); if (client_fd < 0) { log_log(MODULE_NAME, LOG_ERR, "Failed to accept an incoming connection: %s", strerror(errno)); continue; } SSL* ssl_conn = SSL_new(_ssl_server_ctx); SSL_set_fd(ssl_conn, client_fd); if (SSL_accept(ssl_conn) <= 0) { log_log_ssl_err(MODULE_NAME, LOG_ERR, "SSL Handshake failed."); } else { size_t bufsize = 1024; char* buf = malloc(bufsize); if (SSL_read(ssl_conn, buf, bufsize) > 0) { log_log(MODULE_NAME, LOG_INFO, "Received message: %s", buf); } SSL_write(ssl_conn, message, sizeof(message)); } SSL_shutdown(ssl_conn); SSL_free(ssl_conn); close(client_fd); } _server_thread_shutdown: close(sock); } enum server_start_return server_start() { initialize_ssl(); if (!_ssl_server_ctx) { _ssl_server_ctx = SSL_CTX_new(TLS_server_method()); if (!_ssl_server_ctx) { log_log(MODULE_NAME, LOG_ERR, "Failed to create SSL CTX"); return SERVER_FAIL; } if (!ssl_use_ppcerts(_ssl_server_ctx)) { log_log(MODULE_NAME, LOG_ERR, "Failed to set certificates."); SSL_CTX_free(_ssl_server_ctx); _ssl_server_ctx = NULL; return SERVER_FAIL; } } if (!_server_thread) { _server_thread = malloc(sizeof(pthread_t)); if (!_server_thread) { log_log(MODULE_NAME, LOG_ERR, "Failed to allocate resources for server_thread"); return SERVER_FAIL; } thread_queue_init(&_server_thread_queue); pthread_create(_server_thread, NULL, (void* (*)(void*))_server_thread_func, NULL); pthread_join(*_server_thread, NULL); free(_server_thread); _server_thread = NULL; } return SERVER_OK; }