summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2017-09-01 16:25:34 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2017-09-01 16:25:34 -0700
commitf8014413a376551b7853baae81072f969a755e46 (patch)
treef19118672d85310f85cb103af24742af6ca52269 /node
parent2d858b05ac8554ba11374fefaeb583a0bbc0546b (diff)
downloadinfinitytier-f8014413a376551b7853baae81072f969a755e46.tar.gz
infinitytier-f8014413a376551b7853baae81072f969a755e46.zip
Add UDP MTU configurability.
Diffstat (limited to 'node')
-rw-r--r--node/Multicaster.cpp2
-rw-r--r--node/Network.cpp1
-rw-r--r--node/Node.cpp14
-rw-r--r--node/Node.hpp2
-rw-r--r--node/Packet.hpp6
-rw-r--r--node/Switch.cpp13
-rw-r--r--node/Topology.cpp2
-rw-r--r--node/Topology.hpp95
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;