diff options
Diffstat (limited to 'node')
-rw-r--r-- | node/IncomingPacket.cpp | 29 | ||||
-rw-r--r-- | node/Topology.cpp | 19 | ||||
-rw-r--r-- | node/Topology.hpp | 15 |
3 files changed, 43 insertions, 20 deletions
diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 4386e370..6b39963a 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -461,21 +461,26 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr<Peer> bool IncomingPacket::_doRENDEZVOUS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer) { try { - const Address with(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); - const SharedPtr<Peer> withPeer(RR->topology->getPeer(with)); - if (withPeer) { - const unsigned int port = at<uint16_t>(ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT); - const unsigned int addrlen = (*this)[ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN]; - if ((port > 0)&&((addrlen == 4)||(addrlen == 16))) { - InetAddress atAddr(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS,addrlen),addrlen,port); - TRACE("RENDEZVOUS from %s says %s might be at %s, starting NAT-t",peer->address().toString().c_str(),with.toString().c_str(),atAddr.toString().c_str()); - peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP); - RR->sw->rendezvous(withPeer,_localAddress,atAddr); + if (RR->topology->isUpstream(peer->identity())) { + const Address with(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); + const SharedPtr<Peer> withPeer(RR->topology->getPeer(with)); + if (withPeer) { + const unsigned int port = at<uint16_t>(ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT); + const unsigned int addrlen = (*this)[ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN]; + if ((port > 0)&&((addrlen == 4)||(addrlen == 16))) { + InetAddress atAddr(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS,addrlen),addrlen,port); + TRACE("RENDEZVOUS from %s says %s might be at %s, starting NAT-t",peer->address().toString().c_str(),with.toString().c_str(),atAddr.toString().c_str()); + peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP); + RR->sw->rendezvous(withPeer,_localAddress,atAddr); + } else { + TRACE("dropped corrupt RENDEZVOUS from %s(%s) (bad address or port)",peer->address().toString().c_str(),_remoteAddress.toString().c_str()); + } } else { - TRACE("dropped corrupt RENDEZVOUS from %s(%s) (bad address or port)",peer->address().toString().c_str(),_remoteAddress.toString().c_str()); + RR->sw->requestWhois(with); + TRACE("ignored RENDEZVOUS from %s(%s) to meet unknown peer %s",peer->address().toString().c_str(),_remoteAddress.toString().c_str(),with.toString().c_str()); } } else { - TRACE("ignored RENDEZVOUS from %s(%s) to meet unknown peer %s",peer->address().toString().c_str(),_remoteAddress.toString().c_str(),with.toString().c_str()); + TRACE("ignored RENDEZVOUS from %s(%s): not a root server or a network relay",peer->address().toString().c_str(),_remoteAddress.toString().c_str()); } } catch ( ... ) { TRACE("dropped RENDEZVOUS from %s(%s): unexpected exception",peer->address().toString().c_str(),_remoteAddress.toString().c_str()); diff --git a/node/Topology.cpp b/node/Topology.cpp index e36a0609..dc21b243 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -29,6 +29,8 @@ #include "Topology.hpp" #include "RuntimeEnvironment.hpp" #include "Node.hpp" +#include "Network.hpp" +#include "NetworkConfig.hpp" #include "Buffer.hpp" namespace ZeroTier { @@ -283,6 +285,23 @@ keep_searching_for_roots: return bestRoot; } +bool Topology::isUpstream(const Identity &id) const +{ + if (isRoot(id)) + return true; + std::vector< SharedPtr<Network> > nws(RR->node->allNetworks()); + for(std::vector< SharedPtr<Network> >::const_iterator nw(nws.begin());nw!=nws.end();++nw) { + SharedPtr<NetworkConfig> nc((*nw)->config2()); + if (nc) { + for(std::vector< std::pair<Address,InetAddress> >::const_iterator r(nc->relays().begin());r!=nc->relays().end();++r) { + if (r->first == id.address()) + return true; + } + } + } + return false; +} + bool Topology::worldUpdateIfValid(const World &newWorld) { Mutex::Lock _l(_lock); diff --git a/node/Topology.hpp b/node/Topology.hpp index 9e9ccc01..48e264a8 100644 --- a/node/Topology.hpp +++ b/node/Topology.hpp @@ -136,17 +136,16 @@ public: inline bool isRoot(const Identity &id) const { Mutex::Lock _l(_lock); - if (std::find(_rootAddresses.begin(),_rootAddresses.end(),id.address()) != _rootAddresses.end()) { - // Double check full identity for security reasons - for(std::vector<World::Root>::const_iterator r(_world.roots().begin());r!=_world.roots().end();++r) { - if (id == r->identity) - return true; - } - } - return false; + return (std::find(_rootAddresses.begin(),_rootAddresses.end(),id.address()) != _rootAddresses.end()); } /** + * @param id Identity to check + * @return True if this is a root server or a network preferred relay from one of our networks + */ + bool isUpstream(const Identity &id) const; + + /** * @return Vector of root server addresses */ inline std::vector<Address> rootAddresses() const |