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"
|
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;
|
|
|
|
public:
|
2020-04-24 22:04:07 +02:00
|
|
|
enum struct WBufferPopResult {
|
|
|
|
DRAINED,
|
|
|
|
MORE_AVAILABLE
|
|
|
|
};
|
|
|
|
|
2020-01-27 02:21:39 +01:00
|
|
|
struct CommandFragment {
|
|
|
|
uint16_t packet_id{0};
|
|
|
|
uint16_t packet_generation{0};
|
|
|
|
|
|
|
|
uint8_t packet_flags{0};
|
|
|
|
uint32_t payload_length : 24;
|
|
|
|
pipes::buffer payload{};
|
|
|
|
|
|
|
|
CommandFragment() { this->payload_length = 0; }
|
|
|
|
CommandFragment(uint16_t packetId, uint16_t packetGeneration, uint8_t packetFlags, uint32_t payloadLength, pipes::buffer payload) : packet_id{packetId}, packet_generation{packetGeneration}, packet_flags{packetFlags},
|
|
|
|
payload_length{payloadLength}, payload{std::move(payload)} {}
|
|
|
|
|
|
|
|
CommandFragment& operator=(const CommandFragment&) = default;
|
|
|
|
CommandFragment(const CommandFragment& other) = default;
|
|
|
|
CommandFragment(CommandFragment&&) = default;
|
|
|
|
};
|
|
|
|
static_assert(sizeof(CommandFragment) == 8 + sizeof(pipes::buffer));
|
|
|
|
|
|
|
|
typedef protocol::PacketRingBuffer<CommandFragment, 32, CommandFragment> command_fragment_buffer_t;
|
|
|
|
typedef std::array<command_fragment_buffer_t, 2> command_packet_reassembler;
|
2019-07-17 19:37:18 +02:00
|
|
|
|
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; }
|
|
|
|
|
|
|
|
#ifdef VC_USE_READ_QUEUE
|
|
|
|
bool handleNextDatagram();
|
|
|
|
#endif
|
2020-04-24 22:04:07 +02:00
|
|
|
/* if the result is true, ownership has been transferred */
|
|
|
|
WBufferPopResult pop_write_buffer(protocol::OutgoingServerPacket*& /* packet */);
|
|
|
|
void execute_resend(const std::chrono::system_clock::time_point &now, std::chrono::system_clock::time_point &next);
|
2019-07-17 19:37:18 +02:00
|
|
|
|
2020-04-24 22:04:07 +02:00
|
|
|
void encrypt_write_queue();
|
2019-07-17 19:37:18 +02:00
|
|
|
bool wait_empty_write_and_prepare_queue(std::chrono::time_point<std::chrono::system_clock> until = std::chrono::time_point<std::chrono::system_clock>());
|
|
|
|
|
|
|
|
protocol::PacketIdManager& getPacketIdManager() { return this->packet_id_manager; }
|
2020-04-08 13:01:41 +02:00
|
|
|
AcknowledgeManager& getAcknowledgeManager() { return this->acknowledge_handler; }
|
2020-04-02 19:24:57 +02:00
|
|
|
inline auto& get_incoming_generation_estimators() { return this->incoming_generation_estimators; }
|
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 */);
|
|
|
|
void register_initiv_packet();
|
2020-04-08 13:01:41 +02:00
|
|
|
|
|
|
|
[[nodiscard]] inline auto& packet_statistics() { return this->packet_statistics_; }
|
2019-07-17 19:37:18 +02:00
|
|
|
//buffer::SortedBufferQueue<protocol::ClientPacket>** getReadQueue() { return this->readTypedQueue; }
|
|
|
|
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;
|
|
|
|
|
|
|
|
//Decryption / encryption stuff
|
2020-01-27 02:21:39 +01:00
|
|
|
CryptHandler crypt_handler; /* access to CryptHandler is thread save */
|
2019-07-17 19:37:18 +02:00
|
|
|
CompressionHandler compress_handler;
|
|
|
|
AcknowledgeManager acknowledge_handler;
|
|
|
|
|
2020-04-23 15:36:58 +02:00
|
|
|
std::atomic_bool should_reassembled_reschedule{}; /* this get checked as soon the command handle lock has been released so trylock will succeed */
|
2020-03-28 23:08:11 +01:00
|
|
|
|
2019-07-17 19:37:18 +02:00
|
|
|
//Handle stuff
|
2020-01-27 02:21:39 +01:00
|
|
|
void execute_handle_command_packets(const std::chrono::system_clock::time_point& /* scheduled */);
|
2020-01-27 13:02:22 +01:00
|
|
|
bool next_reassembled_command(std::unique_lock<std::recursive_timed_mutex> &buffer_execute_lock /* packet channel execute lock */, pipes::buffer & /* buffer*/, uint16_t& /* packet id */);
|
2019-07-17 19:37:18 +02:00
|
|
|
|
|
|
|
|
2020-04-24 22:04:07 +02:00
|
|
|
/* ---------- Write ---------- */
|
|
|
|
spin_mutex write_queue_mutex{};
|
|
|
|
protocol::OutgoingServerPacket* resend_queue_head{nullptr};
|
|
|
|
protocol::OutgoingServerPacket** resend_queue_tail{&resend_queue_head};
|
2020-01-24 02:57:58 +01:00
|
|
|
|
2020-04-24 22:04:07 +02:00
|
|
|
protocol::OutgoingServerPacket* write_queue_head{nullptr};
|
|
|
|
protocol::OutgoingServerPacket** write_queue_tail{&write_queue_head};
|
2019-10-22 18:39:52 +02:00
|
|
|
|
|
|
|
/* ---------- Processing ---------- */
|
|
|
|
/* automatically locked because packets of the same kind should be lock their "work_lock" from their WritePreprocessQueue object */
|
2020-01-24 02:57:58 +01:00
|
|
|
protocol::PacketIdManager packet_id_manager;
|
2020-04-24 22:04:07 +02:00
|
|
|
spin_mutex packet_id_mutex{};
|
2019-07-17 19:37:18 +02:00
|
|
|
|
|
|
|
/* this function is thread save :) */
|
|
|
|
std::atomic<uint8_t> prepare_process_count{0}; /* current thread count preparing a packet */
|
2020-04-24 22:04:07 +02:00
|
|
|
bool prepare_outgoing_packet(protocol::OutgoingServerPacket* /* packet */);
|
2019-07-17 19:37:18 +02:00
|
|
|
|
2020-01-27 02:21:39 +01:00
|
|
|
std::array<protocol::generation_estimator, 9> incoming_generation_estimators{}; /* implementation is thread save */
|
2020-01-24 02:57:58 +01:00
|
|
|
std::recursive_mutex packet_buffer_lock;
|
2020-01-27 02:21:39 +01:00
|
|
|
command_packet_reassembler _command_fragment_buffers;
|
|
|
|
|
|
|
|
static inline uint8_t command_fragment_buffer_index(uint8_t packet_index) {
|
|
|
|
return packet_index & 0x1U; /* use 0 for command and 1 for command low */
|
|
|
|
}
|
2019-07-17 19:37:18 +02:00
|
|
|
|
2020-04-08 13:01:41 +02:00
|
|
|
server::client::PacketStatistics packet_statistics_{};
|
2019-07-17 19:37:18 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|