2020-03-10 17:03:38 +01:00

72 lines
3.0 KiB
C++

#pragma once
#include <misc/spin_lock.h>
#include <mutex>
#include <deque>
#include <protocol/Packet.h>
#include <protocol/generation.h>
#include <protocol/ringbuffer.h>
namespace ts::connection {
class CryptHandler;
class CompressionHandler;
class AcknowledgeManager;
}
namespace ts::stats {
class ConnectionStatistics;
}
namespace ts::server::server::udp {
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));
class PacketDecoder {
typedef protocol::PacketRingBuffer<CommandFragment, 32, CommandFragment> command_fragment_buffer_t;
typedef std::array<command_fragment_buffer_t, 2> command_packet_reassembler;
public:
typedef std::function<void(const protocol::ClientPacketParser&)> callback_decoded_packet_t;
PacketDecoder(connection::CryptHandler* /* crypt handler */, connection::CompressionHandler* /* compress handler */, connection::AcknowledgeManager* /* acknowledge handler */);
~PacketDecoder();
void reset();
void decode_incoming_data(const pipes::buffer_view &/* buffer */);
[[nodiscard]] inline std::shared_ptr<stats::ConnectionStatistics> get_statistics() { return this->statistics_; }
inline void set_statistics(const std::shared_ptr<stats::ConnectionStatistics>& stats) { this->statistics_ = stats; }
[[nodiscard]] inline bool is_protocol_encrypted() const { return this->protocol_encrypted; }
void set_protocol_encrypted(bool flag) { this->protocol_encrypted = flag; }
callback_decoded_packet_t callback_decoded_packet{};
private:
bool protocol_encrypted{false};
std::shared_ptr<stats::ConnectionStatistics> statistics_{nullptr};
connection::CryptHandler* crypt_handler_{nullptr};
connection::CompressionHandler* compress_handler_{nullptr};
connection::AcknowledgeManager* acknowledge_handler_{nullptr};
std::array<protocol::generation_estimator, 9> incoming_generation_estimators{}; /* implementation is thread save */
std::recursive_mutex packet_buffer_lock;
command_packet_reassembler _command_fragment_buffers;
};
}