mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-01-18 02:40:13 +00:00
Add code to check external surface against reported surface from other trusted peers, and also rename ExternalSurface to SelfAwareness because lulz.
This commit is contained in:
parent
76ad19f411
commit
a2821e9000
@ -39,6 +39,7 @@
|
||||
#include "Switch.hpp"
|
||||
#include "Peer.hpp"
|
||||
#include "NetworkConfigMaster.hpp"
|
||||
#include "SelfAwareness.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
@ -174,7 +175,23 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR)
|
||||
const unsigned int vMinor = (*this)[ZT_PROTO_VERB_HELLO_IDX_MINOR_VERSION];
|
||||
const unsigned int vRevision = at<uint16_t>(ZT_PROTO_VERB_HELLO_IDX_REVISION);
|
||||
const uint64_t timestamp = at<uint64_t>(ZT_PROTO_VERB_HELLO_IDX_TIMESTAMP);
|
||||
const Identity id(*this,ZT_PROTO_VERB_HELLO_IDX_IDENTITY);
|
||||
|
||||
Identity id;
|
||||
unsigned int destAddrPtr = id.deserialize(*this,ZT_PROTO_VERB_HELLO_IDX_IDENTITY) + ZT_PROTO_VERB_HELLO_IDX_IDENTITY;
|
||||
|
||||
unsigned int destAddrType = ZT_PROTO_DEST_ADDRESS_TYPE_NONE;
|
||||
if (destAddrPtr < size()) // ZeroTier One < 1.0.3 did not include this field
|
||||
destAddrType = (*this)[destAddrPtr++];
|
||||
|
||||
InetAddress destAddr;
|
||||
switch(destAddrType) {
|
||||
case ZT_PROTO_DEST_ADDRESS_TYPE_IPV4:
|
||||
destAddr.set(field(destAddrPtr,4),4,at<uint16_t>(destAddrPtr + 4));
|
||||
break;
|
||||
case ZT_PROTO_DEST_ADDRESS_TYPE_IPV6:
|
||||
destAddr.set(field(destAddrPtr,16),16,at<uint16_t>(destAddrPtr + 16));
|
||||
break;
|
||||
}
|
||||
|
||||
if (source() != id.address()) {
|
||||
TRACE("dropped HELLO from %s(%s): identity not for sending address",source().toString().c_str(),_remoteAddress.toString().c_str());
|
||||
@ -245,11 +262,13 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR)
|
||||
peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_HELLO,0,Packet::VERB_NOP);
|
||||
peer->setRemoteVersion(protoVersion,vMajor,vMinor,vRevision);
|
||||
|
||||
// Won't get HELLO *from* supernodes, so skip this for now here. It's done in OK(HELLO).
|
||||
//if (RR->topology->isSupernode(id.address()))
|
||||
// RR->node->postNewerVersionIfNewer(vMajor,vMinor,vRevision);
|
||||
if (RR->topology->isSupernode(id.address())) {
|
||||
RR->node->postNewerVersionIfNewer(vMajor,vMinor,vRevision);
|
||||
RR->sa->iam(destAddr);
|
||||
}
|
||||
|
||||
Packet outp(id.address(),RR->identity.address(),Packet::VERB_OK);
|
||||
|
||||
outp.append((unsigned char)Packet::VERB_HELLO);
|
||||
outp.append(packetId());
|
||||
outp.append(timestamp);
|
||||
@ -257,6 +276,23 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR)
|
||||
outp.append((unsigned char)ZEROTIER_ONE_VERSION_MAJOR);
|
||||
outp.append((unsigned char)ZEROTIER_ONE_VERSION_MINOR);
|
||||
outp.append((uint16_t)ZEROTIER_ONE_VERSION_REVISION);
|
||||
|
||||
switch(_remoteAddress.ss_family) {
|
||||
case AF_INET:
|
||||
outp.append((unsigned char)ZT_PROTO_DEST_ADDRESS_TYPE_IPV4);
|
||||
outp.append(_remoteAddress.rawIpData(),4);
|
||||
outp.append((uint16_t)_remoteAddress.port());
|
||||
break;
|
||||
case AF_INET6:
|
||||
outp.append((unsigned char)ZT_PROTO_DEST_ADDRESS_TYPE_IPV6);
|
||||
outp.append(_remoteAddress.rawIpData(),16);
|
||||
outp.append((uint16_t)_remoteAddress.port());
|
||||
break;
|
||||
default:
|
||||
outp.append((unsigned char)ZT_PROTO_DEST_ADDRESS_TYPE_NONE);
|
||||
break;
|
||||
}
|
||||
|
||||
outp.armor(peer->key(),true);
|
||||
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
|
||||
} catch (std::exception &ex) {
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "Logger.hpp"
|
||||
#include "Address.hpp"
|
||||
#include "Identity.hpp"
|
||||
#include "SelfAwareness.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
@ -77,7 +78,9 @@ Node::Node(
|
||||
RR->mc = new Multicaster(RR);
|
||||
RR->antiRec = new AntiRecursion();
|
||||
RR->topology = new Topology(RR);
|
||||
RR->sa = new SelfAwareness(RR);
|
||||
} catch ( ... ) {
|
||||
delete RR->sa;
|
||||
delete RR->topology;
|
||||
delete RR->antiRec;
|
||||
delete RR->mc;
|
||||
@ -91,6 +94,7 @@ Node::Node(
|
||||
|
||||
Node::~Node()
|
||||
{
|
||||
delete RR->sa;
|
||||
delete RR->topology;
|
||||
delete RR->antiRec;
|
||||
delete RR->mc;
|
||||
|
@ -175,6 +175,12 @@
|
||||
*/
|
||||
#define ZT_PROTO_BEACON_IDX_ADDRESS 8
|
||||
|
||||
// Destination address types from HELLO and OK(HELLO)
|
||||
#define ZT_PROTO_DEST_ADDRESS_TYPE_NONE 0
|
||||
#define ZT_PROTO_DEST_ADDRESS_TYPE_ETHERNET 1
|
||||
#define ZT_PROTO_DEST_ADDRESS_TYPE_IPV4 4
|
||||
#define ZT_PROTO_DEST_ADDRESS_TYPE_IPV6 6
|
||||
|
||||
// Field incides for parsing verbs -------------------------------------------
|
||||
|
||||
// Some verbs have variable-length fields. Those aren't fully defined here
|
||||
@ -467,6 +473,23 @@ public:
|
||||
* <[2] software revision>
|
||||
* <[8] timestamp (ms since epoch)>
|
||||
* <[...] binary serialized identity (see Identity)>
|
||||
* <[1] destination address type>
|
||||
* [<[...] destination address>]
|
||||
*
|
||||
* This is the only message that ever must be sent in the clear, since it
|
||||
* is used to push an identity to a new peer.
|
||||
*
|
||||
* The destination address is the wire address to which this packet is
|
||||
* being sent, and in OK is *also* the destination address of the OK
|
||||
* packet. This can be used by the receiver to detect NAT, learn its real
|
||||
* external address if behind NAT, and detect changes to its external
|
||||
* address that require re-establishing connectivity.
|
||||
*
|
||||
* Destination address types and formats (not all of these are used now):
|
||||
* 0 - None -- no destination address data present
|
||||
* 1 - Ethernet address -- format: <[6] Ethernet MAC>
|
||||
* 4 - 6-byte IPv4 address -- format: <[4] IP>, <[2] port>
|
||||
* 6 - 18-byte IPv6 address -- format: <[16] IP>, <[2] port>
|
||||
*
|
||||
* OK payload:
|
||||
* <[8] timestamp (echoed from original HELLO)>
|
||||
@ -474,6 +497,8 @@ public:
|
||||
* <[1] software major version (of responder)>
|
||||
* <[1] software minor version (of responder)>
|
||||
* <[2] software revision (of responder)>
|
||||
* <[1] destination address type (for this OK, not copied from HELLO)>
|
||||
* [<[...] destination address>]
|
||||
*
|
||||
* ERROR has no payload.
|
||||
*/
|
||||
|
@ -44,6 +44,7 @@ class Node;
|
||||
class Multicaster;
|
||||
class AntiRecursion;
|
||||
class NetworkConfigMaster;
|
||||
class SelfAwareness;
|
||||
|
||||
/**
|
||||
* Holds global state for an instance of ZeroTier::Node
|
||||
@ -69,7 +70,8 @@ public:
|
||||
sw((Switch *)0),
|
||||
mc((Multicaster *)0),
|
||||
antiRec((AntiRecursion *)0),
|
||||
topology((Topology *)0)
|
||||
topology((Topology *)0),
|
||||
sa((SelfAwareness *)0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -96,6 +98,7 @@ public:
|
||||
Multicaster *mc;
|
||||
AntiRecursion *antiRec;
|
||||
Topology *topology;
|
||||
SelfAwareness *sa;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
@ -25,40 +25,32 @@
|
||||
* LLC. Start here: http://www.zerotier.com/
|
||||
*/
|
||||
|
||||
#ifndef ZT_EXTERNALSURFACE_HPP
|
||||
#define ZT_EXTERNALSURFACE_HPP
|
||||
#ifndef ZT_SELFAWARENESS_HPP
|
||||
#define ZT_SELFAWARENESS_HPP
|
||||
|
||||
#include "InetAddress.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class RuntimeEnvironment;
|
||||
|
||||
/**
|
||||
* Tracks changes to this peer's real world addresses
|
||||
*/
|
||||
class ExternalSurface
|
||||
class SelfAwareness
|
||||
{
|
||||
public:
|
||||
ExternalSurface() {}
|
||||
SelfAwareness(const RuntimeEnvironment *renv);
|
||||
~SelfAwareness();
|
||||
|
||||
/**
|
||||
* Revise our external surface image, return true if it changed
|
||||
* Called when a trusted remote peer informs us of our external network address
|
||||
*
|
||||
* @param remote Remote address as reflected by any trusted peer
|
||||
* @return True if our external surface has changed
|
||||
* @param physicalAddress Physical address as reflected by any trusted peer
|
||||
*/
|
||||
inline bool update(const InetAddress &remote)
|
||||
throw()
|
||||
{
|
||||
const unsigned long idx = (remote.isV4() ? 0 : 2) | (remote.isLinkLocal() ? 1 : 0);
|
||||
if (_s[idx] != remote) {
|
||||
_s[idx] = remote;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void iam(const InetAddress &physicalAddress);
|
||||
|
||||
private:
|
||||
InetAddress _s[4]; // global v4, link-local v4, global v6, link-local v6
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
@ -45,7 +45,6 @@
|
||||
#include "InetAddress.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "Dictionary.hpp"
|
||||
#include "ExternalSurface.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
@ -321,20 +320,6 @@ public:
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Update our knowledge of exterior network addresses
|
||||
*
|
||||
* If the remote peer in question is trusted, this will update our internal
|
||||
* instance of ExternalSurface. If our surface has changed, this triggers a
|
||||
* partial or total reset of ephemeral peer addresses and a renegotiation of
|
||||
* new ones using supernodes / relays.
|
||||
*
|
||||
* @param remotePeer Remote peer address
|
||||
* @param mirroredAddress Real-world network address the remote peer told us we have
|
||||
* @param now Current time
|
||||
*/
|
||||
bool updateSurface(const SharedPtr<Peer> &remotePeer,const InetAddress &mirroredAddress,uint64_t now);
|
||||
|
||||
/**
|
||||
* Validate a root topology dictionary against the identities specified in Defaults
|
||||
*
|
||||
@ -356,8 +341,6 @@ private:
|
||||
std::vector< Address > _supernodeAddresses;
|
||||
std::vector< SharedPtr<Peer> > _supernodePeers;
|
||||
|
||||
ExternalSurface _surface;
|
||||
|
||||
Mutex _lock;
|
||||
|
||||
// Set to true if my identity is in _supernodes
|
||||
|
Loading…
Reference in New Issue
Block a user