2019-07-17 19:37:18 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <protocol/ringbuffer.h>
|
|
|
|
#include <protocol/CompressionHandler.h>
|
2020-01-27 02:21:39 +01:00
|
|
|
#include <protocol/CryptHandler.h>
|
2019-07-17 19:37:18 +02:00
|
|
|
#include <ThreadPool/Thread.h>
|
|
|
|
#include <ThreadPool/Mutex.h>
|
|
|
|
#include <protocol/buffers.h>
|
|
|
|
#include <chrono>
|
|
|
|
#include <deque>
|
|
|
|
#include <event.h>
|
|
|
|
#include <condition_variable>
|
2020-01-27 02:21:39 +01:00
|
|
|
#include <utility>
|
2019-07-17 19:37:18 +02:00
|
|
|
#include <pipes/buffer.h>
|
|
|
|
#include "VoiceClient.h"
|
|
|
|
#include "protocol/AcknowledgeManager.h"
|
2020-01-27 02:21:39 +01:00
|
|
|
#include <protocol/generation.h>
|
2020-04-08 13:01:41 +02:00
|
|
|
#include "./PacketStatistics.h"
|
2020-07-29 19:05:38 +02:00
|
|
|
#include "./PacketDecoder.h"
|
|
|
|
#include "./PacketEncoder.h"
|
2019-07-17 19:37:18 +02:00
|
|
|
|
|
|
|
//#define LOG_ACK_SYSTEM
|
|
|
|
#ifdef LOG_ACK_SYSTEM
|
|
|
|
#define LOG_AUTO_ACK_REQUEST
|
|
|
|
#define LOG_AUTO_ACK_RESPONSE
|
|
|
|
#define LOG_PKT_RESEND
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//#define PKT_LOG_PING
|
|
|
|
namespace ts {
|
|
|
|
namespace server {
|
|
|
|
class VoiceClient;
|
|
|
|
class VoiceServer;
|
2020-01-24 02:57:58 +01:00
|
|
|
class POWHandler;
|
2019-07-17 19:37:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
namespace connection {
|
|
|
|
class VoiceClientConnection {
|
2020-01-24 02:57:58 +01:00
|
|
|
friend class AcknowledgeManager;
|
2019-07-17 19:37:18 +02:00
|
|
|
friend class server::VoiceServer;
|
|
|
|
friend class server::VoiceClient;
|
|
|
|
friend class server::POWHandler;
|
|
|
|
|
2020-07-29 19:05:38 +02:00
|
|
|
using PacketDecoder = server::server::udp::PacketDecoder;
|
|
|
|
using PacketEncoder = server::server::udp::PacketEncoder;
|
|
|
|
using ReassembledCommand = server::server::udp::ReassembledCommand;
|
|
|
|
using StatisticsCategory = stats::ConnectionStatistics::category;
|
|
|
|
public:
|
2020-01-24 02:57:58 +01:00
|
|
|
explicit VoiceClientConnection(server::VoiceClient*);
|
2019-07-17 19:37:18 +02:00
|
|
|
virtual ~VoiceClientConnection();
|
|
|
|
|
2020-04-24 22:04:07 +02:00
|
|
|
/* Do not send command packets via send_packet! The send_packet will take ownership of the packet! */
|
|
|
|
void send_packet(protocol::OutgoingServerPacket* /* packet */);
|
|
|
|
void send_packet(protocol::PacketType /* type */, protocol::PacketFlag::PacketFlags /* flags */, const void* /* payload */, size_t /* payload length */);
|
|
|
|
void send_command(const std::string_view& /* build command command */, bool /* command low */, std::unique_ptr<threads::Future<bool>> /* acknowledge listener */);
|
2019-07-17 19:37:18 +02:00
|
|
|
|
2020-01-27 02:21:39 +01:00
|
|
|
CryptHandler* getCryptHandler(){ return &crypt_handler; }
|
2019-07-17 19:37:18 +02:00
|
|
|
|
|
|
|
server::VoiceClient* getClient(){ return client; }
|
|
|
|
|
|
|
|
bool wait_empty_write_and_prepare_queue(std::chrono::time_point<std::chrono::system_clock> until = std::chrono::time_point<std::chrono::system_clock>());
|
|
|
|
|
2020-01-24 02:57:58 +01:00
|
|
|
void reset();
|
2020-01-27 02:21:39 +01:00
|
|
|
|
|
|
|
void force_insert_command(const pipes::buffer_view& /* payload */);
|
2020-04-08 13:01:41 +02:00
|
|
|
|
|
|
|
[[nodiscard]] inline auto& packet_statistics() { return this->packet_statistics_; }
|
2020-07-29 19:05:38 +02:00
|
|
|
[[nodiscard]] inline auto& packet_decoder() { return this->packet_decoder_; }
|
|
|
|
[[nodiscard]] inline auto& packet_encoder() { return this->packet_encoder_; }
|
2019-07-17 19:37:18 +02:00
|
|
|
protected:
|
2020-01-27 02:21:39 +01:00
|
|
|
void handle_incoming_datagram(const pipes::buffer_view &buffer);
|
2020-01-24 02:57:58 +01:00
|
|
|
bool verify_encryption(const pipes::buffer_view& /* full packet */);
|
2019-07-17 19:37:18 +02:00
|
|
|
|
|
|
|
void triggerWrite();
|
|
|
|
private:
|
|
|
|
server::VoiceClient* client = nullptr;
|
|
|
|
|
2020-01-27 02:21:39 +01:00
|
|
|
CryptHandler crypt_handler; /* access to CryptHandler is thread save */
|
2020-07-29 19:05:38 +02:00
|
|
|
server::client::PacketStatistics packet_statistics_{};
|
2019-07-17 19:37:18 +02:00
|
|
|
|
2020-07-29 19:05:38 +02:00
|
|
|
PacketDecoder packet_decoder_;
|
|
|
|
PacketEncoder packet_encoder_;
|
2019-07-17 19:37:18 +02:00
|
|
|
|
2020-07-29 19:05:38 +02:00
|
|
|
spin_mutex pending_commands_lock{};
|
|
|
|
ReassembledCommand* pending_commands_head{nullptr};
|
|
|
|
ReassembledCommand** pending_commands_tail{&pending_commands_head};
|
|
|
|
bool has_command_handling_scheduled{false}; /* locked by pending_commands_lock */
|
2020-01-27 02:21:39 +01:00
|
|
|
|
2020-07-29 19:05:38 +02:00
|
|
|
void enqueue_command_execution(ReassembledCommand*);
|
|
|
|
void execute_handle_command_packets(const std::chrono::system_clock::time_point& /* scheduled */);
|
2019-07-17 19:37:18 +02:00
|
|
|
|
2020-07-29 19:05:38 +02:00
|
|
|
static void callback_packet_decoded(void*, const protocol::ClientPacketParser&);
|
|
|
|
static void callback_command_decoded(void*, ReassembledCommand*&);
|
|
|
|
static void callback_send_acknowledge(void*, uint16_t, bool);
|
|
|
|
static void callback_request_write(void*);
|
|
|
|
static void callback_encode_crypt_error(void*, const PacketEncoder::CryptError&, const std::string&);
|
|
|
|
static void callback_resend_failed(void*, const std::shared_ptr<AcknowledgeManager::Entry>&);
|
|
|
|
static void callback_resend_statistics(void*, size_t);
|
|
|
|
static void callback_outgoing_connection_statistics(void*, StatisticsCategory::value, size_t /* bytes */);
|
2019-07-17 19:37:18 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|