110 lines
4.4 KiB
C
110 lines
4.4 KiB
C
|
#pragma once
|
||
|
|
||
|
#include <protocol/ringbuffer.h>
|
||
|
#include <protocol/CompressionHandler.h>
|
||
|
#include <protocol/CryptionHandler.h>
|
||
|
#include <ThreadPool/Thread.h>
|
||
|
#include <ThreadPool/Mutex.h>
|
||
|
#include <protocol/buffers.h>
|
||
|
#include <chrono>
|
||
|
#include <deque>
|
||
|
#include <event.h>
|
||
|
#include <condition_variable>
|
||
|
#include <pipes/buffer.h>
|
||
|
#include "VoiceClient.h"
|
||
|
#include "protocol/AcknowledgeManager.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;
|
||
|
public:
|
||
|
typedef protocol::PacketRingBuffer<protocol::ClientPacket, 32, std::unique_ptr<protocol::ClientPacket>> packet_buffer_t;
|
||
|
typedef std::array<packet_buffer_t, 8> packet_buffers_t;
|
||
|
|
||
|
explicit VoiceClientConnection(server::VoiceClient*);
|
||
|
virtual ~VoiceClientConnection();
|
||
|
|
||
|
void sendPacket(const std::shared_ptr<protocol::ServerPacket>& original_packet, bool copy = false, bool prepare_directly = false);
|
||
|
|
||
|
CryptionHandler* getCryptHandler(){ return &crypt_handler; }
|
||
|
|
||
|
server::VoiceClient* getClient(){ return client; }
|
||
|
|
||
|
#ifdef VC_USE_READ_QUEUE
|
||
|
bool handleNextDatagram();
|
||
|
#endif
|
||
|
/*
|
||
|
* Split packets waiting in write_process_queue and moves the final buffers to writeQueue.
|
||
|
* @returns true when there are more packets to prepare
|
||
|
*/
|
||
|
bool prepare_write_packets();
|
||
|
/* return 2 => Nothing | 1 => More and buffer is set | 0 => Buffer is set, nothing more */
|
||
|
int pop_write_buffer(pipes::buffer& /* buffer */);
|
||
|
|
||
|
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; }
|
||
|
packet_buffers_t& packet_buffers() { return this->_packet_buffers; }
|
||
|
|
||
|
void reset();
|
||
|
//buffer::SortedBufferQueue<protocol::ClientPacket>** getReadQueue() { return this->readTypedQueue; }
|
||
|
protected:
|
||
|
void handleDatagramReceived(const pipes::buffer_view&);
|
||
|
bool verify_encryption(const pipes::buffer_view& /* full packet */);
|
||
|
|
||
|
void triggerWrite();
|
||
|
private:
|
||
|
server::VoiceClient* client = nullptr;
|
||
|
|
||
|
//Decryption / encryption stuff
|
||
|
CryptionHandler crypt_handler;
|
||
|
CompressionHandler compress_handler;
|
||
|
AcknowledgeManager acknowledge_handler;
|
||
|
|
||
|
//Handle stuff
|
||
|
void execute_handle_packet(const std::chrono::system_clock::time_point& /* scheduled */);
|
||
|
std::unique_ptr<protocol::ClientPacket> next_reassembled_packet(std::unique_lock<std::recursive_timed_mutex>& /* packet channel execute lock */, bool& /* have more */);
|
||
|
|
||
|
|
||
|
#ifdef VC_USE_READ_QUEUE
|
||
|
std::deque<pipes::buffer> readQueue;
|
||
|
#endif
|
||
|
|
||
|
spin_lock write_queue_lock; /* queue access isn't for long in general */
|
||
|
std::deque<pipes::buffer> write_queue;
|
||
|
|
||
|
spin_lock write_prepare_queue_lock; /* preprocess queue access isn't for long in general */
|
||
|
std::deque<std::shared_ptr<protocol::ServerPacket>> write_prepare_queue;
|
||
|
|
||
|
spin_lock packet_id_manager_lock; /* packet id's must be generated in order; Calculating the ID should also not be take too much time */
|
||
|
protocol::PacketIdManager packet_id_manager;
|
||
|
|
||
|
/* this function is thread save :) */
|
||
|
std::atomic<uint8_t> prepare_process_count{0}; /* current thread count preparing a packet */
|
||
|
bool prepare_packet_for_write(std::vector<pipes::buffer> &/* buffers which need to be transferred */, const std::shared_ptr<protocol::ServerPacket> &/* the packet */);
|
||
|
|
||
|
std::recursive_mutex packet_buffer_lock;
|
||
|
packet_buffers_t _packet_buffers;
|
||
|
uint8_t _packet_buffers_index = 0;
|
||
|
|
||
|
};
|
||
|
}
|
||
|
}
|