From a3db7d0728c1bc5181b8a70e8c379632125ee376 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 1 Oct 2015 11:11:52 -0700 Subject: Refactor: move network COMs out of Network and into Peer in prep for tightening up multicast lookup and other things. --- node/Switch.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'node/Switch.cpp') diff --git a/node/Switch.cpp b/node/Switch.cpp index ecae9b76..9ea8ac49 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -202,7 +202,8 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c // Destination is another ZeroTier peer on the same network Address toZT(to.toAddress(network->id())); // since in-network MACs are derived from addresses and network IDs, we can reverse this - const bool includeCom = network->peerNeedsOurMembershipCertificate(toZT,RR->node->now()); + SharedPtr toPeer(RR->topology->getPeer(toZT)); + const bool includeCom = ((!toPeer)||(toPeer->needsOurNetworkMembershipCertificate(network->id(),RR->node->now(),true)));; if ((fromBridged)||(includeCom)) { Packet outp(toZT,RR->identity.address(),Packet::VERB_EXT_FRAME); outp.append(network->id()); @@ -267,9 +268,10 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c } for(unsigned int b=0;b bridgePeer(RR->topology->getPeer(bridges[b])); Packet outp(bridges[b],RR->identity.address(),Packet::VERB_EXT_FRAME); outp.append(network->id()); - if (network->peerNeedsOurMembershipCertificate(bridges[b],RR->node->now())) { + if ((!bridgePeer)||(bridgePeer->needsOurNetworkMembershipCertificate(network->id(),RR->node->now(),true))) { outp.append((unsigned char)0x01); // 0x01 -- COM included nconf->com().serialize(outp); } else { @@ -747,7 +749,7 @@ bool Switch::_trySend(const Packet &packet,bool encrypt,uint64_t nwid) return false; // no paths, no root servers? } - if ((network)&&(relay)&&(network->isAllowed(peer->address()))) { + if ((network)&&(relay)&&(network->isAllowed(peer))) { // Push hints for direct connectivity to this peer if we are relaying peer->pushDirectPaths(RR,viaPath,now,false); } -- cgit v1.2.3 From 3adb183c5f76b69013d052383c4b812e3947041e Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 19 Oct 2015 13:38:27 -0700 Subject: Fix bad COM attachment bug and eliminate an unnecessary redundant check. --- node/IncomingPacket.cpp | 6 ++---- node/Switch.cpp | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'node/Switch.cpp') diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 6b39963a..19747bbd 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -529,15 +529,13 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr

