diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2017-09-01 16:25:34 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2017-09-01 16:25:34 -0700 |
commit | f8014413a376551b7853baae81072f969a755e46 (patch) | |
tree | f19118672d85310f85cb103af24742af6ca52269 /node | |
parent | 2d858b05ac8554ba11374fefaeb583a0bbc0546b (diff) | |
download | infinitytier-f8014413a376551b7853baae81072f969a755e46.tar.gz infinitytier-f8014413a376551b7853baae81072f969a755e46.zip |
Add UDP MTU configurability.
Diffstat (limited to 'node')
-rw-r--r-- | node/Multicaster.cpp | 2 | ||||
-rw-r--r-- | node/Network.cpp | 1 | ||||
-rw-r--r-- | node/Node.cpp | 14 | ||||
-rw-r--r-- | node/Node.hpp | 2 | ||||
-rw-r--r-- | node/Packet.hpp | 6 | ||||
-rw-r--r-- | node/Switch.cpp | 13 | ||||
-rw-r--r-- | node/Topology.cpp | 2 | ||||
-rw-r--r-- | node/Topology.hpp | 95 |
8 files changed, 93 insertions, 42 deletions
diff --git a/node/Multicaster.cpp b/node/Multicaster.cpp index fb7b068f..e8c8613a 100644 --- a/node/Multicaster.cpp +++ b/node/Multicaster.cpp @@ -111,7 +111,7 @@ unsigned int Multicaster::gather(const Address &queryingPeer,uint64_t nwid,const // Members are returned in random order so that repeated gather queries // will return different subsets of a large multicast group. k = 0; - while ((added < limit)&&(k < s->members.size())&&((appendTo.size() + ZT_ADDRESS_LENGTH) <= ZT_UDP_DEFAULT_PAYLOAD_MTU)) { + while ((added < limit)&&(k < s->members.size())&&((appendTo.size() + ZT_ADDRESS_LENGTH) <= ZT_PROTO_MAX_PACKET_LENGTH)) { rptr = (unsigned int)RR->node->prng(); restart_member_scan: diff --git a/node/Network.cpp b/node/Network.cpp index f7b144e3..16155c33 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -1346,7 +1346,6 @@ void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const ec->status = _status(); ec->type = (_config) ? (_config.isPrivate() ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC) : ZT_NETWORK_TYPE_PRIVATE; 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()); ec->bridge = ((_config.allowPassiveBridging())||(std::find(ab.begin(),ab.end(),RR->identity.address()) != ab.end())) ? 1 : 0; diff --git a/node/Node.cpp b/node/Node.cpp index 34609fd4..871fb21b 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -561,9 +561,9 @@ uint64_t Node::prng() return z + y; } -void Node::setTrustedPaths(const struct sockaddr_storage *networks,const uint64_t *ids,unsigned int count) +ZT_ResultCode Node::setPhysicalPathConfiguration(const struct sockaddr_storage *pathNetwork, const ZT_PhysicalPathConfiguration *pathConfig) { - RR->topology->setTrustedPaths(reinterpret_cast<const InetAddress *>(networks),ids,count); + return ZT_RESULT_OK; } World Node::planet() const @@ -815,7 +815,7 @@ enum ZT_ResultCode ZT_Node_orbit(ZT_Node *node,void *tptr,uint64_t moonWorldId,u } } -ZT_ResultCode ZT_Node_deorbit(ZT_Node *node,void *tptr,uint64_t moonWorldId) +enum ZT_ResultCode ZT_Node_deorbit(ZT_Node *node,void *tptr,uint64_t moonWorldId) { try { return reinterpret_cast<ZeroTier::Node *>(node)->deorbit(tptr,moonWorldId); @@ -902,11 +902,13 @@ void ZT_Node_setNetconfMaster(ZT_Node *node,void *networkControllerInstance) } catch ( ... ) {} } -void ZT_Node_setTrustedPaths(ZT_Node *node,const struct sockaddr_storage *networks,const uint64_t *ids,unsigned int count) +enum ZT_ResultCode ZT_Node_setPhysicalPathConfiguration(ZT_Node *node,const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig) { try { - reinterpret_cast<ZeroTier::Node *>(node)->setTrustedPaths(networks,ids,count); - } catch ( ... ) {} + return reinterpret_cast<ZeroTier::Node *>(node)->setPhysicalPathConfiguration(pathNetwork,pathConfig); + } catch ( ... ) { + return ZT_RESULT_FATAL_ERROR_INTERNAL; + } } void ZT_version(int *major,int *minor,int *revision) diff --git a/node/Node.hpp b/node/Node.hpp index 9658174f..1aa01c9a 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -192,7 +192,7 @@ public: inline bool externalPathLookup(void *tPtr,const Address &ztaddr,int family,InetAddress &addr) { return ( (_cb.pathLookupFunction) ? (_cb.pathLookupFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ztaddr.toInt(),family,reinterpret_cast<struct sockaddr_storage *>(&addr)) != 0) : false ); } uint64_t prng(); - void setTrustedPaths(const struct sockaddr_storage *networks,const uint64_t *ids,unsigned int count); + ZT_ResultCode setPhysicalPathConfiguration(const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig); World planet() const; std::vector<World> moons() const; diff --git a/node/Packet.hpp b/node/Packet.hpp index 5fc631b1..db70e06f 100644 --- a/node/Packet.hpp +++ b/node/Packet.hpp @@ -225,12 +225,8 @@ /** * Packet buffer size (can be changed) - * - * The current value is big enough for ZT_MAX_PACKET_FRAGMENTS, the pragmatic - * packet fragment limit, times the default UDP MTU. Most packets won't be - * this big. */ -#define ZT_PROTO_MAX_PACKET_LENGTH (ZT_MAX_PACKET_FRAGMENTS * ZT_UDP_DEFAULT_PAYLOAD_MTU) +#define ZT_PROTO_MAX_PACKET_LENGTH (ZT_MAX_PACKET_FRAGMENTS * ZT_DEFAULT_PHYSMTU) /** * Minimum viable packet length (a.k.a. header length) diff --git a/node/Switch.cpp b/node/Switch.cpp index 952bdef8..f46b3e73 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -722,10 +722,13 @@ bool Switch::_trySend(void *tPtr,Packet &packet,bool encrypt) return false; } - unsigned int chunkSize = std::min(packet.size(),(unsigned int)ZT_UDP_DEFAULT_PAYLOAD_MTU); + unsigned int mtu = ZT_DEFAULT_PHYSMTU; + uint64_t trustedPathId = 0; + RR->topology->getOutboundPathInfo(viaPath->address(),mtu,trustedPathId); + + unsigned int chunkSize = std::min(packet.size(),mtu); packet.setFragmented(chunkSize < packet.size()); - const uint64_t trustedPathId = RR->topology->getOutboundPathTrust(viaPath->address()); if (trustedPathId) { packet.setTrusted(trustedPathId); } else { @@ -737,13 +740,13 @@ bool Switch::_trySend(void *tPtr,Packet &packet,bool encrypt) // Too big for one packet, fragment the rest unsigned int fragStart = chunkSize; unsigned int remaining = packet.size() - chunkSize; - unsigned int fragsRemaining = (remaining / (ZT_UDP_DEFAULT_PAYLOAD_MTU - ZT_PROTO_MIN_FRAGMENT_LENGTH)); - if ((fragsRemaining * (ZT_UDP_DEFAULT_PAYLOAD_MTU - ZT_PROTO_MIN_FRAGMENT_LENGTH)) < remaining) + unsigned int fragsRemaining = (remaining / (mtu - ZT_PROTO_MIN_FRAGMENT_LENGTH)); + if ((fragsRemaining * (mtu - ZT_PROTO_MIN_FRAGMENT_LENGTH)) < remaining) ++fragsRemaining; const unsigned int totalFragments = fragsRemaining + 1; for(unsigned int fno=1;fno<totalFragments;++fno) { - chunkSize = std::min(remaining,(unsigned int)(ZT_UDP_DEFAULT_PAYLOAD_MTU - ZT_PROTO_MIN_FRAGMENT_LENGTH)); + chunkSize = std::min(remaining,(unsigned int)(mtu - ZT_PROTO_MIN_FRAGMENT_LENGTH)); Packet::Fragment frag(packet,fragStart,chunkSize,fno,totalFragments); viaPath->send(RR,tPtr,frag.data(),frag.size(),now); fragStart += chunkSize; diff --git a/node/Topology.cpp b/node/Topology.cpp index ee5d969d..905b6a91 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -65,7 +65,7 @@ static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = {0x01,0x0 Topology::Topology(const RuntimeEnvironment *renv,void *tPtr) : RR(renv), - _trustedPathCount(0), + _numConfiguredPhysicalPaths(0), _amRoot(false) { uint8_t tmp[ZT_WORLD_MAX_SERIALIZED_LENGTH]; diff --git a/node/Topology.hpp b/node/Topology.hpp index 43921896..34df28a1 100644 --- a/node/Topology.hpp +++ b/node/Topology.hpp @@ -340,6 +340,41 @@ public: inline bool amRoot() const { return _amRoot; } /** + * Get info about a path + * + * The supplied result variables are not modified if no special config info is found. + * + * @param physicalAddress Physical endpoint address + * @param mtu Variable set to MTU + * @param trustedPathId Variable set to trusted path ID + */ + inline void getOutboundPathInfo(const InetAddress &physicalAddress,unsigned int &mtu,uint64_t &trustedPathId) + { + for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i) { + if (_physicalPathConfig[i].first.containsAddress(physicalAddress)) { + trustedPathId = _physicalPathConfig[i].second.trustedPathId; + mtu = _physicalPathConfig[i].second.mtu; + return; + } + } + } + + /** + * Get the payload MTU for an outbound physical path (returns default if not configured) + * + * @param physicalAddress Physical endpoint address + * @return MTU + */ + inline unsigned int getOutboundPathMtu(const InetAddress &physicalAddress) + { + for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i) { + if (_physicalPathConfig[i].first.containsAddress(physicalAddress)) + return _physicalPathConfig[i].second.mtu; + } + return ZT_DEFAULT_PHYSMTU; + } + + /** * Get the outbound trusted path ID for a physical address, or 0 if none * * @param physicalAddress Physical address to which we are sending the packet @@ -347,9 +382,9 @@ public: */ inline uint64_t getOutboundPathTrust(const InetAddress &physicalAddress) { - for(unsigned int i=0;i<_trustedPathCount;++i) { - if (_trustedPathNetworks[i].containsAddress(physicalAddress)) - return _trustedPathIds[i]; + for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i) { + if (_physicalPathConfig[i].first.containsAddress(physicalAddress)) + return _physicalPathConfig[i].second.trustedPathId; } return 0; } @@ -362,30 +397,48 @@ public: */ inline bool shouldInboundPathBeTrusted(const InetAddress &physicalAddress,const uint64_t trustedPathId) { - for(unsigned int i=0;i<_trustedPathCount;++i) { - if ((_trustedPathIds[i] == trustedPathId)&&(_trustedPathNetworks[i].containsAddress(physicalAddress))) + for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i) { + if ((_physicalPathConfig[i].second.trustedPathId == trustedPathId)&&(_physicalPathConfig[i].first.containsAddress(physicalAddress))) return true; } return false; } /** - * Set trusted paths in this topology - * - * @param networks Array of networks (prefix/netmask bits) - * @param ids Array of trusted path IDs - * @param count Number of trusted paths (if larger than ZT_MAX_TRUSTED_PATHS overflow is ignored) + * Set or clear physical path configuration (called via Node::setPhysicalPathConfiguration) */ - inline void setTrustedPaths(const InetAddress *networks,const uint64_t *ids,unsigned int count) + inline void setPhysicalPathConfiguration(const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig) { - if (count > ZT_MAX_TRUSTED_PATHS) - count = ZT_MAX_TRUSTED_PATHS; - Mutex::Lock _l(_trustedPaths_m); - for(unsigned int i=0;i<count;++i) { - _trustedPathIds[i] = ids[i]; - _trustedPathNetworks[i] = networks[i]; + if (!pathNetwork) { + _numConfiguredPhysicalPaths = 0; + } else { + std::map<InetAddress,ZT_PhysicalPathConfiguration> cpaths; + for(unsigned int i=0,j=_numConfiguredPhysicalPaths;i<j;++i) + cpaths[_physicalPathConfig[i].first] = _physicalPathConfig[i].second; + + if (pathConfig) { + ZT_PhysicalPathConfiguration pc(*pathConfig); + + if (pc.mtu <= 0) + pc.mtu = ZT_DEFAULT_PHYSMTU; + else if (pc.mtu < ZT_MIN_PHYSMTU) + pc.mtu = ZT_MIN_PHYSMTU; + else if (pc.mtu > ZT_MAX_PHYSMTU) + pc.mtu = ZT_MAX_PHYSMTU; + + cpaths[*(reinterpret_cast<const InetAddress *>(pathNetwork))] = pc; + } else { + cpaths.erase(*(reinterpret_cast<const InetAddress *>(pathNetwork))); + } + + unsigned int cnt = 0; + for(std::map<InetAddress,ZT_PhysicalPathConfiguration>::const_iterator i(cpaths.begin());((i!=cpaths.end())&&(cnt<ZT_MAX_CONFIGURABLE_PATHS));++i) { + _physicalPathConfig[cnt].first = i->first; + _physicalPathConfig[cnt].second = i->second; + ++cnt; + } + _numConfiguredPhysicalPaths = cnt; } - _trustedPathCount = count; } /** @@ -414,10 +467,8 @@ private: const RuntimeEnvironment *const RR; - uint64_t _trustedPathIds[ZT_MAX_TRUSTED_PATHS]; - InetAddress _trustedPathNetworks[ZT_MAX_TRUSTED_PATHS]; - unsigned int _trustedPathCount; - Mutex _trustedPaths_m; + std::pair<InetAddress,ZT_PhysicalPathConfiguration> _physicalPathConfig[ZT_MAX_CONFIGURABLE_PATHS]; + volatile unsigned int _numConfiguredPhysicalPaths; Hashtable< Address,SharedPtr<Peer> > _peers; Mutex _peers_m; |