summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
Diffstat (limited to 'node')
-rw-r--r--node/IncomingPacket.cpp29
-rw-r--r--node/Topology.cpp19
-rw-r--r--node/Topology.hpp15
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