More refactoring: rename RuntimeEnvironment to Context to be more descriptive and make it a reference instead of a raw pointer.

This commit is contained in:
Adam Ierymenko 2021-04-07 18:54:52 -04:00
parent c9dc715389
commit b40eba8fc7
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
32 changed files with 497 additions and 524 deletions

View file

@ -126,7 +126,7 @@ ZT_MAYBE_UNUSED enum ZT_ResultCode ZT_Node_processWirePacket(
try {
ZeroTier::CallContext cc(clock, ticks, tptr);
ZeroTier::SharedPtr< ZeroTier::Buf > buf((isZtBuffer) ? ZT_PTRTOBUF(packetData) : new ZeroTier::Buf(packetData, packetLength & ZT_BUF_MEM_MASK));
reinterpret_cast<ZeroTier::Node *>(node)->RR->vl1->onRemotePacket(cc, localSocket, *ZeroTier::asInetAddress(remoteAddress), buf, packetLength);
reinterpret_cast<ZeroTier::Node *>(node)->context().vl1->onRemotePacket(cc, localSocket, *ZeroTier::asInetAddress(remoteAddress), buf, packetLength);
} catch (std::bad_alloc &exc) {
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
} catch (...) {
@ -153,10 +153,11 @@ ZT_MAYBE_UNUSED enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
{
try {
ZeroTier::CallContext cc(clock, ticks, tptr);
ZeroTier::SharedPtr< ZeroTier::Network > network(reinterpret_cast<ZeroTier::Node *>(node)->RR->networks->get(nwid));
const ZeroTier::Context &ctx = reinterpret_cast<ZeroTier::Node *>(node)->context();
ZeroTier::SharedPtr< ZeroTier::Network > network(ctx.networks->get(nwid));
if (likely(network)) {
ZeroTier::SharedPtr< ZeroTier::Buf > buf((isZtBuffer) ? ZT_PTRTOBUF(frameData) : new ZeroTier::Buf(frameData, frameLength & ZT_BUF_MEM_MASK));
reinterpret_cast<ZeroTier::Node *>(node)->RR->vl2->onLocalEthernet(cc, network, ZeroTier::MAC(sourceMac), ZeroTier::MAC(destMac), etherType, vlanId, buf, frameLength);
ctx.vl2->onLocalEthernet(cc, network, ZeroTier::MAC(sourceMac), ZeroTier::MAC(destMac), etherType, vlanId, buf, frameLength);
return ZT_RESULT_OK;
} else {
return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
@ -261,7 +262,7 @@ ZT_MAYBE_UNUSED enum ZT_ResultCode ZT_Node_multicastUnsubscribe(
}
ZT_MAYBE_UNUSED uint64_t ZT_Node_address(ZT_Node *node)
{ return reinterpret_cast<ZeroTier::Node *>(node)->RR->identity.address().toInt(); }
{ return reinterpret_cast<ZeroTier::Node *>(node)->context().identity.address().toInt(); }
ZT_MAYBE_UNUSED const ZT_Identity *ZT_Node_identity(ZT_Node *node)
{ return (const ZT_Identity *)(&(reinterpret_cast<ZeroTier::Node *>(node)->identity())); }

View file

@ -14,6 +14,7 @@ set(core_headers
CallContext.hpp
CapabilityCredential.hpp
Certificate.hpp
Context.hpp
Defaults.hpp
MembershipCredential.hpp
OwnershipCredential.hpp
@ -44,7 +45,6 @@ set(core_headers
Peer.hpp
Poly1305.hpp
Protocol.hpp
RuntimeEnvironment.hpp
Salsa20.hpp
ScopedPtr.hpp
SelfAwareness.hpp

View file

@ -26,7 +26,7 @@
namespace ZeroTier {
class RuntimeEnvironment;
class Context;
/**
* A set of grouped and signed network flow rules for a specific member.
@ -132,8 +132,8 @@ public:
*
* @param RR Runtime environment to provide for peer lookup, etc.
*/
ZT_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR, CallContext &cc) const noexcept
{ return s_verify(RR, cc, *this); }
ZT_INLINE Credential::VerifyResult verify(const Context &ctx, const CallContext &cc) const noexcept
{ return s_verify(ctx, cc, *this); }
static constexpr int marshalSizeMax() noexcept
{ return ZT_CAPABILITY_MARSHAL_SIZE_MAX; }

View file

@ -36,21 +36,18 @@ class Store;
class Network;
/**
* ZeroTier::Node execution context
*
* This just holds pointers and various other information used by all the
* various moving parts of a node. It's stored or passed as 'RR' to give it
* a common name througout the code.
* Node instance context
*/
class RuntimeEnvironment
class Context
{
public:
ZT_INLINE RuntimeEnvironment(Node *const n) noexcept:
ZT_INLINE Context(Node *const n) noexcept:
instanceId(Utils::getSecureRandomU64()),
node(n),
uPtr(nullptr),
localNetworkController(nullptr),
store(nullptr),
networks(nullptr),
t(nullptr),
expect(nullptr),
vl2(nullptr),
@ -63,7 +60,7 @@ public:
secretIdentityStr[0] = 0;
}
ZT_INLINE ~RuntimeEnvironment() noexcept
ZT_INLINE ~Context() noexcept
{
Utils::burn(secretIdentityStr, sizeof(secretIdentityStr));
}
@ -72,26 +69,26 @@ public:
const uint64_t instanceId;
// Node instance that owns this RuntimeEnvironment
Node *const node;
Node *const restrict node;
// Callbacks specified by caller who created node
ZT_Node_Callbacks cb;
// User pointer specified by external code via API
void *uPtr;
void *restrict uPtr;
// This is set externally to an instance of this base class
NetworkController *localNetworkController;
NetworkController *restrict localNetworkController;
Store *store;
TinyMap< SharedPtr< Network > > *networks;
Trace *t;
Expect *expect;
VL2 *vl2;
VL1 *vl1;
Topology *topology;
SelfAwareness *sa;
TrustStore *ts;
Store *restrict store;
TinyMap< SharedPtr< Network > > *restrict networks;
Trace *restrict t;
Expect *restrict expect;
VL2 *restrict vl2;
VL1 *restrict vl1;
Topology *restrict topology;
SelfAwareness *restrict sa;
TrustStore *restrict ts;
// This node's identity and string representations thereof
Identity identity;

View file

@ -12,7 +12,7 @@
/****/
#include "Constants.hpp"
#include "RuntimeEnvironment.hpp"
#include "Context.hpp"
#include "Credential.hpp"
#include "CapabilityCredential.hpp"
#include "TagCredential.hpp"
@ -43,7 +43,7 @@
namespace ZeroTier {
template< typename CRED >
static ZT_INLINE Credential::VerifyResult p_credVerify(const RuntimeEnvironment *RR, CallContext &cc, CRED credential)
static ZT_INLINE Credential::VerifyResult p_credVerify(const Context &ctx, const CallContext &cc, CRED credential)
{
uint8_t tmp[ZT_BUF_MEM_SIZE + 16];
@ -52,7 +52,7 @@ static ZT_INLINE Credential::VerifyResult p_credVerify(const RuntimeEnvironment
if ((!signedBy) || (signedBy != Network::controllerFor(networkId)))
return Credential::VERIFY_BAD_SIGNATURE;
const SharedPtr< Peer > peer(RR->topology->peer(cc, signedBy));
const SharedPtr< Peer > peer(ctx.topology->peer(cc, signedBy));
if (!peer)
return Credential::VERIFY_NEED_IDENTITY;
@ -66,26 +66,26 @@ static ZT_INLINE Credential::VerifyResult p_credVerify(const RuntimeEnvironment
return Credential::VERIFY_BAD_SIGNATURE;
}
Credential::VerifyResult Credential::s_verify(const RuntimeEnvironment *RR, CallContext &cc, const RevocationCredential &credential)
{ return p_credVerify(RR, cc, credential); }
Credential::VerifyResult Credential::s_verify(const Context &ctx, const CallContext &cc, const RevocationCredential &credential)
{ return p_credVerify(ctx, cc, credential); }
Credential::VerifyResult Credential::s_verify(const RuntimeEnvironment *RR, CallContext &cc, const TagCredential &credential)
{ return p_credVerify(RR, cc, credential); }
Credential::VerifyResult Credential::s_verify(const Context &ctx, const CallContext &cc, const TagCredential &credential)
{ return p_credVerify(ctx, cc, credential); }
Credential::VerifyResult Credential::s_verify(const RuntimeEnvironment *RR, CallContext &cc, const CapabilityCredential &credential)
{ return p_credVerify(RR, cc, credential); }
Credential::VerifyResult Credential::s_verify(const Context &ctx, const CallContext &cc, const CapabilityCredential &credential)
{ return p_credVerify(ctx, cc, credential); }
Credential::VerifyResult Credential::s_verify(const RuntimeEnvironment *RR, CallContext &cc, const OwnershipCredential &credential)
{ return p_credVerify(RR, cc, credential); }
Credential::VerifyResult Credential::s_verify(const Context &ctx, const CallContext &cc, const OwnershipCredential &credential)
{ return p_credVerify(ctx, cc, credential); }
Credential::VerifyResult Credential::s_verify(const RuntimeEnvironment *RR, CallContext &cc, const MembershipCredential &credential)
Credential::VerifyResult Credential::s_verify(const Context &ctx, const CallContext &cc, const MembershipCredential &credential)
{
// Sanity check network ID.
if ((!credential.m_signedBy) || (credential.m_signedBy != Network::controllerFor(credential.m_networkId)))
return Credential::VERIFY_BAD_SIGNATURE;
// If we don't know the peer, get its identity. This shouldn't happen here but should be handled.
const SharedPtr< Peer > peer(RR->topology->peer(cc, credential.m_signedBy));
const SharedPtr< Peer > peer(ctx.topology->peer(cc, credential.m_signedBy));
if (!peer)
return Credential::VERIFY_NEED_IDENTITY;

View file

@ -29,7 +29,7 @@ class RevocationCredential;
class TagCredential;
class MembershipCredential;
class OwnershipCredential;
class RuntimeEnvironment;
class Context;
/**
* Base class for credentials
@ -53,11 +53,11 @@ public:
};
protected:
static VerifyResult s_verify(const RuntimeEnvironment *RR, CallContext &cc, const MembershipCredential &credential);
static VerifyResult s_verify(const RuntimeEnvironment *RR, CallContext &cc, const RevocationCredential &credential);
static VerifyResult s_verify(const RuntimeEnvironment *RR, CallContext &cc, const TagCredential &credential);
static VerifyResult s_verify(const RuntimeEnvironment *RR, CallContext &cc, const OwnershipCredential &credential);
static VerifyResult s_verify(const RuntimeEnvironment *RR, CallContext &cc, const CapabilityCredential &credential);
static VerifyResult s_verify(const Context &ctx, const CallContext &cc, const MembershipCredential &credential);
static VerifyResult s_verify(const Context &ctx, const CallContext &cc, const RevocationCredential &credential);
static VerifyResult s_verify(const Context &ctx, const CallContext &cc, const TagCredential &credential);
static VerifyResult s_verify(const Context &ctx, const CallContext &cc, const OwnershipCredential &credential);
static VerifyResult s_verify(const Context &ctx, const CallContext &cc, const CapabilityCredential &credential);
};
} // namespace ZeroTier

View file

@ -14,7 +14,7 @@
#include <algorithm>
#include "Member.hpp"
#include "RuntimeEnvironment.hpp"
#include "Context.hpp"
#include "Peer.hpp"
#include "Topology.hpp"
@ -28,7 +28,7 @@ Member::Member() :
{
}
void Member::pushCredentials(const RuntimeEnvironment *RR, CallContext &cc, const SharedPtr< Peer > &to, const NetworkConfig &nconf)
void Member::pushCredentials(const Context &ctx, const CallContext &cc, const SharedPtr< Peer > &to, const NetworkConfig &nconf)
{
if (!nconf.com) // sanity check
return;
@ -122,31 +122,36 @@ void Member::clean(const NetworkConfig &nconf)
m_cleanCredImpl< OwnershipCredential >(nconf, m_remoteCoos);
}
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const MembershipCredential &com)
Member::AddCredentialResult Member::addCredential(
const Context &ctx,
const CallContext &cc,
const Identity &sourcePeerIdentity,
const NetworkConfig &nconf,
const MembershipCredential &com)
{
const int64_t newts = com.timestamp();
if (newts <= m_comRevocationThreshold) {
RR->t->credentialRejected(cc, 0xd9992121, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
ctx.t->credentialRejected(cc, 0xd9992121, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
return ADD_REJECTED;
}
const int64_t oldts = m_com.timestamp();
if (newts < oldts) {
RR->t->credentialRejected(cc, 0xd9928192, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
ctx.t->credentialRejected(cc, 0xd9928192, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
return ADD_REJECTED;
}
if ((newts == oldts) && (m_com == com))
return ADD_ACCEPTED_REDUNDANT;
switch (com.verify(RR, cc)) {
switch (com.verify(ctx, cc)) {
default:
RR->t->credentialRejected(cc, 0x0f198241, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
ctx.t->credentialRejected(cc, 0x0f198241, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
return Member::ADD_REJECTED;
case Credential::VERIFY_OK:
m_com = com;
return ADD_ACCEPTED_NEW;
case Credential::VERIFY_BAD_SIGNATURE:
RR->t->credentialRejected(cc, 0xbaf0aaaa, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_SIGNATURE_VERIFICATION_FAILED);
ctx.t->credentialRejected(cc, 0xbaf0aaaa, com.networkId(), sourcePeerIdentity, com.id(), com.timestamp(), ZT_CREDENTIAL_TYPE_COM, ZT_TRACE_CREDENTIAL_REJECTION_REASON_SIGNATURE_VERIFICATION_FAILED);
return ADD_REJECTED;
case Credential::VERIFY_NEED_IDENTITY:
return ADD_DEFERRED_FOR_WHOIS;
@ -158,8 +163,8 @@ template< typename C >
static ZT_INLINE Member::AddCredentialResult _addCredImpl(
Map< uint32_t, C > &remoteCreds,
const Map< uint64_t, int64_t > &revocations,
const RuntimeEnvironment *const RR,
CallContext &cc,
const Context &ctx,
const CallContext &cc,
const Identity &sourcePeerIdentity,
const NetworkConfig &nconf,
const C &cred)
@ -167,7 +172,7 @@ static ZT_INLINE Member::AddCredentialResult _addCredImpl(
typename Map< uint32_t, C >::const_iterator rc(remoteCreds.find(cred.id()));
if (rc != remoteCreds.end()) {
if (rc->second.revision() > cred.revision()) {
RR->t->credentialRejected(cc, 0x40000001, nconf.networkId, sourcePeerIdentity, cred.id(), cred.revision(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
ctx.t->credentialRejected(cc, 0x40000001, nconf.networkId, sourcePeerIdentity, cred.id(), cred.revision(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
return Member::ADD_REJECTED;
}
if (rc->second == cred)
@ -176,13 +181,13 @@ static ZT_INLINE Member::AddCredentialResult _addCredImpl(
typename Map< uint64_t, int64_t >::const_iterator rt(revocations.find(Member::credentialKey(C::credentialType(), cred.id())));
if ((rt != revocations.end()) && (rt->second >= cred.revision())) {
RR->t->credentialRejected(cc, 0x24248124, nconf.networkId, sourcePeerIdentity, cred.id(), cred.revision(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
ctx.t->credentialRejected(cc, 0x24248124, nconf.networkId, sourcePeerIdentity, cred.id(), cred.revision(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
return Member::ADD_REJECTED;
}
switch (cred.verify(RR, cc)) {
switch (cred.verify(ctx, cc)) {
default:
RR->t->credentialRejected(cc, 0x01feba012, nconf.networkId, sourcePeerIdentity, cred.id(), cred.revision(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
ctx.t->credentialRejected(cc, 0x01feba012, nconf.networkId, sourcePeerIdentity, cred.id(), cred.revision(), C::credentialType(), ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
return Member::ADD_REJECTED;
case 0:
if (rc == remoteCreds.end())
@ -193,21 +198,21 @@ static ZT_INLINE Member::AddCredentialResult _addCredImpl(
}
}
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const TagCredential &tag)
{ return _addCredImpl< TagCredential >(m_remoteTags, m_revocations, RR, cc, sourcePeerIdentity, nconf, tag); }
Member::AddCredentialResult Member::addCredential(const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const TagCredential &tag)
{ return _addCredImpl< TagCredential >(m_remoteTags, m_revocations, ctx, cc, sourcePeerIdentity, nconf, tag); }
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const CapabilityCredential &cap)
{ return _addCredImpl< CapabilityCredential >(m_remoteCaps, m_revocations, RR, cc, sourcePeerIdentity, nconf, cap); }
Member::AddCredentialResult Member::addCredential(const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const CapabilityCredential &cap)
{ return _addCredImpl< CapabilityCredential >(m_remoteCaps, m_revocations, ctx, cc, sourcePeerIdentity, nconf, cap); }
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const OwnershipCredential &coo)
{ return _addCredImpl< OwnershipCredential >(m_remoteCoos, m_revocations, RR, cc, sourcePeerIdentity, nconf, coo); }
Member::AddCredentialResult Member::addCredential(const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const OwnershipCredential &coo)
{ return _addCredImpl< OwnershipCredential >(m_remoteCoos, m_revocations, ctx, cc, sourcePeerIdentity, nconf, coo); }
Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const RevocationCredential &rev)
Member::AddCredentialResult Member::addCredential(const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const RevocationCredential &rev)
{
int64_t *rt;
switch (rev.verify(RR, cc)) {
switch (rev.verify(ctx, cc)) {
default:
RR->t->credentialRejected(cc, 0x938fffff, nconf.networkId, sourcePeerIdentity, rev.id(), 0, ZT_CREDENTIAL_TYPE_REVOCATION, ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
ctx.t->credentialRejected(cc, 0x938ff009, nconf.networkId, sourcePeerIdentity, rev.id(), 0, ZT_CREDENTIAL_TYPE_REVOCATION, ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
return ADD_REJECTED;
case 0: {
const ZT_CredentialType ct = rev.typeBeingRevoked();
@ -229,7 +234,7 @@ Member::AddCredentialResult Member::addCredential(const RuntimeEnvironment *RR,
}
return ADD_ACCEPTED_REDUNDANT;
default:
RR->t->credentialRejected(cc, 0x0bbbb1a4, nconf.networkId, sourcePeerIdentity, rev.id(), 0, ZT_CREDENTIAL_TYPE_REVOCATION, ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
ctx.t->credentialRejected(cc, 0x0bbbb1a4, nconf.networkId, sourcePeerIdentity, rev.id(), 0, ZT_CREDENTIAL_TYPE_REVOCATION, ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
return ADD_REJECTED;
}
}

View file

@ -25,7 +25,7 @@
namespace ZeroTier {
class RuntimeEnvironment;
class Context;
class Network;
@ -55,7 +55,7 @@ public:
* @param to Peer identity
* @param nconf My network config
*/
void pushCredentials(const RuntimeEnvironment *RR, CallContext &cc, const SharedPtr< Peer > &to, const NetworkConfig &nconf);
void pushCredentials(const Context &ctx, const CallContext &cc, const SharedPtr< Peer > &to, const NetworkConfig &nconf);
/**
* @return Time we last pushed credentials to this member
@ -145,11 +145,11 @@ public:
return false;
}
AddCredentialResult addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const MembershipCredential &com);
AddCredentialResult addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const TagCredential &tag);
AddCredentialResult addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const CapabilityCredential &cap);
AddCredentialResult addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const OwnershipCredential &coo);
AddCredentialResult addCredential(const RuntimeEnvironment *RR, CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const RevocationCredential &rev);
AddCredentialResult addCredential(const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const MembershipCredential &com);
AddCredentialResult addCredential(const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const TagCredential &tag);
AddCredentialResult addCredential(const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const CapabilityCredential &cap);
AddCredentialResult addCredential(const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const OwnershipCredential &coo);
AddCredentialResult addCredential(const Context &ctx, const CallContext &cc, const Identity &sourcePeerIdentity, const NetworkConfig &nconf, const RevocationCredential &rev);
private:
// This returns true if a resource is an IPv6 NDP-emulated address. These embed the ZT

View file

@ -34,7 +34,7 @@
namespace ZeroTier {
class RuntimeEnvironment;
class Context;
/**
* Certificate of network membership
@ -180,7 +180,7 @@ public:
* @param RR Runtime environment for looking up peers
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
*/
ZT_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR, CallContext &cc) const { return s_verify(RR, cc, *this); }
ZT_INLINE Credential::VerifyResult verify(const Context &ctx, const CallContext &cc) const { return s_verify(ctx, cc, *this); }
// NOTE: right now we use v1 serialization format which works with both ZeroTier 1.x and 2.x. V2 format
// will be switched on once 1.x is pretty much dead and out of support.

View file

@ -16,7 +16,7 @@
#include "Constants.hpp"
#include "Network.hpp"
#include "RuntimeEnvironment.hpp"
#include "Context.hpp"
#include "MAC.hpp"
#include "Address.hpp"
#include "InetAddress.hpp"
@ -70,8 +70,8 @@ enum _doZtFilterResult
DOZTFILTER_SUPER_ACCEPT
};
_doZtFilterResult _doZtFilter(
const RuntimeEnvironment *RR,
ZT_INLINE _doZtFilterResult _doZtFilter(
const Context &ctx,
Trace::RuleResultLog &rrl,
const NetworkConfig &nconf,
const Member *membership, // can be NULL
@ -124,7 +124,7 @@ _doZtFilterResult _doZtFilter(
const Address fwdAddr(rules[rn].v.fwd.address);
if (fwdAddr == ztSource) {
// Skip as no-op since source is target
} else if (fwdAddr == RR->identity.address()) {
} else if (fwdAddr == ctx.identity.address()) {
if (inbound) {
return DOZTFILTER_SUPER_ACCEPT;
} else {
@ -159,7 +159,7 @@ _doZtFilterResult _doZtFilter(
case ZT_NETWORK_RULE_ACTION_TEE:
case ZT_NETWORK_RULE_ACTION_WATCH:
case ZT_NETWORK_RULE_ACTION_REDIRECT:
if (RR->identity.address().toInt() == rules[rn].v.fwd.address)
if (ctx.identity.address().toInt() == rules[rn].v.fwd.address)
superAccept = true;
break;
default:
@ -538,11 +538,11 @@ _doZtFilterResult _doZtFilter(
const ZeroTier::MulticastGroup Network::BROADCAST(ZeroTier::MAC(0xffffffffffffULL), 0);
Network::Network(const RuntimeEnvironment *renv, CallContext &cc, uint64_t nwid, const Fingerprint &controllerFingerprint, void *uptr, const NetworkConfig *nconf) :
RR(renv),
Network::Network(const Context &ctx, const CallContext &cc, uint64_t nwid, const Fingerprint &controllerFingerprint, void *uptr, const NetworkConfig *nconf) :
m_ctx(ctx),
m_uPtr(uptr),
m_id(nwid),
m_mac(renv->identity.address(), nwid),
m_mac(ctx.identity.address(), nwid),
m_portInitialized(false),
m_destroyed(false),
m_lastConfigUpdate(0),
@ -562,7 +562,7 @@ Network::Network(const RuntimeEnvironment *renv, CallContext &cc, uint64_t nwid,
bool got = false;
try {
Dictionary dict;
Vector< uint8_t > nconfData(RR->store->get(cc, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, 1));
Vector< uint8_t > nconfData(m_ctx.store->get(cc, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, 1));
if (nconfData.size() > 2) {
nconfData.push_back(0);
if (dict.decode(nconfData.data(), (unsigned int)nconfData.size())) {
@ -579,13 +579,13 @@ Network::Network(const RuntimeEnvironment *renv, CallContext &cc, uint64_t nwid,
} catch (...) {}
if (!got)
RR->store->put(cc, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, 1, "\n", 1);
m_ctx.store->put(cc, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, 1, "\n", 1);
}
if (!m_portInitialized) {
ZT_VirtualNetworkConfig ctmp;
m_externalConfig(&ctmp);
RR->cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, cc.tPtr, m_id, &m_uPtr, ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP, &ctmp);
m_ctx.cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(m_ctx.node), m_ctx.uPtr, cc.tPtr, m_id, &m_uPtr, ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP, &ctmp);
m_portInitialized = true;
}
}
@ -602,14 +602,14 @@ Network::~Network()
if (m_destroyed) {
// This is done in Node::leave() so we can pass tPtr properly
//RR->node->configureVirtualNetworkPort((void *)0,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp);
//m_ctx.node->configureVirtualNetworkPort((void *)0,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp);
} else {
RR->cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, nullptr, m_id, &m_uPtr, ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN, &ctmp);
m_ctx.cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(m_ctx.node), m_ctx.uPtr, nullptr, m_id, &m_uPtr, ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN, &ctmp);
}
}
bool Network::filterOutgoingPacket(
CallContext &cc,
const CallContext &cc,
const bool noTee,
const Address &ztSource,
const Address &ztDest,
@ -640,7 +640,7 @@ bool Network::filterOutgoingPacket(
membership = nullptr;
}
switch (_doZtFilter(RR, rrl, m_config, membership, false, ztSource, ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, m_config.rules, m_config.ruleCount, ccNodeAddress, ccLength, ccWatch, qosBucket)) {
switch (_doZtFilter(m_ctx, rrl, m_config, membership, false, ztSource, ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, m_config.rules, m_config.ruleCount, ccNodeAddress, ccLength, ccWatch, qosBucket)) {
case DOZTFILTER_NO_MATCH: {
for (unsigned int c = 0; c < m_config.capabilityCount; ++c) {
@ -648,7 +648,7 @@ bool Network::filterOutgoingPacket(
Address cc2;
unsigned int ccLength2 = 0;
bool ccWatch2 = false;
switch (_doZtFilter(RR, crrl, m_config, membership, false, ztSource, ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, m_config.capabilities[c].rules(), m_config.capabilities[c].ruleCount(), cc2, ccLength2, ccWatch2, qosBucket)) {
switch (_doZtFilter(m_ctx, crrl, m_config, membership, false, ztSource, ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, m_config.capabilities[c].rules(), m_config.capabilities[c].ruleCount(), cc2, ccLength2, ccWatch2, qosBucket)) {
case DOZTFILTER_NO_MATCH:
case DOZTFILTER_DROP: // explicit DROP in a capability just terminates its evaluation and is an anti-pattern
break;
@ -662,7 +662,7 @@ bool Network::filterOutgoingPacket(
if ((!noTee) && (cc2)) {
// TODO
/*
Packet outp(cc2,RR->identity.address(),Packet::VERB_EXT_FRAME);
Packet outp(cc2,m_ctx.identity.address(),Packet::VERB_EXT_FRAME);
outp.append(_id);
outp.append((uint8_t)(ccWatch2 ? 0x16 : 0x02));
macDest.appendTo(outp);
@ -670,7 +670,7 @@ bool Network::filterOutgoingPacket(
outp.append((uint16_t)etherType);
outp.append(frameData,ccLength2);
outp.compress();
RR->sw->send(tPtr,outp,true);
m_ctx.sw->send(tPtr,outp,true);
*/
}
@ -683,7 +683,7 @@ bool Network::filterOutgoingPacket(
break;
case DOZTFILTER_DROP:
RR->t->networkFilter(cc, 0xadea5a2a, m_id, rrl.l, nullptr, 0, 0, ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, 0);
m_ctx.t->networkFilter(cc, 0xadea5a2a, m_id, rrl.l, nullptr, 0, 0, ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, 0);
return false;
case DOZTFILTER_REDIRECT: // interpreted as ACCEPT but ztFinalDest will have been changed in _doZtFilter()
@ -700,7 +700,7 @@ bool Network::filterOutgoingPacket(
if ((!noTee) && (ccNodeAddress)) {
// TODO
/*
Packet outp(cc,RR->identity.address(),Packet::VERB_EXT_FRAME);
Packet outp(cc,m_ctx.identity.address(),Packet::VERB_EXT_FRAME);
outp.append(_id);
outp.append((uint8_t)(ccWatch ? 0x16 : 0x02));
macDest.appendTo(outp);
@ -708,14 +708,14 @@ bool Network::filterOutgoingPacket(
outp.append((uint16_t)etherType);
outp.append(frameData,ccLength);
outp.compress();
RR->sw->send(tPtr,outp,true);
m_ctx.sw->send(tPtr,outp,true);
*/
}
if ((ztDest != ztFinalDest) && (ztFinalDest)) {
// TODO
/*
Packet outp(ztFinalDest,RR->identity.address(),Packet::VERB_EXT_FRAME);
Packet outp(ztFinalDest,m_ctx.identity.address(),Packet::VERB_EXT_FRAME);
outp.append(_id);
outp.append((uint8_t)0x04);
macDest.appendTo(outp);
@ -723,7 +723,7 @@ bool Network::filterOutgoingPacket(
outp.append((uint16_t)etherType);
outp.append(frameData,frameLen);
outp.compress();
RR->sw->send(tPtr,outp,true);
m_ctx.sw->send(tPtr,outp,true);
*/
// DROP locally since we redirected
@ -733,16 +733,16 @@ bool Network::filterOutgoingPacket(
if (localCapabilityIndex >= 0) {
const CapabilityCredential &cap = m_config.capabilities[localCapabilityIndex];
RR->t->networkFilter(cc, 0x56ff1a93, m_id, rrl.l, crrl.l, cap.id(), cap.timestamp(), ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, accept);
m_ctx.t->networkFilter(cc, 0x56ff1a93, m_id, rrl.l, crrl.l, cap.id(), cap.timestamp(), ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, accept);
} else {
RR->t->networkFilter(cc, 0x112fbbab, m_id, rrl.l, nullptr, 0, 0, ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, accept);
m_ctx.t->networkFilter(cc, 0x112fbbab, m_id, rrl.l, nullptr, 0, 0, ztSource, ztDest, macSource, macDest, (uint16_t)frameLen, frameData, (uint16_t)etherType, (uint16_t)vlanId, noTee, false, accept);
}
return (accept != 0);
}
int Network::filterIncomingPacket(
CallContext &cc,
const CallContext &cc,
const SharedPtr< Peer > &sourcePeer,
const Address &ztDest,
const MAC &macSource,
@ -767,7 +767,7 @@ int Network::filterIncomingPacket(
Member &membership = m_memberships[sourcePeer->address()];
switch (_doZtFilter(RR, rrl, m_config, &membership, true, sourcePeer->address(), ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, m_config.rules, m_config.ruleCount, ccNodeAddress, ccLength, ccWatch, qosBucket)) {
switch (_doZtFilter(m_ctx, rrl, m_config, &membership, true, sourcePeer->address(), ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, m_config.rules, m_config.ruleCount, ccNodeAddress, ccLength, ccWatch, qosBucket)) {
case DOZTFILTER_NO_MATCH: {
Member::CapabilityIterator mci(membership, m_config);
@ -776,7 +776,7 @@ int Network::filterIncomingPacket(
Address cc2;
unsigned int ccLength2 = 0;
bool ccWatch2 = false;
switch (_doZtFilter(RR, crrl, m_config, &membership, true, sourcePeer->address(), ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, c->rules(), c->ruleCount(), cc2, ccLength2, ccWatch2, qosBucket)) {
switch (_doZtFilter(m_ctx, crrl, m_config, &membership, true, sourcePeer->address(), ztFinalDest, macSource, macDest, frameData, frameLen, etherType, vlanId, c->rules(), c->ruleCount(), cc2, ccLength2, ccWatch2, qosBucket)) {
case DOZTFILTER_NO_MATCH:
case DOZTFILTER_DROP: // explicit DROP in a capability just terminates its evaluation and is an anti-pattern
break;
@ -793,7 +793,7 @@ int Network::filterIncomingPacket(
if (cc2) {
// TODO
/*
Packet outp(cc2,RR->identity.address(),Packet::VERB_EXT_FRAME);
Packet outp(cc2,m_ctx.identity.address(),Packet::VERB_EXT_FRAME);
outp.append(_id);
outp.append((uint8_t)(ccWatch2 ? 0x1c : 0x08));
macDest.appendTo(outp);
@ -801,7 +801,7 @@ int Network::filterIncomingPacket(
outp.append((uint16_t)etherType);
outp.append(frameData,ccLength2);
outp.compress();
RR->sw->send(tPtr,outp,true);
m_ctx.sw->send(tPtr,outp,true);
*/
}
break;
@ -812,7 +812,7 @@ int Network::filterIncomingPacket(
case DOZTFILTER_DROP:
//if (_config.remoteTraceTarget)
// RR->t->networkFilter(tPtr,*this,rrl,(Trace::RuleResultLog *)0,(Capability *)0,sourcePeer->address(),ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,false,true,0);
// m_ctx.t->networkFilter(tPtr,*this,rrl,(Trace::RuleResultLog *)0,(Capability *)0,sourcePeer->address(),ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,false,true,0);
return 0; // DROP
case DOZTFILTER_REDIRECT: // interpreted as ACCEPT but ztFinalDest will have been changed in _doZtFilter()
@ -828,7 +828,7 @@ int Network::filterIncomingPacket(
if (ccNodeAddress) {
// TODO
/*
Packet outp(cc,RR->identity.address(),Packet::VERB_EXT_FRAME);
Packet outp(cc,m_ctx.identity.address(),Packet::VERB_EXT_FRAME);
outp.append(_id);
outp.append((uint8_t)(ccWatch ? 0x1c : 0x08));
macDest.appendTo(outp);
@ -836,14 +836,14 @@ int Network::filterIncomingPacket(
outp.append((uint16_t)etherType);
outp.append(frameData,ccLength);
outp.compress();
RR->sw->send(tPtr,outp,true);
m_ctx.sw->send(tPtr,outp,true);
*/
}
if ((ztDest != ztFinalDest) && (ztFinalDest)) {
// TODO
/*
Packet outp(ztFinalDest,RR->identity.address(),Packet::VERB_EXT_FRAME);
Packet outp(ztFinalDest,m_ctx.identity.address(),Packet::VERB_EXT_FRAME);
outp.append(_id);
outp.append((uint8_t)0x0a);
macDest.appendTo(outp);
@ -851,21 +851,21 @@ int Network::filterIncomingPacket(
outp.append((uint16_t)etherType);
outp.append(frameData,frameLen);
outp.compress();
RR->sw->send(tPtr,outp,true);
m_ctx.sw->send(tPtr,outp,true);
*/
//if (_config.remoteTraceTarget)
// RR->t->networkFilter(tPtr,*this,rrl,(c) ? &crrl : (Trace::RuleResultLog *)0,c,sourcePeer->address(),ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,false,true,0);
// m_ctx.t->networkFilter(tPtr,*this,rrl,(c) ? &crrl : (Trace::RuleResultLog *)0,c,sourcePeer->address(),ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,false,true,0);
return 0; // DROP locally, since we redirected
}
}
//if (_config.remoteTraceTarget)
// RR->t->networkFilter(tPtr,*this,rrl,(c) ? &crrl : (Trace::RuleResultLog *)0,c,sourcePeer->address(),ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,false,true,accept);
// m_ctx.t->networkFilter(tPtr,*this,rrl,(c) ? &crrl : (Trace::RuleResultLog *)0,c,sourcePeer->address(),ztDest,macSource,macDest,frameData,frameLen,etherType,vlanId,false,true,accept);
return accept;
}
void Network::multicastSubscribe(CallContext &cc, const MulticastGroup &mg)
void Network::multicastSubscribe(const CallContext &cc, const MulticastGroup &mg)
{
Mutex::Lock l(m_myMulticastGroups_l);
if (!std::binary_search(m_myMulticastGroups.begin(), m_myMulticastGroups.end(), mg)) {
@ -883,7 +883,7 @@ void Network::multicastUnsubscribe(const MulticastGroup &mg)
m_myMulticastGroups.erase(i);
}
uint64_t Network::handleConfigChunk(CallContext &cc, uint64_t packetId, const SharedPtr< Peer > &source, const Buf &chunk, int ptr, int size)
uint64_t Network::handleConfigChunk(const CallContext &cc, uint64_t packetId, const SharedPtr< Peer > &source, const Buf &chunk, int ptr, int size)
{
// If the controller's full fingerprint is known or was explicitly specified on join(),
// require that the controller's identity match. Otherwise learn it.
@ -940,7 +940,7 @@ uint64_t Network::handleConfigChunk(CallContext &cc, uint64_t packetId, const Sh
return 0;
// Verify this chunk's signature
const SharedPtr<Peer> controllerPeer(RR->topology->get(tPtr,controller()));
const SharedPtr<Peer> controllerPeer(m_ctx.topology->get(tPtr,controller()));
if ((!controllerPeer)||(!controllerPeer->identity().verify(chunk.data.bytes + chunkPayloadStart,chunkPayloadSize,signature,signatureSize)))
return 0;
@ -957,7 +957,7 @@ uint64_t Network::handleConfigChunk(CallContext &cc, uint64_t packetId, const Sh
outp->data.fields.packetId = Protocol::getPacketId();
a->copyTo(outp->data.fields.destination);
RR->identity.address().copyTo(outp->data.fields.source);
m_ctx.identity.address().copyTo(outp->data.fields.source);
outp->data.fields.flags = 0;
outp->data.fields.verb = Protocol::VERB_NETWORK_CONFIG;
@ -967,7 +967,7 @@ uint64_t Network::handleConfigChunk(CallContext &cc, uint64_t packetId, const Sh
if (Buf<>::writeOverflow(outl)) // sanity check... it fit before!
break;
RR->sw->send(tPtr,outp,true);
m_ctx.sw->send(tPtr,outp,true);
}
}
}
@ -1027,16 +1027,16 @@ uint64_t Network::handleConfigChunk(CallContext &cc, uint64_t packetId, const Sh
#endif
}
int Network::setConfiguration(CallContext &cc, const NetworkConfig &nconf, bool saveToDisk)
int Network::setConfiguration(const CallContext &cc, const NetworkConfig &nconf, bool saveToDisk)
{
if (m_destroyed)
return 0;
// _lock is NOT locked when this is called
try {
if ((nconf.issuedTo != RR->identity.address()) || (nconf.networkId != m_id))
if ((nconf.issuedTo != m_ctx.identity.address()) || (nconf.networkId != m_id))
return 0; // invalid config that is not for us or not for this network
if ((!Utils::allZero(nconf.issuedToFingerprintHash, ZT_FINGERPRINT_HASH_SIZE)) && (memcmp(nconf.issuedToFingerprintHash, RR->identity.fingerprint().hash, ZT_FINGERPRINT_HASH_SIZE) != 0))
if ((!Utils::allZero(nconf.issuedToFingerprintHash, ZT_FINGERPRINT_HASH_SIZE)) && (memcmp(nconf.issuedToFingerprintHash, m_ctx.identity.fingerprint().hash, ZT_FINGERPRINT_HASH_SIZE) != 0))
return 0; // full identity hash is present and does not match
if (m_config == nconf)
@ -1057,7 +1057,7 @@ int Network::setConfiguration(CallContext &cc, const NetworkConfig &nconf, bool
m_externalConfig(&ctmp);
}
RR->cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, cc.tPtr, nconf.networkId, &m_uPtr, (oldPortInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP, &ctmp);
m_ctx.cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(m_ctx.node), m_ctx.uPtr, cc.tPtr, nconf.networkId, &m_uPtr, (oldPortInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP, &ctmp);
if (saveToDisk) {
try {
@ -1068,7 +1068,7 @@ int Network::setConfiguration(CallContext &cc, const NetworkConfig &nconf, bool
tmp[1] = 0;
Vector< uint8_t > d2;
d.encode(d2);
RR->store->put(cc, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, 1, d2.data(), (unsigned int)d2.size());
m_ctx.store->put(cc, ZT_STATE_OBJECT_NETWORK_CONFIG, tmp, 1, d2.data(), (unsigned int)d2.size());
}
} catch (...) {}
}
@ -1162,7 +1162,7 @@ Member::AddCredentialResult Network::addCredential(CallContext &cc, const Identi
if (com.networkId() != m_id)
return Member::ADD_REJECTED;
Mutex::Lock _l(m_memberships_l);
return m_memberships[com.issuedTo().address].addCredential(RR, cc, sourcePeerIdentity, m_config, com);
return m_memberships[com.issuedTo().address].addCredential(m_ctx, cc, sourcePeerIdentity, m_config, com);
}
Member::AddCredentialResult Network::addCredential(CallContext &cc, const Identity &sourcePeerIdentity, const CapabilityCredential &cap)
@ -1170,7 +1170,7 @@ Member::AddCredentialResult Network::addCredential(CallContext &cc, const Identi
if (cap.networkId() != m_id)
return Member::ADD_REJECTED;
Mutex::Lock _l(m_memberships_l);
return m_memberships[cap.issuedTo()].addCredential(RR, cc, sourcePeerIdentity, m_config, cap);
return m_memberships[cap.issuedTo()].addCredential(m_ctx, cc, sourcePeerIdentity, m_config, cap);
}
Member::AddCredentialResult Network::addCredential(CallContext &cc, const Identity &sourcePeerIdentity, const TagCredential &tag)
@ -1178,7 +1178,7 @@ Member::AddCredentialResult Network::addCredential(CallContext &cc, const Identi
if (tag.networkId() != m_id)
return Member::ADD_REJECTED;
Mutex::Lock _l(m_memberships_l);
return m_memberships[tag.issuedTo()].addCredential(RR, cc, sourcePeerIdentity, m_config, tag);
return m_memberships[tag.issuedTo()].addCredential(m_ctx, cc, sourcePeerIdentity, m_config, tag);
}
Member::AddCredentialResult Network::addCredential(CallContext &cc, const Identity &sourcePeerIdentity, const RevocationCredential &rev)
@ -1189,7 +1189,7 @@ Member::AddCredentialResult Network::addCredential(CallContext &cc, const Identi
Mutex::Lock l1(m_memberships_l);
Member &m = m_memberships[rev.target()];
const Member::AddCredentialResult result = m.addCredential(RR, cc, sourcePeerIdentity, m_config, rev);
const Member::AddCredentialResult result = m.addCredential(m_ctx, cc, sourcePeerIdentity, m_config, rev);
if ((result == Member::ADD_ACCEPTED_NEW) && (rev.fastPropagate())) {
// TODO
@ -1199,14 +1199,14 @@ Member::AddCredentialResult Network::addCredential(CallContext &cc, const Identi
Hashtable<Address,Membership>::Iterator i(_memberships);
while (i.next(a,m)) {
if ((*a != sourcePeerIdentity.address())&&(*a != rev.signer())) {
Packet outp(*a,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS);
Packet outp(*a,m_ctx.identity.address(),Packet::VERB_NETWORK_CREDENTIALS);
outp.append((uint8_t)0x00); // no COM
outp.append((uint16_t)0); // no capabilities
outp.append((uint16_t)0); // no tags
outp.append((uint16_t)1); // one revocation!
rev.serialize(outp);
outp.append((uint16_t)0); // no certificates of ownership
RR->sw->send(tPtr,outp,true);
m_ctx.sw->send(tPtr,outp,true);
}
}
*/
@ -1220,7 +1220,7 @@ Member::AddCredentialResult Network::addCredential(CallContext &cc, const Identi
if (coo.networkId() != m_id)
return Member::ADD_REJECTED;
Mutex::Lock _l(m_memberships_l);
return m_memberships[coo.issuedTo()].addCredential(RR, cc, sourcePeerIdentity, m_config, coo);
return m_memberships[coo.issuedTo()].addCredential(m_ctx, cc, sourcePeerIdentity, m_config, coo);
}
void Network::pushCredentials(CallContext &cc, const SharedPtr< Peer > &to)
@ -1229,7 +1229,7 @@ void Network::pushCredentials(CallContext &cc, const SharedPtr< Peer > &to)
Mutex::Lock _l(m_memberships_l);
Member &m = m_memberships[to->address()];
if (((cc.ticks - m.lastPushedCredentials()) + 5000) >= tout)
m.pushCredentials(RR, cc, to, m_config);
m.pushCredentials(m_ctx, cc, to, m_config);
}
void Network::destroy()
@ -1247,7 +1247,7 @@ void Network::externalConfig(ZT_VirtualNetworkConfig *ec) const
m_externalConfig(ec);
}
void Network::m_requestConfiguration(CallContext &cc)
void Network::m_requestConfiguration(const CallContext &cc)
{
if (m_destroyed)
return;
@ -1263,13 +1263,13 @@ void Network::m_requestConfiguration(CallContext &cc)
nconf->timestamp = (cc.clock < 0) ? cc.ticks : cc.clock;
nconf->credentialTimeMaxDelta = ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MAX_MAX_DELTA;
nconf->revision = 1;
nconf->issuedTo = RR->identity.address();
nconf->issuedTo = m_ctx.identity.address();
nconf->flags = ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION;
nconf->mtu = ZT_DEFAULT_MTU;
nconf->multicastLimit = 0;
nconf->staticIpCount = 1;
nconf->ruleCount = 14;
nconf->staticIps[0] = InetAddress::makeIpv66plane(m_id, RR->identity.address().toInt());
nconf->staticIps[0] = InetAddress::makeIpv66plane(m_id, m_ctx.identity.address().toInt());
// Drop everything but IPv6
nconf->rules[0].t = (uint8_t)ZT_NETWORK_RULE_MATCH_ETHERTYPE | 0x80U; // NOT
@ -1324,7 +1324,7 @@ void Network::m_requestConfiguration(CallContext &cc)
}
} else if ((m_id & 0xffU) == 0x01) {
// ffAAaaaaaaaaaa01 -- where AA is the IPv4 /8 to use and aaaaaaaaaa is the anchor node for multicast gather and replication
const uint64_t myAddress = RR->identity.address().toInt();
const uint64_t myAddress = m_ctx.identity.address().toInt();
const uint64_t networkHub = (m_id >> 8U) & 0xffffffffffULL;
uint8_t ipv4[4];
@ -1342,7 +1342,7 @@ void Network::m_requestConfiguration(CallContext &cc)
nconf->timestamp = (cc.clock < 0) ? cc.ticks : cc.clock;
nconf->credentialTimeMaxDelta = ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MAX_MAX_DELTA;
nconf->revision = 1;
nconf->issuedTo = RR->identity.address();
nconf->issuedTo = m_ctx.identity.address();
nconf->flags = ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION;
nconf->mtu = ZT_DEFAULT_MTU;
nconf->multicastLimit = 1024;
@ -1396,11 +1396,11 @@ void Network::m_requestConfiguration(CallContext &cc)
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_FLAGS, (uint64_t)0);
rmd.add(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV, (uint64_t)ZT_RULES_ENGINE_REVISION);
RR->t->networkConfigRequestSent(cc, 0x335bb1a2, m_id);
m_ctx.t->networkConfigRequestSent(cc, 0x335bb1a2, m_id);
if (ctrl == RR->identity.address()) {
if (RR->localNetworkController) {
RR->localNetworkController->request(m_id, InetAddress(), 0xffffffffffffffffULL, RR->identity, rmd);
if (ctrl == m_ctx.identity.address()) {
if (m_ctx.localNetworkController) {
m_ctx.localNetworkController->request(m_id, InetAddress(), 0xffffffffffffffffULL, m_ctx.identity, rmd);
} else {
this->setNotFound();
}
@ -1409,7 +1409,7 @@ void Network::m_requestConfiguration(CallContext &cc)
// TODO
/*
Packet outp(ctrl,RR->identity.address(),Packet::VERB_NETWORK_CONFIG_REQUEST);
Packet outp(ctrl,m_ctx.identity.address(),Packet::VERB_NETWORK_CONFIG_REQUEST);
outp.append((uint64_t)_id);
const unsigned int rmdSize = rmd->sizeBytes();
outp.append((uint16_t)rmdSize);
@ -1421,8 +1421,8 @@ void Network::m_requestConfiguration(CallContext &cc)
outp.append((unsigned char)0,16);
}
outp.compress();
RR->node->expectReplyTo(outp.packetId());
RR->sw->send(tPtr,outp,true);
m_ctx.node->expectReplyTo(outp.packetId());
m_ctx.sw->send(tPtr,outp,true);
*/
}
@ -1456,7 +1456,7 @@ void Network::m_externalConfig(ZT_VirtualNetworkConfig *ec) const
if ((m_config.specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE) != 0)
ab.push_back(Address(m_config.specialists[i]));
}
ec->bridge = (std::find(ab.begin(), ab.end(), RR->identity.address()) != ab.end()) ? 1 : 0;
ec->bridge = (std::find(ab.begin(), ab.end(), m_ctx.identity.address()) != ab.end()) ? 1 : 0;
ec->broadcastEnabled = (m_config) ? (m_config.enableBroadcast() ? 1 : 0) : 0;
ec->netconfRevision = (m_config) ? (unsigned long)m_config.revision : 0;
@ -1507,13 +1507,13 @@ void Network::m_announceMulticastGroupsTo(void *tPtr, const Address &peer, const
{
#if 0
// Assumes _myMulticastGroups_l and _memberships_l are locked
ScopedPtr<Packet> outp(new Packet(peer,RR->identity.address(),Packet::VERB_MULTICAST_LIKE));
ScopedPtr<Packet> outp(new Packet(peer,m_ctx.identity.address(),Packet::VERB_MULTICAST_LIKE));
for(Vector<MulticastGroup>::const_iterator mg(allMulticastGroups.begin());mg!=allMulticastGroups.end();++mg) {
if ((outp->size() + 24) >= ZT_PROTO_MAX_PACKET_LENGTH) {
outp->compress();
RR->sw->send(tPtr,*outp,true);
outp->reset(peer,RR->identity.address(),Packet::VERB_MULTICAST_LIKE);
m_ctx.sw->send(tPtr,*outp,true);
outp->reset(peer,m_ctx.identity.address(),Packet::VERB_MULTICAST_LIKE);
}
// network ID, MAC, ADI
@ -1524,7 +1524,7 @@ void Network::m_announceMulticastGroupsTo(void *tPtr, const Address &peer, const
if (outp->size() > ZT_PROTO_MIN_PACKET_LENGTH) {
outp->compress();
RR->sw->send(tPtr,*outp,true);
m_ctx.sw->send(tPtr,*outp,true);
}
#endif
}

View file

@ -32,7 +32,7 @@
namespace ZeroTier {
class RuntimeEnvironment;
class Context;
class Peer;
@ -67,8 +67,8 @@ public:
* @param nconf Network config, if known
*/
Network(
const RuntimeEnvironment *renv,
CallContext &cc,
const Context &ctx,
const CallContext &cc,
uint64_t nwid,
const Fingerprint &controllerFingerprint,
void *uptr,
@ -120,7 +120,7 @@ public:
* @return True if packet should be sent, false if dropped or redirected
*/
bool filterOutgoingPacket(
CallContext &cc,
const CallContext &cc,
bool noTee,
const Address &ztSource,
const Address &ztDest,
@ -151,7 +151,7 @@ public:
* @return 0 == drop, 1 == accept, 2 == accept even if bridged
*/
int filterIncomingPacket(
CallContext &cc,
const CallContext &cc,
const SharedPtr< Peer > &sourcePeer,
const Address &ztDest,
const MAC &macSource,
@ -166,7 +166,7 @@ public:
*
* @param mg New multicast group
*/
void multicastSubscribe(CallContext &cc, const MulticastGroup &mg);
void multicastSubscribe(const CallContext &cc, const MulticastGroup &mg);
/**
* Unsubscribe from a multicast group
@ -191,7 +191,7 @@ public:
* @return Update ID if update was fully assembled and accepted or 0 otherwise
*/
uint64_t handleConfigChunk(
CallContext &cc,
const CallContext &cc,
uint64_t packetId,
const SharedPtr< Peer > &source,
const Buf &chunk,
@ -210,7 +210,7 @@ public:
* @return 0 == bad, 1 == accepted but duplicate/unchanged, 2 == accepted and new
*/
int setConfiguration(
CallContext &cc,
const CallContext &cc,
const NetworkConfig &nconf,
bool saveToDisk);
@ -342,18 +342,14 @@ public:
{ return &m_uPtr; }
private:
void m_requestConfiguration(CallContext &cc);
void m_requestConfiguration(const CallContext &cc);
ZT_VirtualNetworkStatus m_status() const;
void m_externalConfig(ZT_VirtualNetworkConfig *ec) const; // assumes _lock is locked
void m_announceMulticastGroups(void *tPtr, bool force);
void m_announceMulticastGroupsTo(void *tPtr, const Address &peer, const Vector< MulticastGroup > &allMulticastGroups);
Vector< MulticastGroup > m_allMulticastGroups() const;
const RuntimeEnvironment *const RR;
const Context &m_ctx;
void *m_uPtr;
const uint64_t m_id;
Fingerprint m_controllerFingerprint;

View file

@ -35,24 +35,24 @@ namespace {
struct _NodeObjects
{
ZT_INLINE _NodeObjects(RuntimeEnvironment *const RR, CallContext &cc) :
ZT_INLINE _NodeObjects(Context &ctx, const CallContext &cc) :
networks(),
t(RR),
t(ctx),
expect(),
vl2(RR),
vl1(RR),
topology(RR, cc),
sa(RR),
vl2(ctx),
vl1(ctx),
topology(ctx, cc),
sa(ctx),
ts()
{
RR->networks = &networks;
RR->t = &t;
RR->expect = &expect;
RR->vl2 = &vl2;
RR->vl1 = &vl1;
RR->topology = &topology;
RR->sa = &sa;
RR->ts = &ts;
ctx.networks = &networks;
ctx.t = &t;
ctx.expect = &expect;
ctx.vl2 = &vl2;
ctx.vl1 = &vl1;
ctx.topology = &topology;
ctx.sa = &sa;
ctx.ts = &ts;
}
TinyMap< SharedPtr< Network > > networks;
@ -71,9 +71,8 @@ Node::Node(
void *uPtr,
const struct ZT_Node_Callbacks *callbacks,
CallContext &cc) :
m_RR(this),
RR(&m_RR),
m_store(&m_RR),
m_ctx(this),
m_store(&m_ctx),
m_objects(nullptr),
m_lastPeerPulse(0),
m_lastHousekeepingRun(0),
@ -83,55 +82,55 @@ Node::Node(
{
ZT_SPEW("Node starting up!");
Utils::copy< sizeof(ZT_Node_Callbacks) >(&m_RR.cb, callbacks);
m_RR.uPtr = uPtr;
m_RR.store = &m_store;
Utils::copy< sizeof(ZT_Node_Callbacks) >(&m_ctx.cb, callbacks);
m_ctx.uPtr = uPtr;
m_ctx.store = &m_store;
Vector< uint8_t > data(m_store.get(cc, ZT_STATE_OBJECT_IDENTITY_SECRET, Utils::ZERO256, 0));
bool haveIdentity = false;
if (!data.empty()) {
data.push_back(0); // zero-terminate string
if (m_RR.identity.fromString((const char *)data.data())) {
m_RR.identity.toString(false, m_RR.publicIdentityStr);
m_RR.identity.toString(true, m_RR.secretIdentityStr);
if (m_ctx.identity.fromString((const char *)data.data())) {
m_ctx.identity.toString(false, m_ctx.publicIdentityStr);
m_ctx.identity.toString(true, m_ctx.secretIdentityStr);
haveIdentity = true;
ZT_SPEW("loaded identity %s", RR->identity.toString().c_str());
ZT_SPEW("loaded identity %s", m_ctx.identity.toString().c_str());
}
}
if (!haveIdentity) {
m_RR.identity.generate(Identity::C25519);
m_RR.identity.toString(false, m_RR.publicIdentityStr);
m_RR.identity.toString(true, m_RR.secretIdentityStr);
m_store.put(cc, ZT_STATE_OBJECT_IDENTITY_SECRET, Utils::ZERO256, 0, m_RR.secretIdentityStr, (unsigned int)strlen(m_RR.secretIdentityStr));
m_store.put(cc, ZT_STATE_OBJECT_IDENTITY_PUBLIC, Utils::ZERO256, 0, m_RR.publicIdentityStr, (unsigned int)strlen(m_RR.publicIdentityStr));
ZT_SPEW("no pre-existing identity found, created %s", RR->identity.toString().c_str());
m_ctx.identity.generate(Identity::C25519);
m_ctx.identity.toString(false, m_ctx.publicIdentityStr);
m_ctx.identity.toString(true, m_ctx.secretIdentityStr);
m_store.put(cc, ZT_STATE_OBJECT_IDENTITY_SECRET, Utils::ZERO256, 0, m_ctx.secretIdentityStr, (unsigned int)strlen(m_ctx.secretIdentityStr));
m_store.put(cc, ZT_STATE_OBJECT_IDENTITY_PUBLIC, Utils::ZERO256, 0, m_ctx.publicIdentityStr, (unsigned int)strlen(m_ctx.publicIdentityStr));
ZT_SPEW("no pre-existing identity found, created %s", m_ctx.identity.toString().c_str());
} else {
data = m_store.get(cc, ZT_STATE_OBJECT_IDENTITY_PUBLIC, Utils::ZERO256, 0);
if ((data.empty()) || (memcmp(data.data(), m_RR.publicIdentityStr, strlen(m_RR.publicIdentityStr)) != 0))
m_store.put(cc, ZT_STATE_OBJECT_IDENTITY_PUBLIC, Utils::ZERO256, 0, m_RR.publicIdentityStr, (unsigned int)strlen(m_RR.publicIdentityStr));
if ((data.empty()) || (memcmp(data.data(), m_ctx.publicIdentityStr, strlen(m_ctx.publicIdentityStr)) != 0))
m_store.put(cc, ZT_STATE_OBJECT_IDENTITY_PUBLIC, Utils::ZERO256, 0, m_ctx.publicIdentityStr, (unsigned int)strlen(m_ctx.publicIdentityStr));
}
uint8_t localSecretCipherKey[ZT_FINGERPRINT_HASH_SIZE];
m_RR.identity.hashWithPrivate(localSecretCipherKey);
m_ctx.identity.hashWithPrivate(localSecretCipherKey);
++localSecretCipherKey[0];
SHA384(localSecretCipherKey, localSecretCipherKey, ZT_FINGERPRINT_HASH_SIZE);
m_RR.localSecretCipher.init(localSecretCipherKey);
m_ctx.localSecretCipher.init(localSecretCipherKey);
for (unsigned int i = 0; i < 1023; ++i)
m_RR.randomPrivilegedPortOrder[i] = (uint16_t)(i + 1);
m_ctx.randomPrivilegedPortOrder[i] = (uint16_t)(i + 1);
for (unsigned int i = 0; i < 512; ++i) {
uint64_t rn = Utils::random();
const unsigned int a = (unsigned int)rn % 1023;
const unsigned int b = (unsigned int)(rn >> 32U) % 1023;
if (a != b) {
const uint16_t tmp = m_RR.randomPrivilegedPortOrder[a];
m_RR.randomPrivilegedPortOrder[a] = m_RR.randomPrivilegedPortOrder[b];
m_RR.randomPrivilegedPortOrder[b] = tmp;
const uint16_t tmp = m_ctx.randomPrivilegedPortOrder[a];
m_ctx.randomPrivilegedPortOrder[a] = m_ctx.randomPrivilegedPortOrder[b];
m_ctx.randomPrivilegedPortOrder[b] = tmp;
}
}
m_objects = new _NodeObjects(&m_RR, cc);
m_objects = new _NodeObjects(m_ctx, cc);
ZT_SPEW("node initialized!");
postEvent(cc.tPtr, ZT_EVENT_UP);
@ -142,7 +141,7 @@ Node::~Node()
ZT_SPEW("Node shutting down (in destructor).");
m_allNetworks_l.lock();
RR->networks->clear();
m_ctx.networks->clear();
m_allNetworks.clear();
m_allNetworks_l.unlock();
@ -158,14 +157,14 @@ Node::~Node()
void Node::shutdown(CallContext &cc)
{
m_allNetworks_l.lock();
RR->networks->clear();
m_ctx.networks->clear();
m_allNetworks.clear();
m_allNetworks_l.unlock();
postEvent(cc.tPtr, ZT_EVENT_DOWN);
if (RR->topology)
RR->topology->saveAll(cc);
if (m_ctx.topology)
m_ctx.topology->saveAll(cc);
}
ZT_ResultCode Node::processBackgroundTasks(
@ -180,8 +179,8 @@ ZT_ResultCode Node::processBackgroundTasks(
// certificates. This also happens on demand when the trust store is changed.
if ((cc.ticks - m_lastTrustStoreUpdate) >= ZT_TRUSTSTORE_UPDATE_PERIOD) {
m_lastTrustStoreUpdate = cc.ticks;
if (RR->ts->update(cc.ticks, nullptr))
RR->topology->trustStoreChanged(cc);
if (m_ctx.ts->update(cc.ticks, nullptr))
m_ctx.topology->trustStoreChanged(cc);
}
// Networks perform housekeeping here such as refreshing configs.
@ -198,8 +197,8 @@ ZT_ResultCode Node::processBackgroundTasks(
m_lastHousekeepingRun = cc.ticks;
ZT_SPEW("running housekeeping...");
RR->topology->doPeriodicTasks(cc);
RR->sa->clean(cc);
m_ctx.topology->doPeriodicTasks(cc);
m_ctx.sa->clean(cc);
}
// Peers have a "pulse" method that does things like keepalive and path housekeeping.
@ -211,12 +210,12 @@ ZT_ResultCode Node::processBackgroundTasks(
ZT_SPEW("running pulse() on each peer...");
try {
Vector< SharedPtr< Peer > > allPeers, rootPeers;
RR->topology->allPeers(allPeers, rootPeers);
m_ctx.topology->allPeers(allPeers, rootPeers);
bool online = false;
for (Vector< SharedPtr< Peer > >::iterator p(allPeers.begin()); p != allPeers.end(); ++p) {
const bool isRoot = std::find(rootPeers.begin(), rootPeers.end(), *p) != rootPeers.end();
(*p)->pulse(cc, isRoot);
(*p)->pulse(m_ctx, cc, isRoot);
online |= ((isRoot || rootPeers.empty()) && (*p)->directlyConnected(cc));
}
@ -224,7 +223,7 @@ ZT_ResultCode Node::processBackgroundTasks(
postEvent(cc.tPtr, online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE);
ZT_SPEW("ranking roots...");
RR->topology->rankRoots(cc);
m_ctx.topology->rankRoots(cc);
} catch (...) {
return ZT_RESULT_FATAL_ERROR_INTERNAL;
}
@ -258,9 +257,9 @@ ZT_ResultCode Node::join(
if ((*n)->id() == nwid)
return ZT_RESULT_OK;
}
SharedPtr< Network > network(new Network(RR, cc, nwid, fp, uptr, nullptr));
SharedPtr< Network > network(new Network(m_ctx, cc, nwid, fp, uptr, nullptr));
m_allNetworks.push_back(network);
RR->networks->set(nwid, network);
m_ctx.networks->set(nwid, network);
return ZT_RESULT_OK;
}
@ -276,7 +275,7 @@ ZT_ResultCode Node::leave(
ZT_VirtualNetworkConfig ctmp;
SharedPtr< Network > network;
RR->networks->erase(nwid);
m_ctx.networks->erase(nwid);
for (Vector< SharedPtr< Network > >::iterator n(m_allNetworks.begin()); n != m_allNetworks.end(); ++n) {
if ((*n)->id() == nwid) {
network.move(*n);
@ -294,7 +293,7 @@ ZT_ResultCode Node::leave(
if (uptr)
*uptr = *network->userPtr();
network->externalConfig(&ctmp);
RR->cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(this), RR->uPtr, cc.tPtr, nwid, network->userPtr(), ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY, &ctmp);
m_ctx.cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(this), m_ctx.uPtr, cc.tPtr, nwid, network->userPtr(), ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY, &ctmp);
network->destroy();
return ZT_RESULT_OK;
} else {
@ -309,7 +308,7 @@ ZT_ResultCode Node::multicastSubscribe(
unsigned long multicastAdi)
{
ZT_SPEW("multicast subscribe to %s:%lu", MAC(multicastGroup).toString().c_str(), multicastAdi);
const SharedPtr< Network > nw(RR->networks->get(nwid));
const SharedPtr< Network > nw(m_ctx.networks->get(nwid));
if (nw) {
nw->multicastSubscribe(cc, MulticastGroup(MAC(multicastGroup), (uint32_t)(multicastAdi & 0xffffffff)));
return ZT_RESULT_OK;
@ -325,7 +324,7 @@ ZT_ResultCode Node::multicastUnsubscribe(
unsigned long multicastAdi)
{
ZT_SPEW("multicast unsubscribe from %s:%lu", MAC(multicastGroup).toString().c_str(), multicastAdi);
const SharedPtr< Network > nw(RR->networks->get(nwid));
const SharedPtr< Network > nw(m_ctx.networks->get(nwid));
if (nw) {
nw->multicastUnsubscribe(MulticastGroup(MAC(multicastGroup), (uint32_t)(multicastAdi & 0xffffffff)));
return ZT_RESULT_OK;
@ -336,10 +335,10 @@ ZT_ResultCode Node::multicastUnsubscribe(
void Node::status(ZT_NodeStatus *status) const
{
status->address = RR->identity.address().toInt();
status->identity = reinterpret_cast<const ZT_Identity *>(&RR->identity);
status->publicIdentity = RR->publicIdentityStr;
status->secretIdentity = RR->secretIdentityStr;
status->address = m_ctx.identity.address().toInt();
status->identity = reinterpret_cast<const ZT_Identity *>(&m_ctx.identity);
status->publicIdentity = m_ctx.publicIdentityStr;
status->secretIdentity = m_ctx.secretIdentityStr;
status->online = m_online ? 1 : 0;
}
@ -372,7 +371,7 @@ ZT_PeerList *Node::peers(CallContext &cc) const
pl->freeFunction = p_peerListFreeFunction;
Vector< SharedPtr< Peer > > peers, rootPeers;
RR->topology->allPeers(peers, rootPeers);
m_ctx.topology->allPeers(peers, rootPeers);
std::sort(peers.begin(), peers.end(), p_sortPeerPtrsByAddress());
std::sort(rootPeers.begin(), rootPeers.end());
@ -450,7 +449,7 @@ ZT_PeerList *Node::peers(CallContext &cc) const
ZT_VirtualNetworkConfig *Node::networkConfig(uint64_t nwid) const
{
const SharedPtr< Network > nw(RR->networks->get(nwid));
const SharedPtr< Network > nw(m_ctx.networks->get(nwid));
if (nw) {
ZT_VirtualNetworkConfig *const nc = (ZT_VirtualNetworkConfig *)::malloc(sizeof(ZT_VirtualNetworkConfig));
nw->externalConfig(nc);
@ -482,7 +481,7 @@ void Node::setNetworkUserPtr(
uint64_t nwid,
void *ptr)
{
SharedPtr< Network > nw(RR->networks->get(nwid));
SharedPtr< Network > nw(m_ctx.networks->get(nwid));
if (nw) {
m_allNetworks_l.lock(); // ensure no concurrent modification of user PTR in network
*(nw->userPtr()) = ptr;
@ -525,9 +524,9 @@ ZT_CertificateError Node::addCertificate(
if (!c.decode(certData, certSize))
return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
}
RR->ts->add(c, localTrust);
RR->ts->update(cc.clock, nullptr);
SharedPtr< TrustStore::Entry > ent(RR->ts->get(c.getSerialNo()));
m_ctx.ts->add(c, localTrust);
m_ctx.ts->update(cc.clock, nullptr);
SharedPtr< TrustStore::Entry > ent(m_ctx.ts->get(c.getSerialNo()));
return (ent) ? ent->error() : ZT_CERTIFICATE_ERROR_INVALID_FORMAT; // should never be null, but if so it means invalid
}
@ -537,8 +536,8 @@ ZT_ResultCode Node::deleteCertificate(
{
if (!serialNo)
return ZT_RESULT_ERROR_BAD_PARAMETER;
RR->ts->erase(H384(serialNo));
RR->ts->update(-1, nullptr);
m_ctx.ts->erase(H384(serialNo));
m_ctx.ts->update(-1, nullptr);
return ZT_RESULT_OK;
}
@ -566,7 +565,7 @@ ZT_CertificateList *Node::listCertificates()
p_certificateListInternal *const clint = reinterpret_cast<p_certificateListInternal *>(reinterpret_cast<uint8_t *>(cl) + sizeof(ZT_CertificateList));
new(clint) p_certificateListInternal;
clint->entries = RR->ts->all(false);
clint->entries = m_ctx.ts->all(false);
clint->c.reserve(clint->entries.size());
clint->t.reserve(clint->entries.size());
for (Vector< SharedPtr< TrustStore::Entry > >::const_iterator i(clint->entries.begin()); i != clint->entries.end(); ++i) {
@ -590,14 +589,14 @@ int Node::sendUserMessage(
unsigned int /*len*/)
{
try {
if (RR->identity.address().toInt() != dest) {
if (m_ctx.identity.address().toInt() != dest) {
// TODO
/*
Packet outp(Address(dest),RR->identity.address(),Packet::VERB_USER_MESSAGE);
Packet outp(Address(dest),m_ctx.identity.address(),Packet::VERB_USER_MESSAGE);
outp.append(typeId);
outp.append(data,len);
outp.compress();
RR->sw->send(tptr,outp,true);
m_ctx.sw->send(tptr,outp,true);
*/
return 1;
}
@ -607,9 +606,9 @@ int Node::sendUserMessage(
void Node::setController(void *networkControllerInstance)
{
m_RR.localNetworkController = reinterpret_cast<NetworkController *>(networkControllerInstance);
m_ctx.localNetworkController = reinterpret_cast<NetworkController *>(networkControllerInstance);
if (networkControllerInstance)
m_RR.localNetworkController->init(RR->identity, this);
m_ctx.localNetworkController->init(m_ctx.identity, this);
}
// Methods used only within the core ----------------------------------------------------------------------------------
@ -626,10 +625,10 @@ bool Node::shouldUsePathForZeroTierTraffic(void *tPtr, const Identity &id, const
}
}
if (RR->cb.pathCheckFunction) {
return (RR->cb.pathCheckFunction(
if (m_ctx.cb.pathCheckFunction) {
return (m_ctx.cb.pathCheckFunction(
reinterpret_cast<ZT_Node *>(this),
RR->uPtr,
m_ctx.uPtr,
tPtr,
id.address().toInt(),
(const ZT_Identity *)&id,
@ -642,10 +641,10 @@ bool Node::shouldUsePathForZeroTierTraffic(void *tPtr, const Identity &id, const
bool Node::externalPathLookup(void *tPtr, const Identity &id, int family, InetAddress &addr)
{
if (RR->cb.pathLookupFunction) {
return (RR->cb.pathLookupFunction(
if (m_ctx.cb.pathLookupFunction) {
return (m_ctx.cb.pathLookupFunction(
reinterpret_cast<ZT_Node *>(this),
RR->uPtr,
m_ctx.uPtr,
tPtr,
id.address().toInt(),
reinterpret_cast<const ZT_Identity *>(&id),
@ -659,8 +658,8 @@ bool Node::externalPathLookup(void *tPtr, const Identity &id, int family, InetAd
void Node::ncSendConfig(void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address &destination, const NetworkConfig &nc, bool sendLegacyFormatConfig)
{
if (destination == RR->identity.address()) {
SharedPtr< Network > n(RR->networks->get(nwid));
if (destination == m_ctx.identity.address()) {
SharedPtr< Network > n(m_ctx.networks->get(nwid));
if (!n)
return;
CallContext cc(clock, ticks, tPtr);
@ -679,7 +678,7 @@ void Node::ncSendConfig(void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid,
unsigned int chunkIndex = 0;
while (chunkIndex < totalSize) {
const unsigned int chunkLen = std::min(totalSize - chunkIndex,(unsigned int)(ZT_PROTO_MAX_PACKET_LENGTH - (ZT_PACKET_IDX_PAYLOAD + 256)));
Packet outp(destination,RR->identity.address(),(requestPacketId) ? Packet::VERB_OK : Packet::VERB_NETWORK_CONFIG);
Packet outp(destination,m_ctx.identity.address(),(requestPacketId) ? Packet::VERB_OK : Packet::VERB_NETWORK_CONFIG);
if (requestPacketId) {
outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
outp.append(requestPacketId);
@ -696,13 +695,13 @@ void Node::ncSendConfig(void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid,
outp.append((uint32_t)chunkIndex);
uint8_t sig[256];
const unsigned int siglen = RR->identity.sign(reinterpret_cast<const uint8_t *>(outp.data()) + sigStart,outp.size() - sigStart,sig,sizeof(sig));
const unsigned int siglen = m_ctx.identity.sign(reinterpret_cast<const uint8_t *>(outp.data()) + sigStart,outp.size() - sigStart,sig,sizeof(sig));
outp.append((uint8_t)1);
outp.append((uint16_t)siglen);
outp.append(sig,siglen);
outp.compress();
RR->sw->send((void *)0,outp,true);
m_ctx.sw->send((void *)0,outp,true);
chunkIndex += chunkLen;
}
*/
@ -712,31 +711,31 @@ void Node::ncSendConfig(void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid,
void Node::ncSendRevocation(void *tPtr, int64_t clock, int64_t ticks, const Address &destination, const RevocationCredential &rev)
{
if (destination == RR->identity.address()) {
SharedPtr< Network > n(RR->networks->get(rev.networkId()));
if (destination == m_ctx.identity.address()) {
SharedPtr< Network > n(m_ctx.networks->get(rev.networkId()));
if (!n)
return;
CallContext cc(clock, ticks, tPtr);
n->addCredential(cc, RR->identity, rev);
n->addCredential(cc, m_ctx.identity, rev);
} else {
// TODO
/*
Packet outp(destination,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS);
Packet outp(destination,m_ctx.identity.address(),Packet::VERB_NETWORK_CREDENTIALS);
outp.append((uint8_t)0x00);
outp.append((uint16_t)0);
outp.append((uint16_t)0);
outp.append((uint16_t)1);
rev.serialize(outp);
outp.append((uint16_t)0);
RR->sw->send((void *)0,outp,true);
m_ctx.sw->send((void *)0,outp,true);
*/
}
}
void Node::ncSendError(void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address &destination, NetworkController::ErrorCode errorCode)
{
if (destination == RR->identity.address()) {
SharedPtr< Network > n(RR->networks->get(nwid));
if (destination == m_ctx.identity.address()) {
SharedPtr< Network > n(m_ctx.networks->get(nwid));
if (!n)
return;
switch (errorCode) {
@ -754,7 +753,7 @@ void Node::ncSendError(void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid,
} else if (requestPacketId) {
// TODO
/*
Packet outp(destination,RR->identity.address(),Packet::VERB_ERROR);
Packet outp(destination,m_ctx.identity.address(),Packet::VERB_ERROR);
outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
outp.append(requestPacketId);
switch(errorCode) {
@ -768,7 +767,7 @@ void Node::ncSendError(void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid,
break;
}
outp.append(nwid);
RR->sw->send((void *)0,outp,true);
m_ctx.sw->send((void *)0,outp,true);
*/
} // else we can't send an ERROR() in response to nothing, so discard
}

View file

@ -15,7 +15,7 @@
#define ZT_NODE_HPP
#include "Constants.hpp"
#include "RuntimeEnvironment.hpp"
#include "Context.hpp"
#include "InetAddress.hpp"
#include "Mutex.hpp"
#include "MAC.hpp"
@ -128,7 +128,7 @@ public:
* @param mdSize Size of event data
*/
ZT_INLINE void postEvent(void *tPtr, ZT_Event ev, const void *md = nullptr, const unsigned int mdSize = 0) noexcept
{ RR->cb.eventCallback(reinterpret_cast<ZT_Node *>(this), RR->uPtr, tPtr, ev, md, mdSize); }
{ m_ctx.cb.eventCallback(reinterpret_cast<ZT_Node *>(this), m_ctx.uPtr, tPtr, ev, md, mdSize); }
/**
* Check whether a path should be used for ZeroTier traffic
@ -154,11 +154,11 @@ public:
*/
bool externalPathLookup(void *tPtr, const Identity &id, int family, InetAddress &addr);
/**
* @return This node's identity
*/
ZT_INLINE const Identity &identity() const noexcept
{ return m_RR.identity; }
{ return m_ctx.identity; }
ZT_INLINE const Context &context() const noexcept
{ return m_ctx; }
// Implementation of NetworkController::Sender interface
virtual void ncSendConfig(void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address &destination, const NetworkConfig &nc, bool sendLegacyFormatConfig);
@ -166,12 +166,8 @@ public:
virtual void ncSendError(void *tPtr, int64_t clock, int64_t ticks, uint64_t nwid, uint64_t requestPacketId, const Address &destination, NetworkController::ErrorCode errorCode);
private:
RuntimeEnvironment m_RR;
Context m_ctx;
public:
const RuntimeEnvironment *const RR;
private:
// Data store wrapper
Store m_store;

View file

@ -32,7 +32,7 @@
namespace ZeroTier {
class RuntimeEnvironment;
class Context;
/**
* Certificate indicating ownership of a "thing" such as an IP address
@ -146,12 +146,10 @@ public:
/**
* Verify certificate signature
*
* @param RR Runtime environment
* @param tPtr That pointer we pass around
* @return Credential verification result: OK, bad signature, or identity needed
*/
ZT_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR, CallContext &cc) const
{ return s_verify(RR, cc, *this); }
ZT_INLINE Credential::VerifyResult verify(const Context &ctx, const CallContext &cc) const
{ return s_verify(ctx, cc, *this); }
static constexpr int marshalSizeMax() noexcept
{ return ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_SIZE_MAX; }

View file

@ -12,14 +12,14 @@
/****/
#include "Path.hpp"
#include "RuntimeEnvironment.hpp"
#include "Context.hpp"
#include "Node.hpp"
namespace ZeroTier {
bool Path::send(const RuntimeEnvironment *const RR, CallContext &cc, const void *const data, const unsigned int len) noexcept
bool Path::send(const Context &ctx, const CallContext &cc, const void *const data, const unsigned int len) noexcept
{
if (likely(RR->cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, cc.tPtr, m_localSocket, reinterpret_cast<const ZT_InetAddress *>(&m_addr), data, len, 0) == 0)) {
if (likely(ctx.cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(ctx.node), ctx.uPtr, cc.tPtr, m_localSocket, reinterpret_cast<const ZT_InetAddress *>(&m_addr), data, len, 0) == 0)) {
m_lastOut = cc.ticks;
m_outMeter.log(cc.ticks, len);
return true;

View file

@ -25,7 +25,7 @@
namespace ZeroTier {
class RuntimeEnvironment;
class Context;
template< unsigned int MF, unsigned int MFP, unsigned int GCT, unsigned int GCS, typename P >
class Defragmenter;
@ -145,7 +145,7 @@ public:
* @param len Packet length
* @return True if transport reported success
*/
bool send(const RuntimeEnvironment *RR, CallContext &cc, const void *data, unsigned int len) noexcept;
bool send(const Context &ctx, const CallContext &cc, const void *data, unsigned int len) noexcept;
/**
* Explicitly update last sent time

View file

@ -12,7 +12,7 @@
/****/
#include "Constants.hpp"
#include "RuntimeEnvironment.hpp"
#include "Context.hpp"
#include "Trace.hpp"
#include "Peer.hpp"
#include "Topology.hpp"
@ -24,8 +24,7 @@
namespace ZeroTier {
Peer::Peer(const RuntimeEnvironment *renv) :
RR(renv),
Peer::Peer() :
m_ephemeralPairTimestamp(0),
m_lastReceive(0),
m_lastSend(0),
@ -45,7 +44,7 @@ Peer::Peer(const RuntimeEnvironment *renv) :
Peer::~Peer()
{ Utils::burn(m_helloMacKey, sizeof(m_helloMacKey)); }
bool Peer::init(CallContext &cc, const Identity &peerIdentity)
bool Peer::init(const Context &ctx, const CallContext &cc, const Identity &peerIdentity)
{
RWMutex::Lock l(m_lock);
@ -54,7 +53,7 @@ bool Peer::init(CallContext &cc, const Identity &peerIdentity)
m_id = peerIdentity;
uint8_t k[ZT_SYMMETRIC_KEY_SIZE];
if (!RR->identity.agree(peerIdentity, k))
if (!ctx.identity.agree(peerIdentity, k))
return false;
m_identityKey.set(new SymmetricKey(cc.ticks, k));
Utils::burn(k, sizeof(k));
@ -65,7 +64,8 @@ bool Peer::init(CallContext &cc, const Identity &peerIdentity)
}
void Peer::received(
CallContext &cc,
const Context &ctx,
const CallContext &cc,
const SharedPtr< Path > &path,
const unsigned int hops,
const uint64_t packetId,
@ -87,7 +87,7 @@ void Peer::received(
}
// If we made it here, we don't already know this path.
if (RR->node->shouldUsePathForZeroTierTraffic(cc.tPtr, m_id, path->localSocket(), path->address())) {
if (ctx.node->shouldUsePathForZeroTierTraffic(cc.tPtr, m_id, path->localSocket(), path->address())) {
// SECURITY: note that if we've made it here we expected this OK, see Expect.hpp.
// There is replay protection in effect for OK responses.
if (verb == Protocol::VERB_OK) {
@ -139,26 +139,26 @@ void Peer::received(
}
}
RR->t->learnedNewPath(cc, 0x582fabdd, packetId, m_id, path->address(), old);
ctx.t->learnedNewPath(cc, 0x582fabdd, packetId, m_id, path->address(), old);
} else {
path->sent(cc, hello(cc, path->localSocket(), path->address()));
RR->t->tryingNewPath(cc, 0xb7747ddd, m_id, path->address(), path->address(), packetId, (uint8_t)verb, m_id);
path->sent(cc, hello(ctx, cc, path->localSocket(), path->address()));
ctx.t->tryingNewPath(cc, 0xb7747ddd, m_id, path->address(), path->address(), packetId, (uint8_t)verb, m_id);
}
}
}
}
void Peer::send(CallContext &cc, const void *data, unsigned int len) noexcept
void Peer::send(const Context &ctx, const CallContext &cc, const void *data, unsigned int len) noexcept
{
SharedPtr< Path > via(this->path(cc));
if (via) {
via->send(RR, cc, data, len);
via->send(ctx, cc, data, len);
} else {
const SharedPtr< Peer > root(RR->topology->root());
const SharedPtr< Peer > root(ctx.topology->root());
if ((root) && (root.ptr() != this)) {
via = root->path(cc);
if (via) {
via->send(RR, cc, data, len);
via->send(ctx, cc, data, len);
root->relayed(cc, len);
} else {
return;
@ -170,19 +170,19 @@ void Peer::send(CallContext &cc, const void *data, unsigned int len) noexcept
sent(cc, len);
}
unsigned int Peer::hello(CallContext &cc, int64_t localSocket, const InetAddress &atAddress)
unsigned int Peer::hello(const Context &ctx, const CallContext &cc, int64_t localSocket, const InetAddress &atAddress)
{
Buf outp;
const uint64_t packetId = m_identityKey->nextMessage(RR->identity.address(), m_id.address());
int ii = Protocol::newPacket(outp, packetId, m_id.address(), RR->identity.address(), Protocol::VERB_HELLO);
const uint64_t packetId = m_identityKey->nextMessage(ctx.identity.address(), m_id.address());
int ii = Protocol::newPacket(outp, packetId, m_id.address(), ctx.identity.address(), Protocol::VERB_HELLO);
outp.wI8(ii, ZT_PROTO_VERSION);
outp.wI8(ii, ZEROTIER_VERSION_MAJOR);
outp.wI8(ii, ZEROTIER_VERSION_MINOR);
outp.wI16(ii, ZEROTIER_VERSION_REVISION);
outp.wI64(ii, (uint64_t)cc.clock);
outp.wO(ii, RR->identity);
outp.wO(ii, ctx.identity);
outp.wO(ii, atAddress);
const int ivStart = ii;
@ -198,7 +198,7 @@ unsigned int Peer::hello(CallContext &cc, int64_t localSocket, const InetAddress
const int cryptSectionStart = ii;
FCV< uint8_t, 4096 > md;
Dictionary::append(md, ZT_PROTO_HELLO_NODE_META_INSTANCE_ID, RR->instanceId);
Dictionary::append(md, ZT_PROTO_HELLO_NODE_META_INSTANCE_ID, ctx.instanceId);
outp.wI16(ii, (uint16_t)md.size());
outp.wB(ii, md.data(), (unsigned int)md.size());
@ -224,10 +224,10 @@ unsigned int Peer::hello(CallContext &cc, int64_t localSocket, const InetAddress
p1305.finish(polyMac);
Utils::storeMachineEndian< uint64_t >(outp.unsafeData + ZT_PROTO_PACKET_MAC_INDEX, polyMac[0]);
return (likely(RR->cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, cc.tPtr, localSocket, reinterpret_cast<const ZT_InetAddress *>(&atAddress), outp.unsafeData, ii, 0) == 0)) ? ii : 0;
return (likely(ctx.cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(ctx.node), ctx.uPtr, cc.tPtr, localSocket, reinterpret_cast<const ZT_InetAddress *>(&atAddress), outp.unsafeData, ii, 0) == 0)) ? ii : 0;
}
void Peer::pulse(CallContext &cc, const bool isRoot)
void Peer::pulse(const Context &ctx, const CallContext &cc, const bool isRoot)
{
RWMutex::Lock l(m_lock);
@ -254,12 +254,12 @@ void Peer::pulse(CallContext &cc, const bool isRoot)
if (m_locator) {
for (Vector< std::pair<Endpoint, SharedPtr< const Locator::EndpointAttributes > > >::const_iterator ep(m_locator->endpoints().begin()); ep != m_locator->endpoints().end(); ++ep) {
if (ep->first.type == ZT_ENDPOINT_TYPE_IP_UDP) {
if (RR->node->shouldUsePathForZeroTierTraffic(cc.tPtr, m_id, -1, ep->first.ip())) {
if (ctx.node->shouldUsePathForZeroTierTraffic(cc.tPtr, m_id, -1, ep->first.ip())) {
int64_t &lt = m_lastTried[ep->first];
if ((cc.ticks - lt) > ZT_PATH_MIN_TRY_INTERVAL) {
lt = cc.ticks;
RR->t->tryingNewPath(cc, 0x84b22322, m_id, ep->first.ip(), InetAddress::NIL, 0, 0, Identity::NIL);
sent(cc, m_sendProbe(cc, -1, ep->first.ip(), nullptr, 0));
ctx.t->tryingNewPath(cc, 0x84b22322, m_id, ep->first.ip(), InetAddress::NIL, 0, 0, Identity::NIL);
sent(cc, m_sendProbe(ctx, cc, -1, ep->first.ip(), nullptr, 0));
}
}
}
@ -268,25 +268,25 @@ void Peer::pulse(CallContext &cc, const bool isRoot)
for (unsigned int i = 0; i < ZT_PEER_ENDPOINT_CACHE_SIZE; ++i) {
if ((m_endpointCache[i].lastSeen > 0) && (m_endpointCache[i].target.type == ZT_ENDPOINT_TYPE_IP_UDP)) {
if (RR->node->shouldUsePathForZeroTierTraffic(cc.tPtr, m_id, -1, m_endpointCache[i].target.ip())) {
if (ctx.node->shouldUsePathForZeroTierTraffic(cc.tPtr, m_id, -1, m_endpointCache[i].target.ip())) {
int64_t &lt = m_lastTried[m_endpointCache[i].target];
if ((cc.ticks - lt) > ZT_PATH_MIN_TRY_INTERVAL) {
lt = cc.ticks;
RR->t->tryingNewPath(cc, 0x84b22343, m_id, m_endpointCache[i].target.ip(), InetAddress::NIL, 0, 0, Identity::NIL);
sent(cc, m_sendProbe(cc, -1, m_endpointCache[i].target.ip(), nullptr, 0));
ctx.t->tryingNewPath(cc, 0x84b22343, m_id, m_endpointCache[i].target.ip(), InetAddress::NIL, 0, 0, Identity::NIL);
sent(cc, m_sendProbe(ctx, cc, -1, m_endpointCache[i].target.ip(), nullptr, 0));
}
}
}
}
InetAddress addr;
if (RR->node->externalPathLookup(cc.tPtr, m_id, -1, addr)) {
if ((addr) && RR->node->shouldUsePathForZeroTierTraffic(cc.tPtr, m_id, -1, addr)) {
if (ctx.node->externalPathLookup(cc.tPtr, m_id, -1, addr)) {
if ((addr) && ctx.node->shouldUsePathForZeroTierTraffic(cc.tPtr, m_id, -1, addr)) {
int64_t &lt = m_lastTried[Endpoint(addr)];
if ((cc.ticks - lt) > ZT_PATH_MIN_TRY_INTERVAL) {
lt = cc.ticks;
RR->t->tryingNewPath(cc, 0x84a10000, m_id, addr, InetAddress::NIL, 0, 0, Identity::NIL);
sent(cc, m_sendProbe(cc, -1, addr, nullptr, 0));
ctx.t->tryingNewPath(cc, 0x84a10000, m_id, addr, InetAddress::NIL, 0, 0, Identity::NIL);
sent(cc, m_sendProbe(ctx, cc, -1, addr, nullptr, 0));
}
}
}
@ -316,7 +316,7 @@ void Peer::pulse(CallContext &cc, const bool isRoot)
// If iteration is less than zero, try to contact the original address.
// It may be set to a larger negative value to try multiple times such
// as e.g. -3 to try 3 times.
sent(cc, m_sendProbe(cc, -1, qi.target.ip(), nullptr, 0));
sent(cc, m_sendProbe(ctx, cc, -1, qi.target.ip(), nullptr, 0));
++qi.iteration;
goto requeue_item;
@ -333,12 +333,12 @@ void Peer::pulse(CallContext &cc, const bool isRoot)
uint16_t ports[ZT_NAT_T_PORT_SCAN_MAX];
unsigned int pn = 0;
while ((pn < ZT_NAT_T_PORT_SCAN_MAX) && (qi.iteration < 1023)) {
const uint16_t p = RR->randomPrivilegedPortOrder[qi.iteration++];
const uint16_t p = ctx.randomPrivilegedPortOrder[qi.iteration++];
if ((unsigned int)p != qi.target.ip().port())
ports[pn++] = p;
}
if (pn > 0)
sent(cc, m_sendProbe(cc, -1, qi.target.ip(), ports, pn));
sent(cc, m_sendProbe(ctx, cc, -1, qi.target.ip(), ports, pn));
if (qi.iteration < 1023)
goto requeue_item;
@ -352,7 +352,7 @@ void Peer::pulse(CallContext &cc, const bool isRoot)
if (p > 65535)
p -= 64512; // wrap back to 1024
tmp.setPort(p);
sent(cc, m_sendProbe(cc, -1, tmp, nullptr, 0));
sent(cc, m_sendProbe(ctx, cc, -1, tmp, nullptr, 0));
if (qi.iteration < ZT_NAT_T_PORT_SCAN_MAX)
goto requeue_item;
@ -383,23 +383,23 @@ void Peer::pulse(CallContext &cc, const bool isRoot)
for (unsigned int i = 0; i < m_alivePathCount; ++i) {
if (needHello) {
needHello = false;
const unsigned int bytes = hello(cc, m_paths[i]->localSocket(), m_paths[i]->address());
const unsigned int bytes = hello(ctx, cc, m_paths[i]->localSocket(), m_paths[i]->address());
m_paths[i]->sent(cc, bytes);
sent(cc, bytes);
m_lastSentHello = cc.ticks;
} else if ((cc.ticks - m_paths[i]->lastOut()) >= ZT_PATH_KEEPALIVE_PERIOD) {
m_paths[i]->send(RR, cc, reinterpret_cast<uint8_t *>(&randomJunk) + (i & 7U), 1);
m_paths[i]->send(ctx, cc, reinterpret_cast<uint8_t *>(&randomJunk) + (i & 7U), 1);
sent(cc, 1);
}
}
// Send a HELLO indirectly if we were not able to send one via any direct path.
if (needHello) {
const SharedPtr< Peer > root(RR->topology->root());
const SharedPtr< Peer > root(ctx.topology->root());
if (root) {
const SharedPtr< Path > via(root->path(cc));
if (via) {
const unsigned int bytes = hello(cc, via->localSocket(), via->address());
const unsigned int bytes = hello(ctx, cc, via->localSocket(), via->address());
via->sent(cc, bytes);
root->relayed(cc, bytes);
sent(cc, bytes);
@ -416,7 +416,7 @@ void Peer::pulse(CallContext &cc, const bool isRoot)
}
}
void Peer::contact(CallContext &cc, const Endpoint &ep, int tries)
void Peer::contact(const Context &ctx, const CallContext &cc, const Endpoint &ep, int tries)
{
static uint8_t foo = 0;
RWMutex::Lock l(m_lock);
@ -442,7 +442,7 @@ void Peer::contact(CallContext &cc, const Endpoint &ep, int tries)
// traverse some NAT types. It has no effect otherwise.
if (ep.isInetAddr() && ep.ip().isV4()) {
++foo;
RR->cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, cc.tPtr, -1, reinterpret_cast<const ZT_InetAddress *>(&ep.ip()), &foo, 1, 2);
ctx.cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(ctx.node), ctx.uPtr, cc.tPtr, -1, reinterpret_cast<const ZT_InetAddress *>(&ep.ip()), &foo, 1, 2);
}
// Make sure address is not already in the try queue. If so just update it.
@ -457,13 +457,13 @@ void Peer::contact(CallContext &cc, const Endpoint &ep, int tries)
m_tryQueue.push_back(p_TryQueueItem(ep, -tries));
}
void Peer::resetWithinScope(CallContext &cc, InetAddress::IpScope scope, int inetAddressFamily)
void Peer::resetWithinScope(const Context &ctx, const CallContext &cc, InetAddress::IpScope scope, int inetAddressFamily)
{
RWMutex::Lock l(m_lock);
unsigned int pc = 0;
for (unsigned int i = 0; i < m_alivePathCount; ++i) {
if ((m_paths[i]) && (((int)m_paths[i]->address().as.sa.sa_family == inetAddressFamily) && (m_paths[i]->address().ipScope() == scope))) {
const unsigned int bytes = m_sendProbe(cc, m_paths[i]->localSocket(), m_paths[i]->address(), nullptr, 0);
const unsigned int bytes = m_sendProbe(ctx, cc, m_paths[i]->localSocket(), m_paths[i]->address(), nullptr, 0);
m_paths[i]->sent(cc, bytes);
sent(cc, bytes);
} else if (pc != i) {
@ -495,23 +495,23 @@ void Peer::getAllPaths(Vector< SharedPtr< Path > > &paths)
paths.assign(m_paths, m_paths + m_alivePathCount);
}
void Peer::save(CallContext &cc) const
void Peer::save(const Context &ctx, const CallContext &cc) const
{
uint8_t buf[8 + ZT_PEER_MARSHAL_SIZE_MAX];
// Prefix each saved peer with the current timestamp.
Utils::storeBigEndian< uint64_t >(buf, (uint64_t)cc.clock);
const int len = marshal(buf + 8);
const int len = marshal(ctx, buf + 8);
if (len > 0) {
uint64_t id[2];
id[0] = m_id.address().toInt();
id[1] = 0;
RR->store->put(cc, ZT_STATE_OBJECT_PEER, id, 1, buf, (unsigned int)len + 8);
ctx.store->put(cc, ZT_STATE_OBJECT_PEER, id, 1, buf, (unsigned int)len + 8);
}
}
int Peer::marshal(uint8_t data[ZT_PEER_MARSHAL_SIZE_MAX]) const noexcept
int Peer::marshal(const Context &ctx, uint8_t data[ZT_PEER_MARSHAL_SIZE_MAX]) const noexcept
{
RWMutex::RLock l(m_lock);
@ -522,14 +522,14 @@ int Peer::marshal(uint8_t data[ZT_PEER_MARSHAL_SIZE_MAX]) const noexcept
// Include our identity's address to detect if this changes and require
// recomputation of m_identityKey.
RR->identity.address().copyTo(data + 1);
ctx.identity.address().copyTo(data + 1);
// SECURITY: encryption in place is only to protect secrets if they are
// cached to local storage. It's not used over the wire. Dumb ECB is fine
// because secret keys are random and have no structure to reveal.
RR->localSecretCipher.encrypt(m_identityKey->secret, data + 1 + ZT_ADDRESS_LENGTH);
RR->localSecretCipher.encrypt(m_identityKey->secret + 16, data + 1 + ZT_ADDRESS_LENGTH + 16);
RR->localSecretCipher.encrypt(m_identityKey->secret + 32, data + 1 + ZT_ADDRESS_LENGTH + 32);
ctx.localSecretCipher.encrypt(m_identityKey->secret, data + 1 + ZT_ADDRESS_LENGTH);
ctx.localSecretCipher.encrypt(m_identityKey->secret + 16, data + 1 + ZT_ADDRESS_LENGTH + 16);
ctx.localSecretCipher.encrypt(m_identityKey->secret + 32, data + 1 + ZT_ADDRESS_LENGTH + 32);
int p = 1 + ZT_ADDRESS_LENGTH + 48;
@ -578,7 +578,7 @@ int Peer::marshal(uint8_t data[ZT_PEER_MARSHAL_SIZE_MAX]) const noexcept
return p;
}
int Peer::unmarshal(const int64_t ticks, const uint8_t *restrict data, const int len) noexcept
int Peer::unmarshal(const Context &ctx, const int64_t ticks, const uint8_t *restrict data, const int len) noexcept
{
RWMutex::Lock l(m_lock);
@ -589,12 +589,12 @@ int Peer::unmarshal(const int64_t ticks, const uint8_t *restrict data, const int
m_ephemeralKeys[0].zero();
m_ephemeralKeys[1].zero();
if (Address(data + 1) == RR->identity.address()) {
if (Address(data + 1) == ctx.identity.address()) {
uint8_t k[ZT_SYMMETRIC_KEY_SIZE];
static_assert(ZT_SYMMETRIC_KEY_SIZE == 48, "marshal() and unmarshal() must be revisited if ZT_SYMMETRIC_KEY_SIZE is changed");
RR->localSecretCipher.decrypt(data + 1 + ZT_ADDRESS_LENGTH, k);
RR->localSecretCipher.decrypt(data + 1 + ZT_ADDRESS_LENGTH + 16, k + 16);
RR->localSecretCipher.decrypt(data + 1 + ZT_ADDRESS_LENGTH + 32, k + 32);
ctx.localSecretCipher.decrypt(data + 1 + ZT_ADDRESS_LENGTH, k);
ctx.localSecretCipher.decrypt(data + 1 + ZT_ADDRESS_LENGTH + 16, k + 16);
ctx.localSecretCipher.decrypt(data + 1 + ZT_ADDRESS_LENGTH + 32, k + 32);
m_identityKey.set(new SymmetricKey(ticks, k));
Utils::burn(k, sizeof(k));
}
@ -608,7 +608,7 @@ int Peer::unmarshal(const int64_t ticks, const uint8_t *restrict data, const int
if (!m_identityKey) {
uint8_t k[ZT_SYMMETRIC_KEY_SIZE];
if (!RR->identity.agree(m_id, k))
if (!ctx.identity.agree(m_id, k))
return -1;
m_identityKey.set(new SymmetricKey(ticks, k));
Utils::burn(k, sizeof(k));
@ -672,7 +672,7 @@ struct _PathPriorityComparisonOperator
}
};
void Peer::m_prioritizePaths(CallContext &cc)
void Peer::m_prioritizePaths(const CallContext &cc)
{
// assumes _lock is locked for writing
m_lastPrioritizedPaths = cc.ticks;
@ -693,32 +693,32 @@ void Peer::m_prioritizePaths(CallContext &cc)
}
}
unsigned int Peer::m_sendProbe(CallContext &cc, int64_t localSocket, const InetAddress &atAddress, const uint16_t *ports, const unsigned int numPorts)
unsigned int Peer::m_sendProbe(const Context &ctx, const CallContext &cc, int64_t localSocket, const InetAddress &atAddress, const uint16_t *ports, const unsigned int numPorts)
{
// Assumes m_lock is locked
const SharedPtr< SymmetricKey > k(m_key());
const uint64_t packetId = k->nextMessage(RR->identity.address(), m_id.address());
const uint64_t packetId = k->nextMessage(ctx.identity.address(), m_id.address());
uint8_t p[ZT_PROTO_MIN_PACKET_LENGTH];
Utils::storeMachineEndian< uint64_t >(p + ZT_PROTO_PACKET_ID_INDEX, packetId);
m_id.address().copyTo(p + ZT_PROTO_PACKET_DESTINATION_INDEX);
RR->identity.address().copyTo(p + ZT_PROTO_PACKET_SOURCE_INDEX);
ctx.identity.address().copyTo(p + ZT_PROTO_PACKET_SOURCE_INDEX);
p[ZT_PROTO_PACKET_FLAGS_INDEX] = 0;
p[ZT_PROTO_PACKET_VERB_INDEX] = Protocol::VERB_ECHO;
Protocol::armor(p, ZT_PROTO_MIN_PACKET_LENGTH, k, cipher());
RR->expect->sending(packetId, cc.ticks);
ctx.expect->sending(packetId, cc.ticks);
if (numPorts > 0) {
InetAddress tmp(atAddress);
for (unsigned int i = 0; i < numPorts; ++i) {
tmp.setPort(ports[i]);
RR->cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, cc.tPtr, -1, reinterpret_cast<const ZT_InetAddress *>(&tmp), p, ZT_PROTO_MIN_PACKET_LENGTH, 0);
ctx.cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(ctx.node), ctx.uPtr, cc.tPtr, -1, reinterpret_cast<const ZT_InetAddress *>(&tmp), p, ZT_PROTO_MIN_PACKET_LENGTH, 0);
}
return ZT_PROTO_MIN_PACKET_LENGTH * numPorts;
} else {
RR->cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(RR->node), RR->uPtr, cc.tPtr, -1, reinterpret_cast<const ZT_InetAddress *>(&atAddress), p, ZT_PROTO_MIN_PACKET_LENGTH, 0);
ctx.cb.wirePacketSendFunction(reinterpret_cast<ZT_Node *>(ctx.node), ctx.uPtr, cc.tPtr, -1, reinterpret_cast<const ZT_InetAddress *>(&atAddress), p, ZT_PROTO_MIN_PACKET_LENGTH, 0);
return ZT_PROTO_MIN_PACKET_LENGTH;
}
}

View file

@ -15,7 +15,7 @@
#define ZT_PEER_HPP
#include "Constants.hpp"
#include "RuntimeEnvironment.hpp"
#include "Context.hpp"
#include "Node.hpp"
#include "Path.hpp"
#include "Address.hpp"
@ -55,7 +55,6 @@ class Topology;
class Peer
{
friend class SharedPtr< Peer >;
friend class Topology;
public:
@ -64,10 +63,8 @@ public:
*
* New peers must be initialized via either init() or unmarshal() prior to
* use or null pointer dereference may occur.
*
* @param renv Runtime environment
*/
explicit Peer(const RuntimeEnvironment *renv);
Peer();
~Peer();
@ -77,7 +74,7 @@ public:
* @param peerIdentity The peer's identity
* @return True if initialization was succcesful
*/
bool init(CallContext &cc, const Identity &peerIdentity);
bool init(const Context &ctx, const CallContext &cc, const Identity &peerIdentity);
/**
* @return This peer's ZT address (short for identity().address())
@ -133,7 +130,8 @@ public:
* @param inReVerb In-reply verb for OK or ERROR verbs
*/
void received(
CallContext &cc,
const Context &ctx,
const CallContext &cc,
const SharedPtr< Path > &path,
unsigned int hops,
uint64_t packetId,
@ -146,7 +144,7 @@ public:
*
* @param bytes Number of bytes written
*/
ZT_INLINE void sent(CallContext &cc, const unsigned int bytes) noexcept
ZT_INLINE void sent(const CallContext &cc, const unsigned int bytes) noexcept
{
m_lastSend = cc.ticks;
m_outMeter.log(cc.ticks, bytes);
@ -157,7 +155,7 @@ public:
*
* @param bytes Number of bytes relayed
*/
ZT_INLINE void relayed(CallContext &cc, const unsigned int bytes) noexcept
ZT_INLINE void relayed(const CallContext &cc, const unsigned int bytes) noexcept
{ m_relayedMeter.log(cc.ticks, bytes); }
/**
@ -165,7 +163,7 @@ public:
*
* @return Current best path or NULL if there is no direct path
*/
ZT_INLINE SharedPtr< Path > path(CallContext &cc) noexcept
ZT_INLINE SharedPtr< Path > path(const CallContext &cc) noexcept
{
if (likely((cc.ticks - m_lastPrioritizedPaths) < ZT_PEER_PRIORITIZE_PATHS_INTERVAL)) {
RWMutex::RLock l(m_lock);
@ -187,9 +185,9 @@ public:
* @param len Length in bytes
* @param via Path over which to send data (may or may not be an already-learned path for this peer)
*/
ZT_INLINE void send(CallContext &cc, const void *data, unsigned int len, const SharedPtr< Path > &via) noexcept
ZT_INLINE void send(const Context &ctx, const CallContext &cc, const void *data, unsigned int len, const SharedPtr< Path > &via) noexcept
{
via->send(RR, cc, data, len);
via->send(ctx, cc, data, len);
sent(cc, len);
}
@ -202,7 +200,7 @@ public:
* @param data Data to send
* @param len Length in bytes
*/
void send(CallContext &cc, const void *data, unsigned int len) noexcept;
void send(const Context &ctx, const CallContext &cc, const void *data, unsigned int len) noexcept;
/**
* Send a HELLO to this peer at a specified physical address.
@ -211,14 +209,14 @@ public:
* @param atAddress Destination address
* @return Number of bytes sent
*/
unsigned int hello(CallContext &cc, int64_t localSocket, const InetAddress &atAddress);
unsigned int hello(const Context &ctx, const CallContext &cc, int64_t localSocket, const InetAddress &atAddress);
/**
* Ping this peer if needed and/or perform other periodic tasks.
*
* @param isRoot True if this peer is a root
*/
void pulse(CallContext &cc, bool isRoot);
void pulse(const Context &ctx, const CallContext &cc, bool isRoot);
/**
* Attempt to contact this peer at a given endpoint.
@ -226,7 +224,7 @@ public:
* @param ep Endpoint to attempt to contact
* @param tries Number of times to try (default: 1)
*/
void contact(CallContext &cc, const Endpoint &ep, int tries = 1);
void contact(const Context &ctx, const CallContext &cc, const Endpoint &ep, int tries = 1);
/**
* Reset paths within a given IP scope and address family
@ -239,22 +237,22 @@ public:
* @param scope IP scope
* @param inetAddressFamily Family e.g. AF_INET
*/
void resetWithinScope(CallContext &cc, InetAddress::IpScope scope, int inetAddressFamily);
void resetWithinScope(const Context &ctx, const CallContext &cc, InetAddress::IpScope scope, int inetAddressFamily);
/**
* @return Time of last receive of anything, whether direct or relayed
*/
ZT_INLINE int64_t lastReceive() const noexcept
{ return m_lastReceive; }
{ return m_lastReceive.load(std::memory_order_relaxed); }
/**
* @return Average latency of all direct paths or -1 if no direct paths or unknown
*/
ZT_INLINE int latency() const noexcept
{
RWMutex::RLock l(m_lock);
int ltot = 0;
int lcnt = 0;
RWMutex::RLock l(m_lock);
for (unsigned int i = 0; i < m_alivePathCount; ++i) {
int lat = m_paths[i]->latency();
if (lat > 0) {
@ -369,16 +367,16 @@ public:
/**
* Save the latest version of this peer to the data store
*/
void save(CallContext &cc) const;
void save(const Context &ctx, const CallContext &cc) const;
// NOTE: peer marshal/unmarshal only saves/restores the identity, locator, most
// recent bootstrap address, and version information.
static constexpr int marshalSizeMax() noexcept
{ return ZT_PEER_MARSHAL_SIZE_MAX; }
int marshal(uint8_t data[ZT_PEER_MARSHAL_SIZE_MAX]) const noexcept;
int marshal(const Context &ctx, uint8_t data[ZT_PEER_MARSHAL_SIZE_MAX]) const noexcept;
int unmarshal(int64_t ticks, const uint8_t *restrict data, int len) noexcept;
int unmarshal(const Context &ctx, int64_t ticks, const uint8_t *restrict data, int len) noexcept;
/**
* Rate limit gate for inbound WHOIS requests
@ -432,8 +430,8 @@ public:
}
private:
void m_prioritizePaths(CallContext &cc);
unsigned int m_sendProbe(CallContext &cc, int64_t localSocket, const InetAddress &atAddress, const uint16_t *ports, unsigned int numPorts);
void m_prioritizePaths(const CallContext &cc);
unsigned int m_sendProbe(const Context &ctx, const CallContext &cc, int64_t localSocket, const InetAddress &atAddress, const uint16_t *ports, unsigned int numPorts);
void m_deriveSecondaryIdentityKeys() noexcept;
ZT_INLINE SharedPtr< SymmetricKey > m_key() noexcept
@ -442,8 +440,6 @@ private:
return (m_ephemeralKeys[0]) ? m_ephemeralKeys[0] : m_identityKey;
}
const RuntimeEnvironment *RR;
// Read/write mutex for non-atomic non-const fields.
RWMutex m_lock;

View file

@ -30,7 +30,7 @@
namespace ZeroTier {
class RuntimeEnvironment;
class Context;
/**
* Revocation certificate to instantaneously revoke a COM, capability, or tag
@ -44,7 +44,7 @@ public:
{ return ZT_CREDENTIAL_TYPE_REVOCATION; }
ZT_INLINE RevocationCredential() noexcept
{ memoryZero(this); } // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
{ memoryZero(this); }
/**
* @param i ID (arbitrary for revocations, currently random)
@ -110,8 +110,8 @@ public:
* @param RR Runtime environment to provide for peer lookup, etc.
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
*/
ZT_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR, CallContext &cc) const noexcept
{ return s_verify(RR, cc, *this); }
ZT_INLINE Credential::VerifyResult verify(const Context &ctx, const CallContext &cc) const noexcept
{ return s_verify(ctx, cc, *this); }
static constexpr int marshalSizeMax() noexcept
{ return ZT_REVOCATION_MARSHAL_SIZE_MAX; }

View file

@ -13,7 +13,7 @@
#include "Constants.hpp"
#include "SelfAwareness.hpp"
#include "RuntimeEnvironment.hpp"
#include "Context.hpp"
#include "Topology.hpp"
#include "Peer.hpp"
#include "Trace.hpp"
@ -24,10 +24,9 @@
namespace ZeroTier {
SelfAwareness::SelfAwareness(const RuntimeEnvironment *renv) :
RR(renv)
{
}
SelfAwareness::SelfAwareness(const Context &ctx) :
m_ctx(ctx)
{}
void SelfAwareness::iam(CallContext &cc, const Identity &reporter, const int64_t receivedOnLocalSocket, const InetAddress &reporterPhysicalAddress, const InetAddress &myPhysicalAddress, bool trusted)
{
@ -56,11 +55,11 @@ void SelfAwareness::iam(CallContext &cc, const Identity &reporter, const int64_t
// Reset all paths within this scope and address family
Vector< SharedPtr< Peer > > peers, rootPeers;
RR->topology->allPeers(peers, rootPeers);
m_ctx.topology->allPeers(peers, rootPeers);
for(Vector< SharedPtr< Peer > >::const_iterator p(peers.begin());p!=peers.end();++p)
(*p)->resetWithinScope(cc, (InetAddress::IpScope)scope, myPhysicalAddress.as.sa.sa_family);
(*p)->resetWithinScope(m_ctx, cc, (InetAddress::IpScope)scope, myPhysicalAddress.as.sa.sa_family);
RR->t->resettingPathsInScope(cc, 0x9afff100, reporter, reporterPhysicalAddress, entry.mySurface, myPhysicalAddress, scope);
m_ctx.t->resettingPathsInScope(cc, 0x9afff100, reporter, reporterPhysicalAddress, entry.mySurface, myPhysicalAddress, scope);
} else {
// Otherwise just update DB to use to determine external surface info
entry.mySurface = myPhysicalAddress;

View file

@ -25,7 +25,7 @@ namespace ZeroTier {
class Identity;
class RuntimeEnvironment;
class Context;
/**
* SelfAwareness manages awareness of this peer's external address(es) and NAT situation.
@ -35,7 +35,7 @@ class RuntimeEnvironment;
class SelfAwareness
{
public:
explicit SelfAwareness(const RuntimeEnvironment *renv);
explicit SelfAwareness(const Context &ctx);
/**
* Called when a remote peer informs us of our external network address
@ -115,7 +115,7 @@ private:
{}
};
const RuntimeEnvironment *RR;
const Context &m_ctx;
Map< p_PhySurfaceKey, p_PhySurfaceEntry > m_phy;
Mutex m_phy_l;
};

View file

@ -16,7 +16,7 @@
#include "Constants.hpp"
#include "Containers.hpp"
#include "RuntimeEnvironment.hpp"
#include "Context.hpp"
#include "CallContext.hpp"
namespace ZeroTier {
@ -27,7 +27,7 @@ namespace ZeroTier {
class Store
{
public:
ZT_INLINE Store(const RuntimeEnvironment *const renv): RR(renv)
ZT_INLINE Store(const Context *const renv): RR(renv)
{}
/**
@ -38,7 +38,7 @@ public:
* @param idSize Size of object ID in qwords
* @return Data or empty vector if not found
*/
ZT_INLINE Vector< uint8_t > get(CallContext &cc, ZT_StateObjectType type, const uint64_t *id, unsigned int idSize) const
ZT_INLINE Vector< uint8_t > get(const CallContext &cc, ZT_StateObjectType type, const uint64_t *id, unsigned int idSize) const
{
Vector< uint8_t > dv;
void *data = nullptr;
@ -60,7 +60,7 @@ public:
* @param data Data to store
* @param len Length of data
*/
ZT_INLINE void put(CallContext &cc, ZT_StateObjectType type, const uint64_t *const id, const unsigned int idSize, const void *const data, const unsigned int len) noexcept
ZT_INLINE void put(const CallContext &cc, ZT_StateObjectType type, const uint64_t *const id, const unsigned int idSize, const void *const data, const unsigned int len) noexcept
{ RR->cb.statePutFunction(reinterpret_cast<ZT_Node *>(this), RR->uPtr, cc.tPtr, type, id, idSize, data, (int)len); }
/**
@ -70,11 +70,11 @@ public:
* @param id Object ID
* @param idSize Size of object ID in qwords
*/
ZT_INLINE void erase(CallContext &cc, ZT_StateObjectType type, const uint64_t *const id, const unsigned int idSize) noexcept
ZT_INLINE void erase(const CallContext &cc, ZT_StateObjectType type, const uint64_t *const id, const unsigned int idSize) noexcept
{ RR->cb.statePutFunction(reinterpret_cast<ZT_Node *>(this), RR->uPtr, cc.tPtr, type, id, idSize, nullptr, -1); }
private:
const RuntimeEnvironment *RR;
const Context *RR;
};
} // namespace ZeroTier

View file

@ -24,7 +24,7 @@
namespace ZeroTier {
class RuntimeEnvironment;
class Context;
/**
* A tag that can be associated with members and matched in rules
@ -113,8 +113,8 @@ public:
* @param RR Runtime environment to allow identity lookup for signedBy
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
*/
ZT_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR, CallContext &cc) const noexcept
{ return s_verify(RR, cc, *this); }
ZT_INLINE Credential::VerifyResult verify(const Context &ctx, const CallContext &cc) const noexcept
{ return s_verify(ctx, cc, *this); }
static constexpr int marshalSizeMax() noexcept
{ return ZT_TAG_MARSHAL_SIZE_MAX; }

View file

@ -18,11 +18,11 @@
namespace ZeroTier {
Topology::Topology(const RuntimeEnvironment *renv, CallContext &cc) :
RR(renv)
Topology::Topology(const Context &ctx, const CallContext &cc) :
m_ctx(ctx)
{}
SharedPtr< Peer > Topology::add(CallContext &cc, const SharedPtr< Peer > &peer)
SharedPtr< Peer > Topology::add(const CallContext &cc, const SharedPtr< Peer > &peer)
{
RWMutex::Lock _l(m_peers_l);
SharedPtr< Peer > &hp = m_peers[peer->address()];
@ -50,7 +50,7 @@ void Topology::allPeers(Vector< SharedPtr< Peer > > &allPeers, Vector< SharedPtr
}
}
void Topology::doPeriodicTasks(CallContext &cc)
void Topology::doPeriodicTasks(const CallContext &cc)
{
// Get a list of root peer pointer addresses for filtering during peer cleanup.
Vector< uintptr_t > rootLookup;
@ -88,7 +88,7 @@ void Topology::doPeriodicTasks(CallContext &cc)
}
}
if (toSave)
toSave->save(cc);
toSave->save(m_ctx, cc);
}
}
}
@ -119,9 +119,9 @@ void Topology::doPeriodicTasks(CallContext &cc)
}
}
void Topology::trustStoreChanged(CallContext &cc)
void Topology::trustStoreChanged(const CallContext &cc)
{
Map< Identity, SharedPtr< const Locator > > roots(RR->ts->roots());
Map< Identity, SharedPtr< const Locator > > roots(m_ctx.ts->roots());
Vector< SharedPtr< Peer > > newRootList;
newRootList.reserve(roots.size());
@ -129,8 +129,8 @@ void Topology::trustStoreChanged(CallContext &cc)
for (Map< Identity, SharedPtr< const Locator > >::const_iterator r(roots.begin()); r != roots.end(); ++r) {
SharedPtr< Peer > root(this->peer(cc, r->first.address(), true));
if (!root) {
root.set(new Peer(RR));
root->init(cc, r->first);
root.set(new Peer());
root->init(m_ctx, cc, r->first);
root = this->add(cc, root);
}
newRootList.push_back(root);
@ -145,11 +145,11 @@ void Topology::trustStoreChanged(CallContext &cc)
}
}
void Topology::saveAll(CallContext &cc)
void Topology::saveAll(const CallContext &cc)
{
RWMutex::RLock l(m_peers_l);
for (Map< Address, SharedPtr< Peer > >::iterator i(m_peers.begin()); i != m_peers.end(); ++i)
i->second->save(cc);
i->second->save(m_ctx, cc);
}
struct p_RootRankingComparisonOperator
@ -190,7 +190,7 @@ void Topology::m_rankRoots()
}
}
void Topology::m_loadCached(CallContext &cc, const Address &zta, SharedPtr< Peer > &peer)
void Topology::m_loadCached(const CallContext &cc, const Address &zta, SharedPtr< Peer > &peer)
{
// does not require any locks to be held
@ -198,14 +198,14 @@ void Topology::m_loadCached(CallContext &cc, const Address &zta, SharedPtr< Peer
uint64_t id[2];
id[0] = zta.toInt();
id[1] = 0;
Vector< uint8_t > data(RR->store->get(cc, ZT_STATE_OBJECT_PEER, id, 1));
Vector< uint8_t > data(m_ctx.store->get(cc, ZT_STATE_OBJECT_PEER, id, 1));
if (data.size() > 8) {
const uint8_t *d = data.data();
int dl = (int)data.size();
const int64_t ts = (int64_t)Utils::loadBigEndian< uint64_t >(d);
Peer *const p = new Peer(RR);
int n = p->unmarshal(cc.ticks, d + 8, dl - 8);
Peer *const p = new Peer();
int n = p->unmarshal(m_ctx, cc.ticks, d + 8, dl - 8);
if (n < 0) {
delete p;
return;
@ -221,7 +221,7 @@ void Topology::m_loadCached(CallContext &cc, const Address &zta, SharedPtr< Peer
}
}
SharedPtr< Peer > Topology::m_peerFromCached(CallContext &cc, const Address &zta)
SharedPtr< Peer > Topology::m_peerFromCached(const CallContext &cc, const Address &zta)
{
SharedPtr< Peer > p;
m_loadCached(cc, zta, p);

View file

@ -32,7 +32,7 @@
namespace ZeroTier {
class RuntimeEnvironment;
class Context;
/**
* Database of network topology
@ -40,7 +40,7 @@ class RuntimeEnvironment;
class Topology
{
public:
Topology(const RuntimeEnvironment *renv, CallContext &cc);
Topology(const Context &ctx, const CallContext &cc);
/**
* Add peer to database
@ -51,7 +51,7 @@ public:
* @param peer Peer to add
* @return New or existing peer (should replace 'peer')
*/
SharedPtr< Peer > add(CallContext &cc, const SharedPtr< Peer > &peer);
SharedPtr< Peer > add(const CallContext &cc, const SharedPtr< Peer > &peer);
/**
* Get a peer from its address
@ -60,7 +60,7 @@ public:
* @param loadFromCached If false do not load from cache if not in memory (default: true)
* @return Peer or NULL if not found
*/
ZT_INLINE SharedPtr< Peer > peer(CallContext &cc, const Address &zta, const bool loadFromCached = true)
ZT_INLINE SharedPtr< Peer > peer(const CallContext &cc, const Address &zta, const bool loadFromCached = true)
{
{
RWMutex::RLock l(m_peers_l);
@ -125,14 +125,14 @@ public:
/**
* Do periodic tasks such as database cleanup, cert cleanup, root ranking, etc.
*/
void doPeriodicTasks(CallContext &cc);
void doPeriodicTasks(const CallContext &cc);
/**
* Rank root servers in descending order of quality
*
* @param now Current time
*/
ZT_INLINE void rankRoots(CallContext &cc)
ZT_INLINE void rankRoots(const CallContext &cc)
{
Mutex::Lock l(m_roots_l);
m_rankRoots();
@ -141,20 +141,20 @@ public:
/**
* Perform internal updates based on changes in the trust store
*/
void trustStoreChanged(CallContext &cc);
void trustStoreChanged(const CallContext &cc);
/**
* Save all currently known peers to data store
*/
void saveAll(CallContext &cc);
void saveAll(const CallContext &cc);
private:
void m_rankRoots();
void m_loadCached(CallContext &cc, const Address &zta, SharedPtr< Peer > &peer);
SharedPtr< Peer > m_peerFromCached(CallContext &cc, const Address &zta);
void m_loadCached(const CallContext &cc, const Address &zta, SharedPtr< Peer > &peer);
SharedPtr< Peer > m_peerFromCached(const CallContext &cc, const Address &zta);
SharedPtr< Path > m_newPath(int64_t l, const InetAddress &r, const Path::Key &k);
const RuntimeEnvironment *const RR;
const Context &m_ctx;
Vector< SharedPtr< Peer > > m_roots;
Map< Address, SharedPtr< Peer > > m_peers;

View file

@ -12,7 +12,7 @@
/****/
#include "Trace.hpp"
#include "RuntimeEnvironment.hpp"
#include "Context.hpp"
#include "Node.hpp"
#include "Peer.hpp"
#include "InetAddress.hpp"
@ -22,14 +22,13 @@
namespace ZeroTier {
Trace::Trace(const RuntimeEnvironment *renv) :
RR(renv),
Trace::Trace(const Context &ctx) :
m_ctx(ctx),
m_traceFlags(0)
{
}
{}
void Trace::unexpectedError(
CallContext &cc,
const CallContext &cc,
uint32_t codeLocation,
const char *message,
...)
@ -39,7 +38,7 @@ void Trace::unexpectedError(
Dictionary::append(buf, ZT_TRACE_FIELD_CODE_LOCATION, codeLocation);
Dictionary::append(buf, ZT_TRACE_FIELD_MESSAGE, message);
buf.push_back(0);
RR->node->postEvent(cc.tPtr, ZT_EVENT_TRACE, buf.data());
m_ctx.node->postEvent(cc.tPtr, ZT_EVENT_TRACE, buf.data());
}
void Trace::m_resettingPathsInScope(
@ -64,7 +63,7 @@ void Trace::m_resettingPathsInScope(
Dictionary::appendObject(buf, ZT_TRACE_FIELD_NEW_ENDPOINT, Endpoint(newExternal));
Dictionary::append(buf, ZT_TRACE_FIELD_RESET_ADDRESS_SCOPE, scope);
buf.push_back(0);
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
m_ctx.node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
}
void Trace::m_tryingNewPath(
@ -90,7 +89,7 @@ void Trace::m_tryingNewPath(
if (triggeringPeer)
Dictionary::appendObject(buf, ZT_TRACE_FIELD_TRIGGER_FROM_PEER_FINGERPRINT, triggeringPeer.fingerprint());
buf.push_back(0);
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
m_ctx.node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
}
}
@ -113,7 +112,7 @@ void Trace::m_learnedNewPath(
if (replaced)
Dictionary::appendObject(buf, ZT_TRACE_FIELD_OLD_ENDPOINT, Endpoint(replaced));
buf.push_back(0);
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
m_ctx.node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
}
}
@ -141,7 +140,7 @@ void Trace::m_incomingPacketDropped(
Dictionary::append(buf, ZT_TRACE_FIELD_PACKET_VERB, verb);
Dictionary::append(buf, ZT_TRACE_FIELD_REASON, reason);
buf.push_back(0);
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
m_ctx.node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
}
void Trace::m_outgoingNetworkFrameDropped(
@ -167,7 +166,7 @@ void Trace::m_outgoingNetworkFrameDropped(
Dictionary::append(buf, ZT_TRACE_FIELD_FRAME_DATA, frameData, std::min((unsigned int)64, (unsigned int)frameLength));
Dictionary::append(buf, ZT_TRACE_FIELD_REASON, reason);
buf.push_back(0);
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
m_ctx.node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
}
void Trace::m_incomingNetworkFrameDropped(
@ -204,7 +203,7 @@ void Trace::m_incomingNetworkFrameDropped(
Dictionary::append(buf, ZT_TRACE_FIELD_FLAG_CREDENTIAL_REQUEST_SENT, credentialRequestSent);
Dictionary::append(buf, ZT_TRACE_FIELD_REASON, reason);
buf.push_back(0);
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
m_ctx.node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
}
void Trace::m_networkConfigRequestSent(
@ -217,7 +216,7 @@ void Trace::m_networkConfigRequestSent(
Dictionary::append(buf, ZT_TRACE_FIELD_CODE_LOCATION, codeLocation);
Dictionary::append(buf, ZT_TRACE_FIELD_NETWORK_ID, networkId);
buf.push_back(0);
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
m_ctx.node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
}
void Trace::m_networkFilter(
@ -263,7 +262,7 @@ void Trace::m_networkFilter(
Dictionary::append(buf, ZT_TRACE_FIELD_RULE_FLAG_INBOUND, inbound);
Dictionary::append(buf, ZT_TRACE_FIELD_RULE_FLAG_ACCEPT, (int32_t)accept);
buf.push_back(0);
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
m_ctx.node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
}
void Trace::m_credentialRejected(
@ -286,7 +285,7 @@ void Trace::m_credentialRejected(
Dictionary::append(buf, ZT_TRACE_FIELD_CREDENTIAL_TYPE, credentialType);
Dictionary::append(buf, ZT_TRACE_FIELD_REASON, reason);
buf.push_back(0);
RR->node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
m_ctx.node->postEvent(tPtr, ZT_EVENT_TRACE, buf.data());
}
} // namespace ZeroTier

View file

@ -31,7 +31,7 @@
namespace ZeroTier {
class RuntimeEnvironment;
class Context;
class Identity;
class Peer;
class Path;
@ -73,16 +73,16 @@ public:
{ memoryZero(this); }
};
explicit Trace(const RuntimeEnvironment *renv);
explicit Trace(const Context &ctx);
void unexpectedError(
CallContext &cc,
const CallContext &cc,
uint32_t codeLocation,
const char *message,
...);
ZT_INLINE void resettingPathsInScope(
CallContext &cc,
const CallContext &cc,
const uint32_t codeLocation,
const Identity &reporter,
const InetAddress &from,
@ -95,7 +95,7 @@ public:
}
ZT_INLINE void tryingNewPath(
CallContext &cc,
const CallContext &cc,
const uint32_t codeLocation,
const Identity &trying,
const InetAddress &physicalAddress,
@ -109,7 +109,7 @@ public:
}
ZT_INLINE void learnedNewPath(
CallContext &cc,
const CallContext &cc,
const uint32_t codeLocation,
uint64_t packetId,
const Identity &peerIdentity,
@ -121,7 +121,7 @@ public:
}
ZT_INLINE void incomingPacketDropped(
CallContext &cc,
const CallContext &cc,
const uint32_t codeLocation,
uint64_t packetId,
uint64_t networkId,
@ -136,7 +136,7 @@ public:
}
ZT_INLINE void outgoingNetworkFrameDropped(
CallContext &cc,
const CallContext &cc,
const uint32_t codeLocation,
uint64_t networkId,
const MAC &sourceMac,
@ -151,7 +151,7 @@ public:
}
ZT_INLINE void incomingNetworkFrameDropped(
CallContext &cc,
const CallContext &cc,
const uint32_t codeLocation,
uint64_t networkId,
const MAC &sourceMac,
@ -171,7 +171,7 @@ public:
}
ZT_INLINE void networkConfigRequestSent(
CallContext &cc,
const CallContext &cc,
const uint32_t codeLocation,
uint64_t networkId)
{
@ -180,7 +180,7 @@ public:
}
ZT_INLINE void networkFilter(
CallContext &cc,
const CallContext &cc,
const uint32_t codeLocation,
uint64_t networkId,
const uint8_t primaryRuleSetLog[512],
@ -223,7 +223,7 @@ public:
}
ZT_INLINE void credentialRejected(
CallContext &cc,
const CallContext &cc,
const uint32_t codeLocation,
uint64_t networkId,
const Identity &identity,
@ -337,7 +337,7 @@ private:
uint8_t credentialType,
ZT_TraceCredentialRejectionReason reason);
const RuntimeEnvironment *const RR;
const Context &m_ctx;
volatile unsigned int m_traceFlags; // faster than atomic, but may not "instantly" change... should be okay
};

View file

@ -15,7 +15,7 @@
#define ZT_TRUSTSTORE_HPP
#include "Constants.hpp"
#include "RuntimeEnvironment.hpp"
#include "Context.hpp"
#include "Containers.hpp"
#include "Certificate.hpp"
#include "SHA512.hpp"

View file

@ -12,7 +12,7 @@
/****/
#include "VL1.hpp"
#include "RuntimeEnvironment.hpp"
#include "Context.hpp"
#include "Topology.hpp"
#include "VL2.hpp"
#include "AES.hpp"
@ -95,13 +95,13 @@ struct p_PolyCopyFunction
} // anonymous namespace
VL1::VL1(const RuntimeEnvironment *renv) :
RR(renv)
VL1::VL1(const Context &ctx) :
m_ctx(ctx)
{}
void VL1::onRemotePacket(CallContext &cc, const int64_t localSocket, const InetAddress &fromAddr, SharedPtr< Buf > &data, const unsigned int len) noexcept
{
const SharedPtr< Path > path(RR->topology->path(localSocket, fromAddr));
const SharedPtr< Path > path(m_ctx.topology->path(localSocket, fromAddr));
ZT_SPEW("%u bytes from %s (local socket %lld)", len, fromAddr.toString().c_str(), localSocket);
path->received(cc, len);
@ -119,7 +119,7 @@ void VL1::onRemotePacket(CallContext &cc, const int64_t localSocket, const InetA
static_assert((ZT_PROTO_PACKET_DESTINATION_INDEX + ZT_ADDRESS_LENGTH) < ZT_PROTO_MIN_FRAGMENT_LENGTH, "overflow");
const Address destination(data->unsafeData + ZT_PROTO_PACKET_DESTINATION_INDEX);
if (destination != RR->identity.address()) {
if (destination != m_ctx.identity.address()) {
m_relay(cc, path, destination, data, len);
return;
}
@ -215,7 +215,7 @@ void VL1::onRemotePacket(CallContext &cc, const int64_t localSocket, const InetA
}
const SharedPtr< Peer > peer(m_HELLO(cc, path, *pkt, pktSize));
if (likely(peer))
peer->received(cc, path, hops, packetId, pktSize - ZT_PROTO_PACKET_PAYLOAD_START, Protocol::VERB_HELLO, Protocol::VERB_NOP);
peer->received(m_ctx, cc, path, hops, packetId, pktSize - ZT_PROTO_PACKET_PAYLOAD_START, Protocol::VERB_HELLO, Protocol::VERB_NOP);
return;
}
@ -224,7 +224,7 @@ void VL1::onRemotePacket(CallContext &cc, const int64_t localSocket, const InetA
// secrecy status.
unsigned int auth = 0;
SharedPtr< Peer > peer(RR->topology->peer(cc, source));
SharedPtr< Peer > peer(m_ctx.topology->peer(cc, source));
if (likely(peer)) {
switch (cipher) {
@ -244,7 +244,7 @@ void VL1::onRemotePacket(CallContext &cc, const int64_t localSocket, const InetA
static_assert((ZT_PROTO_PACKET_MAC_INDEX + 8) < ZT_PROTO_MIN_PACKET_LENGTH, "overflow");
if (unlikely(Utils::loadMachineEndian< uint64_t >(hdr + ZT_PROTO_PACKET_MAC_INDEX) != mac[0])) {
ZT_SPEW("discarding packet %.16llx from %s(%s): packet MAC failed (none/poly1305)", packetId, source.toString().c_str(), fromAddr.toString().c_str());
RR->t->incomingPacketDropped(cc, 0xcc89c812, packetId, 0, peer->identity(), path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
m_ctx.t->incomingPacketDropped(cc, 0xcc89c812, packetId, 0, peer->identity(), path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
return;
}
@ -268,7 +268,7 @@ void VL1::onRemotePacket(CallContext &cc, const int64_t localSocket, const InetA
static_assert((ZT_PROTO_PACKET_MAC_INDEX + 8) < ZT_PROTO_MIN_PACKET_LENGTH, "overflow");
if (unlikely(Utils::loadMachineEndian< uint64_t >(hdr + ZT_PROTO_PACKET_MAC_INDEX) != mac[0])) {
ZT_SPEW("discarding packet %.16llx from %s(%s): packet MAC failed (salsa/poly1305)", packetId, source.toString().c_str(), fromAddr.toString().c_str());
RR->t->incomingPacketDropped(cc, 0xcc89c812, packetId, 0, peer->identity(), path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
m_ctx.t->incomingPacketDropped(cc, 0xcc89c812, packetId, 0, peer->identity(), path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
return;
}
@ -287,7 +287,7 @@ void VL1::onRemotePacket(CallContext &cc, const int64_t localSocket, const InetA
break;
default:
RR->t->incomingPacketDropped(cc, 0x5b001099, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
m_ctx.t->incomingPacketDropped(cc, 0x5b001099, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
return;
}
}
@ -326,7 +326,7 @@ void VL1::onRemotePacket(CallContext &cc, const int64_t localSocket, const InetA
ZT_SPEW("decompressed packet: %d -> %d", pktSize, ZT_PROTO_PACKET_PAYLOAD_START + uncompressedLen);
pktSize = ZT_PROTO_PACKET_PAYLOAD_START + uncompressedLen;
} else {
RR->t->incomingPacketDropped(cc, 0xee9e4392, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, verb, ZT_TRACE_PACKET_DROP_REASON_INVALID_COMPRESSED_DATA);
m_ctx.t->incomingPacketDropped(cc, 0xee9e4392, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, verb, ZT_TRACE_PACKET_DROP_REASON_INVALID_COMPRESSED_DATA);
return;
}
}
@ -359,31 +359,31 @@ void VL1::onRemotePacket(CallContext &cc, const int64_t localSocket, const InetA
ok = m_RENDEZVOUS(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_FRAME:
ok = RR->vl2->m_FRAME(cc, packetId, auth, path, peer, *pkt, pktSize);
ok = m_ctx.vl2->m_FRAME(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_EXT_FRAME:
ok = RR->vl2->m_EXT_FRAME(cc, packetId, auth, path, peer, *pkt, pktSize);
ok = m_ctx.vl2->m_EXT_FRAME(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_ECHO:
ok = m_ECHO(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_MULTICAST_LIKE:
ok = RR->vl2->m_MULTICAST_LIKE(cc, packetId, auth, path, peer, *pkt, pktSize);
ok = m_ctx.vl2->m_MULTICAST_LIKE(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_NETWORK_CREDENTIALS:
ok = RR->vl2->m_NETWORK_CREDENTIALS(cc, packetId, auth, path, peer, *pkt, pktSize);
ok = m_ctx.vl2->m_NETWORK_CREDENTIALS(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_NETWORK_CONFIG_REQUEST:
ok = RR->vl2->m_NETWORK_CONFIG_REQUEST(cc, packetId, auth, path, peer, *pkt, pktSize);
ok = m_ctx.vl2->m_NETWORK_CONFIG_REQUEST(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_NETWORK_CONFIG:
ok = RR->vl2->m_NETWORK_CONFIG(cc, packetId, auth, path, peer, *pkt, pktSize);
ok = m_ctx.vl2->m_NETWORK_CONFIG(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_MULTICAST_GATHER:
ok = RR->vl2->m_MULTICAST_GATHER(cc, packetId, auth, path, peer, *pkt, pktSize);
ok = m_ctx.vl2->m_MULTICAST_GATHER(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_MULTICAST_FRAME_deprecated:
ok = RR->vl2->m_MULTICAST_FRAME_deprecated(cc, packetId, auth, path, peer, *pkt, pktSize);
ok = m_ctx.vl2->m_MULTICAST_FRAME_deprecated(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_PUSH_DIRECT_PATHS:
ok = m_PUSH_DIRECT_PATHS(cc, packetId, auth, path, peer, *pkt, pktSize);
@ -392,18 +392,18 @@ void VL1::onRemotePacket(CallContext &cc, const int64_t localSocket, const InetA
ok = m_USER_MESSAGE(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_MULTICAST:
ok = RR->vl2->m_MULTICAST(cc, packetId, auth, path, peer, *pkt, pktSize);
ok = m_ctx.vl2->m_MULTICAST(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
case Protocol::VERB_ENCAP:
ok = m_ENCAP(cc, packetId, auth, path, peer, *pkt, pktSize);
break;
default:
RR->t->incomingPacketDropped(cc, 0xeeeeeff0, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, verb, ZT_TRACE_PACKET_DROP_REASON_UNRECOGNIZED_VERB);
m_ctx.t->incomingPacketDropped(cc, 0xeeeeeff0, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, verb, ZT_TRACE_PACKET_DROP_REASON_UNRECOGNIZED_VERB);
break;
}
if (likely(ok))
peer->received(cc, path, hops, packetId, pktSize - ZT_PROTO_PACKET_PAYLOAD_START, verb, inReVerb);
peer->received(m_ctx, cc, path, hops, packetId, pktSize - ZT_PROTO_PACKET_PAYLOAD_START, verb, inReVerb);
} else {
// If decryption and authentication were not successful, try to look up identities.
// This is rate limited by virtue of the retry rate limit timer.
@ -425,7 +425,7 @@ void VL1::onRemotePacket(CallContext &cc, const int64_t localSocket, const InetA
}
}
} catch (...) {
RR->t->unexpectedError(cc, 0xea1b6dea, "unexpected exception in onRemotePacket() parsing packet from %s", path->address().toString().c_str());
m_ctx.t->unexpectedError(cc, 0xea1b6dea, "unexpected exception in onRemotePacket() parsing packet from %s", path->address().toString().c_str());
}
}
@ -435,7 +435,7 @@ void VL1::m_relay(CallContext &cc, const SharedPtr< Path > &path, Address destin
void VL1::m_sendPendingWhois(CallContext &cc)
{
const SharedPtr< Peer > root(RR->topology->root());
const SharedPtr< Peer > root(m_ctx.topology->root());
if (unlikely(!root))
return;
const SharedPtr< Path > rootPath(root->path(cc));
@ -459,16 +459,16 @@ void VL1::m_sendPendingWhois(CallContext &cc)
uint8_t outp[ZT_DEFAULT_UDP_MTU - ZT_PROTO_MIN_PACKET_LENGTH];
Vector< Address >::iterator a(toSend.begin());
while (a != toSend.end()) {
const uint64_t packetId = key->nextMessage(RR->identity.address(), root->address());
int p = Protocol::newPacket(outp, packetId, root->address(), RR->identity.address(), Protocol::VERB_WHOIS);
const uint64_t packetId = key->nextMessage(m_ctx.identity.address(), root->address());
int p = Protocol::newPacket(outp, packetId, root->address(), m_ctx.identity.address(), Protocol::VERB_WHOIS);
while ((a != toSend.end()) && (p < (sizeof(outp) - ZT_ADDRESS_LENGTH))) {
a->copyTo(outp + p);
++a;
p += ZT_ADDRESS_LENGTH;
}
Protocol::armor(outp, p, key, root->cipher());
RR->expect->sending(packetId, cc.ticks);
root->send(cc, outp, p, rootPath);
m_ctx.expect->sending(packetId, cc.ticks);
root->send(m_ctx, cc, outp, p, rootPath);
}
}
}
@ -481,7 +481,7 @@ SharedPtr< Peer > VL1::m_HELLO(CallContext &cc, const SharedPtr< Path > &path, B
const uint8_t protoVersion = pkt.lI8< ZT_PROTO_PACKET_PAYLOAD_START >();
if (unlikely(protoVersion < ZT_PROTO_VERSION_MIN)) {
RR->t->incomingPacketDropped(cc, 0x907a9891, packetId, 0, Identity::NIL, path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_PEER_TOO_OLD);
m_ctx.t->incomingPacketDropped(cc, 0x907a9891, packetId, 0, Identity::NIL, path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_PEER_TOO_OLD);
return SharedPtr< Peer >();
}
const unsigned int versionMajor = pkt.lI8< ZT_PROTO_PACKET_PAYLOAD_START + 1 >();
@ -494,19 +494,19 @@ SharedPtr< Peer > VL1::m_HELLO(CallContext &cc, const SharedPtr< Path > &path, B
// Get identity and verify that it matches the sending address in the packet.
Identity id;
if (unlikely(pkt.rO(ii, id) < 0)) {
RR->t->incomingPacketDropped(cc, 0x707a9810, packetId, 0, Identity::NIL, path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
m_ctx.t->incomingPacketDropped(cc, 0x707a9810, packetId, 0, Identity::NIL, path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
return SharedPtr< Peer >();
}
if (unlikely(id.address() != Address(pkt.unsafeData + ZT_PROTO_PACKET_SOURCE_INDEX))) {
RR->t->incomingPacketDropped(cc, 0x707a9010, packetId, 0, Identity::NIL, path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
m_ctx.t->incomingPacketDropped(cc, 0x707a9010, packetId, 0, Identity::NIL, path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
return SharedPtr< Peer >();
}
// Get the peer that matches this identity, or learn a new one if we don't know it.
SharedPtr< Peer > peer(RR->topology->peer(cc, id.address(), true));
SharedPtr< Peer > peer(m_ctx.topology->peer(cc, id.address(), true));
if (peer) {
if (unlikely(peer->identity() != id)) {
RR->t->incomingPacketDropped(cc, 0x707a9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
m_ctx.t->incomingPacketDropped(cc, 0x707a9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
return SharedPtr< Peer >();
}
if (unlikely(peer->deduplicateIncomingPacket(packetId))) {
@ -515,15 +515,15 @@ SharedPtr< Peer > VL1::m_HELLO(CallContext &cc, const SharedPtr< Path > &path, B
}
} else {
if (unlikely(!id.locallyValidate())) {
RR->t->incomingPacketDropped(cc, 0x707a9892, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
m_ctx.t->incomingPacketDropped(cc, 0x707a9892, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
return SharedPtr< Peer >();
}
peer.set(new Peer(RR));
if (unlikely(!peer->init(cc, id))) {
RR->t->incomingPacketDropped(cc, 0x707a9893, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_UNSPECIFIED);
peer.set(new Peer());
if (unlikely(!peer->init(m_ctx, cc, id))) {
m_ctx.t->incomingPacketDropped(cc, 0x707a9893, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_UNSPECIFIED);
return SharedPtr< Peer >();
}
peer = RR->topology->add(cc, peer);
peer = m_ctx.topology->add(cc, peer);
}
// ------------------------------------------------------------------------------------------------------------------
@ -536,7 +536,7 @@ SharedPtr< Peer > VL1::m_HELLO(CallContext &cc, const SharedPtr< Path > &path, B
// field is ignored, and eventually it'll be undefined.
uint8_t hmac[ZT_HMACSHA384_LEN];
if (unlikely(packetSize < ZT_HMACSHA384_LEN)) {
RR->t->incomingPacketDropped(cc, 0xab9c9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
m_ctx.t->incomingPacketDropped(cc, 0xab9c9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
return SharedPtr< Peer >();
}
packetSize -= ZT_HMACSHA384_LEN;
@ -544,7 +544,7 @@ SharedPtr< Peer > VL1::m_HELLO(CallContext &cc, const SharedPtr< Path > &path, B
Utils::storeMachineEndian< uint64_t >(pkt.unsafeData + ZT_PROTO_PACKET_MAC_INDEX, 0); // set MAC field to 0
HMACSHA384(peer->identityHelloHmacKey(), pkt.unsafeData, packetSize, hmac);
if (unlikely(!Utils::secureEq(hmac, pkt.unsafeData + packetSize, ZT_HMACSHA384_LEN))) {
RR->t->incomingPacketDropped(cc, 0x707a9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
m_ctx.t->incomingPacketDropped(cc, 0x707a9891, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
return SharedPtr< Peer >();
}
} else {
@ -559,11 +559,11 @@ SharedPtr< Peer > VL1::m_HELLO(CallContext &cc, const SharedPtr< Path > &path, B
uint64_t polyMac[2];
poly1305.finish(polyMac);
if (unlikely(mac != polyMac[0])) {
RR->t->incomingPacketDropped(cc, 0x11bfff82, packetId, 0, id, path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
m_ctx.t->incomingPacketDropped(cc, 0x11bfff82, packetId, 0, id, path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
return SharedPtr< Peer >();
}
} else {
RR->t->incomingPacketDropped(cc, 0x11bfff81, packetId, 0, id, path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
m_ctx.t->incomingPacketDropped(cc, 0x11bfff81, packetId, 0, id, path->address(), hops, Protocol::VERB_NOP, ZT_TRACE_PACKET_DROP_REASON_MAC_FAILED);
return SharedPtr< Peer >();
}
}
@ -574,7 +574,7 @@ SharedPtr< Peer > VL1::m_HELLO(CallContext &cc, const SharedPtr< Path > &path, B
InetAddress sentTo;
if (unlikely(pkt.rO(ii, sentTo) < 0)) {
RR->t->incomingPacketDropped(cc, 0x707a9811, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
m_ctx.t->incomingPacketDropped(cc, 0x707a9811, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
return SharedPtr< Peer >();
}
@ -594,12 +594,12 @@ SharedPtr< Peer > VL1::m_HELLO(CallContext &cc, const SharedPtr< Path > &path, B
ii += 2; // skip reserved field
const unsigned int dictSize = pkt.rI16(ii);
if (unlikely((ii + dictSize) > packetSize)) {
RR->t->incomingPacketDropped(cc, 0x707a9815, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
m_ctx.t->incomingPacketDropped(cc, 0x707a9815, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
return peer;
}
Dictionary md;
if (!md.decode(pkt.unsafeData + ii, dictSize)) {
RR->t->incomingPacketDropped(cc, 0x707a9816, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
m_ctx.t->incomingPacketDropped(cc, 0x707a9816, packetId, 0, identityFromPeerPtr(peer), path->address(), hops, Protocol::VERB_HELLO, ZT_TRACE_PACKET_DROP_REASON_INVALID_OBJECT);
return peer;
}
@ -609,7 +609,7 @@ SharedPtr< Peer > VL1::m_HELLO(CallContext &cc, const SharedPtr< Path > &path, B
}
}
Protocol::newPacket(pkt, key->nextMessage(RR->identity.address(), peer->address()), peer->address(), RR->identity.address(), Protocol::VERB_OK);
Protocol::newPacket(pkt, key->nextMessage(m_ctx.identity.address(), peer->address()), peer->address(), m_ctx.identity.address(), Protocol::VERB_OK);
ii = ZT_PROTO_PACKET_PAYLOAD_START;
pkt.wI8(ii, Protocol::VERB_HELLO);
pkt.wI64(ii, packetId);
@ -634,7 +634,7 @@ SharedPtr< Peer > VL1::m_HELLO(CallContext &cc, const SharedPtr< Path > &path, B
}
peer->setRemoteVersion(protoVersion, versionMajor, versionMinor, versionRev);
peer->send(cc, pkt.unsafeData, ii, path);
peer->send(m_ctx, cc, pkt.unsafeData, ii, path);
return peer;
}
@ -692,12 +692,12 @@ bool VL1::m_OK(CallContext &cc, const uint64_t packetId, const unsigned int auth
inReVerb = (Protocol::Verb)pkt.rI8(ii);
const uint64_t inRePacketId = pkt.rI64(ii);
if (unlikely(Buf::readOverflow(ii, packetSize))) {
RR->t->incomingPacketDropped(cc, 0x4c1f1ff7, packetId, 0, identityFromPeerPtr(peer), path->address(), 0, Protocol::VERB_OK, ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET);
m_ctx.t->incomingPacketDropped(cc, 0x4c1f1ff7, packetId, 0, identityFromPeerPtr(peer), path->address(), 0, Protocol::VERB_OK, ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET);
return false;
}
if (unlikely(!RR->expect->expecting(inRePacketId, cc.ticks))) {
RR->t->incomingPacketDropped(cc, 0x4c1f1ff8, packetId, 0, identityFromPeerPtr(peer), path->address(), 0, Protocol::VERB_OK, ZT_TRACE_PACKET_DROP_REASON_REPLY_NOT_EXPECTED);
if (unlikely(!m_ctx.expect->expecting(inRePacketId, cc.ticks))) {
m_ctx.t->incomingPacketDropped(cc, 0x4c1f1ff8, packetId, 0, identityFromPeerPtr(peer), path->address(), 0, Protocol::VERB_OK, ZT_TRACE_PACKET_DROP_REASON_REPLY_NOT_EXPECTED);
return false;
}

View file

@ -32,7 +32,7 @@
namespace ZeroTier {
class RuntimeEnvironment;
class Context;
class Peer;
@ -46,7 +46,7 @@ class VL2;
class VL1
{
public:
explicit VL1(const RuntimeEnvironment *renv);
explicit VL1(const Context &ctx);
/**
* Called when a packet is received from the real network
@ -65,28 +65,18 @@ public:
void onRemotePacket(CallContext &cc, int64_t localSocket, const InetAddress &fromAddr, SharedPtr< Buf > &data, unsigned int len) noexcept;
private:
const RuntimeEnvironment *RR;
const Context &m_ctx;
void m_relay(CallContext &cc, const SharedPtr< Path > &path, Address destination, SharedPtr< Buf > &pkt, int pktSize);
void m_sendPendingWhois(CallContext &cc);
SharedPtr< Peer > m_HELLO(CallContext &cc, const SharedPtr< Path > &path, Buf &pkt, int packetSize);
bool m_ERROR(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize, Protocol::Verb &inReVerb);
bool m_OK(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize, Protocol::Verb &inReVerb);
bool m_WHOIS(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
bool m_RENDEZVOUS(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
bool m_ECHO(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
bool m_PUSH_DIRECT_PATHS(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
bool m_USER_MESSAGE(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
bool m_ENCAP(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, const SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
// Defragmentation engine for handling inbound packets with more than one fragment.

View file

@ -12,7 +12,7 @@
/****/
#include "VL2.hpp"
#include "RuntimeEnvironment.hpp"
#include "Context.hpp"
#include "VL1.hpp"
#include "Topology.hpp"
#include "Peer.hpp"
@ -22,7 +22,8 @@
namespace ZeroTier {
VL2::VL2(const RuntimeEnvironment *renv)
VL2::VL2(const Context &ctx):
m_ctx(ctx)
{
}

View file

@ -26,15 +26,10 @@
namespace ZeroTier {
class Path;
class Peer;
class RuntimeEnvironment;
class Context;
class VL1;
class Network;
class MAC;
class VL2
@ -42,7 +37,7 @@ class VL2
friend class VL1;
public:
explicit VL2(const RuntimeEnvironment *renv);
explicit VL2(const Context &ctx);
/**
* Called when a packet comes from a local Ethernet tap
@ -77,6 +72,7 @@ protected:
bool m_MULTICAST(CallContext &cc, uint64_t packetId, unsigned int auth, const SharedPtr< Path > &path, SharedPtr< Peer > &peer, Buf &pkt, int packetSize);
private:
const Context &m_ctx;
};
} // namespace ZeroTier