mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-05 03:53:44 +02: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
6 changed files with 83 additions and 40 deletions
|
@ -39,6 +39,7 @@
|
||||||
#include "Switch.hpp"
|
#include "Switch.hpp"
|
||||||
#include "Peer.hpp"
|
#include "Peer.hpp"
|
||||||
#include "NetworkConfigMaster.hpp"
|
#include "NetworkConfigMaster.hpp"
|
||||||
|
#include "SelfAwareness.hpp"
|
||||||
|
|
||||||
namespace ZeroTier {
|
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 vMinor = (*this)[ZT_PROTO_VERB_HELLO_IDX_MINOR_VERSION];
|
||||||
const unsigned int vRevision = at<uint16_t>(ZT_PROTO_VERB_HELLO_IDX_REVISION);
|
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 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()) {
|
if (source() != id.address()) {
|
||||||
TRACE("dropped HELLO from %s(%s): identity not for sending address",source().toString().c_str(),_remoteAddress.toString().c_str());
|
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->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_HELLO,0,Packet::VERB_NOP);
|
||||||
peer->setRemoteVersion(protoVersion,vMajor,vMinor,vRevision);
|
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())) {
|
||||||
//if (RR->topology->isSupernode(id.address()))
|
RR->node->postNewerVersionIfNewer(vMajor,vMinor,vRevision);
|
||||||
// RR->node->postNewerVersionIfNewer(vMajor,vMinor,vRevision);
|
RR->sa->iam(destAddr);
|
||||||
|
}
|
||||||
|
|
||||||
Packet outp(id.address(),RR->identity.address(),Packet::VERB_OK);
|
Packet outp(id.address(),RR->identity.address(),Packet::VERB_OK);
|
||||||
|
|
||||||
outp.append((unsigned char)Packet::VERB_HELLO);
|
outp.append((unsigned char)Packet::VERB_HELLO);
|
||||||
outp.append(packetId());
|
outp.append(packetId());
|
||||||
outp.append(timestamp);
|
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_MAJOR);
|
||||||
outp.append((unsigned char)ZEROTIER_ONE_VERSION_MINOR);
|
outp.append((unsigned char)ZEROTIER_ONE_VERSION_MINOR);
|
||||||
outp.append((uint16_t)ZEROTIER_ONE_VERSION_REVISION);
|
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);
|
outp.armor(peer->key(),true);
|
||||||
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
|
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
|
||||||
} catch (std::exception &ex) {
|
} catch (std::exception &ex) {
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "Logger.hpp"
|
#include "Logger.hpp"
|
||||||
#include "Address.hpp"
|
#include "Address.hpp"
|
||||||
#include "Identity.hpp"
|
#include "Identity.hpp"
|
||||||
|
#include "SelfAwareness.hpp"
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
|
@ -77,7 +78,9 @@ Node::Node(
|
||||||
RR->mc = new Multicaster(RR);
|
RR->mc = new Multicaster(RR);
|
||||||
RR->antiRec = new AntiRecursion();
|
RR->antiRec = new AntiRecursion();
|
||||||
RR->topology = new Topology(RR);
|
RR->topology = new Topology(RR);
|
||||||
|
RR->sa = new SelfAwareness(RR);
|
||||||
} catch ( ... ) {
|
} catch ( ... ) {
|
||||||
|
delete RR->sa;
|
||||||
delete RR->topology;
|
delete RR->topology;
|
||||||
delete RR->antiRec;
|
delete RR->antiRec;
|
||||||
delete RR->mc;
|
delete RR->mc;
|
||||||
|
@ -91,6 +94,7 @@ Node::Node(
|
||||||
|
|
||||||
Node::~Node()
|
Node::~Node()
|
||||||
{
|
{
|
||||||
|
delete RR->sa;
|
||||||
delete RR->topology;
|
delete RR->topology;
|
||||||
delete RR->antiRec;
|
delete RR->antiRec;
|
||||||
delete RR->mc;
|
delete RR->mc;
|
||||||
|
|
|
@ -175,6 +175,12 @@
|
||||||
*/
|
*/
|
||||||
#define ZT_PROTO_BEACON_IDX_ADDRESS 8
|
#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 -------------------------------------------
|
// Field incides for parsing verbs -------------------------------------------
|
||||||
|
|
||||||
// Some verbs have variable-length fields. Those aren't fully defined here
|
// Some verbs have variable-length fields. Those aren't fully defined here
|
||||||
|
@ -467,6 +473,23 @@ public:
|
||||||
* <[2] software revision>
|
* <[2] software revision>
|
||||||
* <[8] timestamp (ms since epoch)>
|
* <[8] timestamp (ms since epoch)>
|
||||||
* <[...] binary serialized identity (see Identity)>
|
* <[...] 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:
|
* OK payload:
|
||||||
* <[8] timestamp (echoed from original HELLO)>
|
* <[8] timestamp (echoed from original HELLO)>
|
||||||
|
@ -474,6 +497,8 @@ public:
|
||||||
* <[1] software major version (of responder)>
|
* <[1] software major version (of responder)>
|
||||||
* <[1] software minor version (of responder)>
|
* <[1] software minor version (of responder)>
|
||||||
* <[2] software revision (of responder)>
|
* <[2] software revision (of responder)>
|
||||||
|
* <[1] destination address type (for this OK, not copied from HELLO)>
|
||||||
|
* [<[...] destination address>]
|
||||||
*
|
*
|
||||||
* ERROR has no payload.
|
* ERROR has no payload.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -44,6 +44,7 @@ class Node;
|
||||||
class Multicaster;
|
class Multicaster;
|
||||||
class AntiRecursion;
|
class AntiRecursion;
|
||||||
class NetworkConfigMaster;
|
class NetworkConfigMaster;
|
||||||
|
class SelfAwareness;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds global state for an instance of ZeroTier::Node
|
* Holds global state for an instance of ZeroTier::Node
|
||||||
|
@ -69,7 +70,8 @@ public:
|
||||||
sw((Switch *)0),
|
sw((Switch *)0),
|
||||||
mc((Multicaster *)0),
|
mc((Multicaster *)0),
|
||||||
antiRec((AntiRecursion *)0),
|
antiRec((AntiRecursion *)0),
|
||||||
topology((Topology *)0)
|
topology((Topology *)0),
|
||||||
|
sa((SelfAwareness *)0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,6 +98,7 @@ public:
|
||||||
Multicaster *mc;
|
Multicaster *mc;
|
||||||
AntiRecursion *antiRec;
|
AntiRecursion *antiRec;
|
||||||
Topology *topology;
|
Topology *topology;
|
||||||
|
SelfAwareness *sa;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
|
|
@ -25,40 +25,32 @@
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
* LLC. Start here: http://www.zerotier.com/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ZT_EXTERNALSURFACE_HPP
|
#ifndef ZT_SELFAWARENESS_HPP
|
||||||
#define ZT_EXTERNALSURFACE_HPP
|
#define ZT_SELFAWARENESS_HPP
|
||||||
|
|
||||||
#include "InetAddress.hpp"
|
#include "InetAddress.hpp"
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
|
class RuntimeEnvironment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tracks changes to this peer's real world addresses
|
* Tracks changes to this peer's real world addresses
|
||||||
*/
|
*/
|
||||||
class ExternalSurface
|
class SelfAwareness
|
||||||
{
|
{
|
||||||
public:
|
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
|
* @param physicalAddress Physical address as reflected by any trusted peer
|
||||||
* @return True if our external surface has changed
|
|
||||||
*/
|
*/
|
||||||
inline bool update(const InetAddress &remote)
|
void iam(const InetAddress &physicalAddress);
|
||||||
throw()
|
|
||||||
{
|
|
||||||
const unsigned long idx = (remote.isV4() ? 0 : 2) | (remote.isLinkLocal() ? 1 : 0);
|
|
||||||
if (_s[idx] != remote) {
|
|
||||||
_s[idx] = remote;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
InetAddress _s[4]; // global v4, link-local v4, global v6, link-local v6
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
|
@ -45,7 +45,6 @@
|
||||||
#include "InetAddress.hpp"
|
#include "InetAddress.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
#include "Dictionary.hpp"
|
#include "Dictionary.hpp"
|
||||||
#include "ExternalSurface.hpp"
|
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
|
@ -321,20 +320,6 @@ public:
|
||||||
};
|
};
|
||||||
#endif
|
#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
|
* Validate a root topology dictionary against the identities specified in Defaults
|
||||||
*
|
*
|
||||||
|
@ -356,8 +341,6 @@ private:
|
||||||
std::vector< Address > _supernodeAddresses;
|
std::vector< Address > _supernodeAddresses;
|
||||||
std::vector< SharedPtr<Peer> > _supernodePeers;
|
std::vector< SharedPtr<Peer> > _supernodePeers;
|
||||||
|
|
||||||
ExternalSurface _surface;
|
|
||||||
|
|
||||||
Mutex _lock;
|
Mutex _lock;
|
||||||
|
|
||||||
// Set to true if my identity is in _supernodes
|
// Set to true if my identity is in _supernodes
|
||||||
|
|
Loading…
Add table
Reference in a new issue