mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-02-06 19:19:58 +00:00
Add a rate limiting circuit breaker to the network controller to prevent flooding attacks and race conditions.
This commit is contained in:
parent
3ba54c7e35
commit
b3516c599b
@ -64,6 +64,10 @@
|
|||||||
// API version reported via JSON control plane
|
// API version reported via JSON control plane
|
||||||
#define ZT_NETCONF_CONTROLLER_API_VERSION 1
|
#define ZT_NETCONF_CONTROLLER_API_VERSION 1
|
||||||
|
|
||||||
|
// Drop requests for a given peer and network ID that occur more frequently
|
||||||
|
// than this (ms).
|
||||||
|
#define ZT_NETCONF_MIN_REQUEST_PERIOD 5000
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -316,6 +320,15 @@ NetworkController::ResultCode SqliteNetworkController::doNetworkConfigRequest(co
|
|||||||
return NetworkController::NETCONF_QUERY_INTERNAL_SERVER_ERROR;
|
return NetworkController::NETCONF_QUERY_INTERNAL_SERVER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check rate limit
|
||||||
|
|
||||||
|
{
|
||||||
|
uint64_t &lrt = _lastRequestTime[std::pair<Address,uint64_t>(identity.address(),nwid)];
|
||||||
|
uint64_t lrt2 = lrt;
|
||||||
|
if (((lrt = OSUtils::now()) - lrt2) <= ZT_NETCONF_MIN_REQUEST_PERIOD)
|
||||||
|
return NetworkController::NETCONF_QUERY_IGNORE;
|
||||||
|
}
|
||||||
|
|
||||||
NetworkRecord network;
|
NetworkRecord network;
|
||||||
memset(&network,0,sizeof(network));
|
memset(&network,0,sizeof(network));
|
||||||
Utils::snprintf(network.id,sizeof(network.id),"%.16llx",(unsigned long long)nwid);
|
Utils::snprintf(network.id,sizeof(network.id),"%.16llx",(unsigned long long)nwid);
|
||||||
|
@ -98,6 +98,8 @@ private:
|
|||||||
std::string _dbPath;
|
std::string _dbPath;
|
||||||
std::string _instanceId;
|
std::string _instanceId;
|
||||||
|
|
||||||
|
std::map< std::pair<Address,uint64_t>,uint64_t > _lastRequestTime;
|
||||||
|
|
||||||
sqlite3 *_db;
|
sqlite3 *_db;
|
||||||
|
|
||||||
sqlite3_stmt *_sGetNetworkById;
|
sqlite3_stmt *_sGetNetworkById;
|
||||||
|
@ -717,6 +717,9 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
|
|||||||
TRACE("NETWORK_CONFIG_REQUEST failed: internal error: %s",netconf.get("error","(unknown)").c_str());
|
TRACE("NETWORK_CONFIG_REQUEST failed: internal error: %s",netconf.get("error","(unknown)").c_str());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case NetworkController::NETCONF_QUERY_IGNORE:
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
TRACE("NETWORK_CONFIG_REQUEST failed: invalid return value from NetworkController::doNetworkConfigRequest()");
|
TRACE("NETWORK_CONFIG_REQUEST failed: invalid return value from NetworkController::doNetworkConfigRequest()");
|
||||||
break;
|
break;
|
||||||
|
@ -54,7 +54,8 @@ public:
|
|||||||
NETCONF_QUERY_OK = 0,
|
NETCONF_QUERY_OK = 0,
|
||||||
NETCONF_QUERY_OBJECT_NOT_FOUND = 1,
|
NETCONF_QUERY_OBJECT_NOT_FOUND = 1,
|
||||||
NETCONF_QUERY_ACCESS_DENIED = 2,
|
NETCONF_QUERY_ACCESS_DENIED = 2,
|
||||||
NETCONF_QUERY_INTERNAL_SERVER_ERROR = 3
|
NETCONF_QUERY_INTERNAL_SERVER_ERROR = 3,
|
||||||
|
NETCONF_QUERY_IGNORE = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
NetworkController() {}
|
NetworkController() {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user