Explorar el Código

Add new rule to rules engine: random match.

Adam Ierymenko hace 8 años
padre
commit
988049f39b
Se han modificado 4 ficheros con 33 adiciones y 4 borrados
  1. 8 0
      controller/EmbeddedNetworkController.cpp
  2. 14 4
      include/ZeroTierOne.h
  3. 7 0
      node/Capability.hpp
  4. 4 0
      node/Network.cpp

+ 8 - 0
controller/EmbeddedNetworkController.cpp

@@ -260,6 +260,11 @@ static json _renderRule(ZT_VirtualNetworkRule &rule)
 			r["start"] = (unsigned int)rule.v.frameSize[0];
 			r["end"] = (unsigned int)rule.v.frameSize[1];
 			break;
+		case ZT_NETWORK_RULE_MATCH_RANDOM:
+			r["type"] = "MATCH_RANDOM";
+			r["not"] = ((rule.t & 0x80) != 0);
+			r["probability"] = (unsigned long)rule.v.randomProbability;
+			break;
 		case ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE:
 			r["type"] = "MATCH_TAGS_DIFFERENCE";
 			r["not"] = ((rule.t & 0x80) != 0);
@@ -441,6 +446,9 @@ static bool _parseRule(json &r,ZT_VirtualNetworkRule &rule)
 		rule.v.frameSize[0] = (uint16_t)(_jI(r["start"],0ULL) & 0xffffULL);
 		rule.v.frameSize[1] = (uint16_t)(_jI(r["end"],(uint64_t)rule.v.frameSize[0]) & 0xffffULL);
 		return true;
+	} else if (t == "MATCH_RANDOM") {
+		rule.t |= ZT_NETWORK_RULE_MATCH_RANDOM;
+		rule.v.randomProbability = (uint32_t)(_jI(r["probability"],0ULL) & 0xffffffffULL);
 	} else if (t == "MATCH_TAGS_DIFFERENCE") {
 		rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE;
 		rule.v.tag.id = (uint32_t)(_jI(r["id"],0ULL) & 0xffffffffULL);

+ 14 - 4
include/ZeroTierOne.h

@@ -633,25 +633,30 @@ enum ZT_VirtualNetworkRuleType
 	 */
 	ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE = 50,
 
+	/**
+	 * Random match with selectable probability
+	 */
+	ZT_NETWORK_RULE_MATCH_RANDOM = 51,
+
 	/**
 	 * Match if local and remote tags differ by no more than value, use 0 to check for equality
 	 */
-	ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE = 51,
+	ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE = 52,
 
 	/**
 	 * Match if local and remote tags ANDed together equal value.
 	 */
-	ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND = 52,
+	ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND = 53,
 
 	/**
 	 * Match if local and remote tags ANDed together equal value.
 	 */
-	ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR = 53,
+	ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR = 54,
 
 	/**
 	 * Match if local and remote tags XORed together equal value.
 	 */
-	ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR = 54,
+	ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR = 55,
 
 	/**
 	 * Maximum ID allowed for a MATCH entry in the rules table
@@ -720,6 +725,11 @@ typedef struct
 		 */
 		uint64_t zt;
 
+		/**
+		 * 0 = never, UINT32_MAX = always
+		 */
+		uint32_t randomProbability;
+
 		/**
 		 * 48-bit Ethernet MAC address in big-endian order
 		 */

+ 7 - 0
node/Capability.hpp

@@ -249,6 +249,10 @@ public:
 					b.append((uint16_t)rules[i].v.frameSize[0]);
 					b.append((uint16_t)rules[i].v.frameSize[1]);
 					break;
+				case ZT_NETWORK_RULE_MATCH_RANDOM:
+					b.append((uint8_t)4);
+					b.append((uint32_t)rules[i].v.randomProbability);
+					break;
 				case ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE:
 				case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND:
 				case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR:
@@ -331,6 +335,9 @@ public:
 					rules[ruleCount].v.frameSize[0] = b.template at<uint16_t>(p);
 					rules[ruleCount].v.frameSize[1] = b.template at<uint16_t>(p + 2);
 					break;
+				case ZT_NETWORK_RULE_MATCH_RANDOM:
+					rules[ruleCount].v.randomProbability = b.template at<uint32_t>(p);
+					break;
 				case ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE:
 				case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND:
 				case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR:

+ 4 - 0
node/Network.cpp

@@ -504,6 +504,10 @@ static _doZtFilterResult _doZtFilter(
 				thisRuleMatches = (uint8_t)((frameLen >= (unsigned int)rules[rn].v.frameSize[0])&&(frameLen <= (unsigned int)rules[rn].v.frameSize[1]));
 				FILTER_TRACE("%u %s %c %u in %u-%u -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),frameLen,(unsigned int)rules[rn].v.frameSize[0],(unsigned int)rules[rn].v.frameSize[1],(unsigned int)thisRuleMatches);
 				break;
+			case ZT_NETWORK_RULE_MATCH_RANDOM:
+				thisRuleMatches = (uint8_t)((uint32_t)(RR->node->prng() & 0xffffffffULL) <= rules[rn].v.randomProbability);
+				FILTER_TRACE("%u %s %c -> %u",rn,_rtn(rt),(((rules[rn].t & 0x80) != 0) ? '!' : '='),(unsigned int)thisRuleMatches);
+				break;
 			case ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE:
 			case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND:
 			case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR: