소스 검색

First pass of configurable MTU and max MTU increase.

Adam Ierymenko 8 년 전
부모
커밋
107e3e4106
6개의 변경된 파일22개의 추가작업 그리고 29개의 파일을 삭제
  1. 1 21
      include/ZeroTierOne.h
  2. 3 6
      node/Constants.hpp
  3. 1 1
      node/IncomingPacket.cpp
  4. 3 1
      node/Network.cpp
  5. 7 0
      node/NetworkConfig.cpp
  6. 7 0
      node/NetworkConfig.hpp

+ 1 - 21
include/ZeroTierOne.h

@@ -61,28 +61,8 @@ extern "C" {
 
 /**
  * Maximum MTU for ZeroTier virtual networks
- *
- * This is pretty much an unchangeable global constant. To make it change
- * across nodes would require logic to send ICMP packet too big messages,
- * which would complicate things. 1500 has been good enough on most LANs
- * for ages, so a larger MTU should be fine for the forseeable future. This
- * typically results in two UDP packets per single large frame. Experimental
- * results seem to show that this is good. Larger MTUs resulting in more
- * fragments seemed too brittle on slow/crummy links for no benefit.
- *
- * If this does change, also change it in tap.h in the tuntaposx code under
- * mac-tap.
- *
- * Overhead for a normal frame split into two packets:
- *
- * 1414 = 1444 (typical UDP MTU) - 28 (packet header) - 2 (ethertype)
- * 1428 = 1444 (typical UDP MTU) - 16 (fragment header)
- * SUM: 2842
- *
- * We use 2800, which leaves some room for other payload in other types of
- * messages such as multicast propagation or future support for bridging.
  */
-#define ZT_MAX_MTU 2800
+#define ZT_MAX_MTU 10000
 
 /**
  * Maximum length of network short name

+ 3 - 6
node/Constants.hpp

@@ -159,15 +159,12 @@
 /**
  * Default MTU used for Ethernet tap device
  */
-#define ZT_IF_MTU ZT_MAX_MTU
+#define ZT_DEFAULT_MTU 2800
 
 /**
- * Maximum number of packet fragments we'll support
- *
- * The actual spec allows 16, but this is the most we'll support right
- * now. Packets with more than this many fragments are dropped.
+ * Maximum number of packet fragments we'll support (protocol max: 16)
  */
-#define ZT_MAX_PACKET_FRAGMENTS 4
+#define ZT_MAX_PACKET_FRAGMENTS 7
 
 /**
  * Size of RX queue

+ 1 - 1
node/IncomingPacket.cpp

@@ -1125,7 +1125,7 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,void *tPtr,
 
 			//TRACE("<<MC FRAME %.16llx/%s from %s@%s flags %.2x length %u",nwid,to.toString().c_str(),from.toString().c_str(),peer->address().toString().c_str(),flags,frameLen);
 
-			if ((frameLen > 0)&&(frameLen <= ZT_IF_MTU)) {
+			if ((frameLen > 0)&&(frameLen <= ZT_MAX_MTU)) {
 				if (!to.mac().isMulticast()) {
 					TRACE("dropped MULTICAST_FRAME from %s@%s(%s) to %s: destination is unicast, must use FRAME or EXT_FRAME",from.toString().c_str(),peer->address().toString().c_str(),_path->address().toString().c_str(),to.toString().c_str());
 					peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,true); // trustEstablished because COM is okay

+ 3 - 1
node/Network.cpp

@@ -1225,6 +1225,8 @@ void Network::requestConfiguration(void *tPtr)
 			nconf->revision = 1;
 			nconf->issuedTo = RR->identity.address();
 			nconf->flags = ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION;
+			nconf->mtu = ZT_DEFAULT_MTU;
+			nconf->multicastLimit = 0;
 			nconf->staticIpCount = 1;
 			nconf->ruleCount = 14;
 			nconf->staticIps[0] = InetAddress::makeIpv66plane(_id,RR->identity.address().toInt());
@@ -1495,7 +1497,7 @@ void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const
 	else ec->name[0] = (char)0;
 	ec->status = _status();
 	ec->type = (_config) ? (_config.isPrivate() ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC) : ZT_NETWORK_TYPE_PRIVATE;
-	ec->mtu = ZT_IF_MTU;
+	ec->mtu = (_config) ? _config.mtu : ZT_DEFAULT_MTU;
 	ec->physicalMtu = ZT_UDP_DEFAULT_PAYLOAD_MTU - (ZT_PACKET_IDX_PAYLOAD + 16);
 	ec->dhcp = 0;
 	std::vector<Address> ab(_config.activeBridges());

+ 7 - 0
node/NetworkConfig.cpp

@@ -51,6 +51,7 @@ bool NetworkConfig::toDictionary(Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d,b
 		if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT,(uint64_t)this->multicastLimit)) return false;
 		if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_TYPE,(uint64_t)this->type)) return false;
 		if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_NAME,this->name)) return false;
+		if (!d.add(ZT_NETWORKCONFIG_DICT_KEY_MTU,(uint64_t)this->mtu)) return false;
 
 #ifdef ZT_SUPPORT_OLD_STYLE_NETCONF
 		if (includeLegacy) {
@@ -217,6 +218,12 @@ bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACI
 		this->multicastLimit = (unsigned int)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT,0);
 		d.get(ZT_NETWORKCONFIG_DICT_KEY_NAME,this->name,sizeof(this->name));
 
+		this->mtu = (unsigned int)d.getUI(ZT_NETWORKCONFIG_DICT_KEY_MTU,ZT_DEFAULT_MTU);
+		if (this->mtu < 1280)
+			this->mtu = 1280; // minimum MTU allowed by IPv6 standard and others
+		else if (this->mtu > ZT_MAX_MTU)
+			this->mtu = ZT_MAX_MTU;
+
 		if (d.getUI(ZT_NETWORKCONFIG_DICT_KEY_VERSION,0) < 6) {
 	#ifdef ZT_SUPPORT_OLD_STYLE_NETCONF
 			char tmp2[1024];

+ 7 - 0
node/NetworkConfig.hpp

@@ -167,6 +167,8 @@ namespace ZeroTier {
 #define ZT_NETWORKCONFIG_DICT_KEY_TYPE "t"
 // text
 #define ZT_NETWORKCONFIG_DICT_KEY_NAME "n"
+// network MTU
+#define ZT_NETWORKCONFIG_DICT_KEY_MTU "mtu"
 // credential time max delta in ms
 #define ZT_NETWORKCONFIG_DICT_KEY_CREDENTIAL_TIME_MAX_DELTA "ctmd"
 // binary serialized certificate of membership
@@ -465,6 +467,11 @@ public:
 	 */
 	uint64_t flags;
 
+	/**
+	 * Network MTU
+	 */
+	unsigned int mtu;
+
 	/**
 	 * Maximum number of recipients per multicast (not including active bridges)
 	 */