151 lines
4.6 KiB
C++
151 lines
4.6 KiB
C++
#pragma once
|
|
|
|
#include <chrono>
|
|
#include <cstdint>
|
|
|
|
#define NO_LOG
|
|
#ifdef WIN32
|
|
#include <WinSock2.h> //Needs to be included; No clue why
|
|
#endif
|
|
|
|
#include <protocol/ringbuffer.h>
|
|
#include <protocol/Packet.h>
|
|
#include <protocol/CryptHandler.h>
|
|
#include <protocol/CompressionHandler.h>
|
|
#include <protocol/AcknowledgeManager.h>
|
|
#include <protocol/generation.h>
|
|
#include "ServerConnection.h"
|
|
|
|
namespace ts {
|
|
namespace connection {
|
|
class CryptionHandler;
|
|
class CompressionHandler;
|
|
}
|
|
}
|
|
|
|
namespace tc {
|
|
namespace connection {
|
|
class ServerConnection;
|
|
|
|
namespace connection_state {
|
|
enum value {
|
|
INITIALIZING,
|
|
INIT_LOW,
|
|
INIT_HIGH,
|
|
CONNECTING,
|
|
CONNECTED,
|
|
DISCONNECTING,
|
|
DISCONNECTED
|
|
};
|
|
};
|
|
namespace pow_state {
|
|
enum value : uint8_t {
|
|
COOKIE_GET,
|
|
COOKIE_SET,
|
|
PUZZLE_GET,
|
|
PUZZLE_SET,
|
|
PUZZLE_SOLVE,
|
|
PUZZLE_RESET,
|
|
COMPLETED,
|
|
COMMAND_RESET = 127,
|
|
UNSET = 0xFB
|
|
};
|
|
};
|
|
|
|
class ProtocolHandler {
|
|
typedef ts::protocol::PacketRingBuffer<ts::protocol::ServerPacket, 86> packet_buffer_t;
|
|
typedef std::array<packet_buffer_t, 8> packet_buffers_t;
|
|
friend class ServerConnection;
|
|
public:
|
|
ProtocolHandler(ServerConnection*);
|
|
~ProtocolHandler();
|
|
|
|
void reset();
|
|
void connect();
|
|
void execute_tick();
|
|
void execute_resend();
|
|
|
|
void progress_packet(const pipes::buffer_view& /* buffer */);
|
|
bool handle_packets(); /* if true we have more left */
|
|
void send_packet(const std::shared_ptr<ts::protocol::ClientPacket>& /* packet */);
|
|
void send_command(const ts::Command& /* command */, const std::function<void(bool)> & /* acknowledge callback */ = NULL);
|
|
|
|
void disconnect(const std::string& /* message */);
|
|
|
|
void send_acknowledge(uint16_t /* packet id */, bool /* low */);
|
|
|
|
ecc_key& get_identity_key() { return this->crypto.identity; }
|
|
|
|
inline std::chrono::microseconds current_ping() { return this->ping.value; }
|
|
|
|
connection_state::value connection_state = connection_state::INITIALIZING;
|
|
server_type::value server_type = server_type::TEASPEAK;
|
|
private:
|
|
void do_close_connection(); /* only call from ServerConnection. Close all connections via ServerConnection! */
|
|
|
|
void handlePacketCommand(const std::shared_ptr<ts::protocol::ServerPacket>&);
|
|
void handlePacketAck(const std::shared_ptr<ts::protocol::ServerPacket>&);
|
|
void handlePacketVoice(const std::shared_ptr<ts::protocol::ServerPacket>&);
|
|
void handlePacketPing(const std::shared_ptr<ts::protocol::ServerPacket>&);
|
|
void handlePacketInit(const std::shared_ptr<ts::protocol::ServerPacket>&);
|
|
|
|
bool create_datagram_packets(std::vector<pipes::buffer> &result, const std::shared_ptr<ts::protocol::ClientPacket> &packet);
|
|
|
|
ServerConnection* handle;
|
|
|
|
std::chrono::system_clock::time_point connect_timestamp;
|
|
std::chrono::system_clock::time_point disconnect_timestamp;
|
|
uint8_t disconnect_id = 0;
|
|
|
|
struct {
|
|
pow_state::value state;
|
|
|
|
uint64_t client_ts3_build_timestamp = 173265950 /* TS3 */; /* needs to be lower than 173265950 for old stuff, else new protocol */
|
|
uint8_t client_control_data[4] = {0,0,0,0};
|
|
uint8_t server_control_data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
|
uint8_t server_data[100];
|
|
|
|
std::chrono::system_clock::time_point last_response;
|
|
std::chrono::system_clock::time_point last_resend;
|
|
pipes::buffer last_buffer;
|
|
} pow;
|
|
void pow_send_cookie_get();
|
|
|
|
struct {
|
|
uint8_t alpha[10];
|
|
uint8_t beta[54];
|
|
uint8_t beta_length; /* 10 or 54 */
|
|
|
|
ecc_key identity{};
|
|
|
|
std::string initiv_command;
|
|
} crypto;
|
|
std::string generate_client_initiv();
|
|
|
|
uint16_t client_id = 0;
|
|
ts::protocol::PacketIdManager _packet_id_manager;
|
|
packet_buffers_t _packet_buffers;
|
|
std::array<ts::protocol::generation_estimator, 9> incoming_generation_estimators{}; /* implementation is thread save */
|
|
uint8_t _packet_buffers_index = 0;
|
|
|
|
bool crypt_setupped{false};
|
|
ts::connection::CryptHandler crypt_handler;
|
|
ts::connection::CompressionHandler compression_handler;
|
|
ts::connection::AcknowledgeManager acknowledge_handler;
|
|
|
|
void handleCommandInitIVExpend(ts::Command&);
|
|
void handleCommandInitIVExpend2(ts::Command&);
|
|
void handleCommandInitServer(ts::Command&);
|
|
|
|
struct {
|
|
std::chrono::system_clock::time_point ping_send_timestamp;
|
|
std::chrono::system_clock::time_point ping_received_timestamp;
|
|
std::chrono::microseconds value;
|
|
uint16_t ping_id;
|
|
|
|
std::chrono::microseconds interval = std::chrono::microseconds(2500);
|
|
} ping;
|
|
void ping_send_request();
|
|
};
|
|
}
|
|
} |