Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
29bd5e55c4
@ -3,9 +3,9 @@
|
||||
#include <condition_variable>
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include "src/log/LogUtils.h"
|
||||
#include <src/misc/sassert.h>
|
||||
#include "EventLoop.h"
|
||||
#include "./log/LogUtils.h"
|
||||
#include "./misc/sassert.h"
|
||||
#include "./EventLoop.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ts::event;
|
||||
@ -65,7 +65,7 @@ void EventExecutor::shutdown() {
|
||||
this->_shutdown(lock);
|
||||
}
|
||||
|
||||
bool EventExecutor::schedule(const std::shared_ptr<event::EventEntry> &entry) {
|
||||
bool EventExecutor::schedule(const std::shared_ptr<ts::event::EventEntry> &entry) {
|
||||
unique_lock lock(this->lock);
|
||||
if(!entry || entry->_event_ptr)
|
||||
return true; /* already scheduled */
|
||||
@ -89,7 +89,7 @@ bool EventExecutor::schedule(const std::shared_ptr<event::EventEntry> &entry) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EventExecutor::cancel(const std::shared_ptr<event::EventEntry> &entry) {
|
||||
bool EventExecutor::cancel(const std::shared_ptr<ts::event::EventEntry> &entry) {
|
||||
unique_lock lock(this->lock);
|
||||
if(!entry || !entry->_event_ptr)
|
||||
return false;
|
||||
@ -158,7 +158,7 @@ void EventExecutor::_reassign_thread_names(std::unique_lock<std::mutex> &lock) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void EventExecutor::_executor(event::EventExecutor *loop) {
|
||||
void EventExecutor::_executor(ts::event::EventExecutor *loop) {
|
||||
while(true) {
|
||||
unique_lock lock(loop->lock);
|
||||
loop->condition.wait(lock, [&] {
|
||||
@ -204,11 +204,16 @@ void EventExecutor::_executor(event::EventExecutor *loop) {
|
||||
}
|
||||
|
||||
auto event_handler = linked_entry->entry.lock();
|
||||
if(!event_handler) {
|
||||
/* event handler passed away while waiting for beeing executed */
|
||||
delete linked_entry;
|
||||
continue;
|
||||
}
|
||||
|
||||
sassert(event_handler->_event_ptr == linked_entry);
|
||||
event_handler->_event_ptr = nullptr;
|
||||
lock.unlock();
|
||||
|
||||
if(event_handler)
|
||||
event_handler->event_execute(linked_entry->scheduled);
|
||||
delete linked_entry;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ namespace ts {
|
||||
if(!_instance)
|
||||
return;
|
||||
|
||||
((void(*)(class_t*, const std::chrono::system_clock::time_point &)) this->callback)(&*_instance, point);
|
||||
((void(*)(class_t*, const std::chrono::system_clock::time_point &)) (void*) this->callback)(&*_instance, point);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -190,7 +190,7 @@ namespace std {
|
||||
count--;
|
||||
} else {
|
||||
// normal unlocking
|
||||
owner = std::thread::id();
|
||||
owner = this_id;
|
||||
count = 0;
|
||||
handle.unlock();
|
||||
}
|
||||
|
@ -6,20 +6,22 @@
|
||||
class spin_lock {
|
||||
std::atomic_flag locked = ATOMIC_FLAG_INIT;
|
||||
public:
|
||||
void lock() {
|
||||
inline void lock() {
|
||||
uint8_t round = 0;
|
||||
while (locked.test_and_set(std::memory_order_acquire)) {
|
||||
while(locked._M_i) { /* waiting 'till its zero so we can try an exchanged again; Atomic exchanges have a huge bug overhead to deal with! */
|
||||
//Yield when we're using this lock for a longer time, which we usually not doing
|
||||
if(round++ % 8 == 0)
|
||||
std::this_thread::yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline bool try_lock() {
|
||||
return !locked.test_and_set(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
void unlock() {
|
||||
inline void unlock() {
|
||||
locked.clear(std::memory_order_release);
|
||||
}
|
||||
};
|
@ -1,7 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#define TIMING_START(_name) \
|
||||
struct { \
|
||||
|
||||
#ifndef TIMING_DISABLED
|
||||
#define TIMING_REPORT(expression) \
|
||||
expression
|
||||
|
||||
#define TIMING_START(_name) \
|
||||
struct { \
|
||||
struct entry { \
|
||||
std::string name; \
|
||||
std::chrono::system_clock::time_point ts; \
|
||||
@ -11,26 +16,36 @@ struct { \
|
||||
std::chrono::system_clock::time_point begin; \
|
||||
std::chrono::system_clock::time_point end; \
|
||||
std::deque<entry> timings; \
|
||||
} _name ##_timings; \
|
||||
_name ##_timings.begin = std::chrono::system_clock::now(); \
|
||||
} _name ##_timings; \
|
||||
_name ##_timings.begin = std::chrono::system_clock::now(); \
|
||||
|
||||
#define TIMING_STEP(name, step) \
|
||||
name ##_timings.timings.push_back({step, std::chrono::system_clock::now()});
|
||||
#define TIMING_STEP(name, step) \
|
||||
name ##_timings.timings.push_back({step, std::chrono::system_clock::now()});
|
||||
|
||||
#define TIMING_FINISH(_name) \
|
||||
([&](){ \
|
||||
#define TIMING_FINISH_U(_name, unit, unit_name) \
|
||||
([&](){ \
|
||||
_name ##_timings.end = std::chrono::system_clock::now(); \
|
||||
std::string result; \
|
||||
result = "timings for " + _name ##_timings.name + ": "; \
|
||||
result += std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(_name ##_timings.end - _name ##_timings.begin).count()) + "ms"; \
|
||||
result += std::to_string(std::chrono::duration_cast<std::chrono::unit>(_name ##_timings.end - _name ##_timings.begin).count()) + unit_name; \
|
||||
\
|
||||
auto tp = _name ##_timings.begin; \
|
||||
for(const auto& entry : _name ##_timings.timings) { \
|
||||
result += "\n "; \
|
||||
result += "- " + entry.name + ": "; \
|
||||
result += "@" + std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(entry.ts - _name ##_timings.begin).count()) + "ms"; \
|
||||
result += ": " + std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(entry.ts - tp).count()) + "ms"; \
|
||||
result += "@" + std::to_string(std::chrono::duration_cast<std::chrono::unit>(entry.ts - _name ##_timings.begin).count()) + unit_name; \
|
||||
result += ": " + std::to_string(std::chrono::duration_cast<std::chrono::unit>(entry.ts - tp).count()) + unit_name; \
|
||||
tp = entry.ts; \
|
||||
} \
|
||||
return result; \
|
||||
})()
|
||||
})()
|
||||
|
||||
#define TIMING_FINISH(_name) TIMING_FINISH_U(_name, milliseconds, "ms")
|
||||
#else
|
||||
#define TIMING_REPORT(expression)
|
||||
#define TIMING_START(_name)
|
||||
#define TIMING_STEP(name, step)
|
||||
#define TIMING_FINISH_U(_name, unit, unit_name)
|
||||
#define TIMING_FINISH(_name)
|
||||
#endif
|
||||
/* FIX the "backslash-newline at end of file" warning */
|
||||
|
@ -70,7 +70,7 @@ bool CompressionHandler::progressPacketIn(protocol::BasicPacket* packet, std::st
|
||||
}
|
||||
|
||||
bool CompressionHandler::progressPacketOut(protocol::BasicPacket* packet, std::string& error) {
|
||||
if(packet->hasFlag(protocol::PacketFlag::Compressed) && !packet->isCompressed()) {
|
||||
if(packet->has_flag(protocol::PacketFlag::Compressed) && !packet->isCompressed()) {
|
||||
if(!this->compress(packet, error)) return false;
|
||||
packet->setCompressed(true);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#define NO_OPEN_SSL /* because we're lazy and dont want to build this lib extra for the TeaClient */
|
||||
//#define NO_OPEN_SSL /* because we're lazy and dont want to build this lib extra for the TeaClient */
|
||||
#define FIXEDINT_H_INCLUDED /* else it will be included by ge */
|
||||
|
||||
#include "misc/endianness.h"
|
||||
@ -8,6 +8,7 @@
|
||||
#include "misc/memtracker.h"
|
||||
#include "misc/digest.h"
|
||||
#include "CryptionHandler.h"
|
||||
#include "../misc/sassert.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ts;
|
||||
@ -27,7 +28,7 @@ void CryptionHandler::reset() {
|
||||
this->useDefaultChipherKeyNonce = true;
|
||||
this->iv_struct_length = 0;
|
||||
memset(this->iv_struct, 0, sizeof(this->iv_struct));
|
||||
memcpy(this->current_mac, this->default_mac, sizeof(this->default_mac));
|
||||
memcpy(this->current_mac, CryptionHandler::default_mac, sizeof(CryptionHandler::default_mac));
|
||||
|
||||
for(auto& cache : this->cache_key_client)
|
||||
cache.generation = 0xFFEF;
|
||||
@ -35,21 +36,21 @@ void CryptionHandler::reset() {
|
||||
cache.generation = 0xFFEF;
|
||||
}
|
||||
|
||||
#define SHARED_KEY_BUFFER_LENGTH (256)
|
||||
bool CryptionHandler::setupSharedSecret(const std::string& alpha, const std::string& beta, ecc_key *publicKey, ecc_key *ownKey, std::string &error) {
|
||||
size_t bufferLength = 128;
|
||||
uint8_t* buffer = new uint8_t[bufferLength];
|
||||
size_t buffer_length = SHARED_KEY_BUFFER_LENGTH;
|
||||
uint8_t buffer[SHARED_KEY_BUFFER_LENGTH];
|
||||
int err;
|
||||
if((err = ecc_shared_secret(ownKey, publicKey, buffer, (unsigned long*) &bufferLength)) != CRYPT_OK){
|
||||
delete[] buffer;
|
||||
if((err = ecc_shared_secret(ownKey, publicKey, buffer, (unsigned long*) &buffer_length)) != CRYPT_OK){
|
||||
error = "Could not calculate shared secret. Message: " + string(error_to_string(err));
|
||||
return false;
|
||||
}
|
||||
auto result = this->setupSharedSecret(alpha, beta, string((const char*) buffer, bufferLength), error);
|
||||
delete[] buffer;
|
||||
|
||||
auto result = this->setupSharedSecret(alpha, beta, string((const char*) buffer, buffer_length), error);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CryptionHandler::setupSharedSecret(const std::string& alpha, const std::string& beta, std::string sharedKey, std::string &error) {
|
||||
bool CryptionHandler::setupSharedSecret(const std::string& alpha, const std::string& beta, const std::string& sharedKey, std::string &error) {
|
||||
auto secret_hash = digest::sha1(sharedKey);
|
||||
|
||||
char ivStruct[SHA_DIGEST_LENGTH];
|
||||
@ -108,7 +109,7 @@ void _fe_neg(fe h, const fe f) {
|
||||
h[9] = h9;
|
||||
}
|
||||
|
||||
inline std::string keyMul(const uint8_t* publicKey /* compressed */, const uint8_t* privateKey /* uncompressed */, bool negate){
|
||||
inline void keyMul(uint8_t(& target_buffer)[32], const uint8_t* publicKey /* compressed */, const uint8_t* privateKey /* uncompressed */, bool negate){
|
||||
ge_p3 keyA{};
|
||||
ge_p2 result{};
|
||||
|
||||
@ -119,30 +120,27 @@ inline std::string keyMul(const uint8_t* publicKey /* compressed */, const uint8
|
||||
}
|
||||
ge_scalarmult_vartime(&result, privateKey, &keyA);
|
||||
|
||||
char buffer[32];
|
||||
ge_tobytes((uint8_t*) buffer, &result);
|
||||
return string(buffer, 32);
|
||||
ge_tobytes(target_buffer, &result);
|
||||
}
|
||||
|
||||
bool CryptionHandler::setupSharedSecretNew(const std::string &alpha, const std::string &beta, const char* privateKey /* uncompressed */, const char* publicKey /* compressed */) {
|
||||
assert(alpha.length() == 10);
|
||||
assert(beta.length() == 54);
|
||||
if(alpha.length() != 10 || beta.length() != 54)
|
||||
return false;
|
||||
|
||||
string shared;
|
||||
string sharedIv;
|
||||
shared.resize(32, '\0');
|
||||
sharedIv.resize(64, '\0');
|
||||
ed25519_key_exchange((uint8_t*) shared.data(), (uint8_t*) publicKey, (uint8_t*) privateKey);
|
||||
shared = keyMul(reinterpret_cast<const uint8_t *>(publicKey), reinterpret_cast<const uint8_t *>(privateKey), true); //Remote key get negated
|
||||
sharedIv = digest::sha512(shared);
|
||||
uint8_t shared[32];
|
||||
uint8_t shared_iv[64];
|
||||
|
||||
ed25519_key_exchange(shared, (uint8_t*) publicKey, (uint8_t*) privateKey);
|
||||
keyMul(shared, reinterpret_cast<const uint8_t *>(publicKey), reinterpret_cast<const uint8_t *>(privateKey), true); //Remote key get negated
|
||||
digest::sha512((char*) shared, 32, shared_iv);
|
||||
|
||||
auto xor_key = alpha + beta;
|
||||
for(int i = 0; i < 64; i++)
|
||||
sharedIv[i] ^= xor_key[i];
|
||||
shared_iv[i] ^= xor_key[i];
|
||||
|
||||
{
|
||||
lock_guard lock(this->cache_key_lock);
|
||||
memcpy(this->iv_struct, sharedIv.data(), 64);
|
||||
memcpy(this->iv_struct, shared_iv, 64);
|
||||
this->iv_struct_length = 64;
|
||||
|
||||
auto digest_buffer = digest::sha1((char*) this->iv_struct, 64);
|
||||
@ -165,6 +163,7 @@ bool CryptionHandler::generate_key_nonce(protocol::BasicPacket* packet, bool use
|
||||
);
|
||||
}
|
||||
|
||||
#define GENERATE_BUFFER_LENGTH (128)
|
||||
bool CryptionHandler::generate_key_nonce(
|
||||
bool to_server, /* its from the client to the server */
|
||||
protocol::PacketType type,
|
||||
@ -189,8 +188,10 @@ bool CryptionHandler::generate_key_nonce(
|
||||
auto& key_cache = key_cache_array[type];
|
||||
if(key_cache.generation != generation) {
|
||||
const size_t buffer_length = 6 + this->iv_struct_length;
|
||||
char* buffer = new char[buffer_length];
|
||||
memset(buffer, 0, 6 + this->iv_struct_length);
|
||||
sassert(buffer_length < GENERATE_BUFFER_LENGTH);
|
||||
|
||||
char buffer[GENERATE_BUFFER_LENGTH];
|
||||
memset(buffer, 0, buffer_length);
|
||||
|
||||
if (to_server) {
|
||||
buffer[0] = 0x31;
|
||||
@ -201,13 +202,11 @@ bool CryptionHandler::generate_key_nonce(
|
||||
|
||||
le2be32(generation, buffer, 2);
|
||||
memcpy(&buffer[6], this->iv_struct, this->iv_struct_length);
|
||||
auto key_nonce = digest::sha256(buffer, 6 + this->iv_struct_length);
|
||||
auto key_nonce = digest::sha256(buffer, buffer_length);
|
||||
|
||||
memcpy(key_cache.key, key_nonce.data(), 16);
|
||||
memcpy(key_cache.nonce, key_nonce.data() + 16, 16);
|
||||
key_cache.generation = generation;
|
||||
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
memcpy(key, key_cache.key, 16);
|
||||
@ -234,9 +233,10 @@ bool CryptionHandler::verify_encryption(const pipes::buffer_view &packet, uint16
|
||||
|
||||
auto length = data.length();
|
||||
|
||||
const unsigned long target_length = 2048;
|
||||
uint8_t target_buffer[2048];
|
||||
if(target_length < length)
|
||||
/* static shareable void buffer */
|
||||
const static unsigned long void_target_length = 2048;
|
||||
static uint8_t void_target_buffer[2048];
|
||||
if(void_target_length < length)
|
||||
return false;
|
||||
|
||||
err = eax_decrypt_verify_memory(find_cipher("rijndael"),
|
||||
@ -248,7 +248,7 @@ bool CryptionHandler::verify_encryption(const pipes::buffer_view &packet, uint16
|
||||
(unsigned long) header.length(), /* header length */
|
||||
(const unsigned char *) data.data_ptr(),
|
||||
(unsigned long) data.length(),
|
||||
(unsigned char *) target_buffer,
|
||||
(unsigned char *) void_target_buffer,
|
||||
(unsigned char *) mac.data_ptr(),
|
||||
(unsigned long) mac.length(),
|
||||
&success
|
||||
@ -270,14 +270,6 @@ bool CryptionHandler::decryptPacket(protocol::BasicPacket *packet, std::string &
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t target_length = 2048;
|
||||
uint8_t target_buffer[2048];
|
||||
auto length = data.length();
|
||||
if(target_length < length) {
|
||||
error = "buffer too large";
|
||||
return false;
|
||||
}
|
||||
|
||||
err = eax_decrypt_verify_memory(find_cipher("rijndael"),
|
||||
(uint8_t *) key, /* the key */
|
||||
(unsigned long) 16, /* key is 16 bytes */
|
||||
@ -287,7 +279,7 @@ bool CryptionHandler::decryptPacket(protocol::BasicPacket *packet, std::string &
|
||||
(unsigned long) header.length(), /* header length */
|
||||
(const unsigned char *) data.data_ptr(),
|
||||
(unsigned long) data.length(),
|
||||
(unsigned char *) target_buffer,
|
||||
(unsigned char *) data.data_ptr(),
|
||||
(unsigned char *) packet->mac().data_ptr(),
|
||||
(unsigned long) packet->mac().length(),
|
||||
&success
|
||||
@ -302,7 +294,6 @@ bool CryptionHandler::decryptPacket(protocol::BasicPacket *packet, std::string &
|
||||
return false;
|
||||
}
|
||||
|
||||
packet->data(pipes::buffer_view{target_buffer, length});
|
||||
packet->setEncrypted(false);
|
||||
return true;
|
||||
}
|
||||
@ -314,18 +305,9 @@ bool CryptionHandler::encryptPacket(protocol::BasicPacket *packet, std::string &
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t length = packet->data().length();
|
||||
|
||||
size_t tag_length = 8;
|
||||
char tag_buffer[8];
|
||||
|
||||
size_t target_length = 2048;
|
||||
uint8_t target_buffer[2048];
|
||||
if(target_length < length) {
|
||||
error = "buffer too large";
|
||||
return false;
|
||||
}
|
||||
|
||||
int err;
|
||||
if((err = eax_encrypt_authenticate_memory(find_cipher("rijndael"),
|
||||
(uint8_t *) key, /* the key */
|
||||
@ -336,7 +318,7 @@ bool CryptionHandler::encryptPacket(protocol::BasicPacket *packet, std::string &
|
||||
(unsigned long) packet->header().length(), /* header length */
|
||||
(uint8_t *) packet->data().data_ptr(), /* The plain text */
|
||||
(unsigned long) packet->data().length(), /* Plain text length */
|
||||
(uint8_t *) target_buffer, /* The result buffer */
|
||||
(uint8_t *) packet->data().data_ptr(), /* The result buffer */
|
||||
(uint8_t *) tag_buffer,
|
||||
(unsigned long *) &tag_length
|
||||
)) != CRYPT_OK){
|
||||
@ -344,8 +326,6 @@ bool CryptionHandler::encryptPacket(protocol::BasicPacket *packet, std::string &
|
||||
return false;
|
||||
}
|
||||
assert(tag_length == 8);
|
||||
|
||||
packet->data(pipes::buffer_view{target_buffer, length});
|
||||
packet->mac().write(tag_buffer, tag_length);
|
||||
packet->setEncrypted(true);
|
||||
return true;
|
||||
@ -353,7 +333,7 @@ bool CryptionHandler::encryptPacket(protocol::BasicPacket *packet, std::string &
|
||||
|
||||
bool CryptionHandler::progressPacketIn(protocol::BasicPacket* packet, std::string& error, bool use_default) {
|
||||
while(blocked)
|
||||
this_thread::sleep_for(chrono::microseconds(100));
|
||||
this_thread::yield();
|
||||
|
||||
if(packet->isEncrypted()){
|
||||
bool success = decryptPacket(packet, error, use_default);
|
||||
@ -365,9 +345,9 @@ bool CryptionHandler::progressPacketIn(protocol::BasicPacket* packet, std::strin
|
||||
|
||||
bool CryptionHandler::progressPacketOut(protocol::BasicPacket* packet, std::string& error, bool use_default) {
|
||||
while(blocked)
|
||||
this_thread::sleep_for(chrono::microseconds(100));
|
||||
this_thread::yield();
|
||||
|
||||
if(packet->hasFlag(PacketFlag::Unencrypted)) {
|
||||
if(packet->has_flag(PacketFlag::Unencrypted)) {
|
||||
packet->mac().write(this->current_mac, 8);
|
||||
} else {
|
||||
bool success = encryptPacket(packet, error, use_default);
|
||||
|
@ -26,7 +26,7 @@ namespace ts {
|
||||
|
||||
//TeamSpeak old
|
||||
bool setupSharedSecret(const std::string& alpha, const std::string& beta, ecc_key* publicKey, ecc_key* ownKey, std::string &error);
|
||||
bool setupSharedSecret(const std::string& alpha, const std::string& beta, std::string sharedKey, std::string &error);
|
||||
bool setupSharedSecret(const std::string& alpha, const std::string& beta, const std::string& sharedKey, std::string &error);
|
||||
|
||||
//TeamSpeak new
|
||||
bool setupSharedSecretNew(const std::string& alpha, const std::string& beta, const char privateKey[32], const char publicKey[32]);
|
||||
|
@ -91,10 +91,10 @@ namespace ts {
|
||||
std::string BasicPacket::flags() const {
|
||||
std::string result;
|
||||
|
||||
if(hasFlag(PacketFlag::Unencrypted)) result += string(result.empty() ? "" : " | ") + "Unencrypted";
|
||||
if(hasFlag(PacketFlag::Compressed)) result += string(result.empty() ? "" : " | ") + "Compressed";
|
||||
if(hasFlag(PacketFlag::Fragmented)) result += string(result.empty() ? "" : " | ") + "Fragmented";
|
||||
if(hasFlag(PacketFlag::NewProtocol)) result += string(result.empty() ? "" : " | ") + "NewProtocol";
|
||||
if(this->has_flag(PacketFlag::Unencrypted)) result += string(result.empty() ? "" : " | ") + "Unencrypted";
|
||||
if(this->has_flag(PacketFlag::Compressed)) result += string(result.empty() ? "" : " | ") + "Compressed";
|
||||
if(this->has_flag(PacketFlag::Fragmented)) result += string(result.empty() ? "" : " | ") + "Fragmented";
|
||||
if(this->has_flag(PacketFlag::NewProtocol)) result += string(result.empty() ? "" : " | ") + "NewProtocol";
|
||||
|
||||
if(result.empty()) result = "none";
|
||||
return result;
|
||||
@ -130,6 +130,10 @@ namespace ts {
|
||||
memcpy(this->data().data_ptr(), data.data_ptr(), data.length());
|
||||
}
|
||||
|
||||
ServerPacket::ServerPacket(ts::protocol::PacketTypeInfo type, size_t data_length) : BasicPacket(SERVER_HEADER_SIZE, data_length) {
|
||||
this->header()[2] |= type.type();
|
||||
}
|
||||
|
||||
ServerPacket::~ServerPacket() {}
|
||||
|
||||
uint16_t ServerPacket::packetId() const {
|
||||
@ -149,22 +153,6 @@ namespace ts {
|
||||
return PacketTypeInfo::fromid(this->header()[2] & 0xF);
|
||||
}
|
||||
|
||||
uint8_t ServerPacket::flagMask() const {
|
||||
return this->header()[2];
|
||||
}
|
||||
|
||||
bool ServerPacket::hasFlag(PacketFlag::PacketFlag flag) const {
|
||||
return (this->header()[2] & flag) > 0;
|
||||
}
|
||||
|
||||
void ServerPacket::toggle(PacketFlag::PacketFlag flag, bool state) {
|
||||
if(state){
|
||||
this->header()[2] |= flag;
|
||||
} else {
|
||||
this->header()[2] &= ~flag;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ClientPacket::ClientPacket(const pipes::buffer_view& buffer) : BasicPacket(CLIENT_HEADER_SIZE, buffer.own_buffer()) { }
|
||||
|
||||
@ -198,23 +186,6 @@ namespace ts {
|
||||
field |= type.type();
|
||||
}
|
||||
|
||||
bool ClientPacket::hasFlag(PacketFlag::PacketFlag flag) const {
|
||||
return (this->header()[4] & flag) > 0;
|
||||
}
|
||||
|
||||
uint8_t ClientPacket::flagMask() const {
|
||||
return this->header()[4];
|
||||
}
|
||||
|
||||
|
||||
void ClientPacket::toggle(PacketFlag::PacketFlag flag, bool state) {
|
||||
if(state){
|
||||
this->header()[4] |= flag;
|
||||
} else {
|
||||
this->header()[4] &= ~flag;
|
||||
}
|
||||
}
|
||||
|
||||
void ClientPacket::setPacketId(uint16_t pkId, uint16_t gen) {
|
||||
this->header()[0] = (uint8_t) ((pkId >> 8) & 0xFF);
|
||||
this->header()[1] = (uint8_t) ((pkId >> 0) & 0xFF);
|
||||
|
@ -114,6 +114,7 @@ namespace ts {
|
||||
Compressed = 0x40, //If packet type voice than its the header
|
||||
Unencrypted = 0x80
|
||||
};
|
||||
typedef uint8_t PacketFlags;
|
||||
|
||||
std::string to_string(PacketFlag flag);
|
||||
}
|
||||
@ -134,11 +135,26 @@ namespace ts {
|
||||
virtual uint16_t packetId() const = 0;
|
||||
virtual uint16_t generationId() const = 0;
|
||||
virtual PacketTypeInfo type() const = 0;
|
||||
virtual bool hasFlag(PacketFlag::PacketFlag flag) const = 0;
|
||||
virtual uint8_t flagMask() const = 0;
|
||||
virtual std::string flags() const;
|
||||
virtual void enableFlag(PacketFlag::PacketFlag flag){ toggle(flag, true); }
|
||||
virtual void toggle(PacketFlag::PacketFlag flag, bool state) = 0;
|
||||
|
||||
/* packet flag info */
|
||||
inline bool has_flag(PacketFlag::PacketFlag flag) const { return this->_flags_type_byte() & flag; }
|
||||
inline uint8_t flag_mask() const { return this->_flags_type_byte(); };
|
||||
std::string flags() const;
|
||||
|
||||
/* manipulate flags */
|
||||
inline void set_flags(PacketFlag::PacketFlags flags) {
|
||||
uint8_t& byte = this->_flags_type_byte();
|
||||
byte &= 0xF; /* clear all flags */
|
||||
byte |= (flags & 0xF0);
|
||||
}
|
||||
inline void enabled_flag(PacketFlag::PacketFlag flag){ this->toggle_flag(flag, true); }
|
||||
inline void toggle_flag(PacketFlag::PacketFlag flag, bool state) {
|
||||
if(state)
|
||||
this->_flags_type_byte() |= flag;
|
||||
else
|
||||
this->_flags_type_byte() &= ~flag;
|
||||
}
|
||||
|
||||
virtual void applyPacketId(PacketIdManager &);
|
||||
virtual void applyPacketId(uint16_t, uint16_t);
|
||||
|
||||
@ -149,14 +165,14 @@ namespace ts {
|
||||
}
|
||||
inline std::unique_ptr<threads::Future<bool>>& getListener() { return this->listener; }
|
||||
|
||||
inline pipes::buffer_view mac() const { return this->_buffer.view(0, MAC_SIZE); }
|
||||
inline const pipes::buffer_view mac() const { return this->_buffer.view(0, MAC_SIZE); }
|
||||
inline pipes::buffer mac() { return this->_buffer.range(0, MAC_SIZE); }
|
||||
|
||||
inline pipes::buffer_view header() const { return this->_buffer.view(MAC_SIZE, this->_header_length); }
|
||||
inline const pipes::buffer_view header() const { return this->_buffer.view(MAC_SIZE, this->_header_length); }
|
||||
inline pipes::buffer header() { return this->_buffer.range(MAC_SIZE, this->_header_length); }
|
||||
|
||||
inline size_t data_length() const { return this->_buffer.length() - (MAC_SIZE + this->_header_length); }
|
||||
inline pipes::buffer_view data() const { return this->_buffer.view(MAC_SIZE + this->_header_length); }
|
||||
inline const pipes::buffer_view data() const { return this->_buffer.view(MAC_SIZE + this->_header_length); }
|
||||
inline pipes::buffer data() { return this->_buffer.range(MAC_SIZE + this->_header_length); }
|
||||
|
||||
void append_data(const std::vector<pipes::buffer> &data);
|
||||
@ -206,15 +222,12 @@ namespace ts {
|
||||
pipes::buffer buffer() { return this->_buffer; }
|
||||
void buffer(pipes::buffer buffer) { this->_buffer = std::move(buffer); }
|
||||
protected:
|
||||
virtual const uint8_t& _flags_type_byte() const = 0;
|
||||
virtual uint8_t& _flags_type_byte() = 0;
|
||||
|
||||
virtual void setPacketId(uint16_t, uint16_t) = 0;
|
||||
uint8_t _header_length;
|
||||
pipes::buffer _buffer;
|
||||
//std::unique_ptr<uint8_t, decltype(::free)*> buffer;
|
||||
/*
|
||||
std::string _header;
|
||||
std::string _data;
|
||||
std::string _mac;
|
||||
*/
|
||||
|
||||
uint16_t genId = 0;
|
||||
std::unique_ptr<threads::Future<bool>> listener;
|
||||
@ -237,8 +250,6 @@ namespace ts {
|
||||
ClientPacket(const ClientPacket&) = delete;
|
||||
ClientPacket(ClientPacket&&) = delete;
|
||||
|
||||
void toggle(PacketFlag::PacketFlag flag, bool state) override;
|
||||
|
||||
uint16_t clientId() const;
|
||||
void clientId(uint16_t);
|
||||
|
||||
@ -250,10 +261,15 @@ namespace ts {
|
||||
PacketTypeInfo type() const override;
|
||||
void type(const PacketTypeInfo&);
|
||||
|
||||
bool hasFlag(PacketFlag::PacketFlag flag) const override;
|
||||
uint8_t flagMask() const override;
|
||||
|
||||
private:
|
||||
const uint8_t &_flags_type_byte() const override {
|
||||
return this->header().data_ptr<uint8_t>()[4];
|
||||
}
|
||||
|
||||
uint8_t &_flags_type_byte() override {
|
||||
return this->header().data_ptr<uint8_t>()[4];
|
||||
}
|
||||
|
||||
void setPacketId(uint16_t, uint16_t) override;
|
||||
};
|
||||
|
||||
@ -269,6 +285,7 @@ namespace ts {
|
||||
explicit ServerPacket(const pipes::buffer_view& buffer);
|
||||
ServerPacket(uint8_t flagMask, const pipes::buffer_view& data);
|
||||
ServerPacket(PacketTypeInfo type, const pipes::buffer_view& data);
|
||||
ServerPacket(PacketTypeInfo type, size_t /* data length */);
|
||||
~ServerPacket() override;
|
||||
ServerPacket(const ServerPacket&) = delete;
|
||||
ServerPacket(ServerPacket&&) = delete;
|
||||
@ -278,12 +295,15 @@ namespace ts {
|
||||
void generationId(uint16_t generation) { this->genId = generation; }
|
||||
PacketTypeInfo type() const override;
|
||||
|
||||
bool hasFlag(PacketFlag::PacketFlag flag) const override;
|
||||
uint8_t flagMask() const override;
|
||||
|
||||
void toggle(PacketFlag::PacketFlag flag, bool state) override;
|
||||
|
||||
private:
|
||||
const uint8_t &_flags_type_byte() const override {
|
||||
return this->header().data_ptr<uint8_t>()[2];
|
||||
}
|
||||
|
||||
uint8_t &_flags_type_byte() override {
|
||||
return this->header().data_ptr<uint8_t>()[2];
|
||||
}
|
||||
|
||||
void setPacketId(uint16_t, uint16_t) override;
|
||||
};
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ namespace ts {
|
||||
slot.flag_set = false;
|
||||
auto entry = std::move(slot.entry);
|
||||
this->_ring_base_index += 1;
|
||||
this->_ring_index += 1;
|
||||
this->_ring_index_full += 1;
|
||||
if(this->_ring_base_index >= this->_capacity)
|
||||
this->_ring_base_index -= this->_capacity;
|
||||
return entry;
|
||||
@ -85,7 +85,7 @@ namespace ts {
|
||||
this->_ring_base_index = (size_type) this->_capacity;
|
||||
|
||||
this->_ring_base_index -= 1;
|
||||
this->_ring_index -= 1;
|
||||
this->_ring_index_full -= 1;
|
||||
|
||||
auto& slot = this->_slots[this->_ring_base_index];
|
||||
slot.entry = std::forward<E>(entry);
|
||||
@ -118,7 +118,7 @@ namespace ts {
|
||||
if(index > this->_ring_index)
|
||||
this->_ring_index = index;
|
||||
else if(index < 100 && this->_ring_index > std::numeric_limits<size_type>::max() - 100) {
|
||||
this->_ring_index += 200; /* let the index overflow into the generation counter */
|
||||
this->_ring_index_full += 200; /* let the index overflow into the generation counter */
|
||||
this->_ring_index = index; /* set the lover (16) bytes */
|
||||
}
|
||||
}
|
||||
@ -161,8 +161,9 @@ namespace ts {
|
||||
struct {
|
||||
static_assert(8 - sizeof(size_type) > 0, "Invalid size type!");
|
||||
|
||||
uint8_t padding[8 - sizeof(size_type)];
|
||||
/* little endian */
|
||||
size_type _ring_index; /* index of the insert index | overflow is welcome here */
|
||||
uint8_t padding[8 - sizeof(size_type)];
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -94,5 +94,28 @@ int main() {
|
||||
buffer.push_front(2);
|
||||
buffer.push_front(1);
|
||||
print_queue(buffer);
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
[2019-07-05 13:49:02] [DEBUG] 162 | [127.0.0.1:60793/Another TeaSpeak user | 1] Cant decrypt packet of type Voice. Packet ID: 65527, Estimated generation: 2, Full counter: 65536. Dropping packet. Error: memory verify failed!
|
||||
[2019-07-05 13:49:02] [DEBUG] 162 | [127.0.0.1:60793/Another TeaSpeak user | 1] Cant decrypt packet of type Voice. Packet ID: 65528, Estimated generation: 2, Full counter: 65536. Dropping packet. Error: memory verify failed!
|
||||
[2019-07-05 13:49:02] [DEBUG] 162 | [127.0.0.1:60793/Another TeaSpeak user | 1] Cant decrypt packet of type Voice. Packet ID: 65529, Estimated generation: 2, Full counter: 65536. Dropping packet. Error: memory verify failed!
|
||||
[2019-07-05 13:49:02] [DEBUG] 162 | [127.0.0.1:60793/Another TeaSpeak user | 1] Cant decrypt packet of type Voice. Packet ID: 65530, Estimated generation: 2, Full counter: 65536. Dropping packet. Error: memory verify failed!
|
||||
[2019-07-05 13:49:02] [DEBUG] 162 | [127.0.0.1:60793/Another TeaSpeak user | 1] Cant decrypt packet of type Voice. Packet ID: 65531, Estimated generation: 2, Full counter: 65536. Dropping packet. Error: memory verify failed!
|
||||
[2019-07-05 13:49:02] [DEBUG] 162 | [127.0.0.1:60793/Another TeaSpeak user | 1] Cant decrypt packet of type Voice. Packet ID: 65532, Estimated generation: 2, Full counter: 65536. Dropping packet. Error: memory verify failed!
|
||||
[2019-07-05 13:49:02] [DEBUG] 162 | [127.0.0.1:60793/Another TeaSpeak user | 1] Cant decrypt packet of type Voice. Packet ID: 65533, Estimated generation: 2, Full counter: 65536. Dropping packet. Error: memory verify failed!
|
||||
[2019-07-05 13:49:02] [DEBUG] 162 | [127.0.0.1:60793/Another TeaSpeak user | 1] Cant decrypt packet of type Voice. Packet ID: 65534, Estimated generation: 2, Full counter: 65536. Dropping packet. Error: memory verify failed!
|
||||
[2019-07-05 13:49:02] [DEBUG] 162 | [127.0.0.1:60793/Another TeaSpeak user | 1] Cant decrypt packet of type Voice. Packet ID: 65535, Estimated generation: 2, Full counter: 65536. Dropping packet. Error: memory verify failed!
|
||||
*/
|
||||
PacketRingBuffer<int, 16> buffer;
|
||||
buffer.set_generation_packet(0, 65500);
|
||||
|
||||
while(buffer.current_index() < 100 || (buffer.full_index() >> 16) == 0) {
|
||||
buffer.push_back(nullptr);
|
||||
buffer.pop_front();
|
||||
cout << buffer.full_index() << " | " << buffer.current_index() << " | " << buffer.generation(buffer.current_index()) << endl;
|
||||
}
|
||||
__asm__("nop");
|
||||
}
|
Loading…
Reference in New Issue
Block a user