[Session] Sign data asynchronously to prevent lags

This commit is contained in:
momo5502 2017-07-02 13:13:06 +02:00
parent b489188f38
commit 6649c9344d
3 changed files with 67 additions and 24 deletions

View File

@ -32,7 +32,7 @@ namespace Components
while (!interval.elapsed(15s))
{
Utils::Hook::Call<void()>(0x49F0B0)(); // Com_ClientPacketEvent
Session::RunFrame();
//Session::RunFrame();
Node::RunFrame();
ServerList::Frame();

View File

@ -2,6 +2,9 @@
namespace Components
{
bool Session::Terminate;
std::thread Session::Thread;
std::recursive_mutex Session::Mutex;
std::unordered_map<Network::Address, Session::Frame> Session::Sessions;
std::unordered_map<Network::Address, std::queue<std::shared_ptr<Session::Packet>>> Session::PacketQueue;
@ -10,6 +13,8 @@ namespace Components
std::map<std::string, Utils::Slot<Network::Callback>> Session::PacketHandlers;
std::queue<std::pair<Network::Address, std::string>> Session::SignatureQueue;
void Session::Send(Network::Address target, std::string command, std::string data)
{
std::lock_guard<std::recursive_mutex> _(Session::Mutex);
@ -54,7 +59,8 @@ namespace Components
if (packet->tries <= SESSION_MAX_RETRIES)
{
packet->tries++;
packet->lastTry.emplace(Utils::Time::Point());
if(!packet->lastTry.has_value()) packet->lastTry.emplace(Utils::Time::Point());
packet->lastTry->update();
Network::SendCommand(queue->first, "sessionSyn");
}
@ -68,18 +74,56 @@ namespace Components
}
}
void Session::HandleSignatures()
{
while (!Session::SignatureQueue.empty())
{
std::unique_lock<std::recursive_mutex> lock(Session::Mutex);
auto signature = Session::SignatureQueue.front();
Session::SignatureQueue.pop();
auto queue = Session::PacketQueue.find(signature.first);
if (queue == Session::PacketQueue.end()) continue;
if (!queue->second.empty())
{
std::shared_ptr<Session::Packet> packet = queue->second.front();
queue->second.pop();
lock.unlock();
Proto::Session::Packet dataPacket;
dataPacket.set_publickey(Session::SignatureKey.getPublicKey());
dataPacket.set_signature(Utils::Cryptography::ECC::SignMessage(Session::SignatureKey, signature.second));
dataPacket.set_command(packet->command);
dataPacket.set_data(packet->data);
Network::SendCommand(signature.first, "sessionFin", dataPacket.SerializeAsString());
}
}
}
Session::Session()
{
Session::SignatureKey = Utils::Cryptography::ECC::GenerateKey(512);
//Scheduler::OnFrame(Session::RunFrame);
Scheduler::OnFrame(Session::RunFrame);
Session::Terminate = false;
Session::Thread = std::thread([]()
{
while (!Session::Terminate)
{
Session::RunFrame();
Session::HandleSignatures();
std::this_thread::sleep_for(20ms);
}
});
Network::Handle("sessionSyn", [](Network::Address address, std::string data)
{
std::lock_guard<std::recursive_mutex> _(Session::Mutex);
Session::Frame frame;
frame.challenge = Utils::Cryptography::Rand::GenerateChallenge();
std::lock_guard<std::recursive_mutex> _(Session::Mutex);
Session::Sessions[address] = frame;
Network::SendCommand(address, "sessionAck", frame.challenge);
@ -88,23 +132,7 @@ namespace Components
Network::Handle("sessionAck", [](Network::Address address, std::string data)
{
std::lock_guard<std::recursive_mutex> _(Session::Mutex);
auto queue = Session::PacketQueue.find(address);
if (queue == Session::PacketQueue.end()) return;
if (!queue->second.empty())
{
std::shared_ptr<Session::Packet> packet = queue->second.front();
queue->second.pop();
Proto::Session::Packet dataPacket;
dataPacket.set_publickey(Session::SignatureKey.getPublicKey());
dataPacket.set_signature(Utils::Cryptography::ECC::SignMessage(Session::SignatureKey, data));
dataPacket.set_command(packet->command);
dataPacket.set_data(packet->data);
Network::SendCommand(address, "sessionFin", dataPacket.SerializeAsString());
}
Session::SignatureQueue.push({ address, data });
});
Network::Handle("sessionFin", [](Network::Address address, std::string data)
@ -141,6 +169,15 @@ namespace Components
Session::SignatureKey.free();
}
void Session::preDestroy()
{
Session::Terminate = true;
if (Session::Thread.joinable())
{
Session::Thread.join();
}
}
bool Session::unitTest()
{
printf("Testing ECDSA key...");

View File

@ -30,13 +30,14 @@ namespace Components
~Session();
bool unitTest() override;
void preDestroy() override;
static void Send(Network::Address target, std::string command, std::string data = "");
static void Handle(std::string packet, Utils::Slot<Network::Callback> callback);
static void RunFrame();
private:
static bool Terminate;
static std::thread Thread;
static std::recursive_mutex Mutex;
static std::unordered_map<Network::Address, Frame> Sessions;
static std::unordered_map<Network::Address, std::queue<std::shared_ptr<Packet>>> PacketQueue;
@ -44,5 +45,10 @@ namespace Components
static Utils::Cryptography::ECC::Key SignatureKey;
static std::map<std::string, Utils::Slot<Network::Callback>> PacketHandlers;
static std::queue<std::pair<Network::Address, std::string>> SignatureQueue;
static void RunFrame();
static void HandleSignatures();
};
}