summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
Diffstat (limited to 'node')
-rw-r--r--node/IncomingPacket.cpp14
-rw-r--r--node/Node.cpp130
-rw-r--r--node/Node.hpp14
-rw-r--r--node/Path.cpp2
-rw-r--r--node/Path.hpp51
-rw-r--r--node/Peer.cpp59
-rw-r--r--node/Peer.hpp12
-rw-r--r--node/RuntimeEnvironment.hpp10
-rw-r--r--node/SelfAwareness.cpp4
-rw-r--r--node/SelfAwareness.hpp10
-rw-r--r--node/Switch.cpp8
-rw-r--r--node/Switch.hpp4
-rw-r--r--node/Topology.cpp4
-rw-r--r--node/Topology.hpp4
14 files changed, 88 insertions, 238 deletions
diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp
index 0548387b..f0be96f9 100644
--- a/node/IncomingPacket.cpp
+++ b/node/IncomingPacket.cpp
@@ -309,7 +309,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool
if (ptr < size()) {
ptr += externalSurfaceAddress.deserialize(*this,ptr);
if ((externalSurfaceAddress)&&(hops() == 0))
- RR->sa->iam(tPtr,id.address(),_path->localAddress(),_path->address(),externalSurfaceAddress,RR->topology->isUpstream(id),now);
+ RR->sa->iam(tPtr,id.address(),_path->localSocket(),_path->address(),externalSurfaceAddress,RR->topology->isUpstream(id),now);
}
// Get primary planet world ID and world timestamp if present
@@ -495,7 +495,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,void *tPtr,const SharedP
peer->setRemoteVersion(vProto,vMajor,vMinor,vRevision);
if ((externalSurfaceAddress)&&(hops() == 0))
- RR->sa->iam(tPtr,peer->address(),_path->localAddress(),_path->address(),externalSurfaceAddress,RR->topology->isUpstream(peer->identity()),RR->node->now());
+ RR->sa->iam(tPtr,peer->address(),_path->localSocket(),_path->address(),externalSurfaceAddress,RR->topology->isUpstream(peer->identity()),RR->node->now());
} break;
case Packet::VERB_WHOIS:
@@ -613,9 +613,9 @@ bool IncomingPacket::_doRENDEZVOUS(const RuntimeEnvironment *RR,void *tPtr,const
const unsigned int addrlen = (*this)[ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN];
if ((port > 0)&&((addrlen == 4)||(addrlen == 16))) {
const InetAddress atAddr(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS,addrlen),addrlen,port);
- if (RR->node->shouldUsePathForZeroTierTraffic(tPtr,with,_path->localAddress(),atAddr)) {
- RR->node->putPacket(tPtr,_path->localAddress(),atAddr,"ABRE",4,2); // send low-TTL junk packet to 'open' local NAT(s) and stateful firewalls
- rendezvousWith->attemptToContactAt(tPtr,_path->localAddress(),atAddr,RR->node->now(),false,0);
+ if (RR->node->shouldUsePathForZeroTierTraffic(tPtr,with,_path->localSocket(),atAddr)) {
+ RR->node->putPacket(tPtr,_path->localSocket(),atAddr,"ABRE",4,2); // send low-TTL junk packet to 'open' local NAT(s) and stateful firewalls
+ rendezvousWith->attemptToContactAt(tPtr,_path->localSocket(),atAddr,RR->node->now(),false,0);
TRACE("RENDEZVOUS from %s says %s might be at %s, sent verification attempt",peer->address().toString().c_str(),with.toString().c_str(),atAddr.toString().c_str());
} else {
TRACE("RENDEZVOUS from %s says %s might be at %s, ignoring since path is not suitable",peer->address().toString().c_str(),with.toString().c_str(),atAddr.toString().c_str());
@@ -1197,7 +1197,7 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,void *tPt
if (
((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && // not being told to forget
(!( ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) == 0) && (peer->hasActivePathTo(now,a)) )) && // not already known
- (RR->node->shouldUsePathForZeroTierTraffic(tPtr,peer->address(),_path->localAddress(),a)) ) // should use path
+ (RR->node->shouldUsePathForZeroTierTraffic(tPtr,peer->address(),_path->localSocket(),a)) ) // should use path
{
//if ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) != 0)
// peer->setClusterPreferred(a);
@@ -1214,7 +1214,7 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,void *tPt
if (
((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && // not being told to forget
(!( ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) == 0) && (peer->hasActivePathTo(now,a)) )) && // not already known
- (RR->node->shouldUsePathForZeroTierTraffic(tPtr,peer->address(),_path->localAddress(),a)) ) // should use path
+ (RR->node->shouldUsePathForZeroTierTraffic(tPtr,peer->address(),_path->localSocket(),a)) ) // should use path
{
//if ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_CLUSTER_REDIRECT) != 0)
// peer->setClusterPreferred(a);
diff --git a/node/Node.cpp b/node/Node.cpp
index 4ffe496c..4b598f61 100644
--- a/node/Node.cpp
+++ b/node/Node.cpp
@@ -47,8 +47,6 @@
#include "SelfAwareness.hpp"
#include "Network.hpp"
-const struct sockaddr_storage ZT_SOCKADDR_NULL = {0};
-
namespace ZeroTier {
/****************************************************************************/
@@ -137,114 +135,17 @@ Node::~Node()
delete RR->sw;
}
-ZT_ResultCode Node::processStateUpdate(
- void *tptr,
- ZT_StateObjectType type,
- const uint64_t id[2],
- const void *data,
- unsigned int len)
-{
- ZT_ResultCode r = ZT_RESULT_OK_IGNORED;
- switch(type) {
-
- case ZT_STATE_OBJECT_PEER_STATE:
- if (len) {
- const SharedPtr<Peer> p(RR->topology->getPeer(tptr,Address(id[0])));
- if (p) {
- r = (p->applyStateUpdate(data,len)) ? ZT_RESULT_OK : ZT_RESULT_OK_IGNORED;
- } else {
- r = (Peer::createFromStateUpdate(RR,tptr,data,len)) ? ZT_RESULT_OK : ZT_RESULT_OK_IGNORED;
- }
- }
- break;
-
- case ZT_STATE_OBJECT_NETWORK_CONFIG:
- if (len <= (ZT_NETWORKCONFIG_DICT_CAPACITY - 1)) {
- if (len < 2) {
- Mutex::Lock _l(_networks_m);
- SharedPtr<Network> &nw = _networks[id[0]];
- if (!nw) {
- nw = SharedPtr<Network>(new Network(RR,tptr,id[0],(void *)0,(const NetworkConfig *)0));
- r = ZT_RESULT_OK;
- }
- } else {
- Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> *dict = new Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY>(reinterpret_cast<const char *>(data),len);
- try {
- NetworkConfig *nconf = new NetworkConfig();
- try {
- if (nconf->fromDictionary(*dict)) {
- Mutex::Lock _l(_networks_m);
- SharedPtr<Network> &nw = _networks[id[0]];
- if (nw) {
- switch (nw->setConfiguration(tptr,*nconf,false)) {
- default:
- r = ZT_RESULT_ERROR_BAD_PARAMETER;
- break;
- case 1:
- r = ZT_RESULT_OK_IGNORED;
- break;
- case 2:
- r = ZT_RESULT_OK;
- break;
- }
- } else {
- nw = SharedPtr<Network>(new Network(RR,tptr,id[0],(void *)0,nconf));
- }
- } else {
- r = ZT_RESULT_ERROR_BAD_PARAMETER;
- }
- } catch ( ... ) {
- r = ZT_RESULT_ERROR_BAD_PARAMETER;
- }
- delete nconf;
- } catch ( ... ) {
- r = ZT_RESULT_ERROR_BAD_PARAMETER;
- }
- delete dict;
- }
- } else {
- r = ZT_RESULT_ERROR_BAD_PARAMETER;
- }
- break;
-
- case ZT_STATE_OBJECT_NETWORK_MEMBERSHIP:
- if (len) {
- }
- break;
-
- case ZT_STATE_OBJECT_PLANET:
- case ZT_STATE_OBJECT_MOON:
- if ((len)&&(len <= ZT_WORLD_MAX_SERIALIZED_LENGTH)) {
- World w;
- try {
- w.deserialize(Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH>(data,len));
- if (( (w.type() == World::TYPE_MOON)&&(type == ZT_STATE_OBJECT_MOON) )||( (w.type() == World::TYPE_PLANET)&&(type == ZT_STATE_OBJECT_PLANET) )) {
- r = (RR->topology->addWorld(tptr,w,false)) ? ZT_RESULT_OK : ZT_RESULT_OK_IGNORED;
- }
- } catch ( ... ) {
- r = ZT_RESULT_ERROR_BAD_PARAMETER;
- }
- } else {
- r = ZT_RESULT_ERROR_BAD_PARAMETER;
- }
- break;
-
- default: break;
- }
- return r;
-}
-
ZT_ResultCode Node::processWirePacket(
void *tptr,
uint64_t now,
- const struct sockaddr_storage *localAddress,
+ int64_t localSocket,
const struct sockaddr_storage *remoteAddress,
const void *packetData,
unsigned int packetLength,
volatile uint64_t *nextBackgroundTaskDeadline)
{
_now = now;
- RR->sw->onRemotePacket(tptr,*(reinterpret_cast<const InetAddress *>(localAddress)),*(reinterpret_cast<const InetAddress *>(remoteAddress)),packetData,packetLength);
+ RR->sw->onRemotePacket(tptr,localSocket,*(reinterpret_cast<const InetAddress *>(remoteAddress)),packetData,packetLength);
return ZT_RESULT_OK;
}
@@ -317,7 +218,7 @@ public:
if ((!contacted)&&(_bestCurrentUpstream)) {
const SharedPtr<Path> up(_bestCurrentUpstream->getBestPath(_now,true));
if (up)
- p->sendHELLO(_tPtr,up->localAddress(),up->address(),_now,up->nextOutgoingCounter());
+ p->sendHELLO(_tPtr,up->localSocket(),up->address(),_now,up->nextOutgoingCounter());
}
lastReceiveFromUpstream = std::max(p->lastReceive(),lastReceiveFromUpstream);
@@ -617,7 +518,7 @@ void Node::setNetconfMaster(void *networkControllerInstance)
/* Node methods used only within node/ */
/****************************************************************************/
-bool Node::shouldUsePathForZeroTierTraffic(void *tPtr,const Address &ztaddr,const InetAddress &localAddress,const InetAddress &remoteAddress)
+bool Node::shouldUsePathForZeroTierTraffic(void *tPtr,const Address &ztaddr,const int64_t localSocket,const InetAddress &remoteAddress)
{
if (!Path::isAddressValidForPath(remoteAddress))
return false;
@@ -640,7 +541,7 @@ bool Node::shouldUsePathForZeroTierTraffic(void *tPtr,const Address &ztaddr,cons
}
}
- return ( (_cb.pathCheckFunction) ? (_cb.pathCheckFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ztaddr.toInt(),reinterpret_cast<const struct sockaddr_storage *>(&localAddress),reinterpret_cast<const struct sockaddr_storage *>(&remoteAddress)) != 0) : true);
+ return ( (_cb.pathCheckFunction) ? (_cb.pathCheckFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ztaddr.toInt(),localSocket,reinterpret_cast<const struct sockaddr_storage *>(&remoteAddress)) != 0) : true);
}
#ifdef ZT_TRACE
@@ -837,35 +738,18 @@ void ZT_Node_delete(ZT_Node *node)
} catch ( ... ) {}
}
-enum ZT_ResultCode ZT_Node_processStateUpdate(
- ZT_Node *node,
- void *tptr,
- ZT_StateObjectType type,
- const uint64_t id[2],
- const void *data,
- unsigned int len)
-{
- try {
- return reinterpret_cast<ZeroTier::Node *>(node)->processStateUpdate(tptr,type,id,data,len);
- } catch (std::bad_alloc &exc) {
- return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
- } catch ( ... ) {
- return ZT_RESULT_FATAL_ERROR_INTERNAL;
- }
-}
-
enum ZT_ResultCode ZT_Node_processWirePacket(
ZT_Node *node,
void *tptr,
uint64_t now,
- const struct sockaddr_storage *localAddress,
+ int64_t localSocket,
const struct sockaddr_storage *remoteAddress,
const void *packetData,
unsigned int packetLength,
volatile uint64_t *nextBackgroundTaskDeadline)
{
try {
- return reinterpret_cast<ZeroTier::Node *>(node)->processWirePacket(tptr,now,localAddress,remoteAddress,packetData,packetLength,nextBackgroundTaskDeadline);
+ return reinterpret_cast<ZeroTier::Node *>(node)->processWirePacket(tptr,now,localSocket,remoteAddress,packetData,packetLength,nextBackgroundTaskDeadline);
} catch (std::bad_alloc &exc) {
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
} catch ( ... ) {
diff --git a/node/Node.hpp b/node/Node.hpp
index 17050d24..55491b06 100644
--- a/node/Node.hpp
+++ b/node/Node.hpp
@@ -82,16 +82,10 @@ public:
// Public API Functions ----------------------------------------------------
- ZT_ResultCode processStateUpdate(
- void *tptr,
- ZT_StateObjectType type,
- const uint64_t id[2],
- const void *data,
- unsigned int len);
ZT_ResultCode processWirePacket(
void *tptr,
uint64_t now,
- const struct sockaddr_storage *localAddress,
+ int64_t localSocket,
const struct sockaddr_storage *remoteAddress,
const void *packetData,
unsigned int packetLength,
@@ -129,13 +123,13 @@ public:
inline uint64_t now() const throw() { return _now; }
- inline bool putPacket(void *tPtr,const InetAddress &localAddress,const InetAddress &addr,const void *data,unsigned int len,unsigned int ttl = 0)
+ inline bool putPacket(void *tPtr,const int64_t localSocket,const InetAddress &addr,const void *data,unsigned int len,unsigned int ttl = 0)
{
return (_cb.wirePacketSendFunction(
reinterpret_cast<ZT_Node *>(this),
_uPtr,
tPtr,
- reinterpret_cast<const struct sockaddr_storage *>(&localAddress),
+ localSocket,
reinterpret_cast<const struct sockaddr_storage *>(&addr),
data,
len,
@@ -205,7 +199,7 @@ public:
void postTrace(const char *module,unsigned int line,const char *fmt,...);
#endif
- bool shouldUsePathForZeroTierTraffic(void *tPtr,const Address &ztaddr,const InetAddress &localAddress,const InetAddress &remoteAddress);
+ bool shouldUsePathForZeroTierTraffic(void *tPtr,const Address &ztaddr,const int64_t localSocket,const InetAddress &remoteAddress);
inline bool externalPathLookup(void *tPtr,const Address &ztaddr,int family,InetAddress &addr) { return ( (_cb.pathLookupFunction) ? (_cb.pathLookupFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ztaddr.toInt(),family,reinterpret_cast<struct sockaddr_storage *>(&addr)) != 0) : false ); }
uint64_t prng();
diff --git a/node/Path.cpp b/node/Path.cpp
index a5fe1aa7..9dc9aba5 100644
--- a/node/Path.cpp
+++ b/node/Path.cpp
@@ -32,7 +32,7 @@ namespace ZeroTier {
bool Path::send(const RuntimeEnvironment *RR,void *tPtr,const void *data,unsigned int len,uint64_t now)
{
- if (RR->node->putPacket(tPtr,_localAddress,address(),data,len)) {
+ if (RR->node->putPacket(tPtr,_localSocket,_addr,data,len)) {
_lastOut = now;
return true;
}
diff --git a/node/Path.hpp b/node/Path.hpp
index a6f56d31..854b28e2 100644
--- a/node/Path.hpp
+++ b/node/Path.hpp
@@ -66,49 +66,28 @@ public:
public:
HashKey() {}
- HashKey(const InetAddress &l,const InetAddress &r)
+ HashKey(const int64_t l,const InetAddress &r)
{
- // This is an ad-hoc bit packing algorithm to yield unique keys for
- // remote addresses and their local-side counterparts if defined.
- // Portability across runtimes is not needed.
if (r.ss_family == AF_INET) {
_k[0] = (uint64_t)reinterpret_cast<const struct sockaddr_in *>(&r)->sin_addr.s_addr;
_k[1] = (uint64_t)reinterpret_cast<const struct sockaddr_in *>(&r)->sin_port;
- if (l.ss_family == AF_INET) {
- _k[2] = (uint64_t)reinterpret_cast<const struct sockaddr_in *>(&l)->sin_addr.s_addr;
- _k[3] = (uint64_t)reinterpret_cast<const struct sockaddr_in *>(&r)->sin_port;
- } else {
- _k[2] = 0;
- _k[3] = 0;
- }
+ _k[2] = (uint64_t)l;
} else if (r.ss_family == AF_INET6) {
- const uint8_t *a = reinterpret_cast<const uint8_t *>(reinterpret_cast<const struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr);
- uint8_t *b = reinterpret_cast<uint8_t *>(_k);
- for(unsigned int i=0;i<16;++i) b[i] = a[i];
- _k[2] = ~((uint64_t)reinterpret_cast<const struct sockaddr_in6 *>(&r)->sin6_port);
- if (l.ss_family == AF_INET6) {
- _k[2] ^= ((uint64_t)reinterpret_cast<const struct sockaddr_in6 *>(&r)->sin6_port) << 32;
- a = reinterpret_cast<const uint8_t *>(reinterpret_cast<const struct sockaddr_in6 *>(&l)->sin6_addr.s6_addr);
- b += 24;
- for(unsigned int i=0;i<8;++i) b[i] = a[i];
- a += 8;
- for(unsigned int i=0;i<8;++i) b[i] ^= a[i];
- }
+ memcpy(_k,reinterpret_cast<const struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr,16);
+ _k[2] = ((uint64_t)reinterpret_cast<const struct sockaddr_in6 *>(&r)->sin6_port << 32) ^ (uint64_t)l;
} else {
- _k[0] = 0;
- _k[1] = 0;
- _k[2] = 0;
- _k[3] = 0;
+ memcpy(_k,&r,std::min(sizeof(_k),sizeof(InetAddress)));
+ _k[2] += (uint64_t)l;
}
}
- inline unsigned long hashCode() const { return (unsigned long)(_k[0] + _k[1] + _k[2] + _k[3]); }
+ inline unsigned long hashCode() const { return (unsigned long)(_k[0] + _k[1] + _k[2]); }
- inline bool operator==(const HashKey &k) const { return ( (_k[0] == k._k[0]) && (_k[1] == k._k[1]) && (_k[2] == k._k[2]) && (_k[3] == k._k[3]) ); }
+ inline bool operator==(const HashKey &k) const { return ( (_k[0] == k._k[0]) && (_k[1] == k._k[1]) && (_k[2] == k._k[2]) ); }
inline bool operator!=(const HashKey &k) const { return (!(*this == k)); }
private:
- uint64_t _k[4];
+ uint64_t _k[3];
};
Path() :
@@ -116,29 +95,29 @@ public:
_lastIn(0),
_lastTrustEstablishedPacketReceived(0),
_incomingLinkQualityFastLog(0xffffffffffffffffULL),
+ _localSocket(-1),
_incomingLinkQualitySlowLogPtr(0),
_incomingLinkQualitySlowLogCounter(-64), // discard first fast log
_incomingLinkQualityPreviousPacketCounter(0),
_outgoingPacketCounter(0),
_addr(),
- _localAddress(),
_ipScope(InetAddress::IP_SCOPE_NONE)
{
for(int i=0;i<(int)sizeof(_incomingLinkQualitySlowLog);++i)
_incomingLinkQualitySlowLog[i] = ZT_PATH_LINK_QUALITY_MAX;
}
- Path(const InetAddress &localAddress,const InetAddress &addr) :
+ Path(const int64_t localSocket,const InetAddress &addr) :
_lastOut(0),
_lastIn(0),
_lastTrustEstablishedPacketReceived(0),
_incomingLinkQualityFastLog(0xffffffffffffffffULL),
+ _localSocket(localSocket),
_incomingLinkQualitySlowLogPtr(0),
_incomingLinkQualitySlowLogCounter(-64), // discard first fast log
_incomingLinkQualityPreviousPacketCounter(0),
_outgoingPacketCounter(0),
_addr(addr),
- _localAddress(localAddress),
_ipScope(addr.ipScope())
{
for(int i=0;i<(int)sizeof(_incomingLinkQualitySlowLog);++i)
@@ -210,9 +189,9 @@ public:
inline void sent(const uint64_t t) { _lastOut = t; }
/**
- * @return Address of local side of this path or NULL if unspecified
+ * @return Local socket as specified by external code
*/
- inline const InetAddress &localAddress() const { return _localAddress; }
+ inline const int64_t localSocket() const { return _localSocket; }
/**
* @return Physical address
@@ -328,12 +307,12 @@ private:
volatile uint64_t _lastIn;
volatile uint64_t _lastTrustEstablishedPacketReceived;
volatile uint64_t _incomingLinkQualityFastLog;
+ int64_t _localSocket;
volatile unsigned long _incomingLinkQualitySlowLogPtr;
volatile signed int _incomingLinkQualitySlowLogCounter;
volatile unsigned int _incomingLinkQualityPreviousPacketCounter;
volatile unsigned int _outgoingPacketCounter;
InetAddress _addr;
- InetAddress _localAddress;
InetAddress::IpScope _ipScope; // memoize this since it's a computed value checked often
volatile uint8_t _incomingLinkQualitySlowLog[32];
AtomicCounter __refCount;
diff --git a/node/Peer.cpp b/node/Peer.cpp
index 18d05875..875d651e 100644
--- a/node/Peer.cpp
+++ b/node/Peer.cpp
@@ -154,25 +154,21 @@ void Peer::received(
if ((path->address().ss_family == AF_INET)&&(_v4Path.p)) {
const struct sockaddr_in *const r = reinterpret_cast<const struct sockaddr_in *>(&(path->address()));
const struct sockaddr_in *const l = reinterpret_cast<const struct sockaddr_in *>(&(_v4Path.p->address()));
- const struct sockaddr_in *const rl = reinterpret_cast<const struct sockaddr_in *>(&(path->localAddress()));
- const struct sockaddr_in *const ll = reinterpret_cast<const struct sockaddr_in *>(&(_v4Path.p->localAddress()));
- if ((r->sin_addr.s_addr == l->sin_addr.s_addr)&&(r->sin_port == l->sin_port)&&(rl->sin_addr.s_addr == ll->sin_addr.s_addr)&&(rl->sin_port == ll->sin_port)) {
+ if ((r->sin_addr.s_addr == l->sin_addr.s_addr)&&(r->sin_port == l->sin_port)&&(path->localSocket() == _v4Path.p->localSocket())) {
_v4Path.lr = now;
pathAlreadyKnown = true;
}
} else if ((path->address().ss_family == AF_INET6)&&(_v6Path.p)) {
const struct sockaddr_in6 *const r = reinterpret_cast<const struct sockaddr_in6 *>(&(path->address()));
const struct sockaddr_in6 *const l = reinterpret_cast<const struct sockaddr_in6 *>(&(_v6Path.p->address()));
- const struct sockaddr_in6 *const rl = reinterpret_cast<const struct sockaddr_in6 *>(&(path->localAddress()));
- const struct sockaddr_in6 *const ll = reinterpret_cast<const struct sockaddr_in6 *>(&(_v6Path.p->localAddress()));
- if ((!memcmp(r->sin6_addr.s6_addr,l->sin6_addr.s6_addr,16))&&(r->sin6_port == l->sin6_port)&&(!memcmp(rl->sin6_addr.s6_addr,ll->sin6_addr.s6_addr,16))&&(rl->sin6_port == ll->sin6_port)) {
+ if ((!memcmp(r->sin6_addr.s6_addr,l->sin6_addr.s6_addr,16))&&(r->sin6_port == l->sin6_port)&&(path->localSocket() == _v6Path.p->localSocket())) {
_v6Path.lr = now;
pathAlreadyKnown = true;
}
}
}
- if ( (!pathAlreadyKnown) && (RR->node->shouldUsePathForZeroTierTraffic(tPtr,_id.address(),path->localAddress(),path->address())) ) {
+ if ( (!pathAlreadyKnown) && (RR->node->shouldUsePathForZeroTierTraffic(tPtr,_id.address(),path->localSocket(),path->address())) ) {
Mutex::Lock _l(_paths_m);
_PeerPath *potentialNewPeerPath = (_PeerPath *)0;
if (path->address().ss_family == AF_INET) {
@@ -191,7 +187,7 @@ void Peer::received(
_lastWroteState = 0; // force state write now
} else {
TRACE("got %s via unknown path %s(%s), confirming...",Packet::verbString(verb),_id.address().toString().c_str(),path->address().toString().c_str());
- attemptToContactAt(tPtr,path->localAddress(),path->address(),now,true,path->nextOutgoingCounter());
+ attemptToContactAt(tPtr,path->localSocket(),path->address(),now,true,path->nextOutgoingCounter());
path->sent(now);
}
}
@@ -318,7 +314,7 @@ SharedPtr<Path> Peer::getBestPath(uint64_t now,bool includeExpired)
return SharedPtr<Path>();
}
-void Peer::sendHELLO(void *tPtr,const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,unsigned int counter)
+void Peer::sendHELLO(void *tPtr,const int64_t localSocket,const InetAddress &atAddress,uint64_t now,unsigned int counter)
{
Packet outp(_id.address(),RR->identity.address(),Packet::VERB_HELLO);
@@ -360,21 +356,21 @@ void Peer::sendHELLO(void *tPtr,const InetAddress &localAddr,const InetAddress &
if (atAddress) {
outp.armor(_key,false,counter); // false == don't encrypt full payload, but add MAC
- RR->node->putPacket(tPtr,localAddr,atAddress,outp.data(),outp.size());
+ RR->node->putPacket(tPtr,localSocket,atAddress,outp.data(),outp.size());
} else {
RR->sw->send(tPtr,outp,false); // false == don't encrypt full payload, but add MAC
}
}
-void Peer::attemptToContactAt(void *tPtr,const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,bool sendFullHello,unsigned int counter)
+void Peer::attemptToContactAt(void *tPtr,const int64_t localSocket,const InetAddress &atAddress,uint64_t now,bool sendFullHello,unsigned int counter)
{
if ( (!sendFullHello) && (_vProto >= 5) && (!((_vMajor == 1)&&(_vMinor == 1)&&(_vRevision == 0))) ) {
Packet outp(_id.address(),RR->identity.address(),Packet::VERB_ECHO);
RR->node->expectReplyTo(outp.packetId());
outp.armor(_key,true,counter);
- RR->node->putPacket(tPtr,localAddr,atAddress,outp.data(),outp.size());
+ RR->node->putPacket(tPtr,localSocket,atAddress,outp.data(),outp.size());
} else {
- sendHELLO(tPtr,localAddr,atAddress,now,counter);
+ sendHELLO(tPtr,localSocket,atAddress,now,counter);
}
}
@@ -402,13 +398,13 @@ bool Peer::doPingAndKeepalive(void *tPtr,uint64_t now,int inetAddressFamily)
if (v6lr > v4lr) {
if ( ((now - _v6Path.lr) >= ZT_PEER_PING_PERIOD) || (_v6Path.p->needsHeartbeat(now)) ) {
- attemptToContactAt(tPtr,_v6Path.p->localAddress(),_v6Path.p->address(),now,false,_v6Path.p->nextOutgoingCounter());
+ attemptToContactAt(tPtr,_v6Path.p->localSocket(),_v6Path.p->address(),now,false,_v6Path.p->nextOutgoingCounter());
_v6Path.p->sent(now);
return true;
}
} else if (v4lr) {
if ( ((now - _v4Path.lr) >= ZT_PEER_PING_PERIOD) || (_v4Path.p->needsHeartbeat(now)) ) {
- attemptToContactAt(tPtr,_v4Path.p->localAddress(),_v4Path.p->address(),now,false,_v4Path.p->nextOutgoingCounter());
+ attemptToContactAt(tPtr,_v4Path.p->localSocket(),_v4Path.p->address(),now,false,_v4Path.p->nextOutgoingCounter());
_v4Path.p->sent(now);
return true;
}
@@ -416,13 +412,13 @@ bool Peer::doPingAndKeepalive(void *tPtr,uint64_t now,int inetAddressFamily)
} else {
if ( (inetAddressFamily == AF_INET) && ((now - _v4Path.lr) < ZT_PEER_PATH_EXPIRATION) ) {
if ( ((now - _v4Path.lr) >= ZT_PEER_PING_PERIOD) || (_v4Path.p->needsHeartbeat(now)) ) {
- attemptToContactAt(tPtr,_v4Path.p->localAddress(),_v4Path.p->address(),now,false,_v4Path.p->nextOutgoingCounter());
+ attemptToContactAt(tPtr,_v4Path.p->localSocket(),_v4Path.p->address(),now,false,_v4Path.p->nextOutgoingCounter());
_v4Path.p->sent(now);
return true;
}
} else if ( (inetAddressFamily == AF_INET6) && ((now - _v6Path.lr) < ZT_PEER_PATH_EXPIRATION) ) {
if ( ((now - _v6Path.lr) >= ZT_PEER_PING_PERIOD) || (_v6Path.p->needsHeartbeat(now)) ) {
- attemptToContactAt(tPtr,_v6Path.p->localAddress(),_v6Path.p->address(),now,false,_v6Path.p->nextOutgoingCounter());
+ attemptToContactAt(tPtr,_v6Path.p->localSocket(),_v6Path.p->address(),now,false,_v6Path.p->nextOutgoingCounter());
_v6Path.p->sent(now);
return true;
}
@@ -456,7 +452,6 @@ void Peer::writeState(void *tPtr,const uint64_t now)
b.append(_v4Path.p->lastIn());
b.append(_v4Path.p->lastTrustEstablishedPacketReceived());
_v4Path.p->address().serialize(b);
- _v4Path.p->localAddress().serialize(b);
}
if (_v6Path.lr) {
b.append(_v6Path.lr);
@@ -464,7 +459,6 @@ void Peer::writeState(void *tPtr,const uint64_t now)
b.append(_v6Path.p->lastIn());
b.append(_v6Path.p->lastTrustEstablishedPacketReceived());
_v6Path.p->address().serialize(b);
- _v6Path.p->localAddress().serialize(b);
}
}
@@ -491,7 +485,7 @@ void Peer::writeState(void *tPtr,const uint64_t now)
uint64_t tmp[2];
tmp[0] = _id.address().toInt(); tmp[1] = 0;
- RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_PEER_STATE,tmp,b.data(),b.size());
+ //RR->node->stateObjectPut(tPtr,ZT_STATE_OBJECT_PEER_STATE,tmp,b.data(),b.size());
_lastWroteState = now;
} catch ( ... ) {} // sanity check, should not be possible
@@ -522,22 +516,19 @@ bool Peer::applyStateUpdate(const void *data,unsigned int len)
const uint64_t lastOut = b.at<uint64_t>(ptr); ptr += 8;
const uint64_t lastIn = b.at<uint64_t>(ptr); ptr += 8;
const uint64_t lastTrustEstablishedPacketReceived = b.at<uint64_t>(ptr); ptr += 8;
- InetAddress addr,localAddr;
+ InetAddress addr;
ptr += addr.deserialize(b,ptr);
- ptr += localAddr.deserialize(b,ptr);
- if (addr.ss_family == localAddr.ss_family) {
- _PeerPath *p = (_PeerPath *)0;
- switch(addr.ss_family) {
- case AF_INET: p = &_v4Path; break;
- case AF_INET6: p = &_v6Path; break;
- }
- if (p) {
- if ( (!p->p) || ((p->p->address() != addr)||(p->p->localAddress() != localAddr)) ) {
- p->p = RR->topology->getPath(localAddr,addr);
- }
- p->lr = lr;
- p->p->updateFromRemoteState(lastOut,lastIn,lastTrustEstablishedPacketReceived);
+ _PeerPath *p = (_PeerPath *)0;
+ switch(addr.ss_family) {
+ case AF_INET: p = &_v4Path; break;
+ case AF_INET6: p = &_v6Path; break;
+ }
+ if (p) {
+ if ( (!p->p) || (p->p->address() != addr) ) {
+ p->p = RR->topology->getPath(-1,addr);
}
+ p->lr = lr;
+ p->p->updateFromRemoteState(lastOut,lastIn,lastTrustEstablishedPacketReceived);
}
}
}
diff --git a/node/Peer.hpp b/node/Peer.hpp
index f0eb3ee8..478c7232 100644
--- a/node/Peer.hpp
+++ b/node/Peer.hpp
@@ -154,12 +154,12 @@ public:
* No statistics or sent times are updated here.
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
- * @param localAddr Local address
+ * @param localSocket Local source socket
* @param atAddress Destination address
* @param now Current time
* @param counter Outgoing packet counter
*/
- void sendHELLO(void *tPtr,const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,unsigned int counter);
+ void sendHELLO(void *tPtr,const int64_t localSocket,const InetAddress &atAddress,uint64_t now,unsigned int counter);
/**
* Send ECHO (or HELLO for older peers) to this peer at the given address
@@ -167,13 +167,13 @@ public:
* No statistics or sent times are updated here.
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
- * @param localAddr Local address
+ * @param localSocket Local source socket
* @param atAddress Destination address
* @param now Current time
* @param sendFullHello If true, always send a full HELLO instead of just an ECHO
* @param counter Outgoing packet counter
*/
- void attemptToContactAt(void *tPtr,const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,bool sendFullHello,unsigned int counter);
+ void attemptToContactAt(void *tPtr,const int64_t localSocket,const InetAddress &atAddress,uint64_t now,bool sendFullHello,unsigned int counter);
/**
* Try a memorized or statically defined path if any are known
@@ -227,11 +227,11 @@ public:
{
Mutex::Lock _l(_paths_m);
if ((inetAddressFamily == AF_INET)&&(_v4Path.lr)&&(_v4Path.p->address().ipScope() == scope)) {
- attemptToContactAt(tPtr,_v4Path.p->localAddress(),_v4Path.p->address(),now,false,_v4Path.p->nextOutgoingCounter());
+ attemptToContactAt(tPtr,_v4Path.p->localSocket(),_v4Path.p->address(),now,false,_v4Path.p->nextOutgoingCounter());
_v4Path.p->sent(now);
_v4Path.lr = 0; // path will not be used unless it speaks again
} else if ((inetAddressFamily == AF_INET6)&&(_v6Path.lr)&&(_v6Path.p->address().ipScope() == scope)) {
- attemptToContactAt(tPtr,_v6Path.p->localAddress(),_v6Path.p->address(),now,false,_v6Path.p->nextOutgoingCounter());
+ attemptToContactAt(tPtr,_v6Path.p->localSocket(),_v6Path.p->address(),now,false,_v6Path.p->nextOutgoingCounter());
_v6Path.p->sent(now);
_v6Path.lr = 0; // path will not be used unless it speaks again
}
diff --git a/node/RuntimeEnvironment.hpp b/node/RuntimeEnvironment.hpp
index ee0c8c24..99afe25d 100644
--- a/node/RuntimeEnvironment.hpp
+++ b/node/RuntimeEnvironment.hpp
@@ -67,6 +67,11 @@ public:
Utils::burn(reinterpret_cast<void *>(const_cast<char *>(secretIdentityStr.data())),(unsigned int)secretIdentityStr.length());
}
+ /**
+ * A random integer identifying this running instance in a cluster
+ */
+ uint64_t instanceId;
+
// Node instance that owns this RuntimeEnvironment
Node *const node;
@@ -90,11 +95,6 @@ public:
Multicaster *mc;
Topology *topology;
SelfAwareness *sa;
-
- /**
- * A random integer identifying this run of ZeroTier
- */
- uint32_t instanceId;
};
} // namespace ZeroTier
diff --git a/node/SelfAwareness.cpp b/node/SelfAwareness.cpp
index c5daddc3..3e3397f5 100644
--- a/node/SelfAwareness.cpp
+++ b/node/SelfAwareness.cpp
@@ -69,7 +69,7 @@ SelfAwareness::SelfAwareness(const RuntimeEnvironment *renv) :
{
}
-void SelfAwareness::iam(void *tPtr,const Address &reporter,const InetAddress &receivedOnLocalAddress,const InetAddress &reporterPhysicalAddress,const InetAddress &myPhysicalAddress,bool trusted,uint64_t now)
+void SelfAwareness::iam(void *tPtr,const Address &reporter,const int64_t receivedOnLocalSocket,const InetAddress &reporterPhysicalAddress,const InetAddress &myPhysicalAddress,bool trusted,uint64_t now)
{
const InetAddress::IpScope scope = myPhysicalAddress.ipScope();
@@ -77,7 +77,7 @@ void SelfAwareness::iam(void *tPtr,const Address &reporter,const InetAddress &re
return;
Mutex::Lock _l(_phy_m);
- PhySurfaceEntry &entry = _phy[PhySurfaceKey(reporter,receivedOnLocalAddress,reporterPhysicalAddress,scope)];
+ PhySurfaceEntry &entry = _phy[PhySurfaceKey(reporter,receivedOnLocalSocket,reporterPhysicalAddress,scope)];
if ( (trusted) && ((now - entry.ts) < ZT_SELFAWARENESS_ENTRY_TIMEOUT) && (!entry.mySurface.ipsEqual(myPhysicalAddress)) ) {
// Changes to external surface reported by trusted peers causes path reset in this scope
diff --git a/node/SelfAwareness.hpp b/node/SelfAwareness.hpp
index 63c416bf..35e0ad39 100644
--- a/node/SelfAwareness.hpp
+++ b/node/SelfAwareness.hpp
@@ -55,7 +55,7 @@ public:
* @param trusted True if this peer is trusted as an authority to inform us of external address changes
* @param now Current time
*/
- void iam(void *tPtr,const Address &reporter,const InetAddress &receivedOnLocalAddress,const InetAddress &reporterPhysicalAddress,const InetAddress &myPhysicalAddress,bool trusted,uint64_t now);
+ void iam(void *tPtr,const Address &reporter,const int64_t receivedOnLocalSocket,const InetAddress &reporterPhysicalAddress,const InetAddress &myPhysicalAddress,bool trusted,uint64_t now);
/**
* Clean up database periodically
@@ -75,15 +75,15 @@ private:
struct PhySurfaceKey
{
Address reporter;
- InetAddress receivedOnLocalAddress;
+ int64_t receivedOnLocalSocket;
InetAddress reporterPhysicalAddress;
InetAddress::IpScope scope;
PhySurfaceKey() : reporter(),scope(InetAddress::IP_SCOPE_NONE) {}
- PhySurfaceKey(const Address &r,const InetAddress &rol,const InetAddress &ra,InetAddress::IpScope s) : reporter(r),receivedOnLocalAddress(rol),reporterPhysicalAddress(ra),scope(s) {}
+ PhySurfaceKey(const Address &r,const int64_t rol,const InetAddress &ra,InetAddress::IpScope s) : reporter(r),receivedOnLocalSocket(rol),reporterPhysicalAddress(ra),scope(s) {}
- inline unsigned long hashCode() const throw() { return ((unsigned long)reporter.toInt() + (unsigned long)scope); }
- inline bool operator==(const PhySurfaceKey &k) const throw() { return ((reporter == k.reporter)&&(receivedOnLocalAddress == k.receivedOnLocalAddress)&&(reporterPhysicalAddress == k.reporterPhysicalAddress)&&(scope == k.scope)); }
+ inline unsigned long hashCode() const { return ((unsigned long)reporter.toInt() + (unsigned long)scope); }
+ inline bool operator==(const PhySurfaceKey &k) const { return ((reporter == k.reporter)&&(receivedOnLocalSocket == k.receivedOnLocalSocket)&&(reporterPhysicalAddress == k.reporterPhysicalAddress)&&(scope == k.scope)); }
};
struct PhySurfaceEntry
{
diff --git a/node/Switch.cpp b/node/Switch.cpp
index cbd73a83..a77ca89e 100644
--- a/node/Switch.cpp
+++ b/node/Switch.cpp
@@ -71,12 +71,12 @@ Switch::Switch(const RuntimeEnvironment *renv) :
{
}
-void Switch::onRemotePacket(void *tPtr,const InetAddress &localAddr,const InetAddress &fromAddr,const void *data,unsigned int len)
+void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddress &fromAddr,const void *data,unsigned int len)
{
try {
const uint64_t now = RR->node->now();
- SharedPtr<Path> path(RR->topology->getPath(localAddr,fromAddr));
+ SharedPtr<Path> path(RR->topology->getPath(localSocket,fromAddr));
path->received(now);
if (len == 13) {
@@ -88,7 +88,7 @@ void Switch::onRemotePacket(void *tPtr,const InetAddress &localAddr,const InetAd
const Address beaconAddr(reinterpret_cast<const char *>(data) + 8,5);
if (beaconAddr == RR->identity.address())
return;
- if (!RR->node->shouldUsePathForZeroTierTraffic(tPtr,beaconAddr,localAddr,fromAddr))
+ if (!RR->node->shouldUsePathForZeroTierTraffic(tPtr,beaconAddr,localSocket,fromAddr))
return;
const SharedPtr<Peer> peer(RR->topology->getPeer(tPtr,beaconAddr));
if (peer) { // we'll only respond to beacons from known peers
@@ -752,7 +752,7 @@ bool Switch::_trySend(void *tPtr,Packet &packet,bool encrypt)
viaPath = peer->getBestPath(now,false);
if ( (viaPath) && (!viaPath->alive(now)) && (!RR->topology->isUpstream(peer->identity())) ) {
if ((now - viaPath->lastOut()) > std::max((now - viaPath->lastIn()) * 4,(uint64_t)ZT_PATH_MIN_REACTIVATE_INTERVAL)) {
- peer->attemptToContactAt(tPtr,viaPath->localAddress(),viaPath->address(),now,false,viaPath->nextOutgoingCounter());
+ peer->attemptToContactAt(tPtr,viaPath->localSocket(),viaPath->address(),now,false,viaPath->nextOutgoingCounter());
viaPath->sent(now);
}
viaPath.zero();
diff --git a/node/Switch.hpp b/node/Switch.hpp
index 9793dd45..cebe9e67 100644
--- a/node/Switch.hpp
+++ b/node/Switch.hpp
@@ -68,12 +68,12 @@ public:
* Called when a packet is received from the real network
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
- * @param localAddr Local interface address
+ * @param localSocket Local I/O socket as supplied by external code
* @param fromAddr Internet IP address of origin
* @param data Packet data
* @param len Packet length
*/
- void onRemotePacket(void *tPtr,const InetAddress &localAddr,const InetAddress &fromAddr,const void *data,unsigned int len);
+ void onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddress &fromAddr,const void *data,unsigned int len);
/**
* Called when a packet comes from a local Ethernet tap
diff --git a/node/Topology.cpp b/node/Topology.cpp
index 09a1a895..d4632f43 100644
--- a/node/Topology.cpp
+++ b/node/Topology.cpp
@@ -125,10 +125,11 @@ SharedPtr<Peer> Topology::getPeer(void *tPtr,const Address &zta)
return *ap;
}
+ /*
try {
char buf[ZT_PEER_MAX_SERIALIZED_STATE_SIZE];
uint64_t idbuf[2]; idbuf[0] = zta.toInt(); idbuf[1] = 0;
- int len = RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_PEER_STATE,idbuf,buf,(unsigned int)sizeof(buf));
+ int len = RR->node->stateObjectGet(tPtr,ZT_STATE_OBJECT_PEER,idbuf,buf,(unsigned int)sizeof(buf));
if (len > 0) {
Mutex::Lock _l(_peers_m);
SharedPtr<Peer> &ap = _peers[zta];
@@ -140,6 +141,7 @@ SharedPtr<Peer> Topology::getPeer(void *tPtr,const Address &zta)
return ap;
}
} catch ( ... ) {} // ignore invalid identities or other strage failures
+ */
return SharedPtr<Peer>();
}
diff --git a/node/Topology.hpp b/node/Topology.hpp
index 32e38dd3..5f3e2da1 100644
--- a/node/Topology.hpp
+++ b/node/Topology.hpp
@@ -110,11 +110,11 @@ public:
/**
* Get a Path object for a given local and remote physical address, creating if needed
*
- * @param l Local address or NULL for 'any' or 'wildcard'
+ * @param l Local socket
* @param r Remote address
* @return Pointer to canonicalized Path object
*/
- inline SharedPtr<Path> getPath(const InetAddress &l,const InetAddress &r)
+ inline SharedPtr<Path> getPath(const int64_t l,const InetAddress &r)
{
Mutex::Lock _l(_paths_m);
SharedPtr<Path> &p = _paths[Path::HashKey(l,r)];