#pragma once #include #include #include #include #include #include #include #include #include #include #include #include "DatabaseHandler.h" namespace license { namespace web { class WebStatistics; } namespace stats { class StatisticManager; } class UserManager; enum ClientType { SERVER, MANAGER }; struct ConnectedClient { public: struct { sockaddr_in remoteAddr; int fileDescriptor = 0; event* readEvent = nullptr; /* protected via state_lock (check state and the use these variables) */ event* writeEvent = nullptr; std::mutex write_queue_lock{}; TAILQ_HEAD(, ts::buffer::RawBuffer) write_queue; } network; struct { std::mutex state_lock{}; protocol::RequestState state = protocol::UNCONNECTED; std::chrono::system_clock::time_point last_read; std::string cryptKey = ""; int version{2}; /* current version is 3 */ } protocol; ClientType type = ClientType::SERVER; std::string username; std::string key; uint64_t key_pending_upgrade{0}; std::string unique_identifier; bool invalid_license = false; void init(); void uninit(); void sendPacket(const protocol::packet&); inline std::string address() { return inet_ntoa(network.remoteAddr.sin_addr); } }; struct WebCertificate { std::string revision; std::string key; std::string certificate; }; class LicenseServer { public: explicit LicenseServer(const sockaddr_in&, std::shared_ptr , std::shared_ptr /* stats */, std::shared_ptr /* web stats */, std::shared_ptr /* user manager */); ~LicenseServer(); bool start(); bool isRunning(){ return this->running; } void stop(); std::shared_ptr findClient(int fileDescriptor); void disconnectClient(const std::shared_ptr&, const std::string& reason); void closeConnection(const std::shared_ptr&, bool blocking = false); std::deque> getClients() { std::lock_guard lock(this->client_lock); return clients; } std::shared_ptr web_certificate{nullptr}; private: void unregisterClient(const std::shared_ptr&); void cleanup_clients(); std::shared_ptr web_statistics; std::shared_ptr statistics; std::shared_ptr manager; std::shared_ptr user_manager; std::mutex client_lock; std::deque> clients; bool running = false; /* also secured by client_lock */ sockaddr_in localAddr{}; int server_socket = 0; event_base* evBase = nullptr; event* event_accept = nullptr; event* event_cleanup = nullptr; std::thread event_base_dispatch{}; static void handleEventCleanup(int, short, void*); static void handleEventAccept(int, short, void*); static void handleEventRead(int, short, void*); static void handleEventWrite(int, short, void*); void handleMessage(std::shared_ptr&, const std::string&); bool handleDisconnect(std::shared_ptr&, protocol::packet&, std::string& error); bool handleHandshake(std::shared_ptr&, protocol::packet&, std::string& error); bool handleServerValidation(std::shared_ptr &, protocol::packet &, std::string &error); bool handlePacketLicenseUpgrade(std::shared_ptr &client, protocol::packet &packet, std::string &error); bool handlePacketPropertyUpdate(std::shared_ptr &, protocol::packet &, std::string &error); bool handlePacketAuth(std::shared_ptr &, protocol::packet &, std::string &error); bool handlePacketLicenseCreate(std::shared_ptr &, protocol::packet &, std::string &error); bool handlePacketLicenseList(std::shared_ptr &, protocol::packet &, std::string &error); bool handlePacketLicenseDelete(std::shared_ptr &, protocol::packet &, std::string &error); }; }