This commit is contained in:
2025-02-15 09:53:11 +01:00
commit 0922b77fad
44 changed files with 3384 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
//
// Created by Stepan Usatiuk on 14.12.2024.
//
#ifndef ASYNCMESSAGECLIENT_HPP
#define ASYNCMESSAGECLIENT_HPP
#include "AsyncSslTransport.hpp"
class AsyncSslClientTransport : public AsyncSslTransport {
public:
AsyncSslClientTransport(SSL_CTX* ssl_ctx, int fd) : AsyncSslTransport(ssl_ctx, fd) {}
using SharedMsgPromiseT = std::shared_ptr<std::promise<std::shared_ptr<MsgWrapper>>>;
std::future<std::shared_ptr<MsgWrapper>> send_msg(std::vector<uint8_t> message);
std::vector<uint8_t> send_msg_and_wait(std::vector<uint8_t> message);
protected:
void handle_message(std::shared_ptr<MsgWrapper> msg) override;
void handle_fail() override {
stop();
std::exit(EXIT_FAILURE);
}
void before_entry() override;
private:
std::unordered_map<decltype(MsgWrapper::id), SharedMsgPromiseT> _promises;
uint64_t _msg_id = 0;
std::mutex _promises_mutex;
};
#endif // ASYNCMESSAGECLIENT_HPP

View File

@@ -0,0 +1,32 @@
//
// Created by Stepan Usatiuk on 15.12.2024.
//
#ifndef SERVERMESSAGEPUMP_HPP
#define SERVERMESSAGEPUMP_HPP
#include "AsyncSslTransport.hpp"
class AsyncSslServerTransport : public AsyncSslTransport {
public:
AsyncSslServerTransport(SSL_CTX* ssl_ctx, int fd, int client_id) : AsyncSslTransport(ssl_ctx, fd), _client_id(client_id) {}
// Null if finished
std::shared_ptr<MsgWrapper> get_msg();
protected:
void handle_message(std::shared_ptr<MsgWrapper> msg) override;
void handle_fail() override;
void before_entry() override;
private:
int _client_id;
std::deque<std::shared_ptr<MsgWrapper>> _msgs;
std::mutex _msgs_mutex;
std::condition_variable _msgs_condition;
};
#endif // SERVERMESSAGEPUMP_HPP

View File

@@ -0,0 +1,62 @@
//
// Created by Stepan Usatiuk on 14.12.2024.
//
#ifndef MESSAGEPUMP_HPP
#define MESSAGEPUMP_HPP
#include <condition_variable>
#include <deque>
#include <future>
#include <mutex>
#include <thread>
#include <unordered_map>
#include <openssl/ssl.h>
#include "Helpers.hpp"
class AsyncSslTransport {
public:
AsyncSslTransport(SSL_CTX* ssl_ctx, int fd);
virtual ~AsyncSslTransport() = 0;
void run();
void send_message(std::shared_ptr<MsgWrapper> msg);
bool is_failed() const { return _failed; }
bool is_stopped() const { return _stopped; }
void stop();
protected:
virtual void handle_message(std::shared_ptr<MsgWrapper> msg) = 0;
virtual void handle_fail() = 0;
virtual void before_entry() {}
std::unique_ptr<SSL, decltype(&SSL_free)> _ssl{nullptr, &SSL_free};
int _fd;
private:
void thread_entry();
std::atomic<bool> _stopped = 0;
std::mutex _stopped_mutex;
std::condition_variable _stopped_condition;
std::thread _thread;
std::mutex _to_send_mutex;
int _to_send_notif_pipe[2];
std::deque<std::shared_ptr<MsgWrapper>> _to_send;
std::atomic<bool> _failed;
AsyncSslTransport(const AsyncSslTransport& other) = delete;
AsyncSslTransport(AsyncSslTransport&& other) noexcept = delete;
AsyncSslTransport& operator=(const AsyncSslTransport& other) = delete;
AsyncSslTransport& operator=(AsyncSslTransport&& other) noexcept = delete;
};
#endif // MESSAGEPUMP_HPP

View File

@@ -0,0 +1,43 @@
//
// Created by stepus53 on 11.12.24.
//
#ifndef TCPCLIENT_HPP
#define TCPCLIENT_HPP
#include <cstdint>
#include <mutex>
#include <string>
#include <memory>
#include <optional>
#include <openssl/ssl.h>
#include "AsyncSslClientTransport.hpp"
class Client {
public:
Client(uint16_t port, std::string ip, std::string cert_path, std::string key_path);
void run();
AsyncSslClientTransport& transport() { return *_transport; }
protected:
uint16_t _port;
std::string _ip;
std::string _cert_path;
std::string _key_path;
std::unique_ptr<SSL_CTX, decltype(&SSL_CTX_free)> _ssl_ctx;
std::unique_ptr<SSL, decltype(&SSL_free)> _ssl{nullptr, &SSL_free};
int _sock;
size_t _msg_id = 0;
private:
std::optional<AsyncSslClientTransport> _transport;
};
#endif // TCPCLIENT_HPP

View File

@@ -0,0 +1,37 @@
#ifndef NETWORKING_HELPERS_H
#define NETWORKING_HELPERS_H
#include <cstdint>
#include <deque>
#include <functional>
#include <vector>
#include "Options.h"
#include "stuff.hpp"
#include <openssl/ssl.h>
using MsgIdType = uint64_t;
struct MsgWrapper {
MsgIdType id;
std::vector<uint8_t> data;
};
struct MsgHeader {
uint64_t id;
uint64_t len;
} __attribute__((packed));
namespace Helpers {
void poll_wait(int fd, bool write, int timeout = checked_cast<int>(Options::get<size_t>("timeout")) * 1000);
bool SSL_write(SSL* ctx, int fd, const std::vector<uint8_t>& buf);
void init_nonblock(int fd);
std::vector<uint8_t> SSL_read_n(SSL* ctx, int fd, size_t n);
MsgWrapper SSL_read_msg(SSL* ctx, int fd);
void SSL_send_msg(SSL* ctx, int fd, const MsgWrapper& buf);
} // namespace Helpers
#endif

View File

@@ -0,0 +1,53 @@
//
// Created by Stepan Usatiuk on 09.12.2024.
//
#ifndef TCPSERVER_HPP
#define TCPSERVER_HPP
#include <atomic>
#include <condition_variable>
#include <cstdint>
#include <functional>
#include <optional>
#include <string>
#include <openssl/ssl.h>
#include "AsyncSslServerTransport.hpp"
#include "Helpers.hpp"
struct ClientCtx {
std::optional<std::string> client_name;
AsyncSslServerTransport transport;
std::mutex ctx_mutex;
};
class Server {
public:
Server(uint16_t port, uint32_t ip, std::string cert_path, std::string key_path);
void run();
protected:
uint16_t _port;
uint32_t _ip;
std::string _cert_path;
std::string _key_path;
std::unique_ptr<SSL_CTX, decltype(&SSL_CTX_free)> _ssl_ctx;
void process_req(int conn_fd);
virtual std::vector<uint8_t> handle_message(ClientCtx& client, std::vector<uint8_t> data) = 0;
private:
std::atomic<int> _total_req{0};
std::atomic<int> _req_in_progress{0};
std::mutex _req_in_progress_mutex;
std::condition_variable _req_in_progress_cond;
};
#endif // TCPSERVER_HPP