validateAndSetNetworkMembershipCertificate(RR,network->id(),com)) - comFailed = true; + peer->validateAndSetNetworkMembershipCertificate(RR,network->id(),com); } - if ((comFailed)||(!network->isAllowed(peer))) { + if (!network->isAllowed(peer)) { TRACE("dropped EXT_FRAME from %s(%s): not a member of private network %.16llx",peer->address().toString().c_str(),_remoteAddress.toString().c_str(),network->id()); _sendErrorNeedCertificate(RR,peer,network->id()); return true; diff --git a/node/Switch.cpp b/node/Switch.cpp index 9ea8ac49..249a21d5 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -203,7 +203,7 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c Address toZT(to.toAddress(network->id())); // since in-network MACs are derived from addresses and network IDs, we can reverse this SharedPtr toPeer(RR->topology->getPeer(toZT)); - const bool includeCom = ((!toPeer)||(toPeer->needsOurNetworkMembershipCertificate(network->id(),RR->node->now(),true)));; + const bool includeCom = ( (nconf->isPrivate()) && (nconf->com()) && ((!toPeer)||(toPeer->needsOurNetworkMembershipCertificate(network->id(),RR->node->now(),true))) ); if ((fromBridged)||(includeCom)) { Packet outp(toZT,RR->identity.address(),Packet::VERB_EXT_FRAME); outp.append(network->id()); @@ -271,7 +271,7 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c SharedPtr bridgePeer(RR->topology->getPeer(bridges[b])); Packet outp(bridges[b],RR->identity.address(),Packet::VERB_EXT_FRAME); outp.append(network->id()); - if ((!bridgePeer)||(bridgePeer->needsOurNetworkMembershipCertificate(network->id(),RR->node->now(),true))) { + if ( (nconf->isPrivate()) && (nconf->com()) && ((!bridgePeer)||(bridgePeer->needsOurNetworkMembershipCertificate(network->id(),RR->node->now(),true))) ) { outp.append((unsigned char)0x01); // 0x01 -- COM included nconf->com().serialize(outp); } else { -- cgit v1.2.3 From d6dee7bb5ccb4ae1fcf818afc246befc9133be72 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 20 Oct 2015 17:22:53 -0700 Subject: Clustered handling of relaying. --- node/Cluster.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ node/Cluster.hpp | 11 +++++++++++ node/Switch.cpp | 12 +++++++++++- 3 files changed, 69 insertions(+), 1 deletion(-) (limited to 'node/Switch.cpp') diff --git a/node/Cluster.cpp b/node/Cluster.cpp index 41685a07..7f4a21b0 100644 --- a/node/Cluster.cpp +++ b/node/Cluster.cpp @@ -352,6 +352,53 @@ void Cluster::handleIncomingStateMessage(const void *msg,unsigned int len) } } +bool Cluster::sendViaCluster(const Address &fromPeerAddress,const Address &toPeerAddress,const void *data,unsigned int len) +{ + if (len > 16384) // sanity check + return false; + + uint64_t mostRecentTimestamp = 0; + uint16_t canHasPeer = 0; + + { // Anyone got this peer? + Mutex::Lock _l2(_peerAffinities_m); + std::vector<_PeerAffinity>::iterator i(std::lower_bound(_peerAffinities.begin(),_peerAffinities.end(),_PeerAffinity(toPeerAddress,0,0))); // O(log(n)) + while ((i != _peerAffinities.end())&&(i->address() == toPeerAddress)) { + uint16_t mid = i->clusterMemberId(); + if ((mid != _id)&&(i->timestamp > mostRecentTimestamp)) { + mostRecentTimestamp = i->timestamp; + canHasPeer = mid; + } + } + } + + const uint64_t now = RR->node->now(); + if ((now - mostRecentTimestamp) < ZT_PEER_ACTIVITY_TIMEOUT) { + Buffer<16384> buf; + + InetAddress v4,v6; + if (fromPeerAddress) { + SharedPtr fromPeer(RR->topology->getPeer(fromPeerAddress)); + if (fromPeer) + fromPeer->getBestActiveAddresses(now,v4,v6); + } + buf.append((uint8_t)( (v4) ? ((v6) ? 2 : 1) : ((v6) ? 1 : 0) )); + if (v4) + v4.serialize(buf); + if (v6) + v6.serialize(buf); + buf.append((uint16_t)len); + buf.append(data,len); + + { + Mutex::Lock _l2(_members[canHasPeer].lock); + _send(canHasPeer,STATE_MESSAGE_RELAY,buf.data(),buf.size()); + } + } + + return false; +} + void Cluster::replicateHavePeer(const Identity &peerId) { { // Use peer affinity table to track our own last announce time for peers diff --git a/node/Cluster.hpp b/node/Cluster.hpp index df061c60..60157b15 100644 --- a/node/Cluster.hpp +++ b/node/Cluster.hpp @@ -191,6 +191,17 @@ public: */ void handleIncomingStateMessage(const void *msg,unsigned int len); + /** + * Send this packet via another node in this cluster if another node has this peer + * + * @param fromPeerAddress Source peer address (if known, should be NULL for fragments) + * @param toPeerAddress Destination peer address + * @param data Packet or packet fragment data + * @param len Length of packet or fragment + * @return True if this data was sent via another cluster member, false if none have this peer + */ + bool sendViaCluster(const Address &fromPeerAddress,const Address &toPeerAddress,const void *data,unsigned int len); + /** * Advertise to the cluster that we have this peer * diff --git a/node/Switch.cpp b/node/Switch.cpp index 249a21d5..0edaa96d 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -45,6 +45,7 @@ #include "AntiRecursion.hpp" #include "SelfAwareness.hpp" #include "Packet.hpp" +#include "Cluster.hpp" namespace ZeroTier { @@ -567,6 +568,11 @@ void Switch::_handleRemotePacketFragment(const InetAddress &localAddr,const Inet // It wouldn't hurt anything, just redundant and unnecessary. SharedPtr relayTo = RR->topology->getPeer(destination); if ((!relayTo)||(!relayTo->send(RR,fragment.data(),fragment.size(),RR->node->now()))) { +#ifdef ZT_ENABLE_CLUSTER + if ((RR->cluster)&&(RR->cluster->sendViaCluster(Address(),destination,fragment.data(),fragment.size()))) + return; // sent by way of another member of this cluster +#endif + // Don't know peer or no direct path -- so relay via root server relayTo = RR->topology->getBestRoot(); if (relayTo) @@ -642,7 +648,11 @@ void Switch::_handleRemotePacketHead(const InetAddress &localAddr,const InetAddr if ((relayTo)&&((relayTo->send(RR,packet->data(),packet->size(),RR->node->now())))) { unite(source,destination,false); } else { - // Don't know peer or no direct path -- so relay via root server +#ifdef ZT_ENABLE_CLUSTER + if ((RR->cluster)&&(RR->cluster->sendViaCluster(source,destination,packet->data(),packet->size()))) + return; // sent by way of another member of this cluster +#endif + relayTo = RR->topology->getBestRoot(&source,1,true); if (relayTo) relayTo->send(RR,packet->data(),packet->size(),RR->node->now()); -- cgit v1.2.3 From de761c5a82b7928decf94e93aff4af7adc309e7a Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 26 Oct 2015 15:47:32 -0700 Subject: Fix test world def. --- node/Switch.cpp | 7 +++++++ node/Topology.cpp | 4 ++-- world/alice-test/alice-test.bin | Bin 510 -> 582 bytes world/alice-test/alice-test.out | 8 ++++---- world/alice-test/mkworld.cpp | 1 + 5 files changed, 14 insertions(+), 6 deletions(-) (limited to 'node/Switch.cpp') diff --git a/node/Switch.cpp b/node/Switch.cpp index 0edaa96d..709ed802 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -295,6 +295,8 @@ void Switch::send(const Packet &packet,bool encrypt,uint64_t nwid) return; } + //TRACE(">> %s to %s (%u bytes, encrypt==%d, nwid==%.16llx)",Packet::verbString(packet.verb()),packet.destination().toString().c_str(),packet.size(),(int)encrypt,nwid); + if (!_trySend(packet,encrypt,nwid)) { Mutex::Lock _l(_txQueue_m); _txQueue.push_back(TXQueueEntry(packet.destination(),RR->node->now(),packet,encrypt,nwid)); @@ -637,6 +639,11 @@ void Switch::_handleRemotePacketHead(const InetAddress &localAddr,const InetAddr Address source(packet->source()); Address destination(packet->destination()); + // Catch this and toss it -- it would never work, but it could happen if we somehow + // mistakenly guessed an address we're bound to as a destination for another peer. + if (source == RR->identity.address()) + return; + //TRACE("<< %.16llx %s -> %s (size: %u)",(unsigned long long)packet->packetId(),source.toString().c_str(),destination.toString().c_str(),packet->size()); if (destination != RR->identity.address()) { diff --git a/node/Topology.cpp b/node/Topology.cpp index 2114e5a7..ff4b7225 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -39,8 +39,8 @@ namespace ZeroTier { //#define ZT_DEFAULT_WORLD_LENGTH 494 //static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = {0x01,0x00,0x00,0x00,0x00,0x08,0xea,0xc9,0x0a,0x00,0x00,0x01,0x4f,0xdf,0xbf,0xfc,0xbb,0x6c,0x7e,0x15,0x67,0x85,0x1b,0xb4,0x65,0x04,0x01,0xaf,0x56,0xbf,0xe7,0x63,0x9d,0x77,0xef,0xa4,0x1e,0x61,0x53,0x88,0xcb,0x8d,0x78,0xe5,0x47,0x38,0x98,0x5a,0x6c,0x8a,0xdd,0xe6,0x9c,0x65,0xdf,0x1a,0x80,0x63,0xce,0x2e,0x4d,0x48,0x24,0x3d,0x68,0x87,0x96,0x13,0x89,0xba,0x25,0x6f,0xc9,0xb0,0x9f,0x20,0xc5,0x4c,0x51,0x7b,0x30,0xb7,0x5f,0xba,0xca,0xa4,0xc5,0x48,0xa3,0x15,0xab,0x2f,0x1d,0x64,0xe8,0x04,0x42,0xb3,0x1c,0x51,0x8b,0x2a,0x04,0x01,0xf8,0xe1,0x81,0xaf,0x60,0x2f,0x70,0x3e,0xcd,0x0b,0x21,0x38,0x19,0x62,0x02,0xbd,0x0e,0x33,0x1d,0x0a,0x7b,0xf1,0xec,0xad,0xef,0x54,0xb3,0x7b,0x17,0x84,0xaa,0xda,0x0a,0x85,0x5d,0x0b,0x1c,0x05,0x83,0xb9,0x0e,0x3e,0xe3,0xb4,0xd1,0x8b,0x5b,0x64,0xf7,0xcf,0xe1,0xff,0x5d,0xc2,0x2a,0xcf,0x60,0x7b,0x09,0xb4,0xa3,0x86,0x3c,0x5a,0x7e,0x31,0xa0,0xc7,0xb4,0x86,0xe3,0x41,0x33,0x04,0x7e,0x19,0x87,0x6a,0xba,0x00,0x2a,0x6e,0x2b,0x23,0x18,0x93,0x0f,0x60,0xeb,0x09,0x7f,0x70,0xd0,0xf4,0xb0,0x28,0xb2,0xcd,0x6d,0x3d,0x0c,0x63,0xc0,0x14,0xb9,0x03,0x9f,0xf3,0x53,0x90,0xe4,0x11,0x81,0xf2,0x16,0xfb,0x2e,0x6f,0xa8,0xd9,0x5c,0x1e,0xe9,0x66,0x71,0x56,0x41,0x19,0x05,0xc3,0xdc,0xcf,0xea,0x78,0xd8,0xc6,0xdf,0xaf,0xba,0x68,0x81,0x70,0xb3,0xfa,0x00,0x01,0x04,0xc6,0xc7,0x61,0xdc,0x27,0x09,0x88,0x41,0x40,0x8a,0x2e,0x00,0xbb,0x1d,0x31,0xf2,0xc3,0x23,0xe2,0x64,0xe9,0xe6,0x41,0x72,0xc1,0xa7,0x4f,0x77,0x89,0x95,0x55,0xed,0x10,0x75,0x1c,0xd5,0x6e,0x86,0x40,0x5c,0xde,0x11,0x8d,0x02,0xdf,0xfe,0x55,0x5d,0x46,0x2c,0xcf,0x6a,0x85,0xb5,0x63,0x1c,0x12,0x35,0x0c,0x8d,0x5d,0xc4,0x09,0xba,0x10,0xb9,0x02,0x5d,0x0f,0x44,0x5c,0xf4,0x49,0xd9,0x2b,0x1c,0x00,0x01,0x04,0x6b,0xbf,0x2e,0xd2,0x27,0x09,0x8a,0xcf,0x05,0x9f,0xe3,0x00,0x48,0x2f,0x6e,0xe5,0xdf,0xe9,0x02,0x31,0x9b,0x41,0x9d,0xe5,0xbd,0xc7,0x65,0x20,0x9c,0x0e,0xcd,0xa3,0x8c,0x4d,0x6e,0x4f,0xcf,0x0d,0x33,0x65,0x83,0x98,0xb4,0x52,0x7d,0xcd,0x22,0xf9,0x31,0x12,0xfb,0x9b,0xef,0xd0,0x2f,0xd7,0x8b,0xf7,0x26,0x1b,0x33,0x3f,0xc1,0x05,0xd1,0x92,0xa6,0x23,0xca,0x9e,0x50,0xfc,0x60,0xb3,0x74,0xa5,0x00,0x01,0x04,0xa2,0xf3,0x4d,0x6f,0x27,0x09,0x9d,0x21,0x90,0x39,0xf3,0x00,0x01,0xf0,0x92,0x2a,0x98,0xe3,0xb3,0x4e,0xbc,0xbf,0xf3,0x33,0x26,0x9d,0xc2,0x65,0xd7,0xa0,0x20,0xaa,0xb6,0x9d,0x72,0xbe,0x4d,0x4a,0xcc,0x9c,0x8c,0x92,0x94,0x78,0x57,0x71,0x25,0x6c,0xd1,0xd9,0x42,0xa9,0x0d,0x1b,0xd1,0xd2,0xdc,0xa3,0xea,0x84,0xef,0x7d,0x85,0xaf,0xe6,0x61,0x1f,0xb4,0x3f,0xf0,0xb7,0x41,0x26,0xd9,0x0a,0x6e,0x00,0x01,0x04,0x80,0xc7,0xc5,0xd9,0x27,0x09}; -#define ZT_DEFAULT_WORLD_LENGTH 510 -static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = {0x01,0x00,0x00,0x00,0x00,0x08,0xea,0xc9,0x0a,0x00,0x00,0x01,0x50,0xa6,0x29,0x29,0xcf,0x72,0xb0,0x3b,0xbe,0x73,0xda,0xbd,0xfb,0x85,0x77,0x9f,0xc9,0x2e,0x17,0xc8,0x11,0x6e,0xda,0x61,0x80,0xd1,0x41,0xcb,0x7c,0x2d,0x2b,0xa4,0x34,0x75,0x19,0x64,0x20,0x80,0x0a,0x22,0x32,0xf2,0x01,0x6c,0xfe,0x79,0xa6,0x7d,0xec,0x10,0x7e,0x03,0xf3,0xa2,0xa0,0x19,0xc8,0x7c,0xfd,0x6c,0x56,0x52,0xa8,0xfb,0xdc,0xfb,0x93,0x81,0x3e,0xe9,0x3d,0x15,0xbb,0x20,0x3e,0xd4,0x08,0xc2,0xec,0xd4,0xfd,0xe3,0x49,0x9c,0x3a,0xe2,0x33,0xd4,0x7d,0x62,0xc1,0xec,0x1b,0x74,0x97,0xb7,0x7d,0x2a,0x3e,0xff,0xe5,0x94,0x70,0xe6,0x51,0x6b,0xc2,0x90,0x80,0x50,0x42,0x7e,0x83,0xde,0xe3,0x3a,0xa4,0xc8,0xfb,0xce,0x2b,0x06,0x5b,0x0a,0xf4,0xca,0x1c,0x41,0x3c,0x2a,0x65,0x1c,0x01,0xe3,0x13,0x79,0x9f,0xd1,0xff,0x13,0xa5,0x51,0xf9,0x3e,0x03,0xf6,0x71,0x84,0xed,0x78,0x42,0x82,0x81,0xe0,0x90,0x30,0x7a,0x78,0xd8,0x1b,0x53,0x15,0x49,0x29,0x62,0x01,0x16,0xeb,0xbd,0x6c,0x5d,0x00,0x47,0xd3,0x9b,0xca,0x9d,0x0a,0x5c,0xf7,0x01,0x48,0xe3,0x9f,0x6c,0x45,0x19,0x9e,0x17,0xe0,0xe3,0x2e,0x4e,0x46,0xca,0xc0,0x1a,0xe5,0xbc,0xb2,0x12,0x24,0x13,0x7b,0x09,0x7f,0x40,0xbd,0xd9,0x82,0xa9,0x21,0xc3,0xaa,0xbd,0xcb,0x9a,0xda,0x8b,0x4f,0x2b,0xb0,0x59,0x37,0x53,0xbf,0xdb,0x21,0xcf,0x12,0xea,0xc2,0x8c,0x8d,0x90,0x42,0x00,0x14,0x04,0xbc,0xa6,0x5e,0xb1,0x27,0x09,0x06,0x2a,0x03,0xb0,0xc0,0x00,0x02,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x7d,0x00,0x01,0x27,0x09,0x04,0x9f,0xcb,0x61,0xab,0x27,0x09,0x06,0x26,0x04,0xa8,0x80,0x08,0x00,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,0x54,0x60,0x01,0x27,0x09,0x04,0xa9,0x39,0x8f,0x68,0x27,0x09,0x06,0x26,0x07,0xf0,0xd0,0x1d,0x01,0x00,0x57,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x27,0x09,0x04,0x68,0xee,0xb6,0x53,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0xac,0x00,0x08,0x09,0x54,0x00,0x00,0xff,0xfe,0x15,0xf3,0xf4,0x27,0x09,0x04,0x80,0xc7,0xb6,0x09,0x27,0x09,0x06,0x24,0x00,0x61,0x80,0x00,0x00,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x1b,0x10,0x01,0x27,0x09,0x04,0x2d,0x21,0x04,0x43,0x27,0x09,0x06,0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x67,0xb7,0x04,0x27,0x09,0x04,0x8b,0xa2,0x9d,0xf3,0x27,0x09,0x06,0x2a,0x01,0x7e,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x67,0x3f,0xfd,0x27,0x09,0x04,0x2d,0x20,0xf6,0xb3,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x58,0x00,0x8b,0xf8,0x54,0x00,0x00,0xff,0xfe,0x15,0xb3,0x9a,0x27,0x09,0x04,0x2d,0x20,0xf8,0x57,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x70,0x00,0x9b,0xc9,0x54,0x00,0x00,0xff,0xfe,0x15,0xc4,0xf5,0x27,0x09,0x04,0x9f,0xcb,0x02,0x9a,0x27,0x09,0x06,0x26,0x04,0xa8,0x80,0x0c,0xad,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x26,0x70,0x01,0x27,0x09}; +#define ZT_DEFAULT_WORLD_LENGTH 582 +static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = {0x01,0x00,0x00,0x00,0x00,0x08,0xea,0xc9,0x0a,0x00,0x00,0x01,0x50,0xa6,0x54,0xe4,0x8e,0x72,0xb0,0x3b,0xbe,0x73,0xda,0xbd,0xfb,0x85,0x77,0x9f,0xc9,0x2e,0x17,0xc8,0x11,0x6e,0xda,0x61,0x80,0xd1,0x41,0xcb,0x7c,0x2d,0x2b,0xa4,0x34,0x75,0x19,0x64,0x20,0x80,0x0a,0x22,0x32,0xf2,0x01,0x6c,0xfe,0x79,0xa6,0x7d,0xec,0x10,0x7e,0x03,0xf3,0xa2,0xa0,0x19,0xc8,0x7c,0xfd,0x6c,0x56,0x52,0xa8,0xfb,0xdc,0xfb,0x93,0x81,0x3e,0xe4,0xe9,0x51,0xc1,0xe1,0x39,0x50,0xcd,0x17,0x82,0x9d,0x74,0xf1,0xa9,0x5b,0x03,0x14,0x2c,0xa7,0xc0,0x7f,0x21,0x8b,0xad,0xdd,0xa5,0x04,0x26,0x35,0xa6,0xab,0xc1,0x49,0x64,0x2c,0xda,0x65,0x52,0x77,0xf3,0xf0,0x70,0x00,0xcd,0xc3,0xff,0x3b,0x19,0x77,0x4c,0xab,0xb6,0x35,0xbb,0x77,0xcf,0x54,0xe5,0x6d,0x01,0x9d,0x43,0x92,0x0a,0x6d,0x00,0x23,0x8e,0x0a,0x3d,0xba,0x36,0xc3,0xa1,0xa4,0xad,0x13,0x8f,0x46,0xff,0xcc,0x8f,0x9e,0xc2,0x3c,0x06,0xf8,0x3b,0xf3,0xa2,0x5f,0x71,0xcc,0x07,0x35,0x7f,0x02,0xd6,0xdd,0xca,0x6a,0xb5,0x00,0x4e,0x76,0x12,0x07,0xd8,0xb4,0x20,0x0b,0xe4,0x4f,0x47,0x8e,0x3d,0xa1,0x48,0xc1,0x60,0x99,0x11,0x0e,0xe7,0x1b,0x64,0x58,0x6d,0xda,0x11,0x8e,0x40,0x22,0xab,0x63,0x68,0x2c,0xe1,0x37,0xda,0x8b,0xa8,0x17,0xfc,0x7f,0x73,0xaa,0x31,0x63,0xf2,0xe3,0x33,0x93,0x3e,0x29,0x94,0xc4,0x6b,0x4f,0x41,0x19,0x30,0x7b,0xe8,0x85,0x5a,0x72,0x00,0x0a,0x04,0xbc,0xa6,0x5e,0xb1,0x27,0x09,0x06,0x2a,0x03,0xb0,0xc0,0x00,0x02,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x7d,0x00,0x01,0x27,0x09,0x04,0x9f,0xcb,0x61,0xab,0x27,0x09,0x06,0x26,0x04,0xa8,0x80,0x08,0x00,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,0x54,0x60,0x01,0x27,0x09,0x04,0xa9,0x39,0x8f,0x68,0x27,0x09,0x06,0x26,0x07,0xf0,0xd0,0x1d,0x01,0x00,0x57,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x27,0x09,0x04,0x68,0xee,0xb6,0x53,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0xac,0x00,0x08,0x09,0x54,0x00,0x00,0xff,0xfe,0x15,0xf3,0xf4,0x27,0x09,0x04,0x80,0xc7,0xb6,0x09,0x27,0x09,0x06,0x24,0x00,0x61,0x80,0x00,0x00,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x1b,0x10,0x01,0x27,0x09,0x16,0xeb,0xbd,0x6c,0x5d,0x00,0x47,0xd3,0x9b,0xca,0x9d,0x0a,0x5c,0xf7,0x01,0x48,0xe3,0x9f,0x6c,0x45,0x19,0x9e,0x17,0xe0,0xe3,0x2e,0x4e,0x46,0xca,0xc0,0x1a,0xe5,0xbc,0xb2,0x12,0x24,0x13,0x7b,0x09,0x7f,0x40,0xbd,0xd9,0x82,0xa9,0x21,0xc3,0xaa,0xbd,0xcb,0x9a,0xda,0x8b,0x4f,0x2b,0xb0,0x59,0x37,0x53,0xbf,0xdb,0x21,0xcf,0x12,0xea,0xc2,0x8c,0x8d,0x90,0x42,0x00,0x0a,0x04,0x2d,0x21,0x04,0x43,0x27,0x09,0x06,0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x67,0xb7,0x04,0x27,0x09,0x04,0x8b,0xa2,0x9d,0xf3,0x27,0x09,0x06,0x2a,0x01,0x7e,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x67,0x3f,0xfd,0x27,0x09,0x04,0x2d,0x20,0xf6,0xb3,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x58,0x00,0x8b,0xf8,0x54,0x00,0x00,0xff,0xfe,0x15,0xb3,0x9a,0x27,0x09,0x04,0x2d,0x20,0xf8,0x57,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x70,0x00,0x9b,0xc9,0x54,0x00,0x00,0xff,0xfe,0x15,0xc4,0xf5,0x27,0x09,0x04,0x9f,0xcb,0x02,0x9a,0x27,0x09,0x06,0x26,0x04,0xa8,0x80,0x0c,0xad,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x26,0x70,0x01,0x27,0x09}; Topology::Topology(const RuntimeEnvironment *renv) : RR(renv), diff --git a/world/alice-test/alice-test.bin b/world/alice-test/alice-test.bin index eebe6aaf..910f036f 100644 Binary files a/world/alice-test/alice-test.bin and b/world/alice-test/alice-test.bin differ diff --git a/world/alice-test/alice-test.out b/world/alice-test/alice-test.out index 61d089af..6b9313ce 100644 --- a/world/alice-test/alice-test.out +++ b/world/alice-test/alice-test.out @@ -1,5 +1,5 @@ -INFO: generating and signing id==149604618 ts==1445896726991 -INFO: wrote 510 bytes to stdout +INFO: generating and signing id==149604618 ts==1445899592846 +INFO: wrote 582 bytes to stdout -#define ZT_DEFAULT_WORLD_LENGTH 510 -static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = {0x01,0x00,0x00,0x00,0x00,0x08,0xea,0xc9,0x0a,0x00,0x00,0x01,0x50,0xa6,0x29,0x29,0xcf,0x72,0xb0,0x3b,0xbe,0x73,0xda,0xbd,0xfb,0x85,0x77,0x9f,0xc9,0x2e,0x17,0xc8,0x11,0x6e,0xda,0x61,0x80,0xd1,0x41,0xcb,0x7c,0x2d,0x2b,0xa4,0x34,0x75,0x19,0x64,0x20,0x80,0x0a,0x22,0x32,0xf2,0x01,0x6c,0xfe,0x79,0xa6,0x7d,0xec,0x10,0x7e,0x03,0xf3,0xa2,0xa0,0x19,0xc8,0x7c,0xfd,0x6c,0x56,0x52,0xa8,0xfb,0xdc,0xfb,0x93,0x81,0x3e,0xe9,0x3d,0x15,0xbb,0x20,0x3e,0xd4,0x08,0xc2,0xec,0xd4,0xfd,0xe3,0x49,0x9c,0x3a,0xe2,0x33,0xd4,0x7d,0x62,0xc1,0xec,0x1b,0x74,0x97,0xb7,0x7d,0x2a,0x3e,0xff,0xe5,0x94,0x70,0xe6,0x51,0x6b,0xc2,0x90,0x80,0x50,0x42,0x7e,0x83,0xde,0xe3,0x3a,0xa4,0xc8,0xfb,0xce,0x2b,0x06,0x5b,0x0a,0xf4,0xca,0x1c,0x41,0x3c,0x2a,0x65,0x1c,0x01,0xe3,0x13,0x79,0x9f,0xd1,0xff,0x13,0xa5,0x51,0xf9,0x3e,0x03,0xf6,0x71,0x84,0xed,0x78,0x42,0x82,0x81,0xe0,0x90,0x30,0x7a,0x78,0xd8,0x1b,0x53,0x15,0x49,0x29,0x62,0x01,0x16,0xeb,0xbd,0x6c,0x5d,0x00,0x47,0xd3,0x9b,0xca,0x9d,0x0a,0x5c,0xf7,0x01,0x48,0xe3,0x9f,0x6c,0x45,0x19,0x9e,0x17,0xe0,0xe3,0x2e,0x4e,0x46,0xca,0xc0,0x1a,0xe5,0xbc,0xb2,0x12,0x24,0x13,0x7b,0x09,0x7f,0x40,0xbd,0xd9,0x82,0xa9,0x21,0xc3,0xaa,0xbd,0xcb,0x9a,0xda,0x8b,0x4f,0x2b,0xb0,0x59,0x37,0x53,0xbf,0xdb,0x21,0xcf,0x12,0xea,0xc2,0x8c,0x8d,0x90,0x42,0x00,0x14,0x04,0xbc,0xa6,0x5e,0xb1,0x27,0x09,0x06,0x2a,0x03,0xb0,0xc0,0x00,0x02,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x7d,0x00,0x01,0x27,0x09,0x04,0x9f,0xcb,0x61,0xab,0x27,0x09,0x06,0x26,0x04,0xa8,0x80,0x08,0x00,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,0x54,0x60,0x01,0x27,0x09,0x04,0xa9,0x39,0x8f,0x68,0x27,0x09,0x06,0x26,0x07,0xf0,0xd0,0x1d,0x01,0x00,0x57,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x27,0x09,0x04,0x68,0xee,0xb6,0x53,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0xac,0x00,0x08,0x09,0x54,0x00,0x00,0xff,0xfe,0x15,0xf3,0xf4,0x27,0x09,0x04,0x80,0xc7,0xb6,0x09,0x27,0x09,0x06,0x24,0x00,0x61,0x80,0x00,0x00,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x1b,0x10,0x01,0x27,0x09,0x04,0x2d,0x21,0x04,0x43,0x27,0x09,0x06,0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x67,0xb7,0x04,0x27,0x09,0x04,0x8b,0xa2,0x9d,0xf3,0x27,0x09,0x06,0x2a,0x01,0x7e,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x67,0x3f,0xfd,0x27,0x09,0x04,0x2d,0x20,0xf6,0xb3,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x58,0x00,0x8b,0xf8,0x54,0x00,0x00,0xff,0xfe,0x15,0xb3,0x9a,0x27,0x09,0x04,0x2d,0x20,0xf8,0x57,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x70,0x00,0x9b,0xc9,0x54,0x00,0x00,0xff,0xfe,0x15,0xc4,0xf5,0x27,0x09,0x04,0x9f,0xcb,0x02,0x9a,0x27,0x09,0x06,0x26,0x04,0xa8,0x80,0x0c,0xad,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x26,0x70,0x01,0x27,0x09}; +#define ZT_DEFAULT_WORLD_LENGTH 582 +static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = {0x01,0x00,0x00,0x00,0x00,0x08,0xea,0xc9,0x0a,0x00,0x00,0x01,0x50,0xa6,0x54,0xe4,0x8e,0x72,0xb0,0x3b,0xbe,0x73,0xda,0xbd,0xfb,0x85,0x77,0x9f,0xc9,0x2e,0x17,0xc8,0x11,0x6e,0xda,0x61,0x80,0xd1,0x41,0xcb,0x7c,0x2d,0x2b,0xa4,0x34,0x75,0x19,0x64,0x20,0x80,0x0a,0x22,0x32,0xf2,0x01,0x6c,0xfe,0x79,0xa6,0x7d,0xec,0x10,0x7e,0x03,0xf3,0xa2,0xa0,0x19,0xc8,0x7c,0xfd,0x6c,0x56,0x52,0xa8,0xfb,0xdc,0xfb,0x93,0x81,0x3e,0xe4,0xe9,0x51,0xc1,0xe1,0x39,0x50,0xcd,0x17,0x82,0x9d,0x74,0xf1,0xa9,0x5b,0x03,0x14,0x2c,0xa7,0xc0,0x7f,0x21,0x8b,0xad,0xdd,0xa5,0x04,0x26,0x35,0xa6,0xab,0xc1,0x49,0x64,0x2c,0xda,0x65,0x52,0x77,0xf3,0xf0,0x70,0x00,0xcd,0xc3,0xff,0x3b,0x19,0x77,0x4c,0xab,0xb6,0x35,0xbb,0x77,0xcf,0x54,0xe5,0x6d,0x01,0x9d,0x43,0x92,0x0a,0x6d,0x00,0x23,0x8e,0x0a,0x3d,0xba,0x36,0xc3,0xa1,0xa4,0xad,0x13,0x8f,0x46,0xff,0xcc,0x8f,0x9e,0xc2,0x3c,0x06,0xf8,0x3b,0xf3,0xa2,0x5f,0x71,0xcc,0x07,0x35,0x7f,0x02,0xd6,0xdd,0xca,0x6a,0xb5,0x00,0x4e,0x76,0x12,0x07,0xd8,0xb4,0x20,0x0b,0xe4,0x4f,0x47,0x8e,0x3d,0xa1,0x48,0xc1,0x60,0x99,0x11,0x0e,0xe7,0x1b,0x64,0x58,0x6d,0xda,0x11,0x8e,0x40,0x22,0xab,0x63,0x68,0x2c,0xe1,0x37,0xda,0x8b,0xa8,0x17,0xfc,0x7f,0x73,0xaa,0x31,0x63,0xf2,0xe3,0x33,0x93,0x3e,0x29,0x94,0xc4,0x6b,0x4f,0x41,0x19,0x30,0x7b,0xe8,0x85,0x5a,0x72,0x00,0x0a,0x04,0xbc,0xa6,0x5e,0xb1,0x27,0x09,0x06,0x2a,0x03,0xb0,0xc0,0x00,0x02,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x7d,0x00,0x01,0x27,0x09,0x04,0x9f,0xcb,0x61,0xab,0x27,0x09,0x06,0x26,0x04,0xa8,0x80,0x08,0x00,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,0x54,0x60,0x01,0x27,0x09,0x04,0xa9,0x39,0x8f,0x68,0x27,0x09,0x06,0x26,0x07,0xf0,0xd0,0x1d,0x01,0x00,0x57,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x27,0x09,0x04,0x68,0xee,0xb6,0x53,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0xac,0x00,0x08,0x09,0x54,0x00,0x00,0xff,0xfe,0x15,0xf3,0xf4,0x27,0x09,0x04,0x80,0xc7,0xb6,0x09,0x27,0x09,0x06,0x24,0x00,0x61,0x80,0x00,0x00,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x1b,0x10,0x01,0x27,0x09,0x16,0xeb,0xbd,0x6c,0x5d,0x00,0x47,0xd3,0x9b,0xca,0x9d,0x0a,0x5c,0xf7,0x01,0x48,0xe3,0x9f,0x6c,0x45,0x19,0x9e,0x17,0xe0,0xe3,0x2e,0x4e,0x46,0xca,0xc0,0x1a,0xe5,0xbc,0xb2,0x12,0x24,0x13,0x7b,0x09,0x7f,0x40,0xbd,0xd9,0x82,0xa9,0x21,0xc3,0xaa,0xbd,0xcb,0x9a,0xda,0x8b,0x4f,0x2b,0xb0,0x59,0x37,0x53,0xbf,0xdb,0x21,0xcf,0x12,0xea,0xc2,0x8c,0x8d,0x90,0x42,0x00,0x0a,0x04,0x2d,0x21,0x04,0x43,0x27,0x09,0x06,0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x67,0xb7,0x04,0x27,0x09,0x04,0x8b,0xa2,0x9d,0xf3,0x27,0x09,0x06,0x2a,0x01,0x7e,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x67,0x3f,0xfd,0x27,0x09,0x04,0x2d,0x20,0xf6,0xb3,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x58,0x00,0x8b,0xf8,0x54,0x00,0x00,0xff,0xfe,0x15,0xb3,0x9a,0x27,0x09,0x04,0x2d,0x20,0xf8,0x57,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x70,0x00,0x9b,0xc9,0x54,0x00,0x00,0xff,0xfe,0x15,0xc4,0xf5,0x27,0x09,0x04,0x9f,0xcb,0x02,0x9a,0x27,0x09,0x06,0x26,0x04,0xa8,0x80,0x0c,0xad,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x26,0x70,0x01,0x27,0x09}; diff --git a/world/alice-test/mkworld.cpp b/world/alice-test/mkworld.cpp index 8940db2c..277105c3 100644 --- a/world/alice-test/mkworld.cpp +++ b/world/alice-test/mkworld.cpp @@ -151,6 +151,7 @@ int main(int argc,char **argv) roots.back().stableEndpoints.push_back(InetAddress("2400:6180:0:d0::1b:1001/9993")); // Singapore IPv6 // Bob -- global geo-clustered root #2 + roots.push_back(World::Root()); roots.back().identity = Identity("16ebbd6c5d:0:47d39bca9d0a5cf70148e39f6c45199e17e0e32e4e46cac01ae5bcb21224137b097f40bdd982a921c3aabdcb9ada8b4f2bb0593753bfdb21cf12eac28c8d9042"); roots.back().stableEndpoints.push_back(InetAddress("45.33.4.67/9993")); // Dallas IPv4 roots.back().stableEndpoints.push_back(InetAddress("2600:3c00::f03c:91ff:fe67:b704/9993")); // Dallas IPv6 -- cgit v1.2.3 From f692cec763d67caae54a4f47446657c390563319 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 27 Oct 2015 14:04:12 -0700 Subject: Change how cluster relays packets -- just PROXY_UNITE and then send packet via normal ZeroTier front plane -- more efficient and eliminates fragmentation issues. --- include/ZeroTierOne.h | 2 +- node/Cluster.cpp | 195 +++++++++++++++++++++++++------------------------- node/Cluster.hpp | 22 +++--- node/Switch.cpp | 37 +++++----- node/Switch.hpp | 8 +-- 5 files changed, 133 insertions(+), 131 deletions(-) (limited to 'node/Switch.cpp') diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index 7371b9f0..3457634b 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -141,7 +141,7 @@ extern "C" { /** * Maximum allowed cluster message length in bytes */ -#define ZT_CLUSTER_MAX_MESSAGE_LENGTH (1444 * 4) +#define ZT_CLUSTER_MAX_MESSAGE_LENGTH (1500 - 48) /** * A null/empty sockaddr (all zero) to signify an unspecified socket address diff --git a/node/Cluster.cpp b/node/Cluster.cpp index eef02bc7..c18663bc 100644 --- a/node/Cluster.cpp +++ b/node/Cluster.cpp @@ -250,102 +250,87 @@ void Cluster::handleIncomingStateMessage(const void *msg,unsigned int len) } } break; - case STATE_MESSAGE_RELAY: { + case STATE_MESSAGE_PROXY_UNITE: { + const Address localPeerAddress(dmsg.field(ptr,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); ptr += ZT_ADDRESS_LENGTH; + const Address remotePeerAddress(dmsg.field(ptr,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); ptr += ZT_ADDRESS_LENGTH; const unsigned int numRemotePeerPaths = dmsg[ptr++]; InetAddress remotePeerPaths[256]; // size is 8-bit, so 256 is max for(unsigned int i=0;i(ptr); ptr += 2; - const void *packet = (const void *)dmsg.field(ptr,packetLen); ptr += packetLen; - - if (packetLen >= ZT_PROTO_MIN_FRAGMENT_LENGTH) { // ignore anything too short to contain a dest address - const Address destinationAddress(reinterpret_cast(packet) + 8,ZT_ADDRESS_LENGTH); - TRACE("[%u] relay %u bytes to %s (%u remote paths included)",(unsigned int)fromMemberId,packetLen,destinationAddress.toString().c_str(),numRemotePeerPaths); - - SharedPtr destinationPeer(RR->topology->getPeer(destinationAddress)); - if (destinationPeer) { - if ( - (destinationPeer->send(RR,packet,packetLen,RR->node->now()))&& - (numRemotePeerPaths > 0)&& - (packetLen >= 18)&& - (reinterpret_cast(packet)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_INDICATOR] == ZT_PACKET_FRAGMENT_INDICATOR) - ) { - // If remote peer paths were sent with this relayed packet, we do - // RENDEZVOUS. It's handled here for cluster-relayed packets since - // we don't have both Peer records so this is a different path. - - const Address remotePeerAddress(reinterpret_cast(packet) + 13,ZT_ADDRESS_LENGTH); - - InetAddress bestDestV4,bestDestV6; - destinationPeer->getBestActiveAddresses(RR->node->now(),bestDestV4,bestDestV6); - InetAddress bestRemoteV4,bestRemoteV6; - for(unsigned int i=0;iidentity.address(),Packet::VERB_RENDEZVOUS); - rendezvousForDest.append((uint8_t)0); - remotePeerAddress.appendTo(rendezvousForDest); - - Buffer<2048> rendezvousForOtherEnd; - remotePeerAddress.appendTo(rendezvousForOtherEnd); - rendezvousForOtherEnd.append((uint8_t)Packet::VERB_RENDEZVOUS); - const unsigned int rendezvousForOtherEndPayloadSizePtr = rendezvousForOtherEnd.size(); - rendezvousForOtherEnd.addSize(2); // space for actual packet payload length - rendezvousForOtherEnd.append((uint8_t)0); // flags == 0 - destinationAddress.appendTo(rendezvousForOtherEnd); - - bool haveMatch = false; - if ((bestDestV6)&&(bestRemoteV6)) { - haveMatch = true; - - rendezvousForDest.append((uint16_t)bestRemoteV6.port()); - rendezvousForDest.append((uint8_t)16); - rendezvousForDest.append(bestRemoteV6.rawIpData(),16); - - rendezvousForOtherEnd.append((uint16_t)bestDestV6.port()); - rendezvousForOtherEnd.append((uint8_t)16); - rendezvousForOtherEnd.append(bestDestV6.rawIpData(),16); - rendezvousForOtherEnd.setAt(rendezvousForOtherEndPayloadSizePtr,(uint16_t)(9 + 16)); - } else if ((bestDestV4)&&(bestRemoteV4)) { - haveMatch = true; - - rendezvousForDest.append((uint16_t)bestRemoteV4.port()); - rendezvousForDest.append((uint8_t)4); - rendezvousForDest.append(bestRemoteV4.rawIpData(),4); - - rendezvousForOtherEnd.append((uint16_t)bestDestV4.port()); - rendezvousForOtherEnd.append((uint8_t)4); - rendezvousForOtherEnd.append(bestDestV4.rawIpData(),4); - rendezvousForOtherEnd.setAt(rendezvousForOtherEndPayloadSizePtr,(uint16_t)(9 + 4)); - } - if (haveMatch) { - _send(fromMemberId,STATE_MESSAGE_PROXY_SEND,rendezvousForOtherEnd.data(),rendezvousForOtherEnd.size()); - RR->sw->send(rendezvousForDest,true,0); - } + TRACE("[%u] requested proxy unite between local peer %s and remote peer %s",(unsigned int)fromMemberId,localPeerAddress.toString().c_str(),remotePeerAddress.toString().c_str()); + + SharedPtr localPeer(RR->topology->getPeer(localPeerAddress)); + if ((localPeer)&&(numRemotePeerPaths > 0)) { + InetAddress bestLocalV4,bestLocalV6; + localPeer->getBestActiveAddresses(RR->node->now(),bestLocalV4,bestLocalV6); + + InetAddress bestRemoteV4,bestRemoteV6; + for(unsigned int i=0;iidentity.address(),Packet::VERB_RENDEZVOUS); + rendezvousForLocal.append((uint8_t)0); + remotePeerAddress.appendTo(rendezvousForLocal); + + Buffer<2048> rendezvousForRemote; + remotePeerAddress.appendTo(rendezvousForRemote); + rendezvousForRemote.append((uint8_t)Packet::VERB_RENDEZVOUS); + const unsigned int rendezvousForOtherEndPayloadSizePtr = rendezvousForRemote.size(); + rendezvousForRemote.addSize(2); // space for actual packet payload length + rendezvousForRemote.append((uint8_t)0); // flags == 0 + localPeerAddress.appendTo(rendezvousForRemote); + + bool haveMatch = false; + if ((bestLocalV6)&&(bestRemoteV6)) { + haveMatch = true; + + rendezvousForLocal.append((uint16_t)bestRemoteV6.port()); + rendezvousForLocal.append((uint8_t)16); + rendezvousForLocal.append(bestRemoteV6.rawIpData(),16); + + rendezvousForRemote.append((uint16_t)bestLocalV6.port()); + rendezvousForRemote.append((uint8_t)16); + rendezvousForRemote.append(bestLocalV6.rawIpData(),16); + rendezvousForRemote.setAt(rendezvousForOtherEndPayloadSizePtr,(uint16_t)(9 + 16)); + } else if ((bestLocalV4)&&(bestRemoteV4)) { + haveMatch = true; + + rendezvousForLocal.append((uint16_t)bestRemoteV4.port()); + rendezvousForLocal.append((uint8_t)4); + rendezvousForLocal.append(bestRemoteV4.rawIpData(),4); + + rendezvousForRemote.append((uint16_t)bestLocalV4.port()); + rendezvousForRemote.append((uint8_t)4); + rendezvousForRemote.append(bestLocalV4.rawIpData(),4); + rendezvousForRemote.setAt(rendezvousForOtherEndPayloadSizePtr,(uint16_t)(9 + 4)); + } + + if (haveMatch) { + _send(fromMemberId,STATE_MESSAGE_PROXY_SEND,rendezvousForRemote.data(),rendezvousForRemote.size()); + RR->sw->send(rendezvousForLocal,true,0); + } } } break; case STATE_MESSAGE_PROXY_SEND: { - const Address rcpt(dmsg.field(ptr,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); + const Address rcpt(dmsg.field(ptr,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); ptr += ZT_ADDRESS_LENGTH; const Packet::Verb verb = (Packet::Verb)dmsg[ptr++]; const unsigned int len = dmsg.at(ptr); ptr += 2; Packet outp(rcpt,RR->identity.address(),verb); - outp.append(dmsg.field(ptr,len),len); + outp.append(dmsg.field(ptr,len),len); ptr += len; RR->sw->send(outp,true,0); TRACE("[%u] proxy send %s to %s length %u",(unsigned int)fromMemberId,Packet::verbString(verb),rcpt.toString().c_str(),len); } break; @@ -364,13 +349,13 @@ void Cluster::handleIncomingStateMessage(const void *msg,unsigned int len) } } -bool Cluster::sendViaCluster(const Address &fromPeerAddress,const Address &toPeerAddress,const void *data,unsigned int len) +bool Cluster::sendViaCluster(const Address &fromPeerAddress,const Address &toPeerAddress,const void *data,unsigned int len,bool unite) { if (len > 16384) // sanity check return false; uint64_t mostRecentTimestamp = 0; - uint16_t canHasPeer = 0; + unsigned int canHasPeer = 0; { // Anyone got this peer? Mutex::Lock _l2(_peerAffinities_m); @@ -387,25 +372,37 @@ bool Cluster::sendViaCluster(const Address &fromPeerAddress,const Address &toPee const uint64_t now = RR->node->now(); if ((now - mostRecentTimestamp) < ZT_PEER_ACTIVITY_TIMEOUT) { - Buffer<16384> buf; - - InetAddress v4,v6; - if (fromPeerAddress) { - SharedPtr fromPeer(RR->topology->getPeer(fromPeerAddress)); - if (fromPeer) - fromPeer->getBestActiveAddresses(now,v4,v6); + Buffer<2048> buf; + + if (unite) { + InetAddress v4,v6; + if (fromPeerAddress) { + SharedPtr fromPeer(RR->topology->getPeer(fromPeerAddress)); + if (fromPeer) + fromPeer->getBestActiveAddresses(now,v4,v6); + } + uint8_t addrCount = 0; + if (v4) + ++addrCount; + if (v6) + ++addrCount; + if (addrCount) { + toPeerAddress.appendTo(buf); + fromPeerAddress.appendTo(buf); + buf.append(addrCount); + if (v4) + v4.serialize(buf); + if (v6) + v6.serialize(buf); + } } - buf.append((uint8_t)( (v4) ? ((v6) ? 2 : 1) : ((v6) ? 1 : 0) )); - if (v4) - v4.serialize(buf); - if (v6) - v6.serialize(buf); - buf.append((uint16_t)len); - buf.append(data,len); { Mutex::Lock _l2(_members[canHasPeer].lock); - _send(canHasPeer,STATE_MESSAGE_RELAY,buf.data(),buf.size()); + if (buf.size() > 0) + _send(canHasPeer,STATE_MESSAGE_PROXY_UNITE,buf.data(),buf.size()); + if (_members[canHasPeer].zeroTierPhysicalEndpoints.size() > 0) + RR->node->putPacket(InetAddress(),_members[canHasPeer].zeroTierPhysicalEndpoints.front(),data,len); } TRACE("sendViaCluster(): relaying %u bytes from %s to %s by way of %u",len,fromPeerAddress.toString().c_str(),toPeerAddress.toString().c_str(),(unsigned int)canHasPeer); diff --git a/node/Cluster.hpp b/node/Cluster.hpp index bb7d3b39..282d8120 100644 --- a/node/Cluster.hpp +++ b/node/Cluster.hpp @@ -57,7 +57,7 @@ /** * Desired period between doPeriodicTasks() in milliseconds */ -#define ZT_CLUSTER_PERIODIC_TASK_PERIOD 50 +#define ZT_CLUSTER_PERIODIC_TASK_PERIOD 100 namespace ZeroTier { @@ -136,13 +136,18 @@ public: STATE_MESSAGE_COM = 4, /** - * Relay a packet to a peer: - * <[1] 8-bit number of sending peer active path addresses> - * <[...] series of serialized InetAddresses of sending peer's paths> - * <[2] 16-bit packet length> - * <[...] packet or packet fragment> + * Request that VERB_RENDEZVOUS be sent to a peer that we have: + * <[5] ZeroTier address of peer on recipient's side> + * <[5] ZeroTier address of peer on sender's side> + * <[1] 8-bit number of sender's peer's active path addresses> + * <[...] series of serialized InetAddresses of sender's peer's paths> + * + * This requests that we perform NAT-t introduction between a peer that + * we have and one on the sender's side. The sender furnishes contact + * info for its peer, and we send VERB_RENDEZVOUS to both sides: to ours + * directly and with PROXY_SEND to theirs. */ - STATE_MESSAGE_RELAY = 5, + STATE_MESSAGE_PROXY_UNITE = 5, /** * Request that a cluster member send a packet to a locally-known peer: @@ -211,9 +216,10 @@ public: * @param toPeerAddress Destination peer address * @param data Packet or packet fragment data * @param len Length of packet or fragment + * @param unite If true, also request proxy unite across cluster * @return True if this data was sent via another cluster member, false if none have this peer */ - bool sendViaCluster(const Address &fromPeerAddress,const Address &toPeerAddress,const void *data,unsigned int len); + bool sendViaCluster(const Address &fromPeerAddress,const Address &toPeerAddress,const void *data,unsigned int len,bool unite); /** * Advertise to the cluster that we have this peer diff --git a/node/Switch.cpp b/node/Switch.cpp index 709ed802..772eaf02 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -303,11 +303,10 @@ void Switch::send(const Packet &packet,bool encrypt,uint64_t nwid) } } -bool Switch::unite(const Address &p1,const Address &p2,bool force) +bool Switch::unite(const Address &p1,const Address &p2) { if ((p1 == RR->identity.address())||(p2 == RR->identity.address())) return false; - SharedPtr p1p = RR->topology->getPeer(p1); if (!p1p) return false; @@ -317,14 +316,6 @@ bool Switch::unite(const Address &p1,const Address &p2,bool force) const uint64_t now = RR->node->now(); - { - Mutex::Lock _l(_lastUniteAttempt_m); - uint64_t &luts = _lastUniteAttempt[_LastUniteKey(p1,p2)]; - if (((now - luts) < ZT_MIN_UNITE_INTERVAL)&&(!force)) - return false; - luts = now; - } - std::pair cg(Peer::findCommonGround(*p1p,*p2p,now)); if ((!(cg.first))||(cg.first.ipScope() != cg.second.ipScope())) return false; @@ -571,7 +562,7 @@ void Switch::_handleRemotePacketFragment(const InetAddress &localAddr,const Inet SharedPtr relayTo = RR->topology->getPeer(destination); if ((!relayTo)||(!relayTo->send(RR,fragment.data(),fragment.size(),RR->node->now()))) { #ifdef ZT_ENABLE_CLUSTER - if ((RR->cluster)&&(RR->cluster->sendViaCluster(Address(),destination,fragment.data(),fragment.size()))) + if ((RR->cluster)&&(RR->cluster->sendViaCluster(Address(),destination,fragment.data(),fragment.size(),false))) return; // sent by way of another member of this cluster #endif @@ -634,7 +625,8 @@ void Switch::_handleRemotePacketFragment(const InetAddress &localAddr,const Inet void Switch::_handleRemotePacketHead(const InetAddress &localAddr,const InetAddress &fromAddr,const void *data,unsigned int len) { - SharedPtr packet(new IncomingPacket(data,len,localAddr,fromAddr,RR->node->now())); + const uint64_t now = RR->node->now(); + SharedPtr packet(new IncomingPacket(data,len,localAddr,fromAddr,now)); Address source(packet->source()); Address destination(packet->destination()); @@ -652,17 +644,18 @@ void Switch::_handleRemotePacketHead(const InetAddress &localAddr,const InetAddr packet->incrementHops(); SharedPtr relayTo = RR->topology->getPeer(destination); - if ((relayTo)&&((relayTo->send(RR,packet->data(),packet->size(),RR->node->now())))) { - unite(source,destination,false); + if ((relayTo)&&((relayTo->send(RR,packet->data(),packet->size(),now)))) { + if (_shouldTryUnite(now,source,destination)) + unite(source,destination); } else { #ifdef ZT_ENABLE_CLUSTER - if ((RR->cluster)&&(RR->cluster->sendViaCluster(source,destination,packet->data(),packet->size()))) + if ((RR->cluster)&&(RR->cluster->sendViaCluster(source,destination,packet->data(),packet->size(),_shouldTryUnite(now,source,destination)))) return; // sent by way of another member of this cluster #endif relayTo = RR->topology->getBestRoot(&source,1,true); if (relayTo) - relayTo->send(RR,packet->data(),packet->size(),RR->node->now()); + relayTo->send(RR,packet->data(),packet->size(),now); } } else { TRACE("dropped relay %s(%s) -> %s, max hops exceeded",packet->source().toString().c_str(),fromAddr.toString().c_str(),destination.toString().c_str()); @@ -677,7 +670,7 @@ void Switch::_handleRemotePacketHead(const InetAddress &localAddr,const InetAddr if (!dq.creationTime) { // If we have no other fragments yet, create an entry and save the head - dq.creationTime = RR->node->now(); + dq.creationTime = now; dq.frag0 = packet; dq.totalFragments = 0; // 0 == unknown, waiting for Packet::Fragment dq.haveFragments = 1; // head is first bit (left to right) @@ -805,4 +798,14 @@ bool Switch::_trySend(const Packet &packet,bool encrypt,uint64_t nwid) return false; } +bool Switch::_shouldTryUnite(const uint64_t now,const Address &p1,const Address &p2) +{ + Mutex::Lock _l(_lastUniteAttempt_m); + uint64_t &luts = _lastUniteAttempt[_LastUniteKey(p1,p2)]; + if ((now - luts) < ZT_MIN_UNITE_INTERVAL) + return false; + luts = now; + return true; +} + } // namespace ZeroTier diff --git a/node/Switch.hpp b/node/Switch.hpp index 3bdc0c47..42e87ca5 100644 --- a/node/Switch.hpp +++ b/node/Switch.hpp @@ -127,15 +127,10 @@ public: * This only works if both peers are known, with known working direct * links to this peer. The best link for each peer is sent to the other. * - * A rate limiter is in effect via the _lastUniteAttempt map. If force - * is true, a unite attempt is made even if one has been made less than - * ZT_MIN_UNITE_INTERVAL milliseconds ago. - * * @param p1 One of two peers (order doesn't matter) * @param p2 Second of pair - * @param force If true, send now regardless of interval */ - bool unite(const Address &p1,const Address &p2,bool force); + bool unite(const Address &p1,const Address &p2); /** * Attempt NAT traversal to peer at a given physical address @@ -185,6 +180,7 @@ private: void _handleRemotePacketHead(const InetAddress &localAddr,const InetAddress &fromAddr,const void *data,unsigned int len); Address _sendWhoisRequest(const Address &addr,const Address *peersAlreadyConsulted,unsigned int numPeersAlreadyConsulted); bool _trySend(const Packet &packet,bool encrypt,uint64_t nwid); + bool _shouldTryUnite(const uint64_t now,const Address &p1,const Address &p2); const RuntimeEnvironment *const RR; uint64_t _lastBeaconResponse; -- cgit v1.2.3 From 16bc3e03982286232e1df2da17d8b2fc3c5a5c55 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 27 Oct 2015 15:00:16 -0700 Subject: Factor out RemotePath subclass of Path -- no longer needed, just cruft. --- include/ZeroTierOne.h | 3 +- node/Cluster.cpp | 1 + node/IncomingPacket.cpp | 5 +- node/Multicaster.cpp | 1 + node/Network.cpp | 1 + node/Node.cpp | 14 ++--- node/Node.hpp | 6 +- node/Path.cpp | 45 ++++++++++++++ node/Path.hpp | 117 +++++++++++++++++++++++++++++++++-- node/Peer.cpp | 32 +++++----- node/Peer.hpp | 24 ++++---- node/RemotePath.hpp | 161 ------------------------------------------------ node/SelfAwareness.cpp | 2 +- node/Switch.cpp | 2 +- objects.mk | 1 + service/OneService.cpp | 4 +- 16 files changed, 208 insertions(+), 211 deletions(-) create mode 100644 node/Path.cpp delete mode 100644 node/RemotePath.hpp (limited to 'node/Switch.cpp') diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index 3457634b..01c8bcde 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -1356,11 +1356,10 @@ void ZT_Node_freeQueryResult(ZT_Node *node,void *qr); * reject bad, empty, and unusable addresses. * * @param addr Local interface address - * @param metric Local interface metric * @param trust How much do you trust the local network under this interface? * @return Boolean: non-zero if address was accepted and added */ -int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr,int metric, enum ZT_LocalInterfaceAddressTrust trust); +int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr,enum ZT_LocalInterfaceAddressTrust trust); /** * Clear local interface addresses diff --git a/node/Cluster.cpp b/node/Cluster.cpp index 73ff5846..07ca0ba1 100644 --- a/node/Cluster.cpp +++ b/node/Cluster.cpp @@ -48,6 +48,7 @@ #include "Topology.hpp" #include "Packet.hpp" #include "Switch.hpp" +#include "Node.hpp" namespace ZeroTier { diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 2514cd64..7015535a 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -44,6 +44,7 @@ #include "SHA512.hpp" #include "World.hpp" #include "Cluster.hpp" +#include "Node.hpp" namespace ZeroTier { @@ -888,7 +889,7 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha { try { const uint64_t now = RR->node->now(); - const RemotePath *currentBest = peer->getBestPath(now); + const Path *currentBest = peer->getBestPath(now); unsigned int count = at(ZT_PACKET_IDX_PAYLOAD); unsigned int ptr = ZT_PACKET_IDX_PAYLOAD + 2; @@ -1036,7 +1037,7 @@ bool IncomingPacket::_doCIRCUIT_TEST(const RuntimeEnvironment *RR,const SharedPt remainingHopsPtr += ZT_ADDRESS_LENGTH; SharedPtr nhp(RR->topology->getPeer(nextHop[h])); if (nhp) { - RemotePath *const rp = nhp->getBestPath(now); + Path *const rp = nhp->getBestPath(now); if (rp) nextHopBestPathAddress[h] = rp->address(); } diff --git a/node/Multicaster.cpp b/node/Multicaster.cpp index 6e6cd628..e43d7d88 100644 --- a/node/Multicaster.cpp +++ b/node/Multicaster.cpp @@ -37,6 +37,7 @@ #include "Peer.hpp" #include "C25519.hpp" #include "CertificateOfMembership.hpp" +#include "Node.hpp" namespace ZeroTier { diff --git a/node/Network.cpp b/node/Network.cpp index cd30e386..afbe1074 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -37,6 +37,7 @@ #include "Packet.hpp" #include "Buffer.hpp" #include "NetworkController.hpp" +#include "Node.hpp" #include "../version.h" diff --git a/node/Node.cpp b/node/Node.cpp index 87871e20..82cda66d 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -448,10 +448,10 @@ ZT_PeerList *Node::peers() const p->latency = pi->second->latency(); p->role = RR->topology->isRoot(pi->second->identity()) ? ZT_PEER_ROLE_ROOT : ZT_PEER_ROLE_LEAF; - std::vector paths(pi->second->paths()); - RemotePath *bestPath = pi->second->getBestPath(_now); + std::vector paths(pi->second->paths()); + Path *bestPath = pi->second->getBestPath(_now); p->pathCount = 0; - for(std::vector::iterator path(paths.begin());path!=paths.end();++path) { + for(std::vector::iterator path(paths.begin());path!=paths.end();++path) { memcpy(&(p->paths[p->pathCount].address),&(path->address()),sizeof(struct sockaddr_storage)); p->paths[p->pathCount].lastSend = path->lastSend(); p->paths[p->pathCount].lastReceive = path->lastReceived(); @@ -499,11 +499,11 @@ void Node::freeQueryResult(void *qr) ::free(qr); } -int Node::addLocalInterfaceAddress(const struct sockaddr_storage *addr,int metric,ZT_LocalInterfaceAddressTrust trust) +int Node::addLocalInterfaceAddress(const struct sockaddr_storage *addr,ZT_LocalInterfaceAddressTrust trust) { if (Path::isAddressValidForPath(*(reinterpret_cast(addr)))) { Mutex::Lock _l(_directPaths_m); - _directPaths.push_back(Path(*(reinterpret_cast(addr)),metric,(Path::Trust)trust)); + _directPaths.push_back(*(reinterpret_cast(addr))); std::sort(_directPaths.begin(),_directPaths.end()); _directPaths.erase(std::unique(_directPaths.begin(),_directPaths.end()),_directPaths.end()); return 1; @@ -900,10 +900,10 @@ void ZT_Node_freeQueryResult(ZT_Node *node,void *qr) } catch ( ... ) {} } -int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr,int metric, enum ZT_LocalInterfaceAddressTrust trust) +int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr,enum ZT_LocalInterfaceAddressTrust trust) { try { - return reinterpret_cast(node)->addLocalInterfaceAddress(addr,metric,trust); + return reinterpret_cast(node)->addLocalInterfaceAddress(addr,trust); } catch ( ... ) { return 0; } diff --git a/node/Node.hpp b/node/Node.hpp index 4094a79e..48c5ead8 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -105,7 +105,7 @@ public: ZT_VirtualNetworkConfig *networkConfig(uint64_t nwid) const; ZT_VirtualNetworkList *networks() const; void freeQueryResult(void *qr); - int addLocalInterfaceAddress(const struct sockaddr_storage *addr,int metric,ZT_LocalInterfaceAddressTrust trust); + int addLocalInterfaceAddress(const struct sockaddr_storage *addr,ZT_LocalInterfaceAddressTrust trust); void clearLocalInterfaceAddresses(); void setNetconfMaster(void *networkControllerInstance); ZT_ResultCode circuitTestBegin(ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *)); @@ -207,7 +207,7 @@ public: /** * @return Potential direct paths to me a.k.a. local interface addresses */ - inline std::vector directPaths() const + inline std::vector directPaths() const { Mutex::Lock _l(_directPaths_m); return _directPaths; @@ -285,7 +285,7 @@ private: std::vector< ZT_CircuitTest * > _circuitTests; Mutex _circuitTests_m; - std::vector _directPaths; + std::vector _directPaths; Mutex _directPaths_m; Mutex _backgroundTasksLock; diff --git a/node/Path.cpp b/node/Path.cpp new file mode 100644 index 00000000..e2475751 --- /dev/null +++ b/node/Path.cpp @@ -0,0 +1,45 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#include "Path.hpp" +#include "AntiRecursion.hpp" +#include "RuntimeEnvironment.hpp" +#include "Node.hpp" + +namespace ZeroTier { + +bool Path::send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) +{ + if (RR->node->putPacket(_localAddress,address(),data,len)) { + sent(now); + RR->antiRec->logOutgoingZT(data,len); + return true; + } + return false; +} + +} // namespace ZeroTier diff --git a/node/Path.hpp b/node/Path.hpp index 6fa3c52e..99f6590b 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -28,12 +28,19 @@ #ifndef ZT_PATH_HPP #define ZT_PATH_HPP +#include +#include + +#include +#include + #include "Constants.hpp" #include "InetAddress.hpp" -#include "Utils.hpp" namespace ZeroTier { +class RuntimeEnvironment; + /** * Base class for paths * @@ -67,19 +74,87 @@ public: }; Path() : + _lastSend(0), + _lastReceived(0), _addr(), + _localAddress(), _ipScope(InetAddress::IP_SCOPE_NONE), - _trust(TRUST_NORMAL) + _trust(TRUST_NORMAL), + _flags(0) { } - Path(const InetAddress &addr,int metric,Trust trust) : + Path(const InetAddress &localAddress,const InetAddress &addr,Trust trust) : + _lastSend(0), + _lastReceived(0), _addr(addr), + _localAddress(localAddress), _ipScope(addr.ipScope()), - _trust(trust) + _trust(trust), + _flags(0) + { + } + + /** + * Called when a packet is sent to this remote path + * + * This is called automatically by Path::send(). + * + * @param t Time of send + */ + inline void sent(uint64_t t) + throw() { + _lastSend = t; } + /** + * Called when a packet is received from this remote path + * + * @param t Time of receive + */ + inline void received(uint64_t t) + throw() + { + _lastReceived = t; + } + + /** + * @param now Current time + * @return True if this path appears active + */ + inline bool active(uint64_t now) const + throw() + { + return ((now - _lastReceived) < ZT_PEER_ACTIVITY_TIMEOUT); + } + + /** + * Send a packet via this path + * + * @param RR Runtime environment + * @param data Packet data + * @param len Packet length + * @param now Current time + * @return True if transport reported success + */ + bool send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now); + + /** + * @return Address of local side of this path or NULL if unspecified + */ + inline const InetAddress &localAddress() const throw() { return _localAddress; } + + /** + * @return Time of last send to this path + */ + inline uint64_t lastSend() const throw() { return _lastSend; } + + /** + * @return Time of last receive from this path + */ + inline uint64_t lastReceived() const throw() { return _lastReceived; } + /** * @return Physical address */ @@ -157,10 +232,42 @@ public: return false; } -protected: + template + inline void serialize(Buffer &b) const + { + b.append((uint8_t)0); // version + b.append((uint64_t)_lastSend); + b.append((uint64_t)_lastReceived); + _addr.serialize(b); + _localAddress.serialize(b); + b.append((uint8_t)_trust); + b.append((uint16_t)_flags); + } + + template + inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) + { + unsigned int p = startAt; + if (b[p++] != 0) + throw std::invalid_argument("invalid serialized Path"); + _lastSend = b.template at(p); p += 8; + _lastReceived = b.template at(p); p += 8; + p += _addr.deserialize(b,p); + p += _localAddress.deserialize(b,p); + _ipScope = _addr.ipScope(); + _trust = (Path::Trust)b[p++]; + _flags = b.template at(p); p += 2; + return (p - startAt); + } + +private: + uint64_t _lastSend; + uint64_t _lastReceived; InetAddress _addr; + InetAddress _localAddress; InetAddress::IpScope _ipScope; // memoize this since it's a computed value checked often Trust _trust; + uint16_t _flags; }; } // namespace ZeroTier diff --git a/node/Peer.cpp b/node/Peer.cpp index 009e2be5..ebdb6026 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -169,7 +169,7 @@ void Peer::received( if (!pathIsConfirmed) { if (verb == Packet::VERB_OK) { - RemotePath *slot = (RemotePath *)0; + Path *slot = (Path *)0; if (np < ZT_MAX_PEER_NETWORK_PATHS) { slot = &(_paths[np++]); } else { @@ -182,7 +182,7 @@ void Peer::received( } } if (slot) { - *slot = RemotePath(localAddr,remoteAddr); + *slot = Path(localAddr,remoteAddr,Path::TRUST_NORMAL); slot->received(now); _numPaths = np; pathIsConfirmed = true; @@ -240,7 +240,7 @@ void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &lo bool Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now,int inetAddressFamily) { - RemotePath *p = (RemotePath *)0; + Path *p = (Path *)0; Mutex::Lock _l(_lock); if (inetAddressFamily != 0) { @@ -268,7 +268,7 @@ bool Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now,int inet return false; } -void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_t now,bool force) +void Peer::pushDirectPaths(const RuntimeEnvironment *RR,Path *path,uint64_t now,bool force) { #ifdef ZT_ENABLE_CLUSTER // Cluster mode disables normal PUSH_DIRECT_PATHS in favor of cluster-based peer redirection @@ -281,7 +281,7 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_ if (((now - _lastDirectPathPushSent) >= ZT_DIRECT_PATH_PUSH_INTERVAL)||(force)) { _lastDirectPathPushSent = now; - std::vector dps(RR->node->directPaths()); + std::vector dps(RR->node->directPaths()); if (dps.empty()) return; @@ -291,13 +291,13 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_ for(std::vector::const_iterator p(dps.begin());p!=dps.end();++p) { if (ps.length() > 0) ps.push_back(','); - ps.append(p->address().toString()); + ps.append(p->toString()); } TRACE("pushing %u direct paths to %s: %s",(unsigned int)dps.size(),_id.address().toString().c_str(),ps.c_str()); } #endif - std::vector::const_iterator p(dps.begin()); + std::vector::const_iterator p(dps.begin()); while (p != dps.end()) { Packet outp(_id.address(),RR->identity.address(),Packet::VERB_PUSH_DIRECT_PATHS); outp.addSize(2); // leave room for count @@ -305,7 +305,7 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_ unsigned int count = 0; while ((p != dps.end())&&((outp.size() + 24) < ZT_PROTO_MAX_PACKET_LENGTH)) { uint8_t addressType = 4; - switch(p->address().ss_family) { + switch(p->ss_family) { case AF_INET: break; case AF_INET6: @@ -317,6 +317,7 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_ } uint8_t flags = 0; + /* TODO: path trust is not implemented yet switch(p->trust()) { default: break; @@ -327,13 +328,14 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_ flags |= (0x04 | 0x08); // no encryption, no authentication (redundant but go ahead and set both) break; } + */ outp.append(flags); outp.append((uint16_t)0); // no extensions outp.append(addressType); outp.append((uint8_t)((addressType == 4) ? 6 : 18)); - outp.append(p->address().rawIpData(),((addressType == 4) ? 4 : 16)); - outp.append((uint16_t)p->address().port()); + outp.append(p->rawIpData(),((addressType == 4) ? 4 : 16)); + outp.append((uint16_t)p->port()); ++count; ++p; @@ -506,7 +508,7 @@ struct _SortPathsByQuality { uint64_t _now; _SortPathsByQuality(const uint64_t now) : _now(now) {} - inline bool operator()(const RemotePath &a,const RemotePath &b) const + inline bool operator()(const Path &a,const Path &b) const { const uint64_t qa = ( ((uint64_t)a.active(_now) << 63) | @@ -526,7 +528,7 @@ void Peer::_sortPaths(const uint64_t now) std::sort(&(_paths[0]),&(_paths[_numPaths]),_SortPathsByQuality(now)); } -RemotePath *Peer::_getBestPath(const uint64_t now) +Path *Peer::_getBestPath(const uint64_t now) { // assumes _lock is locked if ((now - _lastPathSort) >= ZT_PEER_PATH_SORT_INTERVAL) @@ -538,10 +540,10 @@ RemotePath *Peer::_getBestPath(const uint64_t now) if (_paths[0].active(now)) return &(_paths[0]); } - return (RemotePath *)0; + return (Path *)0; } -RemotePath *Peer::_getBestPath(const uint64_t now,int inetAddressFamily) +Path *Peer::_getBestPath(const uint64_t now,int inetAddressFamily) { // assumes _lock is locked if ((now - _lastPathSort) >= ZT_PEER_PATH_SORT_INTERVAL) @@ -553,7 +555,7 @@ RemotePath *Peer::_getBestPath(const uint64_t now,int inetAddressFamily) } _sortPaths(now); } - return (RemotePath *)0; + return (Path *)0; } } // namespace ZeroTier diff --git a/node/Peer.hpp b/node/Peer.hpp index 04b541af..aa75b3f4 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -41,7 +41,7 @@ #include "RuntimeEnvironment.hpp" #include "CertificateOfMembership.hpp" -#include "RemotePath.hpp" +#include "Path.hpp" #include "Address.hpp" #include "Utils.hpp" #include "Identity.hpp" @@ -135,7 +135,7 @@ public: * @param now Current time * @return Best path or NULL if there are no active direct paths */ - inline RemotePath *getBestPath(uint64_t now) + inline Path *getBestPath(uint64_t now) { Mutex::Lock _l(_lock); return _getBestPath(now); @@ -150,14 +150,14 @@ public: * @param now Current time * @return Path used on success or NULL on failure */ - inline RemotePath *send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) + inline Path *send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) { - RemotePath *bestPath = getBestPath(now); + Path *bestPath = getBestPath(now); if (bestPath) { if (bestPath->send(RR,data,len,now)) return bestPath; } - return (RemotePath *)0; + return (Path *)0; } /** @@ -191,14 +191,14 @@ public: * @param now Current time * @param force If true, push regardless of rate limit */ - void pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_t now,bool force); + void pushDirectPaths(const RuntimeEnvironment *RR,Path *path,uint64_t now,bool force); /** * @return All known direct paths to this peer */ - inline std::vector paths() const + inline std::vector paths() const { - std::vector pp; + std::vector pp; Mutex::Lock _l(_lock); for(unsigned int p=0,np=_numPaths;p_paths[np->_numPaths++].deserialize(b,p); } else { // Skip any paths beyond max, but still read stream - RemotePath foo; + Path foo; p += foo.deserialize(b,p); } } @@ -557,8 +557,8 @@ public: private: void _sortPaths(const uint64_t now); - RemotePath *_getBestPath(const uint64_t now); - RemotePath *_getBestPath(const uint64_t now,int inetAddressFamily); + Path *_getBestPath(const uint64_t now); + Path *_getBestPath(const uint64_t now,int inetAddressFamily); unsigned char _key[ZT_PEER_SECRET_KEY_LENGTH]; // computed with key agreement, not serialized @@ -575,7 +575,7 @@ private: uint16_t _vMinor; uint16_t _vRevision; Identity _id; - RemotePath _paths[ZT_MAX_PEER_NETWORK_PATHS]; + Path _paths[ZT_MAX_PEER_NETWORK_PATHS]; unsigned int _numPaths; unsigned int _latency; diff --git a/node/RemotePath.hpp b/node/RemotePath.hpp deleted file mode 100644 index 8b37621a..00000000 --- a/node/RemotePath.hpp +++ /dev/null @@ -1,161 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2015 ZeroTier, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * ZeroTier may be used and distributed under the terms of the GPLv3, which - * are available at: http://www.gnu.org/licenses/gpl-3.0.html - * - * If you would like to embed ZeroTier into a commercial application or - * redistribute it in a modified binary form, please contact ZeroTier Networks - * LLC. Start here: http://www.zerotier.com/ - */ - -#ifndef ZT_REMOTEPATH_HPP -#define ZT_REMOTEPATH_HPP - -#include -#include - -#include -#include - -#include "Path.hpp" -#include "Node.hpp" -#include "AntiRecursion.hpp" -#include "RuntimeEnvironment.hpp" - -namespace ZeroTier { - -/** - * Path to a remote peer - * - * This extends Path to include status information about path activity. - */ -class RemotePath : public Path -{ -public: - RemotePath() : - Path(), - _lastSend(0), - _lastReceived(0), - _localAddress(), - _flags(0) {} - - RemotePath(const InetAddress &localAddress,const InetAddress &addr) : - Path(addr,0,TRUST_NORMAL), - _lastSend(0), - _lastReceived(0), - _localAddress(localAddress), - _flags(0) {} - - inline const InetAddress &localAddress() const throw() { return _localAddress; } - - inline uint64_t lastSend() const throw() { return _lastSend; } - inline uint64_t lastReceived() const throw() { return _lastReceived; } - - /** - * Called when a packet is sent to this remote path - * - * This is called automatically by RemotePath::send(). - * - * @param t Time of send - */ - inline void sent(uint64_t t) - throw() - { - _lastSend = t; - } - - /** - * Called when a packet is received from this remote path - * - * @param t Time of receive - */ - inline void received(uint64_t t) - throw() - { - _lastReceived = t; - } - - /** - * @param now Current time - * @return True if this path appears active - */ - inline bool active(uint64_t now) const - throw() - { - return ((now - _lastReceived) < ZT_PEER_ACTIVITY_TIMEOUT); - } - - /** - * Send a packet via this path - * - * @param RR Runtime environment - * @param data Packet data - * @param len Packet length - * @param now Current time - * @return True if transport reported success - */ - inline bool send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) - { - if (RR->node->putPacket(_localAddress,address(),data,len)) { - sent(now); - RR->antiRec->logOutgoingZT(data,len); - return true; - } - return false; - } - - template - inline void serialize(Buffer &b) const - { - b.append((uint8_t)1); // version - _addr.serialize(b); - b.append((uint8_t)_trust); - b.append((uint64_t)_lastSend); - b.append((uint64_t)_lastReceived); - _localAddress.serialize(b); - b.append((uint16_t)_flags); - } - - template - inline unsigned int deserialize(const Buffer &b,unsigned int startAt = 0) - { - unsigned int p = startAt; - if (b[p++] != 1) - throw std::invalid_argument("invalid serialized RemotePath"); - p += _addr.deserialize(b,p); - _ipScope = _addr.ipScope(); - _trust = (Path::Trust)b[p++]; - _lastSend = b.template at(p); p += 8; - _lastReceived = b.template at(p); p += 8; - p += _localAddress.deserialize(b,p); - _flags = b.template at(p); p += 2; - return (p - startAt); - } - -protected: - uint64_t _lastSend; - uint64_t _lastReceived; - InetAddress _localAddress; - uint16_t _flags; -}; - -} // namespace ZeroTier - -#endif diff --git a/node/SelfAwareness.cpp b/node/SelfAwareness.cpp index 81d19369..b4841544 100644 --- a/node/SelfAwareness.cpp +++ b/node/SelfAwareness.cpp @@ -125,7 +125,7 @@ void SelfAwareness::iam(const Address &reporter,const InetAddress &reporterPhysi // they are still considered alive so that we will re-establish direct links. SharedPtr r(RR->topology->getBestRoot()); if (r) { - RemotePath *rp = r->getBestPath(now); + Path *rp = r->getBestPath(now); if (rp) { for(std::vector< SharedPtr >::const_iterator p(rset.peersReset.begin());p!=rset.peersReset.end();++p) { if ((*p)->alive(now)) { diff --git a/node/Switch.cpp b/node/Switch.cpp index 772eaf02..2f72f57a 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -736,7 +736,7 @@ bool Switch::_trySend(const Packet &packet,bool encrypt,uint64_t nwid) return false; // sanity check: unconfigured network? why are we trying to talk to it? } - RemotePath *viaPath = peer->getBestPath(now); + Path *viaPath = peer->getBestPath(now); SharedPtr relay; if (!viaPath) { // See if this network has a preferred relay (if packet has an associated network) diff --git a/objects.mk b/objects.mk index 6dd5ea30..540072d5 100644 --- a/objects.mk +++ b/objects.mk @@ -15,6 +15,7 @@ OBJS=\ node/Node.o \ node/OutboundMulticast.o \ node/Packet.o \ + node/Path.o \ node/Peer.o \ node/Poly1305.o \ node/Salsa20.o \ diff --git a/service/OneService.cpp b/service/OneService.cpp index 1765b5c4..4e3f24c7 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -731,7 +731,7 @@ public: #ifdef ZT_USE_MINIUPNPC std::vector upnpAddresses(_upnpClient->get()); for(std::vector::const_iterator ext(upnpAddresses.begin());ext!=upnpAddresses.end();++ext) - _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext)),0,ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); + _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext)),ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); #endif struct ifaddrs *ifatbl = (struct ifaddrs *)0; @@ -749,7 +749,7 @@ public: if (!isZT) { InetAddress ip(ifa->ifa_addr); ip.setPort(_port); - _node->addLocalInterfaceAddress(reinterpret_cast(&ip),0,ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); + _node->addLocalInterfaceAddress(reinterpret_cast(&ip),ZT_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); } } ifa = ifa->ifa_next; -- cgit v1.2.3 From 7fbe2f7adf3575f3a21fc1ab3a5a2a036e18e6e2 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 2 Nov 2015 15:38:53 -0800 Subject: Tweak some more timings for better reliability. --- node/Cluster.hpp | 2 +- node/Constants.hpp | 10 +++++----- node/Node.cpp | 2 +- node/Peer.hpp | 4 ++-- node/SelfAwareness.cpp | 2 +- node/Switch.cpp | 6 +++--- node/Topology.hpp | 9 ++++++--- tests/http/big-test-start.sh | 4 ++-- 8 files changed, 21 insertions(+), 18 deletions(-) (limited to 'node/Switch.cpp') diff --git a/node/Cluster.hpp b/node/Cluster.hpp index f1caa436..ee220999 100644 --- a/node/Cluster.hpp +++ b/node/Cluster.hpp @@ -55,7 +55,7 @@ /** * How often should we announce that we have a peer? */ -#define ZT_CLUSTER_HAVE_PEER_ANNOUNCE_PERIOD (ZT_PEER_DIRECT_PING_DELAY / 2) +#define ZT_CLUSTER_HAVE_PEER_ANNOUNCE_PERIOD ZT_PEER_DIRECT_PING_DELAY /** * Desired period between doPeriodicTasks() in milliseconds diff --git a/node/Constants.hpp b/node/Constants.hpp index bb62484d..552688a6 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -267,14 +267,14 @@ #define ZT_PEER_DIRECT_PING_DELAY 60000 /** - * Delay between requests for updated network autoconf information + * Timeout for overall peer activity (measured from last receive) */ -#define ZT_NETWORK_AUTOCONF_DELAY 60000 +#define ZT_PEER_ACTIVITY_TIMEOUT ((ZT_PEER_DIRECT_PING_DELAY * 4) + ZT_PING_CHECK_INVERVAL) /** - * Timeout for overall peer activity (measured from last receive) + * Delay between requests for updated network autoconf information */ -#define ZT_PEER_ACTIVITY_TIMEOUT ((ZT_PEER_DIRECT_PING_DELAY * 3) + (ZT_PING_CHECK_INVERVAL * 2)) +#define ZT_NETWORK_AUTOCONF_DELAY 60000 /** * Minimum interval between attempts by relays to unite peers @@ -283,7 +283,7 @@ * a RENDEZVOUS message no more than this often. This instructs the peers * to attempt NAT-t and gives each the other's corresponding IP:port pair. */ -#define ZT_MIN_UNITE_INTERVAL 60000 +#define ZT_MIN_UNITE_INTERVAL 30000 /** * Delay between initial direct NAT-t packet and more aggressive techniques diff --git a/node/Node.cpp b/node/Node.cpp index 74acc869..82cb7ddb 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -263,7 +263,7 @@ public: } lastReceiveFromUpstream = std::max(p->lastReceive(),lastReceiveFromUpstream); - } else if (p->alive(_now)) { + } else if (p->activelyTransferringFrames(_now)) { // Normal nodes get their preferred link kept alive if the node has generated frame traffic recently p->doPingAndKeepalive(RR,_now,0); } diff --git a/node/Peer.hpp b/node/Peer.hpp index e5db3bde..ad4c6746 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -231,9 +231,9 @@ public: inline uint64_t lastAnnouncedTo() const throw() { return _lastAnnouncedTo; } /** - * @return True if peer has received an actual data frame within ZT_PEER_ACTIVITY_TIMEOUT milliseconds + * @return True if this peer is actively sending real network frames */ - inline uint64_t alive(uint64_t now) const throw() { return ((now - lastFrame()) < ZT_PEER_ACTIVITY_TIMEOUT); } + inline uint64_t activelyTransferringFrames(uint64_t now) const throw() { return ((now - lastFrame()) < ZT_PEER_ACTIVITY_TIMEOUT); } /** * @return Current latency or 0 if unknown (max: 65535) diff --git a/node/SelfAwareness.cpp b/node/SelfAwareness.cpp index d8eca071..ce75eb03 100644 --- a/node/SelfAwareness.cpp +++ b/node/SelfAwareness.cpp @@ -128,7 +128,7 @@ void SelfAwareness::iam(const Address &reporter,const InetAddress &reporterPhysi // links to be re-established if possible, possibly using a root server or some // other relay. for(std::vector< SharedPtr >::const_iterator p(rset.peersReset.begin());p!=rset.peersReset.end();++p) { - if ((*p)->alive(now)) { + if ((*p)->activelyTransferringFrames(now)) { Packet outp((*p)->address(),RR->identity.address(),Packet::VERB_NOP); RR->sw->send(outp,true,0); } diff --git a/node/Switch.cpp b/node/Switch.cpp index 2f72f57a..120ce7a4 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -442,8 +442,8 @@ unsigned long Switch::doTimerTasks(uint64_t now) Mutex::Lock _l(_contactQueue_m); for(std::list::iterator qi(_contactQueue.begin());qi!=_contactQueue.end();) { if (now >= qi->fireAtTime) { - if ((!qi->peer->alive(now))||(qi->peer->hasActiveDirectPath(now))) { - // Cancel attempt if we've already connected or peer is no longer "alive" + if (qi->peer->hasActiveDirectPath(now)) { + // Cancel if connection has succeeded _contactQueue.erase(qi++); continue; } else { @@ -539,7 +539,7 @@ unsigned long Switch::doTimerTasks(uint64_t now) _LastUniteKey *k = (_LastUniteKey *)0; uint64_t *v = (uint64_t *)0; while (i.next(k,v)) { - if ((now - *v) >= (ZT_MIN_UNITE_INTERVAL * 16)) + if ((now - *v) >= (ZT_MIN_UNITE_INTERVAL * 8)) _lastUniteAttempt.erase(*k); } } diff --git a/node/Topology.hpp b/node/Topology.hpp index 4c1a2ab3..a0c28b0f 100644 --- a/node/Topology.hpp +++ b/node/Topology.hpp @@ -81,6 +81,11 @@ public: /** * Get a peer only if it is presently in memory (no disk cache) * + * This also does not update the lastUsed() time for peers, which means + * that it won't prevent them from falling out of RAM. This is currently + * used in the Cluster code to update peer info without forcing all peers + * across the entire cluster to remain in memory cache. + * * @param zta ZeroTier address * @param now Current time */ @@ -88,10 +93,8 @@ public: { Mutex::Lock _l(_lock); const SharedPtr *const ap = _peers.get(zta); - if (ap) { - (*ap)->use(now); + if (ap) return *ap; - } return SharedPtr(); } diff --git a/tests/http/big-test-start.sh b/tests/http/big-test-start.sh index 43166c6e..f300ac61 100755 --- a/tests/http/big-test-start.sh +++ b/tests/http/big-test-start.sh @@ -1,7 +1,7 @@ #!/bin/bash # Edit as needed -- note that >1000 per host is likely problematic due to Linux kernel limits -NUM_CONTAINERS=25 +NUM_CONTAINERS=50 CONTAINER_IMAGE=zerotier/http-test # @@ -25,6 +25,6 @@ export PATH=/bin:/usr/bin:/usr/local/bin:/usr/sbin:/sbin # docker run --device=/dev/net/tun --privileged -d $CONTAINER_IMAGE #done -pssh -h big-test-hosts -i -t 0 -p 256 "for ((n=0;n<$NUM_CONTAINERS;n++)); do docker run --device=/dev/net/tun --privileged -d $CONTAINER_IMAGE; sleep 0.25; done" +pssh -h big-test-hosts -o big-test-out -t 0 -p 256 "for ((n=0;n<$NUM_CONTAINERS;n++)); do docker run --device=/dev/net/tun --privileged -d $CONTAINER_IMAGE; sleep 0.25; done" exit 0 -- cgit v1.2.3 From 4e9d4304761f93a1764d3ec2d2b0c38140decad8 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 2 Nov 2015 16:03:28 -0800 Subject: Make root and relay selection somewhat more robust. --- node/Peer.hpp | 26 ++++++++++++++++++++++---- node/Switch.cpp | 7 +++++-- node/Topology.cpp | 37 +++++++++++++++++-------------------- 3 files changed, 44 insertions(+), 26 deletions(-) (limited to 'node/Switch.cpp') diff --git a/node/Peer.hpp b/node/Peer.hpp index ad4c6746..a70d9868 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -236,15 +236,33 @@ public: inline uint64_t activelyTransferringFrames(uint64_t now) const throw() { return ((now - lastFrame()) < ZT_PEER_ACTIVITY_TIMEOUT); } /** - * @return Current latency or 0 if unknown (max: 65535) + * @return Latency in milliseconds or 0 if unknown */ - inline unsigned int latency() const - throw() + inline unsigned int latency() const { return _latency; } + + /** + * This computes a quality score for relays and root servers + * + * If we haven't heard anything from these in ZT_PEER_ACTIVITY_TIMEOUT, they + * receive the worst possible quality (max unsigned int). Otherwise the + * quality is a product of latency and the number of potential missed + * pings. This causes roots and relays to switch over a bit faster if they + * fail. + * + * @return Relay quality score computed from latency and other factors, lower is better + */ + inline unsigned int relayQuality(const uint64_t now) const { + const uint64_t tsr = now - _lastReceive; + if (tsr >= ZT_PEER_ACTIVITY_TIMEOUT) + return (~(unsigned int)0); unsigned int l = _latency; - return std::min(l,(unsigned int)65535); + if (!l) + l = 0xffff; + return (l * (((unsigned int)tsr / (ZT_PEER_DIRECT_PING_DELAY + 1000)) + 1)); } + /** * Update latency with a new direct measurment * diff --git a/node/Switch.cpp b/node/Switch.cpp index 120ce7a4..b7a9c522 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -741,12 +741,15 @@ bool Switch::_trySend(const Packet &packet,bool encrypt,uint64_t nwid) if (!viaPath) { // See if this network has a preferred relay (if packet has an associated network) if (nconf) { - unsigned int latency = ~((unsigned int)0); + unsigned int bestq = ~((unsigned int)0); for(std::vector< std::pair >::const_iterator r(nconf->relays().begin());r!=nconf->relays().end();++r) { if (r->first != peer->address()) { SharedPtr rp(RR->topology->getPeer(r->first)); - if ((rp)&&(rp->hasActiveDirectPath(now))&&(rp->latency() <= latency)) + const unsigned int q = rp->relayQuality(now); + if ((rp)&&(q < bestq)) { // SUBTILE: < == don't use these if they are nil quality (unsigned int max), instead use a root + bestq = q; rp.swap(relay); + } } } } diff --git a/node/Topology.cpp b/node/Topology.cpp index b8bb55f2..bea97ab9 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -227,33 +227,30 @@ SharedPtr Topology::getBestRoot(const Address *avoid,unsigned int avoidCou } else { /* If I am not a root server, the best root server is the active one with - * the lowest latency. */ + * the lowest quality score. (lower == better) */ - unsigned int bestLatencyOverall = ~((unsigned int)0); - unsigned int bestLatencyNotAvoid = ~((unsigned int)0); + unsigned int bestQualityOverall = ~((unsigned int)0); + unsigned int bestQualityNotAvoid = ~((unsigned int)0); const SharedPtr *bestOverall = (const SharedPtr *)0; const SharedPtr *bestNotAvoid = (const SharedPtr *)0; for(std::vector< SharedPtr >::const_iterator r(_rootPeers.begin());r!=_rootPeers.end();++r) { - if ((*r)->hasActiveDirectPath(now)) { - bool avoiding = false; - for(unsigned int i=0;iaddress()) { - avoiding = true; - break; - } - } - unsigned int l = (*r)->latency(); - if (!l) l = ~l; // zero latency indicates no measurment, so make this 'max' - if (l <= bestLatencyOverall) { - bestLatencyOverall = l; - bestOverall = &(*r); - } - if ((!avoiding)&&(l <= bestLatencyNotAvoid)) { - bestLatencyNotAvoid = l; - bestNotAvoid = &(*r); + bool avoiding = false; + for(unsigned int i=0;iaddress()) { + avoiding = true; + break; } } + const unsigned int q = (*r)->relayQuality(now); + if (q <= bestQualityOverall) { + bestQualityOverall = q; + bestOverall = &(*r); + } + if ((!avoiding)&&(q <= bestQualityNotAvoid)) { + bestQualityNotAvoid = q; + bestNotAvoid = &(*r); + } } if (bestNotAvoid) { -- cgit v1.2.3