Node invalidation security stuff.

This commit is contained in:
momo5502 2016-02-01 21:59:45 +01:00
parent ad6220fa0b
commit 2a29232a6f
3 changed files with 71 additions and 33 deletions

View File

@ -52,6 +52,7 @@ namespace Components
Node::NodeEntry entry;
entry.lastHeard = Game::Com_Milliseconds();
entry.lastHeartbeat = 0;
entry.lastTime = (valid ? Game::Com_Milliseconds() : 0);
entry.state = (valid ? Node::STATE_VALID : Node::STATE_UNKNOWN);
@ -63,7 +64,14 @@ namespace Components
{
if (ourEntry.address == entry.address)
{
// Validate it
ourEntry.lastHeard = Game::Com_Milliseconds();
// if (ourEntry.state == Node::STATE_INVALID)
// {
// Logger::Print("Node %s was invalidated, but we still received a reference from another node. Suspicous...\n", address.GetString());
// }
// Validate it
if (valid)
{
ourEntry.state = Node::STATE_VALID;
@ -86,6 +94,7 @@ namespace Components
{
Node::DediEntry entry;
entry.lastHeard = Game::Com_Milliseconds();
entry.lastTime = 0;
entry.state = Node::STATE_UNKNOWN;
entry.address = address;
@ -96,6 +105,13 @@ namespace Components
{
if (ourEntry.address == entry.address)
{
ourEntry.lastHeard = Game::Com_Milliseconds();
// if (ourEntry.state == Node::STATE_INVALID)
// {
// Logger::Print("Dedi %s was invalidated, but we still received a reference from another node. Suspicous...\n", address.GetString());
// }
if (dirty)
{
ourEntry.lastTime = Game::Com_Milliseconds();
@ -130,7 +146,7 @@ namespace Components
entries.push_back(thisAddress);
}
if (entries.size() >= 111)
if (entries.size() >= NODE_PACKET_LIMIT)
{
std::string packet = "nodeNodeList\n";
packet.append(reinterpret_cast<char*>(entries.data()), entries.size() * sizeof(Node::AddressEntry));
@ -162,6 +178,16 @@ namespace Components
entries.push_back(thisAddress);
}
if (entries.size() >= DEDI_PACKET_LIMIT)
{
std::string packet = "nodeDediList\n";
packet.append(reinterpret_cast<char*>(entries.data()), entries.size() * sizeof(Node::AddressEntry));
Network::SendRaw(target, packet);
entries.clear();
}
}
std::string packet = "nodeDediList\n";
@ -194,13 +220,13 @@ namespace Components
for (auto node : Node::Nodes)
{
if (node.state != Node::STATE_INVALID)
if (node.state == Node::STATE_INVALID && (Game::Com_Milliseconds() - node.lastHeard) > NODE_INVALID_DELETE)
{
cleanNodes.push_back(node);
Logger::Print("Removing invalid node %s\n", node.address.GetString());
}
else
{
Logger::Print("Removing invalid node %s\n", node.address.GetString());
cleanNodes.push_back(node);
}
}
@ -217,13 +243,13 @@ namespace Components
for (auto dedi : Node::Dedis)
{
if (dedi.state != Node::STATE_INVALID)
if (dedi.state == Node::STATE_INVALID && (Game::Com_Milliseconds() - dedi.lastHeard) > DEDI_INVALID_DELETE)
{
cleanDedis.push_back(dedi);
Logger::Print("Removing invalid dedi %s\n", dedi.address.GetString());
}
else
{
Logger::Print("Removing invalid dedi %s\n", dedi.address.GetString());
cleanDedis.push_back(dedi);
}
}
@ -236,7 +262,6 @@ namespace Components
Node::Node()
{
//#ifdef USE_NODE_STUFF
Assert_Size(Node::AddressEntry, 6);
Dvar::OnInit([] ()
@ -349,7 +374,7 @@ namespace Components
// Send requests
for (auto &node : Node::Nodes)
{
if (count < NODE_FRAME_QUERY_LIMIT && (node.state == Node::STATE_UNKNOWN || (/*node.state != Node::STATE_INVALID && */node.state != Node::STATE_QUERYING && (Game::Com_Milliseconds() - node.lastTime) > (NODE_VALIDITY_EXPIRE))))
if (count < NODE_FRAME_QUERY_LIMIT && (node.state == Node::STATE_UNKNOWN || (/*node.state != Node::STATE_INVALID && */node.state != Node::STATE_QUERYING && (Game::Com_Milliseconds() - node.lastTime) >(NODE_VALIDITY_EXPIRE))))
{
count++;
@ -374,7 +399,7 @@ namespace Components
if (node.state == Node::STATE_VALID)
{
if (heartbeatCount < HEARTBEATS_FRAME_LIMIT && (!node.lastHeartbeat || (Game::Com_Milliseconds() - node.lastHeartbeat) > (HEARTBEAT_INTERVAL)))
if (heartbeatCount < HEARTBEATS_FRAME_LIMIT && (!node.lastHeartbeat || (Game::Com_Milliseconds() - node.lastHeartbeat) >(HEARTBEAT_INTERVAL)))
{
heartbeatCount++;
@ -389,7 +414,7 @@ namespace Components
for (auto &dedi : Node::Dedis)
{
if (count < DEDI_FRAME_QUERY_LIMIT && (dedi.state == Node::STATE_UNKNOWN || (/*node.state != Node::STATE_INVALID && */dedi.state != Node::STATE_QUERYING && (Game::Com_Milliseconds() - dedi.lastTime) > (DEDI_VALIDITY_EXPIRE))))
if (count < DEDI_FRAME_QUERY_LIMIT && (dedi.state == Node::STATE_UNKNOWN || (/*node.state != Node::STATE_INVALID && */dedi.state != Node::STATE_QUERYING && (Game::Com_Milliseconds() - dedi.lastTime) >(DEDI_VALIDITY_EXPIRE))))
{
count++;
@ -444,7 +469,7 @@ namespace Components
}
});
Command::Add("addnode", [](Command::Params params)
Command::Add("addnode", [] (Command::Params params)
{
if (params.Length() < 2) return;
@ -461,7 +486,28 @@ namespace Components
}
}
});
//#endif
Command::Add("syncnodes", [] (Command::Params params)
{
for (auto &node : Node::Nodes)
{
if (node.state != Node::STATE_INVALID)
{
node.state = Node::STATE_UNKNOWN;
}
}
});
Command::Add("syncdedis", [] (Command::Params params)
{
for (auto &dedi : Node::Dedis)
{
if (dedi.state != Node::STATE_INVALID)
{
dedi.state = Node::STATE_UNKNOWN;
}
}
});
}
Node::~Node()

View File

@ -7,10 +7,16 @@
#define NODE_QUERY_TIMEOUT 1000 * 30 * 1 // Invalidate nodes after 30 seconds without query response
#define DEDI_QUERY_TIMEOUT 1000 * 10 * 1 // Invalidate dedis after 10 seconds without query response
#define NODE_INVALID_DELETE 1000 * 60 * 10 // Delete invalidated nodes after 10 minutes
#define DEDI_INVALID_DELETE 1000 * 60 * 10 // Delete invalidated dedis after 10 minutes
#define HEARTBEATS_FRAME_LIMIT 1 // Limit of heartbeats sent to nodes per frame
#define NODE_FRAME_QUERY_LIMIT 1 // Limit of nodes to be queried per frame
#define DEDI_FRAME_QUERY_LIMIT 1 // Limit of dedis to be queried per frame
#define NODE_PACKET_LIMIT 111 // Send 111 nodes per synchronization packet
#define DEDI_PACKET_LIMIT 111 // Send 111 dedis per synchronization packet
namespace Components
{
class Node : public Component
@ -28,15 +34,16 @@ namespace Components
STATE_UNKNOWN,
STATE_QUERYING,
STATE_VALID,
STATE_INVALID
STATE_INVALID,
};
struct NodeEntry
{
Network::Address address;
EntryState state;
int lastTime;
int lastHeartbeat;
int lastTime; // Last time we heard anything from the server itself
int lastHeartbeat; // Last time we got a heartbeat from it
int lastHeard; // Last time we heard something of the server at all (refs form other nodes)
};
struct DediEntry
@ -45,6 +52,7 @@ namespace Components
std::string challenge;
EntryState state;
int lastTime;
int lastHeard;
};
#pragma pack(push, 1)

View File

@ -41,22 +41,6 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReser
}
})->Install();
// auto key = Utils::Cryptography::RSA::GenerateKey(2048);
// std::string message = "ZOB1234543253253452345";
// std::string signature = Utils::Cryptography::RSA::SignMessage(key, message);
//
// // Invalidate the signature
// //signature[0] ^= 0xFF;
//
// if (Utils::Cryptography::RSA::VerifyMessage(key, message, signature))
// {
// MessageBoxA(0, "Valid", 0, 0);
// }
// else
// {
// MessageBoxA(0, "Invalid!", 0, 0);
// }
}
else if (ul_reason_for_call == DLL_PROCESS_DETACH)
{