From da9f2f2d519434f024c80446c6cfee2bfefadc7a Mon Sep 17 00:00:00 2001 From: Nicholas Orlowsky Date: Mon, 17 Feb 2025 18:46:33 -0500 Subject: [PATCH] broken ssl --- CMakeLists.txt | 4 +++ lib/anthracite.cpp | 71 ++++++++++++++++++++++++++++++------------- lib/socket/socket.hpp | 18 ++++++----- src/file_main.cpp | 3 +- 4 files changed, 66 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 949bb34..2449bbd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,8 @@ set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_CXX_FLAGS_RELEASE "-O3") set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +find_package(OpenSSL REQUIRED) + add_custom_target(build-version COMMAND cd ../build_supp && ./version.sh DEPENDS build_supp/version.txt @@ -29,6 +31,8 @@ add_custom_target(run FILE(GLOB LIB_SOURCES lib/*.cpp lib/**/*.cpp build_supp/version.cpp) add_library(anthracite ${LIB_SOURCES}) add_dependencies(anthracite build-version) +target_link_libraries(anthracite OpenSSL::SSL OpenSSL::Crypto) +target_include_directories(anthracite PUBLIC ${OPENSSL_INCLUDE_DIR}) add_executable(anthracite-bin src/file_main.cpp) target_link_libraries(anthracite-bin anthracite) diff --git a/lib/anthracite.cpp b/lib/anthracite.cpp index 51a646e..d10cacb 100644 --- a/lib/anthracite.cpp +++ b/lib/anthracite.cpp @@ -11,6 +11,8 @@ #include #include #include +#include "./socket/openssl_socket.hpp" +#include using namespace anthracite; @@ -24,10 +26,10 @@ using std::chrono::duration_cast; using std::chrono::duration; using std::chrono::milliseconds; -void handle_client(socket::anthracite_socket s, backends::backend& b, backends::file_backend& fb, std::mutex& thread_wait_mutex, std::condition_variable& thread_wait_condvar, int& active_threads) +void handle_client(socket::anthracite_socket* s, backends::backend& b, backends::file_backend& fb, std::mutex& thread_wait_mutex, std::condition_variable& thread_wait_condvar, int& active_threads) { while (true) { - std::string raw_request = s.recv_message(http::HEADER_BYTES); + std::string raw_request = s->recv_message(http::HEADER_BYTES); // We're doing the start here even though it would ideally be done // before the first line since if we leave the connection open for @@ -38,11 +40,11 @@ void handle_client(socket::anthracite_socket s, backends::backend& b, backends:: break; } - http::request req(raw_request, s.get_client_ip()); + http::request req(raw_request, s->get_client_ip()); std::unique_ptr resp = req.is_supported_version() ? b.handle_request(req) : fb.handle_error(http::status_codes::HTTP_VERSION_NOT_SUPPORTED); std::string header = resp->header_to_string(); - s.send_message(header); - s.send_message(resp->content()); + s->send_message(header); + s->send_message(resp->content()); auto end = high_resolution_clock::now(); auto ms_int = duration_cast(end-start); @@ -53,7 +55,8 @@ void handle_client(socket::anthracite_socket s, backends::backend& b, backends:: break; } } - s.close_conn(); + s->close_conn(); + delete s; { std::lock_guard lock(thread_wait_mutex); active_threads--; @@ -61,34 +64,60 @@ void handle_client(socket::anthracite_socket s, backends::backend& b, backends:: thread_wait_condvar.notify_one(); } -int anthracite_main(int argc, char** argv, backends::backend& be) -{ - log::logger.initialize(log::LOG_LEVEL_INFO); - auto args = std::span(argv, size_t(argc)); - int port_number = default_port; +int listen_loop(int port_number, backends::backend& be, bool tls) { + socket::anthracite_socket* socket; - if (argc > 1) { - port_number = atoi(args[1]); + if (tls){ + socket = new socket::openssl_socket(port_number); + } else { + socket = new socket::anthracite_socket(port_number); } - log::verbose << "Initializing Anthracite" << std::endl; - socket::anthracite_socket s(port_number); - backends::file_backend fb(argc > 2 ? args[2] : "./www"); - log::verbose << "Initialization Complete" << std::endl; - log::info << "Listening for HTTP connections on port " << port_number << std::endl; + backends::file_backend fb("./www"); + log::info << "Listening for " << (tls ? "HTTPS" : "HTTP" ) << " connections on port " << port_number << std::endl; + int active_threads = 0; std::mutex thread_wait_mutex; std::condition_variable thread_wait_condvar; while (true) { - s.wait_for_conn(); + socket->wait_for_conn(); std::unique_lock lock(thread_wait_mutex); thread_wait_condvar.wait(lock, [active_threads] { return active_threads < max_worker_threads; }); active_threads++; - std::thread(handle_client, s, std::ref(be), std::ref(fb), std::ref(thread_wait_mutex), std::ref(thread_wait_condvar), std::ref(active_threads)).detach(); + + socket::anthracite_socket* client_sock; + + if (tls){ + client_sock = new socket::openssl_socket(*dynamic_cast(socket)); + } else { + client_sock = new socket::anthracite_socket(*socket); + } + + std::thread(handle_client, socket, std::ref(be), std::ref(fb), std::ref(thread_wait_mutex), std::ref(thread_wait_condvar), std::ref(active_threads)).detach(); } - exit(0); + delete socket; +} + +int anthracite_main(int argc, char** argv, backends::backend& be) +{ + log::logger.initialize(log::LOG_LEVEL_INFO); + auto args = std::span(argv, size_t(argc)); + + std::vector threads; + + if (argc > 1) { + auto thread = std::thread(listen_loop, atoi(argv[1]), std::ref(be), false); + thread.detach(); + threads.push_back(std::move(thread)); + } if (argc > 2) { + auto thread = std::thread(listen_loop, atoi(argv[2]), std::ref(be), true); + thread.detach(); + threads.push_back(std::move(thread)); + } + std::promise().get_future().wait(); + return 0; } void log_request_and_response(http::request& req, std::unique_ptr& resp, uint32_t micros) diff --git a/lib/socket/socket.hpp b/lib/socket/socket.hpp index 7a57de7..648c404 100644 --- a/lib/socket/socket.hpp +++ b/lib/socket/socket.hpp @@ -1,3 +1,5 @@ +#pragma once + #include #include #include @@ -10,23 +12,25 @@ namespace anthracite::socket { class anthracite_socket { - static const int MAX_QUEUE_LENGTH = 100; -private: + +protected: int server_socket; int client_socket {}; std::string client_ip; struct sockaddr_in client_addr {}; socklen_t client_addr_len {}; static const struct timeval timeout_tv; + static const int MAX_QUEUE_LENGTH = 100; public: anthracite_socket(int port, int max_queue = MAX_QUEUE_LENGTH); - void wait_for_conn(); - const std::string& get_client_ip(); - void close_conn(); - void send_message(std::string& msg); - std::string recv_message(int buffer_size); + virtual const std::string& get_client_ip() final; + + virtual void wait_for_conn(); + virtual void close_conn(); + virtual void send_message(std::string& msg); + virtual std::string recv_message(int buffer_size); }; }; diff --git a/src/file_main.cpp b/src/file_main.cpp index c81b1e9..2af7664 100644 --- a/src/file_main.cpp +++ b/src/file_main.cpp @@ -5,7 +5,6 @@ using namespace anthracite; int main(int argc, char** argv) { - auto args = std::span(argv, size_t(argc)); - backends::file_backend fb(argc > 2 ? args[2] : "./www"); + backends::file_backend fb("./www"); anthracite_main(argc, argv, fb); }