فهرست منبع

Add a rate limiting circuit breaker to the network controller to prevent flooding attacks and race conditions.

Adam Ierymenko 10 سال پیش
والد
کامیت
b3516c599b
4فایلهای تغییر یافته به همراه20 افزوده شده و 1 حذف شده
  1. 13 0
      controller/SqliteNetworkController.cpp
  2. 2 0
      controller/SqliteNetworkController.hpp
  3. 3 0
      node/IncomingPacket.cpp
  4. 2 1
      node/NetworkController.hpp

+ 13 - 0
controller/SqliteNetworkController.cpp

@@ -64,6 +64,10 @@
 // API version reported via JSON control plane
 #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 {
@@ -316,6 +320,15 @@ NetworkController::ResultCode SqliteNetworkController::doNetworkConfigRequest(co
 		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;
 	memset(&network,0,sizeof(network));
 	Utils::snprintf(network.id,sizeof(network.id),"%.16llx",(unsigned long long)nwid);

+ 2 - 0
controller/SqliteNetworkController.hpp

@@ -98,6 +98,8 @@ private:
 	std::string _dbPath;
 	std::string _instanceId;
 
+	std::map< std::pair<Address,uint64_t>,uint64_t > _lastRequestTime;
+
 	sqlite3 *_db;
 
 	sqlite3_stmt *_sGetNetworkById;

+ 3 - 0
node/IncomingPacket.cpp

@@ -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());
 					break;
 
+				case NetworkController::NETCONF_QUERY_IGNORE:
+					break;
+
 				default:
 					TRACE("NETWORK_CONFIG_REQUEST failed: invalid return value from NetworkController::doNetworkConfigRequest()");
 					break;

+ 2 - 1
node/NetworkController.hpp

@@ -54,7 +54,8 @@ public:
 		NETCONF_QUERY_OK = 0,
 		NETCONF_QUERY_OBJECT_NOT_FOUND = 1,
 		NETCONF_QUERY_ACCESS_DENIED = 2,
-		NETCONF_QUERY_INTERNAL_SERVER_ERROR = 3
+		NETCONF_QUERY_INTERNAL_SERVER_ERROR = 3,
+		NETCONF_QUERY_IGNORE = 4
 	};
 
 	NetworkController() {}