Teaspeak-Server/server/src/client/voice/VoiceClientConnection.h

128 lines
5.9 KiB
C++

#pragma once
#include <protocol/ringbuffer.h>
#include <protocol/CompressionHandler.h>
#include <protocol/CryptHandler.h>
#include <ThreadPool/Thread.h>
#include <ThreadPool/Mutex.h>
#include <protocol/buffers.h>
#include <chrono>
#include <deque>
#include <event.h>
#include <condition_variable>
#include <utility>
#include <pipes/buffer.h>
#include "VoiceClient.h"
#include "protocol/AcknowledgeManager.h"
#include <protocol/generation.h>
#include "./PacketStatistics.h"
#include "./PacketDecoder.h"
#include "./PacketEncoder.h"
#include "./ServerCommandExecutor.h"
#include "CryptSetupHandler.h"
#include "PingHandler.h"
//#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;
class POWHandler;
}
namespace connection {
class VoiceClientConnection {
friend class AcknowledgeManager;
friend class server::VoiceServer;
friend class server::VoiceClient;
friend class server::POWHandler;
using PacketDecoder = server::server::udp::PacketDecoder;
using PacketEncoder = server::server::udp::PacketEncoder;
using PingHandler = server::server::udp::PingHandler;
using CryptSetupHandler = server::server::udp::CryptSetupHandler;
using ReassembledCommand = server::server::udp::ReassembledCommand;
using StatisticsCategory = stats::ConnectionStatistics::category;
public:
explicit VoiceClientConnection(server::VoiceClient*);
virtual ~VoiceClientConnection();
void send_packet(protocol::PacketType /* type */, protocol::PacketFlag::PacketFlags /* flags */, const void* /* payload */, size_t /* payload length */);
void send_packet(protocol::OutgoingServerPacket* /* packet */); /* method takes ownership of the packet */
void send_command(const std::string_view& /* build command command */, bool /* command low */, std::unique_ptr<threads::Future<bool>> /* acknowledge listener */);
CryptHandler* getCryptHandler(){ return &crypt_handler; }
std::shared_ptr<server::VoiceClient> getCurrentClient();
bool wait_empty_write_and_prepare_queue(std::chrono::time_point<std::chrono::system_clock> until = std::chrono::time_point<std::chrono::system_clock>());
void reset();
void reset_remote_address();
[[nodiscard]] std::string log_prefix();
[[nodiscard]] inline auto virtual_server_id() const { return this->virtual_server_id_; }
[[nodiscard]] inline const auto& remote_address() const { return this->remote_address_; }
[[nodiscard]] inline const auto& socket_id() const { return this->socket_id_; }
[[nodiscard]] inline auto& packet_statistics() { return this->packet_statistics_; }
[[nodiscard]] inline auto& packet_decoder() { return this->packet_decoder_; }
[[nodiscard]] inline auto& packet_encoder() { return this->packet_encoder_; }
[[nodiscard]] inline auto& ping_handler() { return this->ping_handler_; }
[[nodiscard]] inline auto& crypt_setup_handler() { return this->crypt_setup_handler_; }
protected:
void handle_incoming_datagram(const pipes::buffer_view &buffer);
bool verify_encryption(const pipes::buffer_view& /* full packet */);
void triggerWrite();
private:
ServerId virtual_server_id_;
server::VoiceClient* current_client;
int socket_id_{0};
sockaddr_storage remote_address_{};
server::udp::pktinfo_storage remote_address_info_{};
CryptHandler crypt_handler; /* access to CryptHandler is thread save */
server::client::PacketStatistics packet_statistics_{};
PacketDecoder packet_decoder_;
PacketEncoder packet_encoder_;
CryptSetupHandler crypt_setup_handler_;
PingHandler ping_handler_{};
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 */);
static void callback_ping_send(void*, uint16_t&);
static void callback_ping_send_recovery(void*);
static void callback_ping_timeout(void*);
/* Attention: All packet callbacks are called from the IO threads and are not thread save! */
void handlePacketCommand(ReassembledCommand* /* command */); /* The ownership will be transferred */
void handlePacketAck(const protocol::ClientPacketParser&);
void handlePacketAckLow(const protocol::ClientPacketParser&);
void handlePacketVoice(const protocol::ClientPacketParser&);
void handlePacketVoiceWhisper(const protocol::ClientPacketParser&);
void handlePacketPing(const protocol::ClientPacketParser&);
void handlePacketPong(const protocol::ClientPacketParser&);
};
}
}