Add thread PTR that gets passed through the entire ZT core call stack and then passed to handler functions resulting from a call.

This commit is contained in:
Adam Ierymenko 2017-03-27 17:03:17 -07:00
parent 592cac5815
commit e4896b257f
44 changed files with 672 additions and 582 deletions

View File

@ -790,7 +790,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
test->timestamp = OSUtils::now();
if (_node) {
_node->circuitTestBegin(test,&(EmbeddedNetworkController::_circuitTestCallback));
_node->circuitTestBegin((void *)0,test,&(EmbeddedNetworkController::_circuitTestCallback));
} else {
_tests.pop_back();
return 500;

View File

@ -1408,6 +1408,7 @@ typedef void ZT_Node;
typedef int (*ZT_VirtualNetworkConfigFunction)(
ZT_Node *, /* Node */
void *, /* User ptr */
void *, /* Thread ptr */
uint64_t, /* Network ID */
void **, /* Modifiable network user PTR */
enum ZT_VirtualNetworkConfigOperation, /* Config operation */
@ -1423,6 +1424,7 @@ typedef int (*ZT_VirtualNetworkConfigFunction)(
typedef void (*ZT_VirtualNetworkFrameFunction)(
ZT_Node *, /* Node */
void *, /* User ptr */
void *, /* Thread ptr */
uint64_t, /* Network ID */
void **, /* Modifiable network user PTR */
uint64_t, /* Source MAC */
@ -1442,10 +1444,11 @@ typedef void (*ZT_VirtualNetworkFrameFunction)(
* in the definition of ZT_Event.
*/
typedef void (*ZT_EventCallback)(
ZT_Node *,
void *,
enum ZT_Event,
const void *);
ZT_Node *, /* Node */
void *, /* User ptr */
void *, /* Thread ptr */
enum ZT_Event, /* Event type */
const void *); /* Event payload (if applicable) */
/**
* Function to get an object from the data store
@ -1468,8 +1471,9 @@ typedef void (*ZT_EventCallback)(
* object.
*/
typedef long (*ZT_DataStoreGetFunction)(
ZT_Node *,
void *,
ZT_Node *, /* Node */
void *, /* User ptr */
void *, /* Thread ptr */
const char *,
void *,
unsigned long,
@ -1495,6 +1499,7 @@ typedef long (*ZT_DataStoreGetFunction)(
typedef int (*ZT_DataStorePutFunction)(
ZT_Node *,
void *,
void *, /* Thread ptr */
const char *,
const void *,
unsigned long,
@ -1529,6 +1534,7 @@ typedef int (*ZT_DataStorePutFunction)(
typedef int (*ZT_WirePacketSendFunction)(
ZT_Node *, /* Node */
void *, /* User ptr */
void *, /* Thread ptr */
const struct sockaddr_storage *, /* Local address */
const struct sockaddr_storage *, /* Remote address */
const void *, /* Packet data */
@ -1562,6 +1568,7 @@ typedef int (*ZT_WirePacketSendFunction)(
typedef int (*ZT_PathCheckFunction)(
ZT_Node *, /* Node */
void *, /* User ptr */
void *, /* Thread ptr */
uint64_t, /* ZeroTier address */
const struct sockaddr_storage *, /* Local address */
const struct sockaddr_storage *); /* Remote address */
@ -1584,6 +1591,7 @@ typedef int (*ZT_PathCheckFunction)(
typedef int (*ZT_PathLookupFunction)(
ZT_Node *, /* Node */
void *, /* User ptr */
void *, /* Thread ptr */
uint64_t, /* ZeroTier address (40 bits) */
int, /* Desired ss_family or -1 for any */
struct sockaddr_storage *); /* Result buffer */
@ -1654,11 +1662,12 @@ struct ZT_Node_Callbacks
*
* @param node Result: pointer is set to new node instance on success
* @param uptr User pointer to pass to functions/callbacks
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
* @param callbacks Callback function configuration
* @param now Current clock in milliseconds
* @return OK (0) or error code if a fatal error condition has occurred
*/
enum ZT_ResultCode ZT_Node_new(ZT_Node **node,void *uptr,const struct ZT_Node_Callbacks *callbacks,uint64_t now);
enum ZT_ResultCode ZT_Node_new(ZT_Node **node,void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,uint64_t now);
/**
* Delete a node and free all resources it consumes
@ -1674,6 +1683,7 @@ void ZT_Node_delete(ZT_Node *node);
* Process a packet received from the physical wire
*
* @param node Node instance
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
* @param now Current clock in milliseconds
* @param localAddress Local address, or point to ZT_SOCKADDR_NULL if unspecified
* @param remoteAddress Origin of packet
@ -1684,6 +1694,7 @@ void ZT_Node_delete(ZT_Node *node);
*/
enum ZT_ResultCode ZT_Node_processWirePacket(
ZT_Node *node,
void *tptr,
uint64_t now,
const struct sockaddr_storage *localAddress,
const struct sockaddr_storage *remoteAddress,
@ -1695,6 +1706,7 @@ enum ZT_ResultCode ZT_Node_processWirePacket(
* Process a frame from a virtual network port (tap)
*
* @param node Node instance
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
* @param now Current clock in milliseconds
* @param nwid ZeroTier 64-bit virtual network ID
* @param sourceMac Source MAC address (least significant 48 bits)
@ -1708,6 +1720,7 @@ enum ZT_ResultCode ZT_Node_processWirePacket(
*/
enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
ZT_Node *node,
void *tptr,
uint64_t now,
uint64_t nwid,
uint64_t sourceMac,
@ -1722,11 +1735,12 @@ enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
* Perform periodic background operations
*
* @param node Node instance
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
* @param now Current clock in milliseconds
* @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks()
* @return OK (0) or error code if a fatal error condition has occurred
*/
enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline);
enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,void *tptr,uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline);
/**
* Join a network
@ -1742,7 +1756,7 @@ enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,uint64_t now,vol
* @param uptr An arbitrary pointer to associate with this network (default: NULL)
* @return OK (0) or error code if a fatal error condition has occurred
*/
enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *uptr);
enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *uptr,void *tptr);
/**
* Leave a network
@ -1759,7 +1773,7 @@ enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *uptr);
* @param uptr Target pointer is set to uptr (if not NULL)
* @return OK (0) or error code if a fatal error condition has occurred
*/
enum ZT_ResultCode ZT_Node_leave(ZT_Node *node,uint64_t nwid,void **uptr);
enum ZT_ResultCode ZT_Node_leave(ZT_Node *node,uint64_t nwid,void **uptr,void *tptr);
/**
* Subscribe to an Ethernet multicast group
@ -1781,12 +1795,13 @@ enum ZT_ResultCode ZT_Node_leave(ZT_Node *node,uint64_t nwid,void **uptr);
* This does not generate an update call to networkConfigCallback().
*
* @param node Node instance
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
* @param nwid 64-bit network ID
* @param multicastGroup Ethernet multicast or broadcast MAC (least significant 48 bits)
* @param multicastAdi Multicast ADI (least significant 32 bits only, use 0 if not needed)
* @return OK (0) or error code if a fatal error condition has occurred
*/
enum ZT_ResultCode ZT_Node_multicastSubscribe(ZT_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);
enum ZT_ResultCode ZT_Node_multicastSubscribe(ZT_Node *node,void *tptr,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);
/**
* Unsubscribe from an Ethernet multicast group (or all groups)
@ -1811,21 +1826,24 @@ enum ZT_ResultCode ZT_Node_multicastUnsubscribe(ZT_Node *node,uint64_t nwid,uint
* across invocations if the contents of moon.d are scanned and orbit is
* called for each on startup.
*
* @param node Node instance
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
* @param moonWorldId Moon's world ID
* @param moonSeed If non-zero, the ZeroTier address of any member of the moon to query for moon definition
* @param len Length of moonWorld in bytes
* @return Error if moon was invalid or failed to be added
*/
enum ZT_ResultCode ZT_Node_orbit(ZT_Node *node,uint64_t moonWorldId,uint64_t moonSeed);
enum ZT_ResultCode ZT_Node_orbit(ZT_Node *node,void *tptr,uint64_t moonWorldId,uint64_t moonSeed);
/**
* Remove a moon (does nothing if not present)
*
* @param node Node instance
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
* @param moonWorldId World ID of moon to remove
* @return Error if anything bad happened
*/
enum ZT_ResultCode ZT_Node_deorbit(ZT_Node *node,uint64_t moonWorldId);
enum ZT_ResultCode ZT_Node_deorbit(ZT_Node *node,void *tptr,uint64_t moonWorldId);
/**
* Get this node's 40-bit ZeroTier address
@ -1919,13 +1937,15 @@ void ZT_Node_clearLocalInterfaceAddresses(ZT_Node *node);
* There is no delivery guarantee here. Failure can occur if the message is
* too large or if dest is not a valid ZeroTier address.
*
* @param node Node instance
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
* @param dest Destination ZeroTier address
* @param typeId VERB_USER_MESSAGE type ID
* @param data Payload data to attach to user message
* @param len Length of data in bytes
* @return Boolean: non-zero on success, zero on failure
*/
int ZT_Node_sendUserMessage(ZT_Node *node,uint64_t dest,uint64_t typeId,const void *data,unsigned int len);
int ZT_Node_sendUserMessage(ZT_Node *node,void *tptr,uint64_t dest,uint64_t typeId,const void *data,unsigned int len);
/**
* Set a network configuration master instance for this node
@ -1957,11 +1977,12 @@ void ZT_Node_setNetconfMaster(ZT_Node *node,void *networkConfigMasterInstance);
* for results forever.
*
* @param node Node instance
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
* @param test Test configuration
* @param reportCallback Function to call each time a report is received
* @return OK or error if, for example, test is too big for a packet or support isn't compiled in
*/
enum ZT_ResultCode ZT_Node_circuitTestBegin(ZT_Node *node,ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *, ZT_CircuitTest *,const ZT_CircuitTestReport *));
enum ZT_ResultCode ZT_Node_circuitTestBegin(ZT_Node *node,void *tptr,ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *, ZT_CircuitTest *,const ZT_CircuitTestReport *));
/**
* Stop listening for results to a given circuit test

View File

@ -25,7 +25,7 @@
namespace ZeroTier {
int Capability::verify(const RuntimeEnvironment *RR) const
int Capability::verify(const RuntimeEnvironment *RR,void *tPtr) const
{
try {
// There must be at least one entry, and sanity check for bad chain max length
@ -46,12 +46,12 @@ int Capability::verify(const RuntimeEnvironment *RR) const
return -1; // otherwise if we have another entry it must be from the previous holder in the chain
}
const Identity id(RR->topology->getIdentity(_custody[c].from));
const Identity id(RR->topology->getIdentity(tPtr,_custody[c].from));
if (id) {
if (!id.verify(tmp.data(),tmp.size(),_custody[c].signature))
return -1;
} else {
RR->sw->requestWhois(_custody[c].from);
RR->sw->requestWhois(tPtr,_custody[c].from);
return 1;
}
}

View File

@ -161,7 +161,7 @@ public:
* @param RR Runtime environment to provide for peer lookup, etc.
* @return 0 == OK, 1 == waiting for WHOIS, -1 == BAD signature or chain
*/
int verify(const RuntimeEnvironment *RR) const;
int verify(const RuntimeEnvironment *RR,void *tPtr) const;
template<unsigned int C>
static inline void serializeRules(Buffer<C> &b,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount)

View File

@ -207,14 +207,14 @@ bool CertificateOfMembership::sign(const Identity &with)
}
}
int CertificateOfMembership::verify(const RuntimeEnvironment *RR) const
int CertificateOfMembership::verify(const RuntimeEnvironment *RR,void *tPtr) const
{
if ((!_signedBy)||(_signedBy != Network::controllerFor(networkId()))||(_qualifierCount > ZT_NETWORK_COM_MAX_QUALIFIERS))
return -1;
const Identity id(RR->topology->getIdentity(_signedBy));
const Identity id(RR->topology->getIdentity(tPtr,_signedBy));
if (!id) {
RR->sw->requestWhois(_signedBy);
RR->sw->requestWhois(tPtr,_signedBy);
return 1;
}

View File

@ -250,9 +250,10 @@ public:
* Verify this COM and its signature
*
* @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
* @return 0 == OK, 1 == waiting for WHOIS, -1 == BAD signature or credential
*/
int verify(const RuntimeEnvironment *RR) const;
int verify(const RuntimeEnvironment *RR,void *tPtr) const;
/**
* @return True if signed

View File

@ -25,13 +25,13 @@
namespace ZeroTier {
int CertificateOfOwnership::verify(const RuntimeEnvironment *RR) const
int CertificateOfOwnership::verify(const RuntimeEnvironment *RR,void *tPtr) const
{
if ((!_signedBy)||(_signedBy != Network::controllerFor(_networkId)))
return -1;
const Identity id(RR->topology->getIdentity(_signedBy));
const Identity id(RR->topology->getIdentity(tPtr,_signedBy));
if (!id) {
RR->sw->requestWhois(_signedBy);
RR->sw->requestWhois(tPtr,_signedBy);
return 1;
}
try {

View File

@ -137,9 +137,10 @@ 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
* @return 0 == OK, 1 == waiting for WHOIS, -1 == BAD signature
*/
int verify(const RuntimeEnvironment *RR) const;
int verify(const RuntimeEnvironment *RR,void *tPtr) const;
template<unsigned int C>
inline void serialize(Buffer<C> &b,const bool forSign = false) const

View File

@ -44,7 +44,7 @@
namespace ZeroTier {
bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR)
bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,void *tPtr)
{
const Address sourceAddress(source());
@ -65,10 +65,10 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR)
}
} else if ((c == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE)&&(verb() == Packet::VERB_HELLO)) {
// Only HELLO is allowed in the clear, but will still have a MAC
return _doHELLO(RR,false);
return _doHELLO(RR,tPtr,false);
}
const SharedPtr<Peer> peer(RR->topology->getPeer(sourceAddress));
const SharedPtr<Peer> peer(RR->topology->getPeer(tPtr,sourceAddress));
if (peer) {
if (!trusted) {
if (!dearmor(peer->key())) {
@ -89,30 +89,30 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR)
switch(v) {
//case Packet::VERB_NOP:
default: // ignore unknown verbs, but if they pass auth check they are "received"
peer->received(_path,hops(),packetId(),v,0,Packet::VERB_NOP,false);
peer->received(tPtr,_path,hops(),packetId(),v,0,Packet::VERB_NOP,false);
return true;
case Packet::VERB_HELLO: return _doHELLO(RR,true);
case Packet::VERB_ERROR: return _doERROR(RR,peer);
case Packet::VERB_OK: return _doOK(RR,peer);
case Packet::VERB_WHOIS: return _doWHOIS(RR,peer);
case Packet::VERB_RENDEZVOUS: return _doRENDEZVOUS(RR,peer);
case Packet::VERB_FRAME: return _doFRAME(RR,peer);
case Packet::VERB_EXT_FRAME: return _doEXT_FRAME(RR,peer);
case Packet::VERB_ECHO: return _doECHO(RR,peer);
case Packet::VERB_MULTICAST_LIKE: return _doMULTICAST_LIKE(RR,peer);
case Packet::VERB_NETWORK_CREDENTIALS: return _doNETWORK_CREDENTIALS(RR,peer);
case Packet::VERB_NETWORK_CONFIG_REQUEST: return _doNETWORK_CONFIG_REQUEST(RR,peer);
case Packet::VERB_NETWORK_CONFIG: return _doNETWORK_CONFIG(RR,peer);
case Packet::VERB_MULTICAST_GATHER: return _doMULTICAST_GATHER(RR,peer);
case Packet::VERB_MULTICAST_FRAME: return _doMULTICAST_FRAME(RR,peer);
case Packet::VERB_PUSH_DIRECT_PATHS: return _doPUSH_DIRECT_PATHS(RR,peer);
case Packet::VERB_CIRCUIT_TEST: return _doCIRCUIT_TEST(RR,peer);
case Packet::VERB_CIRCUIT_TEST_REPORT: return _doCIRCUIT_TEST_REPORT(RR,peer);
case Packet::VERB_USER_MESSAGE: return _doUSER_MESSAGE(RR,peer);
case Packet::VERB_HELLO: return _doHELLO(RR,tPtr,true);
case Packet::VERB_ERROR: return _doERROR(RR,tPtr,peer);
case Packet::VERB_OK: return _doOK(RR,tPtr,peer);
case Packet::VERB_WHOIS: return _doWHOIS(RR,tPtr,peer);
case Packet::VERB_RENDEZVOUS: return _doRENDEZVOUS(RR,tPtr,peer);
case Packet::VERB_FRAME: return _doFRAME(RR,tPtr,peer);
case Packet::VERB_EXT_FRAME: return _doEXT_FRAME(RR,tPtr,peer);
case Packet::VERB_ECHO: return _doECHO(RR,tPtr,peer);
case Packet::VERB_MULTICAST_LIKE: return _doMULTICAST_LIKE(RR,tPtr,peer);
case Packet::VERB_NETWORK_CREDENTIALS: return _doNETWORK_CREDENTIALS(RR,tPtr,peer);
case Packet::VERB_NETWORK_CONFIG_REQUEST: return _doNETWORK_CONFIG_REQUEST(RR,tPtr,peer);
case Packet::VERB_NETWORK_CONFIG: return _doNETWORK_CONFIG(RR,tPtr,peer);
case Packet::VERB_MULTICAST_GATHER: return _doMULTICAST_GATHER(RR,tPtr,peer);
case Packet::VERB_MULTICAST_FRAME: return _doMULTICAST_FRAME(RR,tPtr,peer);
case Packet::VERB_PUSH_DIRECT_PATHS: return _doPUSH_DIRECT_PATHS(RR,tPtr,peer);
case Packet::VERB_CIRCUIT_TEST: return _doCIRCUIT_TEST(RR,tPtr,peer);
case Packet::VERB_CIRCUIT_TEST_REPORT: return _doCIRCUIT_TEST_REPORT(RR,tPtr,peer);
case Packet::VERB_USER_MESSAGE: return _doUSER_MESSAGE(RR,tPtr,peer);
}
} else {
RR->sw->requestWhois(sourceAddress);
RR->sw->requestWhois(tPtr,sourceAddress);
return false;
}
} catch ( ... ) {
@ -123,7 +123,7 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR)
}
}
bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{
try {
const Packet::Verb inReVerb = (Packet::Verb)(*this)[ZT_PROTO_VERB_ERROR_IDX_IN_RE_VERB];
@ -163,7 +163,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer>
case Packet::ERROR_IDENTITY_COLLISION:
// FIXME: for federation this will need a payload with a signature or something.
if (RR->topology->isUpstream(peer->identity()))
RR->node->postEvent(ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION);
RR->node->postEvent(tPtr,ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION);
break;
case Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE: {
@ -171,7 +171,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer>
const SharedPtr<Network> network(RR->node->network(at<uint64_t>(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD)));
const uint64_t now = RR->node->now();
if ( (network) && (network->config().com) && (peer->rateGateIncomingComRequest(now)) )
network->pushCredentialsNow(peer->address(),now);
network->pushCredentialsNow(tPtr,peer->address(),now);
} break;
case Packet::ERROR_NETWORK_ACCESS_DENIED_: {
@ -185,7 +185,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer>
// Members of networks can use this error to indicate that they no longer
// want to receive multicasts on a given channel.
const SharedPtr<Network> network(RR->node->network(at<uint64_t>(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD)));
if ((network)&&(network->gate(peer))) {
if ((network)&&(network->gate(tPtr,peer))) {
const MulticastGroup mg(MAC(field(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 8,6),6),at<uint32_t>(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 14));
TRACE("%.16llx: peer %s unsubscrubed from multicast group %s",network->id(),peer->address().toString().c_str(),mg.toString().c_str());
RR->mc->remove(network->id(),mg,peer->address());
@ -195,14 +195,14 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer>
default: break;
}
peer->received(_path,hops(),packetId(),Packet::VERB_ERROR,inRePacketId,inReVerb,false);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_ERROR,inRePacketId,inReVerb,false);
} catch ( ... ) {
TRACE("dropped ERROR from %s(%s): unexpected exception",peer->address().toString().c_str(),_path->address().toString().c_str());
}
return true;
}
bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,const bool alreadyAuthenticated)
bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool alreadyAuthenticated)
{
try {
const uint64_t now = RR->node->now();
@ -226,7 +226,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,const bool alreadyAut
return true;
}
SharedPtr<Peer> peer(RR->topology->getPeer(id.address()));
SharedPtr<Peer> peer(RR->topology->getPeer(tPtr,id.address()));
if (peer) {
// We already have an identity with this address -- check for collisions
if (!alreadyAuthenticated) {
@ -246,7 +246,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,const bool alreadyAut
outp.append((uint64_t)pid);
outp.append((uint8_t)Packet::ERROR_IDENTITY_COLLISION);
outp.armor(key,true,_path->nextOutgoingCounter());
_path->send(RR,outp.data(),outp.size(),RR->node->now());
_path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now());
} else {
TRACE("rejected HELLO from %s(%s): packet failed authentication",id.address().toString().c_str(),_path->address().toString().c_str());
}
@ -292,7 +292,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,const bool alreadyAut
return true;
}
peer = RR->topology->addPeer(newPeer);
peer = RR->topology->addPeer(tPtr,newPeer);
// Continue at // VALID
}
@ -304,7 +304,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,const bool alreadyAut
if (ptr < size()) {
ptr += externalSurfaceAddress.deserialize(*this,ptr);
if ((externalSurfaceAddress)&&(hops() == 0))
RR->sa->iam(id.address(),_path->localAddress(),_path->address(),externalSurfaceAddress,RR->topology->isUpstream(id),now);
RR->sa->iam(tPtr,id.address(),_path->localAddress(),_path->address(),externalSurfaceAddress,RR->topology->isUpstream(id),now);
}
// Get primary planet world ID and world timestamp if present
@ -408,17 +408,17 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,const bool alreadyAut
outp.setAt(corSizeAt,(uint16_t)(outp.size() - (corSizeAt + 2)));
outp.armor(peer->key(),true,_path->nextOutgoingCounter());
_path->send(RR,outp.data(),outp.size(),now);
_path->send(RR,tPtr,outp.data(),outp.size(),now);
peer->setRemoteVersion(protoVersion,vMajor,vMinor,vRevision); // important for this to go first so received() knows the version
peer->received(_path,hops(),pid,Packet::VERB_HELLO,0,Packet::VERB_NOP,false);
peer->received(tPtr,_path,hops(),pid,Packet::VERB_HELLO,0,Packet::VERB_NOP,false);
} catch ( ... ) {
TRACE("dropped HELLO from %s(%s): unexpected exception",source().toString().c_str(),_path->address().toString().c_str());
}
return true;
}
bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{
try {
const Packet::Verb inReVerb = (Packet::Verb)(*this)[ZT_PROTO_VERB_OK_IDX_IN_RE_VERB];
@ -463,7 +463,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p
while (ptr < endOfWorlds) {
World w;
ptr += w.deserialize(*this,ptr);
RR->topology->addWorld(w,false);
RR->topology->addWorld(tPtr,w,false);
}
} else {
ptr += worldsLen;
@ -490,20 +490,20 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p
peer->setRemoteVersion(vProto,vMajor,vMinor,vRevision);
if ((externalSurfaceAddress)&&(hops() == 0))
RR->sa->iam(peer->address(),_path->localAddress(),_path->address(),externalSurfaceAddress,RR->topology->isUpstream(peer->identity()),RR->node->now());
RR->sa->iam(tPtr,peer->address(),_path->localAddress(),_path->address(),externalSurfaceAddress,RR->topology->isUpstream(peer->identity()),RR->node->now());
} break;
case Packet::VERB_WHOIS:
if (RR->topology->isUpstream(peer->identity())) {
const Identity id(*this,ZT_PROTO_VERB_WHOIS__OK__IDX_IDENTITY);
RR->sw->doAnythingWaitingForPeer(RR->topology->addPeer(SharedPtr<Peer>(new Peer(RR,RR->identity,id))));
RR->sw->doAnythingWaitingForPeer(tPtr,RR->topology->addPeer(tPtr,SharedPtr<Peer>(new Peer(RR,RR->identity,id))));
}
break;
case Packet::VERB_NETWORK_CONFIG_REQUEST: {
const SharedPtr<Network> network(RR->node->network(at<uint64_t>(ZT_PROTO_VERB_OK_IDX_PAYLOAD)));
if (network)
network->handleConfigChunk(packetId(),source(),*this,ZT_PROTO_VERB_OK_IDX_PAYLOAD);
network->handleConfigChunk(tPtr,packetId(),source(),*this,ZT_PROTO_VERB_OK_IDX_PAYLOAD);
} break;
case Packet::VERB_MULTICAST_GATHER: {
@ -513,7 +513,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p
const MulticastGroup mg(MAC(field(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_MAC,6),6),at<uint32_t>(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_ADI));
//TRACE("%s(%s): OK(MULTICAST_GATHER) %.16llx/%s length %u",source().toString().c_str(),_path->address().toString().c_str(),nwid,mg.toString().c_str(),size());
const unsigned int count = at<uint16_t>(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS + 4);
RR->mc->addMultiple(RR->node->now(),nwid,mg,field(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS + 6,count * 5),count,at<uint32_t>(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS));
RR->mc->addMultiple(tPtr,RR->node->now(),nwid,mg,field(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS + 6,count * 5),count,at<uint32_t>(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS));
}
} break;
@ -532,7 +532,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p
CertificateOfMembership com;
offset += com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_COM_AND_GATHER_RESULTS);
if (com)
network->addCredential(com);
network->addCredential(tPtr,com);
}
if ((flags & 0x02) != 0) {
@ -540,7 +540,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p
offset += ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_COM_AND_GATHER_RESULTS;
unsigned int totalKnown = at<uint32_t>(offset); offset += 4;
unsigned int count = at<uint16_t>(offset); offset += 2;
RR->mc->addMultiple(RR->node->now(),nwid,mg,field(offset,count * 5),count,totalKnown);
RR->mc->addMultiple(tPtr,RR->node->now(),nwid,mg,field(offset,count * 5),count,totalKnown);
}
}
} break;
@ -548,14 +548,14 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p
default: break;
}
peer->received(_path,hops(),packetId(),Packet::VERB_OK,inRePacketId,inReVerb,false);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_OK,inRePacketId,inReVerb,false);
} catch ( ... ) {
TRACE("dropped OK from %s(%s): unexpected exception",source().toString().c_str(),_path->address().toString().c_str());
}
return true;
}
bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{
try {
if ((!RR->topology->amRoot())&&(!peer->rateGateInboundWhoisRequest(RR->node->now()))) {
@ -573,13 +573,13 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr<Peer>
const Address addr(field(ptr,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
ptr += ZT_ADDRESS_LENGTH;
const Identity id(RR->topology->getIdentity(addr));
const Identity id(RR->topology->getIdentity(tPtr,addr));
if (id) {
id.serialize(outp,false);
++count;
} else {
// Request unknown WHOIS from upstream from us (if we have one)
RR->sw->requestWhois(addr);
RR->sw->requestWhois(tPtr,addr);
#ifdef ZT_ENABLE_CLUSTER
// Distribute WHOIS queries across a cluster if we do not know the ID.
// This may result in duplicate OKs to the querying peer, which is fine.
@ -591,32 +591,32 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr<Peer>
if (count > 0) {
outp.armor(peer->key(),true,_path->nextOutgoingCounter());
_path->send(RR,outp.data(),outp.size(),RR->node->now());
_path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now());
}
peer->received(_path,hops(),packetId(),Packet::VERB_WHOIS,0,Packet::VERB_NOP,false);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_WHOIS,0,Packet::VERB_NOP,false);
} catch ( ... ) {
TRACE("dropped WHOIS from %s(%s): unexpected exception",source().toString().c_str(),_path->address().toString().c_str());
}
return true;
}
bool IncomingPacket::_doRENDEZVOUS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
bool IncomingPacket::_doRENDEZVOUS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{
try {
if (!RR->topology->isUpstream(peer->identity())) {
TRACE("RENDEZVOUS from %s ignored since source is not upstream",peer->address().toString().c_str());
} else {
const Address with(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
const SharedPtr<Peer> rendezvousWith(RR->topology->getPeer(with));
const SharedPtr<Peer> rendezvousWith(RR->topology->getPeer(tPtr,with));
if (rendezvousWith) {
const unsigned int port = at<uint16_t>(ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT);
const unsigned int addrlen = (*this)[ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN];
if ((port > 0)&&((addrlen == 4)||(addrlen == 16))) {
const InetAddress atAddr(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS,addrlen),addrlen,port);
if (RR->node->shouldUsePathForZeroTierTraffic(with,_path->localAddress(),atAddr)) {
RR->node->putPacket(_path->localAddress(),atAddr,"ABRE",4,2); // send low-TTL junk packet to 'open' local NAT(s) and stateful firewalls
rendezvousWith->attemptToContactAt(_path->localAddress(),atAddr,RR->node->now(),false,0);
if (RR->node->shouldUsePathForZeroTierTraffic(tPtr,with,_path->localAddress(),atAddr)) {
RR->node->putPacket(tPtr,_path->localAddress(),atAddr,"ABRE",4,2); // send low-TTL junk packet to 'open' local NAT(s) and stateful firewalls
rendezvousWith->attemptToContactAt(tPtr,_path->localAddress(),atAddr,RR->node->now(),false,0);
TRACE("RENDEZVOUS from %s says %s might be at %s, sent verification attempt",peer->address().toString().c_str(),with.toString().c_str(),atAddr.toString().c_str());
} else {
TRACE("RENDEZVOUS from %s says %s might be at %s, ignoring since path is not suitable",peer->address().toString().c_str(),with.toString().c_str(),atAddr.toString().c_str());
@ -628,46 +628,46 @@ bool IncomingPacket::_doRENDEZVOUS(const RuntimeEnvironment *RR,const SharedPtr<
TRACE("ignored RENDEZVOUS from %s(%s) to meet unknown peer %s",peer->address().toString().c_str(),_path->address().toString().c_str(),with.toString().c_str());
}
}
peer->received(_path,hops(),packetId(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP,false);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP,false);
} catch ( ... ) {
TRACE("dropped RENDEZVOUS from %s(%s): unexpected exception",peer->address().toString().c_str(),_path->address().toString().c_str());
}
return true;
}
bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{
try {
const uint64_t nwid = at<uint64_t>(ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID);
const SharedPtr<Network> network(RR->node->network(nwid));
bool trustEstablished = false;
if (network) {
if (network->gate(peer)) {
if (network->gate(tPtr,peer)) {
trustEstablished = true;
if (size() > ZT_PROTO_VERB_FRAME_IDX_PAYLOAD) {
const unsigned int etherType = at<uint16_t>(ZT_PROTO_VERB_FRAME_IDX_ETHERTYPE);
const MAC sourceMac(peer->address(),nwid);
const unsigned int frameLen = size() - ZT_PROTO_VERB_FRAME_IDX_PAYLOAD;
const uint8_t *const frameData = reinterpret_cast<const uint8_t *>(data()) + ZT_PROTO_VERB_FRAME_IDX_PAYLOAD;
if (network->filterIncomingPacket(peer,RR->identity.address(),sourceMac,network->mac(),frameData,frameLen,etherType,0) > 0)
RR->node->putFrame(nwid,network->userPtr(),sourceMac,network->mac(),etherType,0,(const void *)frameData,frameLen);
if (network->filterIncomingPacket(tPtr,peer,RR->identity.address(),sourceMac,network->mac(),frameData,frameLen,etherType,0) > 0)
RR->node->putFrame(tPtr,nwid,network->userPtr(),sourceMac,network->mac(),etherType,0,(const void *)frameData,frameLen);
}
} else {
TRACE("dropped FRAME from %s(%s): not a member of private network %.16llx",peer->address().toString().c_str(),_path->address().toString().c_str(),(unsigned long long)network->id());
_sendErrorNeedCredentials(RR,peer,nwid);
_sendErrorNeedCredentials(RR,tPtr,peer,nwid);
}
} else {
TRACE("dropped FRAME from %s(%s): we are not a member of network %.16llx",source().toString().c_str(),_path->address().toString().c_str(),at<uint64_t>(ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID));
_sendErrorNeedCredentials(RR,peer,nwid);
_sendErrorNeedCredentials(RR,tPtr,peer,nwid);
}
peer->received(_path,hops(),packetId(),Packet::VERB_FRAME,0,Packet::VERB_NOP,trustEstablished);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_FRAME,0,Packet::VERB_NOP,trustEstablished);
} catch ( ... ) {
TRACE("dropped FRAME from %s(%s): unexpected exception",source().toString().c_str(),_path->address().toString().c_str());
}
return true;
}
bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{
try {
const uint64_t nwid = at<uint64_t>(ZT_PROTO_VERB_EXT_FRAME_IDX_NETWORK_ID);
@ -680,13 +680,13 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr<P
CertificateOfMembership com;
comLen = com.deserialize(*this,ZT_PROTO_VERB_EXT_FRAME_IDX_COM);
if (com)
network->addCredential(com);
network->addCredential(tPtr,com);
}
if (!network->gate(peer)) {
if (!network->gate(tPtr,peer)) {
TRACE("dropped EXT_FRAME from %s(%s): not a member of private network %.16llx",peer->address().toString().c_str(),_path->address().toString().c_str(),network->id());
_sendErrorNeedCredentials(RR,peer,nwid);
peer->received(_path,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,false);
_sendErrorNeedCredentials(RR,tPtr,peer,nwid);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,false);
return true;
}
@ -699,36 +699,36 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr<P
if ((!from)||(from.isMulticast())||(from == network->mac())) {
TRACE("dropped EXT_FRAME from %s@%s(%s) to %s: invalid source MAC %s",from.toString().c_str(),peer->address().toString().c_str(),_path->address().toString().c_str(),to.toString().c_str(),from.toString().c_str());
peer->received(_path,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,true); // trustEstablished because COM is okay
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,true); // trustEstablished because COM is okay
return true;
}
switch (network->filterIncomingPacket(peer,RR->identity.address(),from,to,frameData,frameLen,etherType,0)) {
switch (network->filterIncomingPacket(tPtr,peer,RR->identity.address(),from,to,frameData,frameLen,etherType,0)) {
case 1:
if (from != MAC(peer->address(),nwid)) {
if (network->config().permitsBridging(peer->address())) {
network->learnBridgeRoute(from,peer->address());
} else {
TRACE("dropped EXT_FRAME from %s@%s(%s) to %s: sender not allowed to bridge into %.16llx",from.toString().c_str(),peer->address().toString().c_str(),_path->address().toString().c_str(),to.toString().c_str(),network->id());
peer->received(_path,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,true); // trustEstablished because COM is okay
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,true); // trustEstablished because COM is okay
return true;
}
} else if (to != network->mac()) {
if (to.isMulticast()) {
if (network->config().multicastLimit == 0) {
TRACE("dropped EXT_FRAME from %s@%s(%s) to %s: network %.16llx does not allow multicast",from.toString().c_str(),peer->address().toString().c_str(),_path->address().toString().c_str(),to.toString().c_str(),network->id());
peer->received(_path,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,true); // trustEstablished because COM is okay
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,true); // trustEstablished because COM is okay
return true;
}
} else if (!network->config().permitsBridging(RR->identity.address())) {
TRACE("dropped EXT_FRAME from %s@%s(%s) to %s: I cannot bridge to %.16llx or bridging disabled on network",from.toString().c_str(),peer->address().toString().c_str(),_path->address().toString().c_str(),to.toString().c_str(),network->id());
peer->received(_path,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,true); // trustEstablished because COM is okay
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,true); // trustEstablished because COM is okay
return true;
}
}
// fall through -- 2 means accept regardless of bridging checks or other restrictions
case 2:
RR->node->putFrame(nwid,network->userPtr(),from,to,etherType,0,(const void *)frameData,frameLen);
RR->node->putFrame(tPtr,nwid,network->userPtr(),from,to,etherType,0,(const void *)frameData,frameLen);
break;
}
}
@ -739,14 +739,14 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr<P
outp.append((uint64_t)packetId());
outp.append((uint64_t)nwid);
outp.armor(peer->key(),true,_path->nextOutgoingCounter());
_path->send(RR,outp.data(),outp.size(),RR->node->now());
_path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now());
}
peer->received(_path,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,true);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,true);
} else {
TRACE("dropped EXT_FRAME from %s(%s): we are not connected to network %.16llx",source().toString().c_str(),_path->address().toString().c_str(),at<uint64_t>(ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID));
_sendErrorNeedCredentials(RR,peer,nwid);
peer->received(_path,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,false);
_sendErrorNeedCredentials(RR,tPtr,peer,nwid);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP,false);
}
} catch ( ... ) {
TRACE("dropped EXT_FRAME from %s(%s): unexpected exception",source().toString().c_str(),_path->address().toString().c_str());
@ -754,7 +754,7 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr<P
return true;
}
bool IncomingPacket::_doECHO(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
bool IncomingPacket::_doECHO(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{
try {
if (!peer->rateGateEchoRequest(RR->node->now())) {
@ -769,16 +769,16 @@ bool IncomingPacket::_doECHO(const RuntimeEnvironment *RR,const SharedPtr<Peer>
if (size() > ZT_PACKET_IDX_PAYLOAD)
outp.append(reinterpret_cast<const unsigned char *>(data()) + ZT_PACKET_IDX_PAYLOAD,size() - ZT_PACKET_IDX_PAYLOAD);
outp.armor(peer->key(),true,_path->nextOutgoingCounter());
_path->send(RR,outp.data(),outp.size(),RR->node->now());
_path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now());
peer->received(_path,hops(),pid,Packet::VERB_ECHO,0,Packet::VERB_NOP,false);
peer->received(tPtr,_path,hops(),pid,Packet::VERB_ECHO,0,Packet::VERB_NOP,false);
} catch ( ... ) {
TRACE("dropped ECHO from %s(%s): unexpected exception",source().toString().c_str(),_path->address().toString().c_str());
}
return true;
}
bool IncomingPacket::_doMULTICAST_LIKE(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
bool IncomingPacket::_doMULTICAST_LIKE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{
try {
const uint64_t now = RR->node->now();
@ -802,9 +802,9 @@ bool IncomingPacket::_doMULTICAST_LIKE(const RuntimeEnvironment *RR,const Shared
if (!auth) {
if ((!network)||(network->id() != nwid))
network = RR->node->network(nwid);
const bool authOnNet = ((network)&&(network->gate(peer)));
const bool authOnNet = ((network)&&(network->gate(tPtr,peer)));
if (!authOnNet)
_sendErrorNeedCredentials(RR,peer,nwid);
_sendErrorNeedCredentials(RR,tPtr,peer,nwid);
trustEstablished |= authOnNet;
if (authOnNet||RR->mc->cacheAuthorized(peer->address(),nwid,now)) {
auth = true;
@ -815,18 +815,18 @@ bool IncomingPacket::_doMULTICAST_LIKE(const RuntimeEnvironment *RR,const Shared
if (auth) {
const MulticastGroup group(MAC(field(ptr + 8,6),6),at<uint32_t>(ptr + 14));
RR->mc->add(now,nwid,group,peer->address());
RR->mc->add(tPtr,now,nwid,group,peer->address());
}
}
peer->received(_path,hops(),packetId(),Packet::VERB_MULTICAST_LIKE,0,Packet::VERB_NOP,trustEstablished);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_MULTICAST_LIKE,0,Packet::VERB_NOP,trustEstablished);
} catch ( ... ) {
TRACE("dropped MULTICAST_LIKE from %s(%s): unexpected exception",source().toString().c_str(),_path->address().toString().c_str());
}
return true;
}
bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{
try {
if (!peer->rateGateCredentialsReceived(RR->node->now())) {
@ -847,7 +847,7 @@ bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,const S
if (com) {
const SharedPtr<Network> network(RR->node->network(com.networkId()));
if (network) {
switch (network->addCredential(com)) {
switch (network->addCredential(tPtr,com)) {
case Membership::ADD_REJECTED:
break;
case Membership::ADD_ACCEPTED_NEW:
@ -857,7 +857,7 @@ bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,const S
case Membership::ADD_DEFERRED_FOR_WHOIS:
return false;
}
} else RR->mc->addCredential(com,false);
} else RR->mc->addCredential(tPtr,com,false);
}
}
++p; // skip trailing 0 after COMs if present
@ -868,7 +868,7 @@ bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,const S
p += cap.deserialize(*this,p);
const SharedPtr<Network> network(RR->node->network(cap.networkId()));
if (network) {
switch (network->addCredential(cap)) {
switch (network->addCredential(tPtr,cap)) {
case Membership::ADD_REJECTED:
break;
case Membership::ADD_ACCEPTED_NEW:
@ -888,7 +888,7 @@ bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,const S
p += tag.deserialize(*this,p);
const SharedPtr<Network> network(RR->node->network(tag.networkId()));
if (network) {
switch (network->addCredential(tag)) {
switch (network->addCredential(tPtr,tag)) {
case Membership::ADD_REJECTED:
break;
case Membership::ADD_ACCEPTED_NEW:
@ -908,7 +908,7 @@ bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,const S
p += revocation.deserialize(*this,p);
const SharedPtr<Network> network(RR->node->network(revocation.networkId()));
if (network) {
switch(network->addCredential(peer->address(),revocation)) {
switch(network->addCredential(tPtr,peer->address(),revocation)) {
case Membership::ADD_REJECTED:
break;
case Membership::ADD_ACCEPTED_NEW:
@ -928,7 +928,7 @@ bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,const S
p += coo.deserialize(*this,p);
const SharedPtr<Network> network(RR->node->network(coo.networkId()));
if (network) {
switch(network->addCredential(coo)) {
switch(network->addCredential(tPtr,coo)) {
case Membership::ADD_REJECTED:
break;
case Membership::ADD_ACCEPTED_NEW:
@ -942,7 +942,7 @@ bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,const S
}
}
peer->received(_path,hops(),packetId(),Packet::VERB_NETWORK_CREDENTIALS,0,Packet::VERB_NOP,trustEstablished);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_NETWORK_CREDENTIALS,0,Packet::VERB_NOP,trustEstablished);
} catch (std::exception &exc) {
//fprintf(stderr,"dropped NETWORK_CREDENTIALS from %s(%s): %s" ZT_EOL_S,source().toString().c_str(),_path->address().toString().c_str(),exc.what());
TRACE("dropped NETWORK_CREDENTIALS from %s(%s): %s",source().toString().c_str(),_path->address().toString().c_str(),exc.what());
@ -953,7 +953,7 @@ bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,const S
return true;
}
bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{
try {
const uint64_t nwid = at<uint64_t>(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID);
@ -972,10 +972,10 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
outp.append((unsigned char)Packet::ERROR_UNSUPPORTED_OPERATION);
outp.append(nwid);
outp.armor(peer->key(),true,_path->nextOutgoingCounter());
_path->send(RR,outp.data(),outp.size(),RR->node->now());
_path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now());
}
peer->received(_path,hopCount,requestPacketId,Packet::VERB_NETWORK_CONFIG_REQUEST,0,Packet::VERB_NOP,false);
peer->received(tPtr,_path,hopCount,requestPacketId,Packet::VERB_NETWORK_CONFIG_REQUEST,0,Packet::VERB_NOP,false);
} catch (std::exception &exc) {
//fprintf(stderr,"dropped NETWORK_CONFIG_REQUEST from %s(%s): %s" ZT_EOL_S,source().toString().c_str(),_path->address().toString().c_str(),exc.what());
TRACE("dropped NETWORK_CONFIG_REQUEST from %s(%s): %s",source().toString().c_str(),_path->address().toString().c_str(),exc.what());
@ -986,12 +986,12 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
return true;
}
bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{
try {
const SharedPtr<Network> network(RR->node->network(at<uint64_t>(ZT_PACKET_IDX_PAYLOAD)));
if (network) {
const uint64_t configUpdateId = network->handleConfigChunk(packetId(),source(),*this,ZT_PACKET_IDX_PAYLOAD);
const uint64_t configUpdateId = network->handleConfigChunk(tPtr,packetId(),source(),*this,ZT_PACKET_IDX_PAYLOAD);
if (configUpdateId) {
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK);
outp.append((uint8_t)Packet::VERB_ECHO);
@ -999,17 +999,17 @@ bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment *RR,const Shared
outp.append((uint64_t)network->id());
outp.append((uint64_t)configUpdateId);
outp.armor(peer->key(),true,_path->nextOutgoingCounter());
_path->send(RR,outp.data(),outp.size(),RR->node->now());
_path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now());
}
}
peer->received(_path,hops(),packetId(),Packet::VERB_NETWORK_CONFIG,0,Packet::VERB_NOP,false);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_NETWORK_CONFIG,0,Packet::VERB_NOP,false);
} catch ( ... ) {
TRACE("dropped NETWORK_CONFIG_REFRESH from %s(%s): unexpected exception",source().toString().c_str(),_path->address().toString().c_str());
}
return true;
}
bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{
try {
const uint64_t nwid = at<uint64_t>(ZT_PROTO_VERB_MULTICAST_GATHER_IDX_NETWORK_ID);
@ -1027,17 +1027,17 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,const Shar
com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_GATHER_IDX_COM);
if (com) {
if (network)
network->addCredential(com);
else RR->mc->addCredential(com,false);
network->addCredential(tPtr,com);
else RR->mc->addCredential(tPtr,com,false);
}
} catch ( ... ) {
TRACE("MULTICAST_GATHER from %s(%s): discarded invalid COM",peer->address().toString().c_str(),_path->address().toString().c_str());
}
}
const bool trustEstablished = ((network)&&(network->gate(peer)));
const bool trustEstablished = ((network)&&(network->gate(tPtr,peer)));
if (!trustEstablished)
_sendErrorNeedCredentials(RR,peer,nwid);
_sendErrorNeedCredentials(RR,tPtr,peer,nwid);
if ( ( trustEstablished || RR->mc->cacheAuthorized(peer->address(),nwid,RR->node->now()) ) && (gatherLimit > 0) ) {
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK);
outp.append((unsigned char)Packet::VERB_MULTICAST_GATHER);
@ -1048,7 +1048,7 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,const Shar
const unsigned int gatheredLocally = RR->mc->gather(peer->address(),nwid,mg,outp,gatherLimit);
if (gatheredLocally > 0) {
outp.armor(peer->key(),true,_path->nextOutgoingCounter());
_path->send(RR,outp.data(),outp.size(),RR->node->now());
_path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now());
}
// If we are a member of a cluster, distribute this GATHER across it
@ -1058,14 +1058,14 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,const Shar
#endif
}
peer->received(_path,hops(),packetId(),Packet::VERB_MULTICAST_GATHER,0,Packet::VERB_NOP,trustEstablished);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_MULTICAST_GATHER,0,Packet::VERB_NOP,trustEstablished);
} catch ( ... ) {
TRACE("dropped MULTICAST_GATHER from %s(%s): unexpected exception",peer->address().toString().c_str(),_path->address().toString().c_str());
}
return true;
}
bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{
try {
const uint64_t nwid = at<uint64_t>(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_NETWORK_ID);
@ -1081,19 +1081,19 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share
CertificateOfMembership com;
offset += com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME_IDX_COM);
if (com)
network->addCredential(com);
network->addCredential(tPtr,com);
}
if (!network->gate(peer)) {
if (!network->gate(tPtr,peer)) {
TRACE("dropped MULTICAST_FRAME from %s(%s): not a member of private network %.16llx",peer->address().toString().c_str(),_path->address().toString().c_str(),(unsigned long long)network->id());
_sendErrorNeedCredentials(RR,peer,nwid);
peer->received(_path,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,false);
_sendErrorNeedCredentials(RR,tPtr,peer,nwid);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,false);
return true;
}
if (network->config().multicastLimit == 0) {
TRACE("dropped MULTICAST_FRAME from %s(%s): network %.16llx does not allow multicast",peer->address().toString().c_str(),_path->address().toString().c_str(),(unsigned long long)network->id());
peer->received(_path,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,false);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,false);
return true;
}
@ -1120,12 +1120,12 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share
if ((frameLen > 0)&&(frameLen <= ZT_IF_MTU)) {
if (!to.mac().isMulticast()) {
TRACE("dropped MULTICAST_FRAME from %s@%s(%s) to %s: destination is unicast, must use FRAME or EXT_FRAME",from.toString().c_str(),peer->address().toString().c_str(),_path->address().toString().c_str(),to.toString().c_str());
peer->received(_path,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,true); // trustEstablished because COM is okay
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,true); // trustEstablished because COM is okay
return true;
}
if ((!from)||(from.isMulticast())||(from == network->mac())) {
TRACE("dropped MULTICAST_FRAME from %s@%s(%s) to %s: invalid source MAC",from.toString().c_str(),peer->address().toString().c_str(),_path->address().toString().c_str(),to.toString().c_str());
peer->received(_path,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,true); // trustEstablished because COM is okay
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,true); // trustEstablished because COM is okay
return true;
}
@ -1134,14 +1134,14 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share
network->learnBridgeRoute(from,peer->address());
} else {
TRACE("dropped MULTICAST_FRAME from %s@%s(%s) to %s: sender not allowed to bridge into %.16llx",from.toString().c_str(),peer->address().toString().c_str(),_path->address().toString().c_str(),to.toString().c_str(),network->id());
peer->received(_path,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,true); // trustEstablished because COM is okay
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,true); // trustEstablished because COM is okay
return true;
}
}
const uint8_t *const frameData = (const uint8_t *)field(offset + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME,frameLen);
if (network->filterIncomingPacket(peer,RR->identity.address(),from,to.mac(),frameData,frameLen,etherType,0) > 0) {
RR->node->putFrame(nwid,network->userPtr(),from,to.mac(),etherType,0,(const void *)frameData,frameLen);
if (network->filterIncomingPacket(tPtr,peer,RR->identity.address(),from,to.mac(),frameData,frameLen,etherType,0) > 0) {
RR->node->putFrame(tPtr,nwid,network->userPtr(),from,to.mac(),etherType,0,(const void *)frameData,frameLen);
}
}
@ -1155,14 +1155,14 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share
outp.append((unsigned char)0x02); // flag 0x02 = contains gather results
if (RR->mc->gather(peer->address(),nwid,to,outp,gatherLimit)) {
outp.armor(peer->key(),true,_path->nextOutgoingCounter());
_path->send(RR,outp.data(),outp.size(),RR->node->now());
_path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now());
}
}
peer->received(_path,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,true);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,true);
} else {
_sendErrorNeedCredentials(RR,peer,nwid);
peer->received(_path,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,false);
_sendErrorNeedCredentials(RR,tPtr,peer,nwid);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,false);
}
} catch ( ... ) {
TRACE("dropped MULTICAST_FRAME from %s(%s): unexpected exception",source().toString().c_str(),_path->address().toString().c_str());
@ -1170,7 +1170,7 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share
return true;
}
bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{
try {
const uint64_t now = RR->node->now();
@ -1178,7 +1178,7 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha
// First, subject this to a rate limit
if (!peer->rateGatePushDirectPaths(now)) {
TRACE("dropped PUSH_DIRECT_PATHS from %s(%s): circuit breaker tripped",source().toString().c_str(),_path->address().toString().c_str());
peer->received(_path,hops(),packetId(),Packet::VERB_PUSH_DIRECT_PATHS,0,Packet::VERB_NOP,false);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_PUSH_DIRECT_PATHS,0,Packet::VERB_NOP,false);
return true;
}
@ -1209,10 +1209,10 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha
redundant = peer->hasActivePathTo(now,a);
}
if ( ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && (!redundant) && (RR->node->shouldUsePathForZeroTierTraffic(peer->address(),_path->localAddress(),a)) ) {
if ( ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && (!redundant) && (RR->node->shouldUsePathForZeroTierTraffic(tPtr,peer->address(),_path->localAddress(),a)) ) {
if (++countPerScope[(int)a.ipScope()][0] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) {
TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str());
peer->attemptToContactAt(InetAddress(),a,now,false,0);
peer->attemptToContactAt(tPtr,InetAddress(),a,now,false,0);
} else {
TRACE("ignoring contact for %s at %s -- too many per scope",peer->address().toString().c_str(),a.toString().c_str());
}
@ -1228,10 +1228,10 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha
redundant = peer->hasActivePathTo(now,a);
}
if ( ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && (!redundant) && (RR->node->shouldUsePathForZeroTierTraffic(peer->address(),_path->localAddress(),a)) ) {
if ( ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && (!redundant) && (RR->node->shouldUsePathForZeroTierTraffic(tPtr,peer->address(),_path->localAddress(),a)) ) {
if (++countPerScope[(int)a.ipScope()][1] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) {
TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str());
peer->attemptToContactAt(InetAddress(),a,now,false,0);
peer->attemptToContactAt(tPtr,InetAddress(),a,now,false,0);
} else {
TRACE("ignoring contact for %s at %s -- too many per scope",peer->address().toString().c_str(),a.toString().c_str());
}
@ -1241,20 +1241,20 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha
ptr += addrLen;
}
peer->received(_path,hops(),packetId(),Packet::VERB_PUSH_DIRECT_PATHS,0,Packet::VERB_NOP,false);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_PUSH_DIRECT_PATHS,0,Packet::VERB_NOP,false);
} catch ( ... ) {
TRACE("dropped PUSH_DIRECT_PATHS from %s(%s): unexpected exception",source().toString().c_str(),_path->address().toString().c_str());
}
return true;
}
bool IncomingPacket::_doCIRCUIT_TEST(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
bool IncomingPacket::_doCIRCUIT_TEST(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{
try {
const Address originatorAddress(field(ZT_PACKET_IDX_PAYLOAD,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
SharedPtr<Peer> originator(RR->topology->getPeer(originatorAddress));
SharedPtr<Peer> originator(RR->topology->getPeer(tPtr,originatorAddress));
if (!originator) {
RR->sw->requestWhois(originatorAddress);
RR->sw->requestWhois(tPtr,originatorAddress);
return false;
}
@ -1285,7 +1285,7 @@ bool IncomingPacket::_doCIRCUIT_TEST(const RuntimeEnvironment *RR,const SharedPt
const unsigned int signatureLength = at<uint16_t>(ZT_PACKET_IDX_PAYLOAD + 27 + vlf);
if (!originator->identity().verify(field(ZT_PACKET_IDX_PAYLOAD,27 + vlf),27 + vlf,field(ZT_PACKET_IDX_PAYLOAD + 29 + vlf,signatureLength),signatureLength)) {
TRACE("dropped CIRCUIT_TEST from %s(%s): signature by originator %s invalid",source().toString().c_str(),_path->address().toString().c_str(),originatorAddress.toString().c_str());
peer->received(_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST,0,Packet::VERB_NOP,false);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST,0,Packet::VERB_NOP,false);
return true;
}
vlf += signatureLength;
@ -1304,14 +1304,14 @@ bool IncomingPacket::_doCIRCUIT_TEST(const RuntimeEnvironment *RR,const SharedPt
SharedPtr<Network> network(RR->node->network(originatorCredentialNetworkId));
if ((!network)||(!network->config().circuitTestingAllowed(originatorAddress))) {
TRACE("dropped CIRCUIT_TEST from %s(%s): originator %s specified network ID %.16llx as credential, and we don't belong to that network or originator is not allowed'",source().toString().c_str(),_path->address().toString().c_str(),originatorAddress.toString().c_str(),originatorCredentialNetworkId);
peer->received(_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST,0,Packet::VERB_NOP,false);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST,0,Packet::VERB_NOP,false);
return true;
}
if (network->gate(peer))
if (network->gate(tPtr,peer))
reportFlags |= ZT_CIRCUIT_TEST_REPORT_FLAGS_UPSTREAM_AUTHORIZED_IN_PATH;
} else {
TRACE("dropped CIRCUIT_TEST from %s(%s): originator %s did not specify a credential or credential type",source().toString().c_str(),_path->address().toString().c_str(),originatorAddress.toString().c_str());
peer->received(_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST,0,Packet::VERB_NOP,false);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST,0,Packet::VERB_NOP,false);
return true;
}
@ -1327,7 +1327,7 @@ bool IncomingPacket::_doCIRCUIT_TEST(const RuntimeEnvironment *RR,const SharedPt
for(unsigned int h=0;h<breadth;++h) {
nextHop[h].setTo(field(remainingHopsPtr,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
remainingHopsPtr += ZT_ADDRESS_LENGTH;
SharedPtr<Peer> nhp(RR->topology->getPeer(nextHop[h]));
SharedPtr<Peer> nhp(RR->topology->getPeer(tPtr,nextHop[h]));
if (nhp) {
SharedPtr<Path> nhbp(nhp->getBestPath(now,false));
if ((nhbp)&&(nhbp->alive(now)))
@ -1362,7 +1362,7 @@ bool IncomingPacket::_doCIRCUIT_TEST(const RuntimeEnvironment *RR,const SharedPt
nextHop[h].appendTo(outp);
nextHopBestPathAddress[h].serialize(outp); // appends 0 if null InetAddress
}
RR->sw->send(outp,true);
RR->sw->send(tPtr,outp,true);
}
// If there are next hops, forward the test along through the graph
@ -1377,19 +1377,19 @@ bool IncomingPacket::_doCIRCUIT_TEST(const RuntimeEnvironment *RR,const SharedPt
if (RR->identity.address() != nextHop[h]) { // next hops that loop back to the current hop are not valid
outp.newInitializationVector();
outp.setDestination(nextHop[h]);
RR->sw->send(outp,true);
RR->sw->send(tPtr,outp,true);
}
}
}
peer->received(_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST,0,Packet::VERB_NOP,false);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST,0,Packet::VERB_NOP,false);
} catch ( ... ) {
TRACE("dropped CIRCUIT_TEST from %s(%s): unexpected exception",source().toString().c_str(),_path->address().toString().c_str());
}
return true;
}
bool IncomingPacket::_doCIRCUIT_TEST_REPORT(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
bool IncomingPacket::_doCIRCUIT_TEST_REPORT(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{
try {
ZT_CircuitTestReport report;
@ -1431,14 +1431,14 @@ bool IncomingPacket::_doCIRCUIT_TEST_REPORT(const RuntimeEnvironment *RR,const S
RR->node->postCircuitTestReport(&report);
peer->received(_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST_REPORT,0,Packet::VERB_NOP,false);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST_REPORT,0,Packet::VERB_NOP,false);
} catch ( ... ) {
TRACE("dropped CIRCUIT_TEST_REPORT from %s(%s): unexpected exception",source().toString().c_str(),_path->address().toString().c_str());
}
return true;
}
bool IncomingPacket::_doUSER_MESSAGE(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
bool IncomingPacket::_doUSER_MESSAGE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{
try {
if (size() >= (ZT_PACKET_IDX_PAYLOAD + 8)) {
@ -1447,16 +1447,16 @@ bool IncomingPacket::_doUSER_MESSAGE(const RuntimeEnvironment *RR,const SharedPt
um.typeId = at<uint64_t>(ZT_PACKET_IDX_PAYLOAD);
um.data = reinterpret_cast<const void *>(reinterpret_cast<const uint8_t *>(data()) + ZT_PACKET_IDX_PAYLOAD + 8);
um.length = size() - (ZT_PACKET_IDX_PAYLOAD + 8);
RR->node->postEvent(ZT_EVENT_USER_MESSAGE,reinterpret_cast<const void *>(&um));
RR->node->postEvent(tPtr,ZT_EVENT_USER_MESSAGE,reinterpret_cast<const void *>(&um));
}
peer->received(_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST_REPORT,0,Packet::VERB_NOP,false);
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_CIRCUIT_TEST_REPORT,0,Packet::VERB_NOP,false);
} catch ( ... ) {
TRACE("dropped CIRCUIT_TEST_REPORT from %s(%s): unexpected exception",source().toString().c_str(),_path->address().toString().c_str());
}
return true;
}
void IncomingPacket::_sendErrorNeedCredentials(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer,const uint64_t nwid)
void IncomingPacket::_sendErrorNeedCredentials(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer,const uint64_t nwid)
{
const uint64_t now = RR->node->now();
if (peer->rateGateOutgoingComRequest(now)) {
@ -1466,7 +1466,7 @@ void IncomingPacket::_sendErrorNeedCredentials(const RuntimeEnvironment *RR,cons
outp.append((uint8_t)Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE);
outp.append(nwid);
outp.armor(peer->key(),true,_path->nextOutgoingCounter());
_path->send(RR,outp.data(),outp.size(),now);
_path->send(RR,tPtr,outp.data(),outp.size(),now);
}
}

View File

@ -102,9 +102,10 @@ public:
* may no longer be valid.
*
* @param RR Runtime environment
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @return True if decoding and processing is complete, false if caller should try again
*/
bool tryDecode(const RuntimeEnvironment *RR);
bool tryDecode(const RuntimeEnvironment *RR,void *tPtr);
/**
* @return Time of packet receipt / start of decode
@ -114,26 +115,26 @@ public:
private:
// These are called internally to handle packet contents once it has
// been authenticated, decrypted, decompressed, and classified.
bool _doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doHELLO(const RuntimeEnvironment *RR,const bool alreadyAuthenticated);
bool _doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doWHOIS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doRENDEZVOUS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doFRAME(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doECHO(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doMULTICAST_LIKE(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doNETWORK_CONFIG(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doMULTICAST_GATHER(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doMULTICAST_FRAME(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doCIRCUIT_TEST(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doCIRCUIT_TEST_REPORT(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doUSER_MESSAGE(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer);
bool _doERROR(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
bool _doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool alreadyAuthenticated);
bool _doOK(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
bool _doWHOIS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
bool _doRENDEZVOUS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
bool _doFRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
bool _doEXT_FRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
bool _doECHO(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
bool _doMULTICAST_LIKE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
bool _doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
bool _doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
bool _doNETWORK_CONFIG(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
bool _doMULTICAST_GATHER(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
bool _doMULTICAST_FRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
bool _doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
bool _doCIRCUIT_TEST(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
bool _doCIRCUIT_TEST_REPORT(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
bool _doUSER_MESSAGE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
void _sendErrorNeedCredentials(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer,const uint64_t nwid);
void _sendErrorNeedCredentials(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer,const uint64_t nwid);
uint64_t _receiveTime;
SharedPtr<Path> _path;

View File

@ -40,7 +40,7 @@ Membership::Membership() :
for(unsigned int i=0;i<ZT_MAX_CERTIFICATES_OF_OWNERSHIP;++i) _remoteCoos[i] = &(_cooMem[i]);
}
void Membership::pushCredentials(const RuntimeEnvironment *RR,const uint64_t now,const Address &peerAddress,const NetworkConfig &nconf,int localCapabilityIndex,const bool force)
void Membership::pushCredentials(const RuntimeEnvironment *RR,void *tPtr,const uint64_t now,const Address &peerAddress,const NetworkConfig &nconf,int localCapabilityIndex,const bool force)
{
bool sendCom = ( (nconf.com) && ( ((now - _lastPushedCom) >= ZT_CREDENTIAL_PUSH_EVERY) || (force) ) );
@ -113,7 +113,7 @@ void Membership::pushCredentials(const RuntimeEnvironment *RR,const uint64_t now
outp.setAt(cooCountAt,(uint16_t)thisPacketCooCount);
outp.compress();
RR->sw->send(outp,true);
RR->sw->send(tPtr,outp,true);
}
}
@ -123,7 +123,7 @@ const Tag *Membership::getTag(const NetworkConfig &nconf,const uint32_t id) cons
return ( ((t != &(_remoteTags[ZT_MAX_NETWORK_CAPABILITIES]))&&((*t)->id == (uint64_t)id)) ? ((((*t)->lastReceived)&&(_isCredentialTimestampValid(nconf,**t))) ? &((*t)->credential) : (const Tag *)0) : (const Tag *)0);
}
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,const NetworkConfig &nconf,const CertificateOfMembership &com)
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const CertificateOfMembership &com)
{
const uint64_t newts = com.timestamp().first;
if (newts <= _comRevocationThreshold) {
@ -141,7 +141,7 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
return ADD_ACCEPTED_REDUNDANT;
}
switch(com.verify(RR)) {
switch(com.verify(RR,tPtr)) {
default:
TRACE("addCredential(CertificateOfMembership) for %s on %.16llx REJECTED (invalid signature or object)",com.issuedTo().toString().c_str(),com.networkId());
return ADD_REJECTED;
@ -154,7 +154,7 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
}
}
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,const NetworkConfig &nconf,const Tag &tag)
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Tag &tag)
{
_RemoteCredential<Tag> *const *htmp = std::lower_bound(&(_remoteTags[0]),&(_remoteTags[ZT_MAX_NETWORK_TAGS]),(uint64_t)tag.id(),_RemoteCredentialComp<Tag>());
_RemoteCredential<Tag> *have = ((htmp != &(_remoteTags[ZT_MAX_NETWORK_TAGS]))&&((*htmp)->id == (uint64_t)tag.id())) ? *htmp : (_RemoteCredential<Tag> *)0;
@ -169,7 +169,7 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
}
}
switch(tag.verify(RR)) {
switch(tag.verify(RR,tPtr)) {
default:
TRACE("addCredential(Tag) for %s on %.16llx REJECTED (invalid)",tag.issuedTo().toString().c_str(),tag.networkId());
return ADD_REJECTED;
@ -184,7 +184,7 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
}
}
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,const NetworkConfig &nconf,const Capability &cap)
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Capability &cap)
{
_RemoteCredential<Capability> *const *htmp = std::lower_bound(&(_remoteCaps[0]),&(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]),(uint64_t)cap.id(),_RemoteCredentialComp<Capability>());
_RemoteCredential<Capability> *have = ((htmp != &(_remoteCaps[ZT_MAX_NETWORK_CAPABILITIES]))&&((*htmp)->id == (uint64_t)cap.id())) ? *htmp : (_RemoteCredential<Capability> *)0;
@ -199,7 +199,7 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
}
}
switch(cap.verify(RR)) {
switch(cap.verify(RR,tPtr)) {
default:
TRACE("addCredential(Capability) for %s on %.16llx REJECTED (invalid)",cap.issuedTo().toString().c_str(),cap.networkId());
return ADD_REJECTED;
@ -214,9 +214,9 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
}
}
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,const NetworkConfig &nconf,const Revocation &rev)
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Revocation &rev)
{
switch(rev.verify(RR)) {
switch(rev.verify(RR,tPtr)) {
default:
return ADD_REJECTED;
case 0: {
@ -239,7 +239,7 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
}
}
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,const NetworkConfig &nconf,const CertificateOfOwnership &coo)
Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const CertificateOfOwnership &coo)
{
_RemoteCredential<CertificateOfOwnership> *const *htmp = std::lower_bound(&(_remoteCoos[0]),&(_remoteCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP]),(uint64_t)coo.id(),_RemoteCredentialComp<CertificateOfOwnership>());
_RemoteCredential<CertificateOfOwnership> *have = ((htmp != &(_remoteCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP]))&&((*htmp)->id == (uint64_t)coo.id())) ? *htmp : (_RemoteCredential<CertificateOfOwnership> *)0;
@ -254,7 +254,7 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
}
}
switch(coo.verify(RR)) {
switch(coo.verify(RR,tPtr)) {
default:
TRACE("addCredential(CertificateOfOwnership) for %s on %.16llx REJECTED (invalid)",coo.issuedTo().toString().c_str(),coo.networkId());
return ADD_REJECTED;

View File

@ -158,13 +158,14 @@ public:
* sends VERB_NETWORK_CREDENTIALS if the recipient might need them.
*
* @param RR Runtime environment
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param now Current time
* @param peerAddress Address of member peer (the one that this Membership describes)
* @param nconf My network config
* @param localCapabilityIndex Index of local capability to include (in nconf.capabilities[]) or -1 if none
* @param force If true, send objects regardless of last push time
*/
void pushCredentials(const RuntimeEnvironment *RR,const uint64_t now,const Address &peerAddress,const NetworkConfig &nconf,int localCapabilityIndex,const bool force);
void pushCredentials(const RuntimeEnvironment *RR,void *tPtr,const uint64_t now,const Address &peerAddress,const NetworkConfig &nconf,int localCapabilityIndex,const bool force);
/**
* Check whether we should push MULTICAST_LIKEs to this peer
@ -226,27 +227,27 @@ public:
/**
* Validate and add a credential if signature is okay and it's otherwise good
*/
AddCredentialResult addCredential(const RuntimeEnvironment *RR,const NetworkConfig &nconf,const CertificateOfMembership &com);
AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const CertificateOfMembership &com);
/**
* Validate and add a credential if signature is okay and it's otherwise good
*/
AddCredentialResult addCredential(const RuntimeEnvironment *RR,const NetworkConfig &nconf,const Tag &tag);
AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Tag &tag);
/**
* Validate and add a credential if signature is okay and it's otherwise good
*/
AddCredentialResult addCredential(const RuntimeEnvironment *RR,const NetworkConfig &nconf,const Capability &cap);
AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Capability &cap);
/**
* Validate and add a credential if signature is okay and it's otherwise good
*/
AddCredentialResult addCredential(const RuntimeEnvironment *RR,const NetworkConfig &nconf,const Revocation &rev);
AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const Revocation &rev);
/**
* Validate and add a credential if signature is okay and it's otherwise good
*/
AddCredentialResult addCredential(const RuntimeEnvironment *RR,const NetworkConfig &nconf,const CertificateOfOwnership &coo);
AddCredentialResult addCredential(const RuntimeEnvironment *RR,void *tPtr,const NetworkConfig &nconf,const CertificateOfOwnership &coo);
private:
_RemoteCredential<Tag> *_newTag(const uint64_t id);

View File

@ -43,14 +43,14 @@ Multicaster::~Multicaster()
{
}
void Multicaster::addMultiple(uint64_t now,uint64_t nwid,const MulticastGroup &mg,const void *addresses,unsigned int count,unsigned int totalKnown)
void Multicaster::addMultiple(void *tPtr,uint64_t now,uint64_t nwid,const MulticastGroup &mg,const void *addresses,unsigned int count,unsigned int totalKnown)
{
const unsigned char *p = (const unsigned char *)addresses;
const unsigned char *e = p + (5 * count);
Mutex::Lock _l(_groups_m);
MulticastGroupStatus &gs = _groups[Multicaster::Key(nwid,mg)];
while (p != e) {
_add(now,nwid,mg,gs,Address(p,5));
_add(tPtr,now,nwid,mg,gs,Address(p,5));
p += 5;
}
}
@ -152,6 +152,7 @@ std::vector<Address> Multicaster::getMembers(uint64_t nwid,const MulticastGroup
}
void Multicaster::send(
void *tPtr,
unsigned int limit,
uint64_t now,
uint64_t nwid,
@ -207,7 +208,7 @@ void Multicaster::send(
for(std::vector<Address>::const_iterator ast(alwaysSendTo.begin());ast!=alwaysSendTo.end();++ast) {
if (*ast != RR->identity.address()) {
out.sendOnly(RR,*ast); // optimization: don't use dedup log if it's a one-pass send
out.sendOnly(RR,tPtr,*ast); // optimization: don't use dedup log if it's a one-pass send
if (++count >= limit)
break;
}
@ -217,7 +218,7 @@ void Multicaster::send(
while ((count < limit)&&(idx < gs.members.size())) {
Address ma(gs.members[indexes[idx++]].address);
if (std::find(alwaysSendTo.begin(),alwaysSendTo.end(),ma) == alwaysSendTo.end()) {
out.sendOnly(RR,ma); // optimization: don't use dedup log if it's a one-pass send
out.sendOnly(RR,tPtr,ma); // optimization: don't use dedup log if it's a one-pass send
++count;
}
}
@ -256,7 +257,7 @@ void Multicaster::send(
if (com)
com->serialize(outp);
RR->node->expectReplyTo(outp.packetId());
RR->sw->send(outp,true);
RR->sw->send(tPtr,outp,true);
}
}
@ -280,7 +281,7 @@ void Multicaster::send(
for(std::vector<Address>::const_iterator ast(alwaysSendTo.begin());ast!=alwaysSendTo.end();++ast) {
if (*ast != RR->identity.address()) {
out.sendAndLog(RR,*ast);
out.sendAndLog(RR,tPtr,*ast);
if (++count >= limit)
break;
}
@ -290,7 +291,7 @@ void Multicaster::send(
while ((count < limit)&&(idx < gs.members.size())) {
Address ma(gs.members[indexes[idx++]].address);
if (std::find(alwaysSendTo.begin(),alwaysSendTo.end(),ma) == alwaysSendTo.end()) {
out.sendAndLog(RR,ma);
out.sendAndLog(RR,tPtr,ma);
++count;
}
}
@ -352,15 +353,15 @@ void Multicaster::clean(uint64_t now)
}
}
void Multicaster::addCredential(const CertificateOfMembership &com,bool alreadyValidated)
void Multicaster::addCredential(void *tPtr,const CertificateOfMembership &com,bool alreadyValidated)
{
if ((alreadyValidated)||(com.verify(RR) == 0)) {
if ((alreadyValidated)||(com.verify(RR,tPtr) == 0)) {
Mutex::Lock _l(_gatherAuth_m);
_gatherAuth[_GatherAuthKey(com.networkId(),com.issuedTo())] = RR->node->now();
}
}
void Multicaster::_add(uint64_t now,uint64_t nwid,const MulticastGroup &mg,MulticastGroupStatus &gs,const Address &member)
void Multicaster::_add(void *tPtr,uint64_t now,uint64_t nwid,const MulticastGroup &mg,MulticastGroupStatus &gs,const Address &member)
{
// assumes _groups_m is locked
@ -383,7 +384,7 @@ void Multicaster::_add(uint64_t now,uint64_t nwid,const MulticastGroup &mg,Multi
if (tx->atLimit())
gs.txQueue.erase(tx++);
else {
tx->sendIfNew(RR,member);
tx->sendIfNew(RR,tPtr,member);
if (tx->atLimit())
gs.txQueue.erase(tx++);
else ++tx;

View File

@ -90,10 +90,10 @@ public:
* @param mg Multicast group
* @param member New member address
*/
inline void add(uint64_t now,uint64_t nwid,const MulticastGroup &mg,const Address &member)
inline void add(void *tPtr,uint64_t now,uint64_t nwid,const MulticastGroup &mg,const Address &member)
{
Mutex::Lock _l(_groups_m);
_add(now,nwid,mg,_groups[Multicaster::Key(nwid,mg)],member);
_add(tPtr,now,nwid,mg,_groups[Multicaster::Key(nwid,mg)],member);
}
/**
@ -101,6 +101,7 @@ public:
*
* It's up to the caller to check bounds on the array before calling this.
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param now Current time
* @param nwid Network ID
* @param mg Multicast group
@ -108,7 +109,7 @@ public:
* @param count Number of addresses
* @param totalKnown Total number of known addresses as reported by peer
*/
void addMultiple(uint64_t now,uint64_t nwid,const MulticastGroup &mg,const void *addresses,unsigned int count,unsigned int totalKnown);
void addMultiple(void *tPtr,uint64_t now,uint64_t nwid,const MulticastGroup &mg,const void *addresses,unsigned int count,unsigned int totalKnown);
/**
* Remove a multicast group member (if present)
@ -150,6 +151,7 @@ public:
/**
* Send a multicast
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param limit Multicast limit
* @param now Current time
* @param nwid Network ID
@ -162,6 +164,7 @@ public:
* @param len Length of packet data
*/
void send(
void *tPtr,
unsigned int limit,
uint64_t now,
uint64_t nwid,
@ -191,7 +194,7 @@ public:
* @param com Certificate of membership
* @param alreadyValidated If true, COM has already been checked and found to be valid and signed
*/
void addCredential(const CertificateOfMembership &com,bool alreadyValidated);
void addCredential(void *tPtr,const CertificateOfMembership &com,bool alreadyValidated);
/**
* Check authorization for GATHER and LIKE for non-network-members
@ -209,7 +212,7 @@ public:
}
private:
void _add(uint64_t now,uint64_t nwid,const MulticastGroup &mg,MulticastGroupStatus &gs,const Address &member);
void _add(void *tPtr,uint64_t now,uint64_t nwid,const MulticastGroup &mg,MulticastGroupStatus &gs,const Address &member);
const RuntimeEnvironment *RR;

View File

@ -674,7 +674,7 @@ static _doZtFilterResult _doZtFilter(
const ZeroTier::MulticastGroup Network::BROADCAST(ZeroTier::MAC(0xffffffffffffULL),0);
Network::Network(const RuntimeEnvironment *renv,uint64_t nwid,void *uptr) :
Network::Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,void *uptr) :
RR(renv),
_uPtr(uptr),
_id(nwid),
@ -696,11 +696,11 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid,void *uptr) :
Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> *dconf = new Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY>();
NetworkConfig *nconf = new NetworkConfig();
try {
std::string conf(RR->node->dataStoreGet(confn));
std::string conf(RR->node->dataStoreGet(tPtr,confn));
if (conf.length()) {
dconf->load(conf.c_str());
if (nconf->fromDictionary(*dconf)) {
this->setConfiguration(*nconf,false);
this->setConfiguration(tPtr,*nconf,false);
_lastConfigUpdate = 0; // we still want to re-request a new config from the network
gotConf = true;
}
@ -711,13 +711,13 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid,void *uptr) :
if (!gotConf) {
// Save a one-byte CR to persist membership while we request a real netconf
RR->node->dataStorePut(confn,"\n",1,false);
RR->node->dataStorePut(tPtr,confn,"\n",1,false);
}
if (!_portInitialized) {
ZT_VirtualNetworkConfig ctmp;
_externalConfig(&ctmp);
_portError = RR->node->configureVirtualNetworkPort(_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp);
_portError = RR->node->configureVirtualNetworkPort(tPtr,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp);
_portInitialized = true;
}
}
@ -729,15 +729,16 @@ Network::~Network()
char n[128];
if (_destroyed) {
RR->node->configureVirtualNetworkPort(_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp);
RR->node->configureVirtualNetworkPort((void *)0,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp);
Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.conf",_id);
RR->node->dataStoreDelete(n);
RR->node->dataStoreDelete((void *)0,n);
} else {
RR->node->configureVirtualNetworkPort(_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN,&ctmp);
RR->node->configureVirtualNetworkPort((void *)0,_id,&_uPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN,&ctmp);
}
}
bool Network::filterOutgoingPacket(
void *tPtr,
const bool noTee,
const Address &ztSource,
const Address &ztDest,
@ -781,7 +782,7 @@ bool Network::filterOutgoingPacket(
if ((!noTee)&&(cc2)) {
Membership &m2 = _membership(cc2);
m2.pushCredentials(RR,now,cc2,_config,localCapabilityIndex,false);
m2.pushCredentials(RR,tPtr,now,cc2,_config,localCapabilityIndex,false);
Packet outp(cc2,RR->identity.address(),Packet::VERB_EXT_FRAME);
outp.append(_id);
@ -791,7 +792,7 @@ bool Network::filterOutgoingPacket(
outp.append((uint16_t)etherType);
outp.append(frameData,ccLength2);
outp.compress();
RR->sw->send(outp,true);
RR->sw->send(tPtr,outp,true);
}
break;
@ -813,11 +814,11 @@ bool Network::filterOutgoingPacket(
if (accept) {
if (membership)
membership->pushCredentials(RR,now,ztDest,_config,localCapabilityIndex,false);
membership->pushCredentials(RR,tPtr,now,ztDest,_config,localCapabilityIndex,false);
if ((!noTee)&&(cc)) {
Membership &m2 = _membership(cc);
m2.pushCredentials(RR,now,cc,_config,localCapabilityIndex,false);
m2.pushCredentials(RR,tPtr,now,cc,_config,localCapabilityIndex,false);
Packet outp(cc,RR->identity.address(),Packet::VERB_EXT_FRAME);
outp.append(_id);
@ -827,12 +828,12 @@ bool Network::filterOutgoingPacket(
outp.append((uint16_t)etherType);
outp.append(frameData,ccLength);
outp.compress();
RR->sw->send(outp,true);
RR->sw->send(tPtr,outp,true);
}
if ((ztDest != ztFinalDest)&&(ztFinalDest)) {
Membership &m2 = _membership(ztFinalDest);
m2.pushCredentials(RR,now,ztFinalDest,_config,localCapabilityIndex,false);
m2.pushCredentials(RR,tPtr,now,ztFinalDest,_config,localCapabilityIndex,false);
Packet outp(ztFinalDest,RR->identity.address(),Packet::VERB_EXT_FRAME);
outp.append(_id);
@ -842,7 +843,7 @@ bool Network::filterOutgoingPacket(
outp.append((uint16_t)etherType);
outp.append(frameData,frameLen);
outp.compress();
RR->sw->send(outp,true);
RR->sw->send(tPtr,outp,true);
return false; // DROP locally, since we redirected
} else {
@ -854,6 +855,7 @@ bool Network::filterOutgoingPacket(
}
int Network::filterIncomingPacket(
void *tPtr,
const SharedPtr<Peer> &sourcePeer,
const Address &ztDest,
const MAC &macSource,
@ -898,7 +900,7 @@ int Network::filterIncomingPacket(
if (accept) {
if (cc2) {
_membership(cc2).pushCredentials(RR,RR->node->now(),cc2,_config,-1,false);
_membership(cc2).pushCredentials(RR,tPtr,RR->node->now(),cc2,_config,-1,false);
Packet outp(cc2,RR->identity.address(),Packet::VERB_EXT_FRAME);
outp.append(_id);
@ -908,7 +910,7 @@ int Network::filterIncomingPacket(
outp.append((uint16_t)etherType);
outp.append(frameData,ccLength2);
outp.compress();
RR->sw->send(outp,true);
RR->sw->send(tPtr,outp,true);
}
break;
}
@ -929,7 +931,7 @@ int Network::filterIncomingPacket(
if (accept) {
if (cc) {
_membership(cc).pushCredentials(RR,RR->node->now(),cc,_config,-1,false);
_membership(cc).pushCredentials(RR,tPtr,RR->node->now(),cc,_config,-1,false);
Packet outp(cc,RR->identity.address(),Packet::VERB_EXT_FRAME);
outp.append(_id);
@ -939,11 +941,11 @@ int Network::filterIncomingPacket(
outp.append((uint16_t)etherType);
outp.append(frameData,ccLength);
outp.compress();
RR->sw->send(outp,true);
RR->sw->send(tPtr,outp,true);
}
if ((ztDest != ztFinalDest)&&(ztFinalDest)) {
_membership(ztFinalDest).pushCredentials(RR,RR->node->now(),ztFinalDest,_config,-1,false);
_membership(ztFinalDest).pushCredentials(RR,tPtr,RR->node->now(),ztFinalDest,_config,-1,false);
Packet outp(ztFinalDest,RR->identity.address(),Packet::VERB_EXT_FRAME);
outp.append(_id);
@ -953,7 +955,7 @@ int Network::filterIncomingPacket(
outp.append((uint16_t)etherType);
outp.append(frameData,frameLen);
outp.compress();
RR->sw->send(outp,true);
RR->sw->send(tPtr,outp,true);
return 0; // DROP locally, since we redirected
}
@ -972,12 +974,12 @@ bool Network::subscribedToMulticastGroup(const MulticastGroup &mg,bool includeBr
return false;
}
void Network::multicastSubscribe(const MulticastGroup &mg)
void Network::multicastSubscribe(void *tPtr,const MulticastGroup &mg)
{
Mutex::Lock _l(_lock);
if (!std::binary_search(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg)) {
_myMulticastGroups.insert(std::upper_bound(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg),mg);
_sendUpdatesToMembers(&mg);
_sendUpdatesToMembers(tPtr,&mg);
}
}
@ -989,7 +991,7 @@ void Network::multicastUnsubscribe(const MulticastGroup &mg)
_myMulticastGroups.erase(i);
}
uint64_t Network::handleConfigChunk(const uint64_t packetId,const Address &source,const Buffer<ZT_PROTO_MAX_PACKET_LENGTH> &chunk,unsigned int ptr)
uint64_t Network::handleConfigChunk(void *tPtr,const uint64_t packetId,const Address &source,const Buffer<ZT_PROTO_MAX_PACKET_LENGTH> &chunk,unsigned int ptr)
{
const unsigned int start = ptr;
@ -1043,7 +1045,7 @@ uint64_t Network::handleConfigChunk(const uint64_t packetId,const Address &sourc
}
// If it's not a duplicate, check chunk signature
const Identity controllerId(RR->topology->getIdentity(controller()));
const Identity controllerId(RR->topology->getIdentity(tPtr,controller()));
if (!controllerId) { // we should always have the controller identity by now, otherwise how would we have queried it the first time?
TRACE("unable to verify chunk from %s: don't have controller identity",source.toString().c_str());
return 0;
@ -1067,7 +1069,7 @@ uint64_t Network::handleConfigChunk(const uint64_t packetId,const Address &sourc
if ((*a != source)&&(*a != controller())) {
Packet outp(*a,RR->identity.address(),Packet::VERB_NETWORK_CONFIG);
outp.append(reinterpret_cast<const uint8_t *>(chunk.data()) + start,chunk.size() - start);
RR->sw->send(outp,true);
RR->sw->send(tPtr,outp,true);
}
}
}
@ -1126,7 +1128,7 @@ uint64_t Network::handleConfigChunk(const uint64_t packetId,const Address &sourc
}
if (nc) {
this->setConfiguration(*nc,true);
this->setConfiguration(tPtr,*nc,true);
delete nc;
return configUpdateId;
} else {
@ -1136,7 +1138,7 @@ uint64_t Network::handleConfigChunk(const uint64_t packetId,const Address &sourc
return 0;
}
int Network::setConfiguration(const NetworkConfig &nconf,bool saveToDisk)
int Network::setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToDisk)
{
// _lock is NOT locked when this is called
try {
@ -1156,7 +1158,7 @@ int Network::setConfiguration(const NetworkConfig &nconf,bool saveToDisk)
_portInitialized = true;
_externalConfig(&ctmp);
}
_portError = RR->node->configureVirtualNetworkPort(_id,&_uPtr,(oldPortInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp);
_portError = RR->node->configureVirtualNetworkPort(tPtr,_id,&_uPtr,(oldPortInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp);
if (saveToDisk) {
Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> *d = new Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY>();
@ -1164,7 +1166,7 @@ int Network::setConfiguration(const NetworkConfig &nconf,bool saveToDisk)
char n[64];
Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.conf",_id);
if (nconf.toDictionary(*d,false))
RR->node->dataStorePut(n,(const void *)d->data(),d->sizeBytes(),true);
RR->node->dataStorePut(tPtr,n,(const void *)d->data(),d->sizeBytes(),true);
} catch ( ... ) {}
delete d;
}
@ -1176,7 +1178,7 @@ int Network::setConfiguration(const NetworkConfig &nconf,bool saveToDisk)
return 0;
}
void Network::requestConfiguration()
void Network::requestConfiguration(void *tPtr)
{
/* ZeroTier addresses can't begin with 0xff, so this is used to mark controllerless
* network IDs. Controllerless network IDs only support unicast IPv6 using the 6plane
@ -1236,7 +1238,7 @@ void Network::requestConfiguration()
nconf->type = ZT_NETWORK_TYPE_PUBLIC;
Utils::snprintf(nconf->name,sizeof(nconf->name),"adhoc-%.04x-%.04x",(int)startPortRange,(int)endPortRange);
this->setConfiguration(*nconf,false);
this->setConfiguration(tPtr,*nconf,false);
delete nconf;
} else {
this->setNotFound();
@ -1284,10 +1286,10 @@ void Network::requestConfiguration()
}
outp.compress();
RR->node->expectReplyTo(outp.packetId());
RR->sw->send(outp,true);
RR->sw->send(tPtr,outp,true);
}
bool Network::gate(const SharedPtr<Peer> &peer)
bool Network::gate(void *tPtr,const SharedPtr<Peer> &peer)
{
const uint64_t now = RR->node->now();
Mutex::Lock _l(_lock);
@ -1298,8 +1300,8 @@ bool Network::gate(const SharedPtr<Peer> &peer)
if (!m)
m = &(_membership(peer->address()));
if (m->shouldLikeMulticasts(now)) {
m->pushCredentials(RR,now,peer->address(),_config,-1,false);
_announceMulticastGroupsTo(peer->address(),_allMulticastGroups());
m->pushCredentials(RR,tPtr,now,peer->address(),_config,-1,false);
_announceMulticastGroupsTo(tPtr,peer->address(),_allMulticastGroups());
m->likingMulticasts(now);
}
return true;
@ -1377,31 +1379,31 @@ void Network::learnBridgeRoute(const MAC &mac,const Address &addr)
}
}
void Network::learnBridgedMulticastGroup(const MulticastGroup &mg,uint64_t now)
void Network::learnBridgedMulticastGroup(void *tPtr,const MulticastGroup &mg,uint64_t now)
{
Mutex::Lock _l(_lock);
const unsigned long tmp = (unsigned long)_multicastGroupsBehindMe.size();
_multicastGroupsBehindMe.set(mg,now);
if (tmp != _multicastGroupsBehindMe.size())
_sendUpdatesToMembers(&mg);
_sendUpdatesToMembers(tPtr,&mg);
}
Membership::AddCredentialResult Network::addCredential(const CertificateOfMembership &com)
Membership::AddCredentialResult Network::addCredential(void *tPtr,const CertificateOfMembership &com)
{
if (com.networkId() != _id)
return Membership::ADD_REJECTED;
const Address a(com.issuedTo());
Mutex::Lock _l(_lock);
Membership &m = _membership(a);
const Membership::AddCredentialResult result = m.addCredential(RR,_config,com);
const Membership::AddCredentialResult result = m.addCredential(RR,tPtr,_config,com);
if ((result == Membership::ADD_ACCEPTED_NEW)||(result == Membership::ADD_ACCEPTED_REDUNDANT)) {
m.pushCredentials(RR,RR->node->now(),a,_config,-1,false);
RR->mc->addCredential(com,true);
m.pushCredentials(RR,tPtr,RR->node->now(),a,_config,-1,false);
RR->mc->addCredential(tPtr,com,true);
}
return result;
}
Membership::AddCredentialResult Network::addCredential(const Address &sentFrom,const Revocation &rev)
Membership::AddCredentialResult Network::addCredential(void *tPtr,const Address &sentFrom,const Revocation &rev)
{
if (rev.networkId() != _id)
return Membership::ADD_REJECTED;
@ -1409,7 +1411,7 @@ Membership::AddCredentialResult Network::addCredential(const Address &sentFrom,c
Mutex::Lock _l(_lock);
Membership &m = _membership(rev.target());
const Membership::AddCredentialResult result = m.addCredential(RR,_config,rev);
const Membership::AddCredentialResult result = m.addCredential(RR,tPtr,_config,rev);
if ((result == Membership::ADD_ACCEPTED_NEW)&&(rev.fastPropagate())) {
Address *a = (Address *)0;
@ -1424,7 +1426,7 @@ Membership::AddCredentialResult Network::addCredential(const Address &sentFrom,c
outp.append((uint16_t)1); // one revocation!
rev.serialize(outp);
outp.append((uint16_t)0); // no certificates of ownership
RR->sw->send(outp,true);
RR->sw->send(tPtr,outp,true);
}
}
}
@ -1495,7 +1497,7 @@ void Network::_externalConfig(ZT_VirtualNetworkConfig *ec) const
}
}
void Network::_sendUpdatesToMembers(const MulticastGroup *const newMulticastGroup)
void Network::_sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMulticastGroup)
{
// Assumes _lock is locked
const uint64_t now = RR->node->now();
@ -1521,9 +1523,9 @@ void Network::_sendUpdatesToMembers(const MulticastGroup *const newMulticastGrou
outp.append((uint16_t)0); // no tags
outp.append((uint16_t)0); // no revocations
outp.append((uint16_t)0); // no certificates of ownership
RR->sw->send(outp,true);
RR->sw->send(tPtr,outp,true);
}
_announceMulticastGroupsTo(*a,groups);
_announceMulticastGroupsTo(tPtr,*a,groups);
}
// Also announce to controller, and send COM to simplify and generalize behavior even though in theory it does not need it
@ -1537,9 +1539,9 @@ void Network::_sendUpdatesToMembers(const MulticastGroup *const newMulticastGrou
outp.append((uint16_t)0); // no tags
outp.append((uint16_t)0); // no revocations
outp.append((uint16_t)0); // no certificates of ownership
RR->sw->send(outp,true);
RR->sw->send(tPtr,outp,true);
}
_announceMulticastGroupsTo(c,groups);
_announceMulticastGroupsTo(tPtr,c,groups);
}
}
@ -1556,17 +1558,17 @@ void Network::_sendUpdatesToMembers(const MulticastGroup *const newMulticastGrou
Membership *m = (Membership *)0;
Hashtable<Address,Membership>::Iterator i(_memberships);
while (i.next(a,m)) {
m->pushCredentials(RR,now,*a,_config,-1,false);
m->pushCredentials(RR,tPtr,now,*a,_config,-1,false);
if ( ((newMulticastGroup)||(m->shouldLikeMulticasts(now))) && (m->isAllowedOnNetwork(_config)) ) {
if (!newMulticastGroup)
m->likingMulticasts(now);
_announceMulticastGroupsTo(*a,groups);
_announceMulticastGroupsTo(tPtr,*a,groups);
}
}
}
}
void Network::_announceMulticastGroupsTo(const Address &peer,const std::vector<MulticastGroup> &allMulticastGroups)
void Network::_announceMulticastGroupsTo(void *tPtr,const Address &peer,const std::vector<MulticastGroup> &allMulticastGroups)
{
// Assumes _lock is locked
Packet outp(peer,RR->identity.address(),Packet::VERB_MULTICAST_LIKE);
@ -1574,7 +1576,7 @@ void Network::_announceMulticastGroupsTo(const Address &peer,const std::vector<M
for(std::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(outp,true);
RR->sw->send(tPtr,outp,true);
outp.reset(peer,RR->identity.address(),Packet::VERB_MULTICAST_LIKE);
}
@ -1586,7 +1588,7 @@ void Network::_announceMulticastGroupsTo(const Address &peer,const std::vector<M
if (outp.size() > ZT_PROTO_MIN_PACKET_LENGTH) {
outp.compress();
RR->sw->send(outp,true);
RR->sw->send(tPtr,outp,true);
}
}

View File

@ -77,10 +77,11 @@ public:
* constructed to actually configure the port.
*
* @param renv Runtime environment
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param nwid Network ID
* @param uptr Arbitrary pointer used by externally-facing API (for user use)
*/
Network(const RuntimeEnvironment *renv,uint64_t nwid,void *uptr);
Network(const RuntimeEnvironment *renv,void *tPtr,uint64_t nwid,void *uptr);
~Network();
@ -101,6 +102,7 @@ public:
* such as TEE may be taken, and credentials may be pushed, so this is not
* side-effect-free. It's basically step one in sending something over VL2.
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param noTee If true, do not TEE anything anywhere (for two-pass filtering as done with multicast and bridging)
* @param ztSource Source ZeroTier address
* @param ztDest Destination ZeroTier address
@ -113,6 +115,7 @@ public:
* @return True if packet should be sent, false if dropped or redirected
*/
bool filterOutgoingPacket(
void *tPtr,
const bool noTee,
const Address &ztSource,
const Address &ztDest,
@ -131,6 +134,7 @@ public:
* a match certain actions may be taken such as sending a copy of the packet
* to a TEE or REDIRECT target.
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param sourcePeer Source Peer
* @param ztDest Destination ZeroTier address
* @param macSource Ethernet layer source address
@ -142,6 +146,7 @@ public:
* @return 0 == drop, 1 == accept, 2 == accept even if bridged
*/
int filterIncomingPacket(
void *tPtr,
const SharedPtr<Peer> &sourcePeer,
const Address &ztDest,
const MAC &macSource,
@ -163,9 +168,10 @@ public:
/**
* Subscribe to a multicast group
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param mg New multicast group
*/
void multicastSubscribe(const MulticastGroup &mg);
void multicastSubscribe(void *tPtr,const MulticastGroup &mg);
/**
* Unsubscribe from a multicast group
@ -181,22 +187,24 @@ public:
* chunks via OK(NETWORK_CONFIG_REQUEST) or NETWORK_CONFIG. It verifies
* each chunk and once assembled applies the configuration.
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param packetId Packet ID or 0 if none (e.g. via cluster path)
* @param source Address of sender of chunk or NULL if none (e.g. via cluster path)
* @param chunk Buffer containing chunk
* @param ptr Index of chunk and related fields in packet
* @return Update ID if update was fully assembled and accepted or 0 otherwise
*/
uint64_t handleConfigChunk(const uint64_t packetId,const Address &source,const Buffer<ZT_PROTO_MAX_PACKET_LENGTH> &chunk,unsigned int ptr);
uint64_t handleConfigChunk(void *tPtr,const uint64_t packetId,const Address &source,const Buffer<ZT_PROTO_MAX_PACKET_LENGTH> &chunk,unsigned int ptr);
/**
* Set network configuration
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param nconf Network configuration
* @param saveToDisk Save to disk? Used during loading, should usually be true otherwise.
* @return 0 == bad, 1 == accepted but duplicate/unchanged, 2 == accepted and new
*/
int setConfiguration(const NetworkConfig &nconf,bool saveToDisk);
int setConfiguration(void *tPtr,const NetworkConfig &nconf,bool saveToDisk);
/**
* Set netconf failure to 'access denied' -- called in IncomingPacket when controller reports this
@ -218,13 +226,18 @@ public:
/**
* Causes this network to request an updated configuration from its master node now
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
*/
void requestConfiguration();
void requestConfiguration(void *tPtr);
/**
* Determine whether this peer is permitted to communicate on this network
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param peer Peer to check
*/
bool gate(const SharedPtr<Peer> &peer);
bool gate(void *tPtr,const SharedPtr<Peer> &peer);
/**
* Do periodic cleanup and housekeeping tasks
@ -233,11 +246,13 @@ public:
/**
* Push state to members such as multicast group memberships and latest COM (if needed)
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
*/
inline void sendUpdatesToMembers()
inline void sendUpdatesToMembers(void *tPtr)
{
Mutex::Lock _l(_lock);
_sendUpdatesToMembers((const MulticastGroup *)0);
_sendUpdatesToMembers(tPtr,(const MulticastGroup *)0);
}
/**
@ -264,64 +279,66 @@ public:
/**
* Learn a multicast group that is bridged to our tap device
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param mg Multicast group
* @param now Current time
*/
void learnBridgedMulticastGroup(const MulticastGroup &mg,uint64_t now);
void learnBridgedMulticastGroup(void *tPtr,const MulticastGroup &mg,uint64_t now);
/**
* Validate a credential and learn it if it passes certificate and other checks
*/
Membership::AddCredentialResult addCredential(const CertificateOfMembership &com);
Membership::AddCredentialResult addCredential(void *tPtr,const CertificateOfMembership &com);
/**
* Validate a credential and learn it if it passes certificate and other checks
*/
inline Membership::AddCredentialResult addCredential(const Capability &cap)
inline Membership::AddCredentialResult addCredential(void *tPtr,const Capability &cap)
{
if (cap.networkId() != _id)
return Membership::ADD_REJECTED;
Mutex::Lock _l(_lock);
return _membership(cap.issuedTo()).addCredential(RR,_config,cap);
return _membership(cap.issuedTo()).addCredential(RR,tPtr,_config,cap);
}
/**
* Validate a credential and learn it if it passes certificate and other checks
*/
inline Membership::AddCredentialResult addCredential(const Tag &tag)
inline Membership::AddCredentialResult addCredential(void *tPtr,const Tag &tag)
{
if (tag.networkId() != _id)
return Membership::ADD_REJECTED;
Mutex::Lock _l(_lock);
return _membership(tag.issuedTo()).addCredential(RR,_config,tag);
return _membership(tag.issuedTo()).addCredential(RR,tPtr,_config,tag);
}
/**
* Validate a credential and learn it if it passes certificate and other checks
*/
Membership::AddCredentialResult addCredential(const Address &sentFrom,const Revocation &rev);
Membership::AddCredentialResult addCredential(void *tPtr,const Address &sentFrom,const Revocation &rev);
/**
* Validate a credential and learn it if it passes certificate and other checks
*/
inline Membership::AddCredentialResult addCredential(const CertificateOfOwnership &coo)
inline Membership::AddCredentialResult addCredential(void *tPtr,const CertificateOfOwnership &coo)
{
if (coo.networkId() != _id)
return Membership::ADD_REJECTED;
Mutex::Lock _l(_lock);
return _membership(coo.issuedTo()).addCredential(RR,_config,coo);
return _membership(coo.issuedTo()).addCredential(RR,tPtr,_config,coo);
}
/**
* Force push credentials (COM, etc.) to a peer now
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param to Destination peer address
* @param now Current time
*/
inline void pushCredentialsNow(const Address &to,const uint64_t now)
inline void pushCredentialsNow(void *tPtr,const Address &to,const uint64_t now)
{
Mutex::Lock _l(_lock);
_membership(to).pushCredentials(RR,now,to,_config,-1,true);
_membership(to).pushCredentials(RR,tPtr,now,to,_config,-1,true);
}
/**
@ -353,8 +370,8 @@ private:
ZT_VirtualNetworkStatus _status() const;
void _externalConfig(ZT_VirtualNetworkConfig *ec) const; // assumes _lock is locked
bool _gate(const SharedPtr<Peer> &peer);
void _sendUpdatesToMembers(const MulticastGroup *const newMulticastGroup);
void _announceMulticastGroupsTo(const Address &peer,const std::vector<MulticastGroup> &allMulticastGroups);
void _sendUpdatesToMembers(void *tPtr,const MulticastGroup *const newMulticastGroup);
void _announceMulticastGroupsTo(void *tPtr,const Address &peer,const std::vector<MulticastGroup> &allMulticastGroups);
std::vector<MulticastGroup> _allMulticastGroups() const;
Membership &_membership(const Address &a);

View File

@ -46,7 +46,7 @@ namespace ZeroTier {
/* Public Node interface (C++, exposed via CAPI bindings) */
/****************************************************************************/
Node::Node(void *uptr,const struct ZT_Node_Callbacks *callbacks,uint64_t now) :
Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,uint64_t now) :
_RR(this),
RR(&_RR),
_uPtr(uptr),
@ -72,26 +72,26 @@ Node::Node(void *uptr,const struct ZT_Node_Callbacks *callbacks,uint64_t now) :
memset(_prngStream,0,sizeof(_prngStream));
_prng.crypt12(_prngStream,_prngStream,sizeof(_prngStream));
std::string idtmp(dataStoreGet("identity.secret"));
std::string idtmp(dataStoreGet(tptr,"identity.secret"));
if ((!idtmp.length())||(!RR->identity.fromString(idtmp))||(!RR->identity.hasPrivate())) {
TRACE("identity.secret not found, generating...");
RR->identity.generate();
idtmp = RR->identity.toString(true);
if (!dataStorePut("identity.secret",idtmp,true))
if (!dataStorePut(tptr,"identity.secret",idtmp,true))
throw std::runtime_error("unable to write identity.secret");
}
RR->publicIdentityStr = RR->identity.toString(false);
RR->secretIdentityStr = RR->identity.toString(true);
idtmp = dataStoreGet("identity.public");
idtmp = dataStoreGet(tptr,"identity.public");
if (idtmp != RR->publicIdentityStr) {
if (!dataStorePut("identity.public",RR->publicIdentityStr,false))
if (!dataStorePut(tptr,"identity.public",RR->publicIdentityStr,false))
throw std::runtime_error("unable to write identity.public");
}
try {
RR->sw = new Switch(RR);
RR->mc = new Multicaster(RR);
RR->topology = new Topology(RR);
RR->topology = new Topology(RR,tptr);
RR->sa = new SelfAwareness(RR);
} catch ( ... ) {
delete RR->sa;
@ -101,7 +101,7 @@ Node::Node(void *uptr,const struct ZT_Node_Callbacks *callbacks,uint64_t now) :
throw;
}
postEvent(ZT_EVENT_UP);
postEvent(tptr,ZT_EVENT_UP);
}
Node::~Node()
@ -121,6 +121,7 @@ Node::~Node()
}
ZT_ResultCode Node::processWirePacket(
void *tptr,
uint64_t now,
const struct sockaddr_storage *localAddress,
const struct sockaddr_storage *remoteAddress,
@ -129,11 +130,12 @@ ZT_ResultCode Node::processWirePacket(
volatile uint64_t *nextBackgroundTaskDeadline)
{
_now = now;
RR->sw->onRemotePacket(*(reinterpret_cast<const InetAddress *>(localAddress)),*(reinterpret_cast<const InetAddress *>(remoteAddress)),packetData,packetLength);
RR->sw->onRemotePacket(tptr,*(reinterpret_cast<const InetAddress *>(localAddress)),*(reinterpret_cast<const InetAddress *>(remoteAddress)),packetData,packetLength);
return ZT_RESULT_OK;
}
ZT_ResultCode Node::processVirtualNetworkFrame(
void *tptr,
uint64_t now,
uint64_t nwid,
uint64_t sourceMac,
@ -147,7 +149,7 @@ ZT_ResultCode Node::processVirtualNetworkFrame(
_now = now;
SharedPtr<Network> nw(this->network(nwid));
if (nw) {
RR->sw->onLocalEthernet(nw,MAC(sourceMac),MAC(destMac),etherType,vlanId,frameData,frameLength);
RR->sw->onLocalEthernet(tptr,nw,MAC(sourceMac),MAC(destMac),etherType,vlanId,frameData,frameLength);
return ZT_RESULT_OK;
} else return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
}
@ -156,9 +158,10 @@ ZT_ResultCode Node::processVirtualNetworkFrame(
class _PingPeersThatNeedPing
{
public:
_PingPeersThatNeedPing(const RuntimeEnvironment *renv,Hashtable< Address,std::vector<InetAddress> > &upstreamsToContact,uint64_t now) :
_PingPeersThatNeedPing(const RuntimeEnvironment *renv,void *tPtr,Hashtable< Address,std::vector<InetAddress> > &upstreamsToContact,uint64_t now) :
lastReceiveFromUpstream(0),
RR(renv),
_tPtr(tPtr),
_upstreamsToContact(upstreamsToContact),
_now(now),
_bestCurrentUpstream(RR->topology->getUpstreamPeer())
@ -176,21 +179,21 @@ public:
// Upstreams must be pinged constantly over both IPv4 and IPv6 to allow
// them to perform three way handshake introductions for both stacks.
if (!p->doPingAndKeepalive(_now,AF_INET)) {
if (!p->doPingAndKeepalive(_tPtr,_now,AF_INET)) {
for(unsigned long k=0,ptr=(unsigned long)RR->node->prng();k<(unsigned long)upstreamStableEndpoints->size();++k) {
const InetAddress &addr = (*upstreamStableEndpoints)[ptr++ % upstreamStableEndpoints->size()];
if (addr.ss_family == AF_INET) {
p->sendHELLO(InetAddress(),addr,_now,0);
p->sendHELLO(_tPtr,InetAddress(),addr,_now,0);
contacted = true;
break;
}
}
} else contacted = true;
if (!p->doPingAndKeepalive(_now,AF_INET6)) {
if (!p->doPingAndKeepalive(_tPtr,_now,AF_INET6)) {
for(unsigned long k=0,ptr=(unsigned long)RR->node->prng();k<(unsigned long)upstreamStableEndpoints->size();++k) {
const InetAddress &addr = (*upstreamStableEndpoints)[ptr++ % upstreamStableEndpoints->size()];
if (addr.ss_family == AF_INET6) {
p->sendHELLO(InetAddress(),addr,_now,0);
p->sendHELLO(_tPtr,InetAddress(),addr,_now,0);
contacted = true;
break;
}
@ -200,24 +203,25 @@ public:
if ((!contacted)&&(_bestCurrentUpstream)) {
const SharedPtr<Path> up(_bestCurrentUpstream->getBestPath(_now,true));
if (up)
p->sendHELLO(up->localAddress(),up->address(),_now,up->nextOutgoingCounter());
p->sendHELLO(_tPtr,up->localAddress(),up->address(),_now,up->nextOutgoingCounter());
}
lastReceiveFromUpstream = std::max(p->lastReceive(),lastReceiveFromUpstream);
_upstreamsToContact.erase(p->address()); // erase from upstreams to contact so that we can WHOIS those that remain
} else if (p->isActive(_now)) {
p->doPingAndKeepalive(_now,-1);
p->doPingAndKeepalive(_tPtr,_now,-1);
}
}
private:
const RuntimeEnvironment *RR;
void *_tPtr;
Hashtable< Address,std::vector<InetAddress> > &_upstreamsToContact;
const uint64_t _now;
const SharedPtr<Peer> _bestCurrentUpstream;
};
ZT_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline)
ZT_ResultCode Node::processBackgroundTasks(void *tptr,uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline)
{
_now = now;
Mutex::Lock bl(_backgroundTasksLock);
@ -235,16 +239,16 @@ ZT_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *nextB
for(std::vector< std::pair< uint64_t,SharedPtr<Network> > >::const_iterator n(_networks.begin());n!=_networks.end();++n) {
if (((now - n->second->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY)||(!n->second->hasConfig()))
needConfig.push_back(n->second);
n->second->sendUpdatesToMembers();
n->second->sendUpdatesToMembers(tptr);
}
}
for(std::vector< SharedPtr<Network> >::const_iterator n(needConfig.begin());n!=needConfig.end();++n)
(*n)->requestConfiguration();
(*n)->requestConfiguration(tptr);
// Do pings and keepalives
Hashtable< Address,std::vector<InetAddress> > upstreamsToContact;
RR->topology->getUpstreamsToContact(upstreamsToContact);
_PingPeersThatNeedPing pfunc(RR,upstreamsToContact,now);
_PingPeersThatNeedPing pfunc(RR,tptr,upstreamsToContact,now);
RR->topology->eachPeer<_PingPeersThatNeedPing &>(pfunc);
// Run WHOIS to create Peer for any upstreams we could not contact (including pending moon seeds)
@ -252,13 +256,13 @@ ZT_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *nextB
Address *upstreamAddress = (Address *)0;
std::vector<InetAddress> *upstreamStableEndpoints = (std::vector<InetAddress> *)0;
while (i.next(upstreamAddress,upstreamStableEndpoints))
RR->sw->requestWhois(*upstreamAddress);
RR->sw->requestWhois(tptr,*upstreamAddress);
// Update online status, post status change as event
const bool oldOnline = _online;
_online = (((now - pfunc.lastReceiveFromUpstream) < ZT_PEER_ACTIVITY_TIMEOUT)||(RR->topology->amRoot()));
if (oldOnline != _online)
postEvent(_online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE);
postEvent(tptr,_online ? ZT_EVENT_ONLINE : ZT_EVENT_OFFLINE);
} catch ( ... ) {
return ZT_RESULT_FATAL_ERROR_INTERNAL;
}
@ -286,7 +290,7 @@ ZT_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *nextB
*nextBackgroundTaskDeadline = now + ZT_CLUSTER_PERIODIC_TASK_PERIOD; // this is really short so just tick at this rate
} else {
#endif
*nextBackgroundTaskDeadline = now + (uint64_t)std::max(std::min(timeUntilNextPingCheck,RR->sw->doTimerTasks(now)),(unsigned long)ZT_CORE_TIMER_TASK_GRANULARITY);
*nextBackgroundTaskDeadline = now + (uint64_t)std::max(std::min(timeUntilNextPingCheck,RR->sw->doTimerTasks(tptr,now)),(unsigned long)ZT_CORE_TIMER_TASK_GRANULARITY);
#ifdef ZT_ENABLE_CLUSTER
}
#endif
@ -297,17 +301,17 @@ ZT_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *nextB
return ZT_RESULT_OK;
}
ZT_ResultCode Node::join(uint64_t nwid,void *uptr)
ZT_ResultCode Node::join(uint64_t nwid,void *uptr,void *tptr)
{
Mutex::Lock _l(_networks_m);
SharedPtr<Network> nw = _network(nwid);
if(!nw)
_networks.push_back(std::pair< uint64_t,SharedPtr<Network> >(nwid,SharedPtr<Network>(new Network(RR,nwid,uptr))));
_networks.push_back(std::pair< uint64_t,SharedPtr<Network> >(nwid,SharedPtr<Network>(new Network(RR,tptr,nwid,uptr))));
std::sort(_networks.begin(),_networks.end()); // will sort by nwid since it's the first in a pair<>
return ZT_RESULT_OK;
}
ZT_ResultCode Node::leave(uint64_t nwid,void **uptr)
ZT_ResultCode Node::leave(uint64_t nwid,void **uptr,void *tptr)
{
std::vector< std::pair< uint64_t,SharedPtr<Network> > > newn;
Mutex::Lock _l(_networks_m);
@ -324,11 +328,11 @@ ZT_ResultCode Node::leave(uint64_t nwid,void **uptr)
return ZT_RESULT_OK;
}
ZT_ResultCode Node::multicastSubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi)
ZT_ResultCode Node::multicastSubscribe(void *tptr,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi)
{
SharedPtr<Network> nw(this->network(nwid));
if (nw) {
nw->multicastSubscribe(MulticastGroup(MAC(multicastGroup),(uint32_t)(multicastAdi & 0xffffffff)));
nw->multicastSubscribe(tptr,MulticastGroup(MAC(multicastGroup),(uint32_t)(multicastAdi & 0xffffffff)));
return ZT_RESULT_OK;
} else return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
}
@ -342,15 +346,15 @@ ZT_ResultCode Node::multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,u
} else return ZT_RESULT_ERROR_NETWORK_NOT_FOUND;
}
ZT_ResultCode Node::orbit(uint64_t moonWorldId,uint64_t moonSeed)
ZT_ResultCode Node::orbit(void *tptr,uint64_t moonWorldId,uint64_t moonSeed)
{
RR->topology->addMoon(moonWorldId,Address(moonSeed));
RR->topology->addMoon(tptr,moonWorldId,Address(moonSeed));
return ZT_RESULT_OK;
}
ZT_ResultCode Node::deorbit(uint64_t moonWorldId)
ZT_ResultCode Node::deorbit(void *tptr,uint64_t moonWorldId)
{
RR->topology->removeMoon(moonWorldId);
RR->topology->removeMoon(tptr,moonWorldId);
return ZT_RESULT_OK;
}
@ -465,7 +469,7 @@ void Node::clearLocalInterfaceAddresses()
_directPaths.clear();
}
int Node::sendUserMessage(uint64_t dest,uint64_t typeId,const void *data,unsigned int len)
int Node::sendUserMessage(void *tptr,uint64_t dest,uint64_t typeId,const void *data,unsigned int len)
{
try {
if (RR->identity.address().toInt() != dest) {
@ -473,7 +477,7 @@ int Node::sendUserMessage(uint64_t dest,uint64_t typeId,const void *data,unsigne
outp.append(typeId);
outp.append(data,len);
outp.compress();
RR->sw->send(outp,true);
RR->sw->send(tptr,outp,true);
return 1;
}
} catch ( ... ) {}
@ -486,7 +490,7 @@ void Node::setNetconfMaster(void *networkControllerInstance)
RR->localNetworkController->init(RR->identity,this);
}
ZT_ResultCode Node::circuitTestBegin(ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *))
ZT_ResultCode Node::circuitTestBegin(void *tptr,ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *))
{
if (test->hopCount > 0) {
try {
@ -516,7 +520,7 @@ ZT_ResultCode Node::circuitTestBegin(ZT_CircuitTest *test,void (*reportCallback)
for(unsigned int a=0;a<test->hops[0].breadth;++a) {
outp.newInitializationVector();
outp.setDestination(Address(test->hops[0].addresses[a]));
RR->sw->send(outp,true);
RR->sw->send(tptr,outp,true);
}
} catch ( ... ) {
return ZT_RESULT_FATAL_ERROR_INTERNAL; // probably indicates FIFO too big for packet
@ -616,13 +620,13 @@ void Node::clusterStatus(ZT_ClusterStatus *cs)
/* Node methods used only within node/ */
/****************************************************************************/
std::string Node::dataStoreGet(const char *name)
std::string Node::dataStoreGet(void *tPtr,const char *name)
{
char buf[1024];
std::string r;
unsigned long olen = 0;
do {
long n = _cb.dataStoreGetFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,name,buf,sizeof(buf),(unsigned long)r.length(),&olen);
long n = _cb.dataStoreGetFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,name,buf,sizeof(buf),(unsigned long)r.length(),&olen);
if (n <= 0)
return std::string();
r.append(buf,n);
@ -630,7 +634,7 @@ std::string Node::dataStoreGet(const char *name)
return r;
}
bool Node::shouldUsePathForZeroTierTraffic(const Address &ztaddr,const InetAddress &localAddress,const InetAddress &remoteAddress)
bool Node::shouldUsePathForZeroTierTraffic(void *tPtr,const Address &ztaddr,const InetAddress &localAddress,const InetAddress &remoteAddress)
{
if (!Path::isAddressValidForPath(remoteAddress))
return false;
@ -650,7 +654,7 @@ bool Node::shouldUsePathForZeroTierTraffic(const Address &ztaddr,const InetAddre
}
}
return ( (_cb.pathCheckFunction) ? (_cb.pathCheckFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,ztaddr.toInt(),reinterpret_cast<const struct sockaddr_storage *>(&localAddress),reinterpret_cast<const struct sockaddr_storage *>(&remoteAddress)) != 0) : true);
return ( (_cb.pathCheckFunction) ? (_cb.pathCheckFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ztaddr.toInt(),reinterpret_cast<const struct sockaddr_storage *>(&localAddress),reinterpret_cast<const struct sockaddr_storage *>(&remoteAddress)) != 0) : true);
}
#ifdef ZT_TRACE
@ -728,7 +732,7 @@ void Node::ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &de
if (destination == RR->identity.address()) {
SharedPtr<Network> n(network(nwid));
if (!n) return;
n->setConfiguration(nc,true);
n->setConfiguration((void *)0,nc,true);
} else {
Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> *dconf = new Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY>();
try {
@ -762,7 +766,7 @@ void Node::ncSendConfig(uint64_t nwid,uint64_t requestPacketId,const Address &de
outp.append(sig.data,ZT_C25519_SIGNATURE_LEN);
outp.compress();
RR->sw->send(outp,true);
RR->sw->send((void *)0,outp,true);
chunkIndex += chunkLen;
}
}
@ -779,7 +783,7 @@ void Node::ncSendRevocation(const Address &destination,const Revocation &rev)
if (destination == RR->identity.address()) {
SharedPtr<Network> n(network(rev.networkId()));
if (!n) return;
n->addCredential(RR->identity.address(),rev);
n->addCredential((void *)0,RR->identity.address(),rev);
} else {
Packet outp(destination,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS);
outp.append((uint8_t)0x00);
@ -788,7 +792,7 @@ void Node::ncSendRevocation(const Address &destination,const Revocation &rev)
outp.append((uint16_t)1);
rev.serialize(outp);
outp.append((uint16_t)0);
RR->sw->send(outp,true);
RR->sw->send((void *)0,outp,true);
}
}
@ -823,7 +827,7 @@ void Node::ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &des
break;
}
outp.append(nwid);
RR->sw->send(outp,true);
RR->sw->send((void *)0,outp,true);
} // else we can't send an ERROR() in response to nothing, so discard
}
@ -835,11 +839,11 @@ void Node::ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &des
extern "C" {
enum ZT_ResultCode ZT_Node_new(ZT_Node **node,void *uptr,const struct ZT_Node_Callbacks *callbacks,uint64_t now)
enum ZT_ResultCode ZT_Node_new(ZT_Node **node,void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,uint64_t now)
{
*node = (ZT_Node *)0;
try {
*node = reinterpret_cast<ZT_Node *>(new ZeroTier::Node(uptr,callbacks,now));
*node = reinterpret_cast<ZT_Node *>(new ZeroTier::Node(uptr,tptr,callbacks,now));
return ZT_RESULT_OK;
} catch (std::bad_alloc &exc) {
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
@ -859,6 +863,7 @@ void ZT_Node_delete(ZT_Node *node)
enum ZT_ResultCode ZT_Node_processWirePacket(
ZT_Node *node,
void *tptr,
uint64_t now,
const struct sockaddr_storage *localAddress,
const struct sockaddr_storage *remoteAddress,
@ -867,7 +872,7 @@ enum ZT_ResultCode ZT_Node_processWirePacket(
volatile uint64_t *nextBackgroundTaskDeadline)
{
try {
return reinterpret_cast<ZeroTier::Node *>(node)->processWirePacket(now,localAddress,remoteAddress,packetData,packetLength,nextBackgroundTaskDeadline);
return reinterpret_cast<ZeroTier::Node *>(node)->processWirePacket(tptr,now,localAddress,remoteAddress,packetData,packetLength,nextBackgroundTaskDeadline);
} catch (std::bad_alloc &exc) {
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
} catch ( ... ) {
@ -877,6 +882,7 @@ enum ZT_ResultCode ZT_Node_processWirePacket(
enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
ZT_Node *node,
void *tptr,
uint64_t now,
uint64_t nwid,
uint64_t sourceMac,
@ -888,7 +894,7 @@ enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
volatile uint64_t *nextBackgroundTaskDeadline)
{
try {
return reinterpret_cast<ZeroTier::Node *>(node)->processVirtualNetworkFrame(now,nwid,sourceMac,destMac,etherType,vlanId,frameData,frameLength,nextBackgroundTaskDeadline);
return reinterpret_cast<ZeroTier::Node *>(node)->processVirtualNetworkFrame(tptr,now,nwid,sourceMac,destMac,etherType,vlanId,frameData,frameLength,nextBackgroundTaskDeadline);
} catch (std::bad_alloc &exc) {
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
} catch ( ... ) {
@ -896,10 +902,10 @@ enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
}
}
enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline)
enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,void *tptr,uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline)
{
try {
return reinterpret_cast<ZeroTier::Node *>(node)->processBackgroundTasks(now,nextBackgroundTaskDeadline);
return reinterpret_cast<ZeroTier::Node *>(node)->processBackgroundTasks(tptr,now,nextBackgroundTaskDeadline);
} catch (std::bad_alloc &exc) {
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
} catch ( ... ) {
@ -907,10 +913,10 @@ enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,uint64_t now,vol
}
}
enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *uptr)
enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *uptr,void *tptr)
{
try {
return reinterpret_cast<ZeroTier::Node *>(node)->join(nwid,uptr);
return reinterpret_cast<ZeroTier::Node *>(node)->join(nwid,uptr,tptr);
} catch (std::bad_alloc &exc) {
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
} catch ( ... ) {
@ -918,10 +924,10 @@ enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *uptr)
}
}
enum ZT_ResultCode ZT_Node_leave(ZT_Node *node,uint64_t nwid,void **uptr)
enum ZT_ResultCode ZT_Node_leave(ZT_Node *node,uint64_t nwid,void **uptr,void *tptr)
{
try {
return reinterpret_cast<ZeroTier::Node *>(node)->leave(nwid,uptr);
return reinterpret_cast<ZeroTier::Node *>(node)->leave(nwid,uptr,tptr);
} catch (std::bad_alloc &exc) {
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
} catch ( ... ) {
@ -929,10 +935,10 @@ enum ZT_ResultCode ZT_Node_leave(ZT_Node *node,uint64_t nwid,void **uptr)
}
}
enum ZT_ResultCode ZT_Node_multicastSubscribe(ZT_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi)
enum ZT_ResultCode ZT_Node_multicastSubscribe(ZT_Node *node,void *tptr,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi)
{
try {
return reinterpret_cast<ZeroTier::Node *>(node)->multicastSubscribe(nwid,multicastGroup,multicastAdi);
return reinterpret_cast<ZeroTier::Node *>(node)->multicastSubscribe(tptr,nwid,multicastGroup,multicastAdi);
} catch (std::bad_alloc &exc) {
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
} catch ( ... ) {
@ -951,19 +957,19 @@ enum ZT_ResultCode ZT_Node_multicastUnsubscribe(ZT_Node *node,uint64_t nwid,uint
}
}
enum ZT_ResultCode ZT_Node_orbit(ZT_Node *node,uint64_t moonWorldId,uint64_t moonSeed)
enum ZT_ResultCode ZT_Node_orbit(ZT_Node *node,void *tptr,uint64_t moonWorldId,uint64_t moonSeed)
{
try {
return reinterpret_cast<ZeroTier::Node *>(node)->orbit(moonWorldId,moonSeed);
return reinterpret_cast<ZeroTier::Node *>(node)->orbit(tptr,moonWorldId,moonSeed);
} catch ( ... ) {
return ZT_RESULT_FATAL_ERROR_INTERNAL;
}
}
ZT_ResultCode ZT_Node_deorbit(ZT_Node *node,uint64_t moonWorldId)
ZT_ResultCode ZT_Node_deorbit(ZT_Node *node,void *tptr,uint64_t moonWorldId)
{
try {
return reinterpret_cast<ZeroTier::Node *>(node)->deorbit(moonWorldId);
return reinterpret_cast<ZeroTier::Node *>(node)->deorbit(tptr,moonWorldId);
} catch ( ... ) {
return ZT_RESULT_FATAL_ERROR_INTERNAL;
}
@ -1031,10 +1037,10 @@ void ZT_Node_clearLocalInterfaceAddresses(ZT_Node *node)
} catch ( ... ) {}
}
int ZT_Node_sendUserMessage(ZT_Node *node,uint64_t dest,uint64_t typeId,const void *data,unsigned int len)
int ZT_Node_sendUserMessage(ZT_Node *node,void *tptr,uint64_t dest,uint64_t typeId,const void *data,unsigned int len)
{
try {
return reinterpret_cast<ZeroTier::Node *>(node)->sendUserMessage(dest,typeId,data,len);
return reinterpret_cast<ZeroTier::Node *>(node)->sendUserMessage(tptr,dest,typeId,data,len);
} catch ( ... ) {
return 0;
}
@ -1047,10 +1053,10 @@ void ZT_Node_setNetconfMaster(ZT_Node *node,void *networkControllerInstance)
} catch ( ... ) {}
}
enum ZT_ResultCode ZT_Node_circuitTestBegin(ZT_Node *node,ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *))
enum ZT_ResultCode ZT_Node_circuitTestBegin(ZT_Node *node,void *tptr,ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *))
{
try {
return reinterpret_cast<ZeroTier::Node *>(node)->circuitTestBegin(test,reportCallback);
return reinterpret_cast<ZeroTier::Node *>(node)->circuitTestBegin(tptr,test,reportCallback);
} catch ( ... ) {
return ZT_RESULT_FATAL_ERROR_INTERNAL;
}

View File

@ -65,7 +65,7 @@ class World;
class Node : public NetworkController::Sender
{
public:
Node(void *uptr,const struct ZT_Node_Callbacks *callbacks,uint64_t now);
Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,uint64_t now);
virtual ~Node();
// Get rid of alignment warnings on 32-bit Windows and possibly improve performance
@ -77,6 +77,7 @@ public:
// Public API Functions ----------------------------------------------------
ZT_ResultCode processWirePacket(
void *tptr,
uint64_t now,
const struct sockaddr_storage *localAddress,
const struct sockaddr_storage *remoteAddress,
@ -84,6 +85,7 @@ public:
unsigned int packetLength,
volatile uint64_t *nextBackgroundTaskDeadline);
ZT_ResultCode processVirtualNetworkFrame(
void *tptr,
uint64_t now,
uint64_t nwid,
uint64_t sourceMac,
@ -93,13 +95,13 @@ public:
const void *frameData,
unsigned int frameLength,
volatile uint64_t *nextBackgroundTaskDeadline);
ZT_ResultCode processBackgroundTasks(uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline);
ZT_ResultCode join(uint64_t nwid,void *uptr);
ZT_ResultCode leave(uint64_t nwid,void **uptr);
ZT_ResultCode multicastSubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);
ZT_ResultCode processBackgroundTasks(void *tptr,uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline);
ZT_ResultCode join(uint64_t nwid,void *uptr,void *tptr);
ZT_ResultCode leave(uint64_t nwid,void **uptr,void *tptr);
ZT_ResultCode multicastSubscribe(void *tptr,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);
ZT_ResultCode multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);
ZT_ResultCode orbit(uint64_t moonWorldId,uint64_t moonSeed);
ZT_ResultCode deorbit(uint64_t moonWorldId);
ZT_ResultCode orbit(void *tptr,uint64_t moonWorldId,uint64_t moonSeed);
ZT_ResultCode deorbit(void *tptr,uint64_t moonWorldId);
uint64_t address() const;
void status(ZT_NodeStatus *status) const;
ZT_PeerList *peers() const;
@ -108,9 +110,9 @@ public:
void freeQueryResult(void *qr);
int addLocalInterfaceAddress(const struct sockaddr_storage *addr);
void clearLocalInterfaceAddresses();
int sendUserMessage(uint64_t dest,uint64_t typeId,const void *data,unsigned int len);
int sendUserMessage(void *tptr,uint64_t dest,uint64_t typeId,const void *data,unsigned int len);
void setNetconfMaster(void *networkControllerInstance);
ZT_ResultCode circuitTestBegin(ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *));
ZT_ResultCode circuitTestBegin(void *tptr,ZT_CircuitTest *test,void (*reportCallback)(ZT_Node *,ZT_CircuitTest *,const ZT_CircuitTestReport *));
void circuitTestEnd(ZT_CircuitTest *test);
ZT_ResultCode clusterInit(
unsigned int myId,
@ -132,11 +134,12 @@ public:
inline uint64_t now() const throw() { return _now; }
inline bool putPacket(const InetAddress &localAddress,const InetAddress &addr,const void *data,unsigned int len,unsigned int ttl = 0)
inline bool putPacket(void *tPtr,const InetAddress &localAddress,const InetAddress &addr,const void *data,unsigned int len,unsigned int ttl = 0)
{
return (_cb.wirePacketSendFunction(
reinterpret_cast<ZT_Node *>(this),
_uPtr,
tPtr,
reinterpret_cast<const struct sockaddr_storage *>(&localAddress),
reinterpret_cast<const struct sockaddr_storage *>(&addr),
data,
@ -144,11 +147,12 @@ public:
ttl) == 0);
}
inline void putFrame(uint64_t nwid,void **nuptr,const MAC &source,const MAC &dest,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
inline void putFrame(void *tPtr,uint64_t nwid,void **nuptr,const MAC &source,const MAC &dest,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
{
_cb.virtualNetworkFrameFunction(
reinterpret_cast<ZT_Node *>(this),
_uPtr,
tPtr,
nwid,
nuptr,
source.toInt(),
@ -191,14 +195,14 @@ public:
return _directPaths;
}
inline bool dataStorePut(const char *name,const void *data,unsigned int len,bool secure) { return (_cb.dataStorePutFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,name,data,len,(int)secure) == 0); }
inline bool dataStorePut(const char *name,const std::string &data,bool secure) { return dataStorePut(name,(const void *)data.data(),(unsigned int)data.length(),secure); }
inline void dataStoreDelete(const char *name) { _cb.dataStorePutFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,name,(const void *)0,0,0); }
std::string dataStoreGet(const char *name);
inline bool dataStorePut(void *tPtr,const char *name,const void *data,unsigned int len,bool secure) { return (_cb.dataStorePutFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,name,data,len,(int)secure) == 0); }
inline bool dataStorePut(void *tPtr,const char *name,const std::string &data,bool secure) { return dataStorePut(tPtr,name,(const void *)data.data(),(unsigned int)data.length(),secure); }
inline void dataStoreDelete(void *tPtr,const char *name) { _cb.dataStorePutFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,name,(const void *)0,0,0); }
std::string dataStoreGet(void *tPtr,const char *name);
inline void postEvent(ZT_Event ev,const void *md = (const void *)0) { _cb.eventCallback(reinterpret_cast<ZT_Node *>(this),_uPtr,ev,md); }
inline void postEvent(void *tPtr,ZT_Event ev,const void *md = (const void *)0) { _cb.eventCallback(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ev,md); }
inline int configureVirtualNetworkPort(uint64_t nwid,void **nuptr,ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nc) { return _cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,nwid,nuptr,op,nc); }
inline int configureVirtualNetworkPort(void *tPtr,uint64_t nwid,void **nuptr,ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nc) { return _cb.virtualNetworkConfigFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,nwid,nuptr,op,nc); }
inline bool online() const throw() { return _online; }
@ -206,8 +210,8 @@ public:
void postTrace(const char *module,unsigned int line,const char *fmt,...);
#endif
bool shouldUsePathForZeroTierTraffic(const Address &ztaddr,const InetAddress &localAddress,const InetAddress &remoteAddress);
inline bool externalPathLookup(const Address &ztaddr,int family,InetAddress &addr) { return ( (_cb.pathLookupFunction) ? (_cb.pathLookupFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,ztaddr.toInt(),family,reinterpret_cast<struct sockaddr_storage *>(&addr)) != 0) : false ); }
bool shouldUsePathForZeroTierTraffic(void *tPtr,const Address &ztaddr,const InetAddress &localAddress,const InetAddress &remoteAddress);
inline bool externalPathLookup(void *tPtr,const Address &ztaddr,int family,InetAddress &addr) { return ( (_cb.pathLookupFunction) ? (_cb.pathLookupFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ztaddr.toInt(),family,reinterpret_cast<struct sockaddr_storage *>(&addr)) != 0) : false ); }
uint64_t prng();
void postCircuitTestReport(const ZT_CircuitTestReport *report);

View File

@ -85,18 +85,18 @@ void OutboundMulticast::init(
memcpy(_frameData,payload,_frameLen);
}
void OutboundMulticast::sendOnly(const RuntimeEnvironment *RR,const Address &toAddr)
void OutboundMulticast::sendOnly(const RuntimeEnvironment *RR,void *tPtr,const Address &toAddr)
{
const SharedPtr<Network> nw(RR->node->network(_nwid));
const Address toAddr2(toAddr);
if ((nw)&&(nw->filterOutgoingPacket(true,RR->identity.address(),toAddr2,_macSrc,_macDest,_frameData,_frameLen,_etherType,0))) {
if ((nw)&&(nw->filterOutgoingPacket(tPtr,true,RR->identity.address(),toAddr2,_macSrc,_macDest,_frameData,_frameLen,_etherType,0))) {
//TRACE(">>MC %.16llx -> %s",(unsigned long long)this,toAddr.toString().c_str());
_packet.newInitializationVector();
_packet.setDestination(toAddr2);
RR->node->expectReplyTo(_packet.packetId());
Packet tmp(_packet); // make a copy of packet so as not to garble the original -- GitHub issue #461
RR->sw->send(tmp,true);
RR->sw->send(tPtr,tmp,true);
}
}

View File

@ -99,33 +99,36 @@ public:
* Just send without checking log
*
* @param RR Runtime environment
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param toAddr Destination address
*/
void sendOnly(const RuntimeEnvironment *RR,const Address &toAddr);
void sendOnly(const RuntimeEnvironment *RR,void *tPtr,const Address &toAddr);
/**
* Just send and log but do not check sent log
*
* @param RR Runtime environment
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param toAddr Destination address
*/
inline void sendAndLog(const RuntimeEnvironment *RR,const Address &toAddr)
inline void sendAndLog(const RuntimeEnvironment *RR,void *tPtr,const Address &toAddr)
{
_alreadySentTo.push_back(toAddr);
sendOnly(RR,toAddr);
sendOnly(RR,tPtr,toAddr);
}
/**
* Try to send this to a given peer if it hasn't been sent to them already
*
* @param RR Runtime environment
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param toAddr Destination address
* @return True if address is new and packet was sent to switch, false if duplicate
*/
inline bool sendIfNew(const RuntimeEnvironment *RR,const Address &toAddr)
inline bool sendIfNew(const RuntimeEnvironment *RR,void *tPtr,const Address &toAddr)
{
if (std::find(_alreadySentTo.begin(),_alreadySentTo.end(),toAddr) == _alreadySentTo.end()) {
sendAndLog(RR,toAddr);
sendAndLog(RR,tPtr,toAddr);
return true;
} else {
return false;

View File

@ -22,9 +22,9 @@
namespace ZeroTier {
bool Path::send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now)
bool Path::send(const RuntimeEnvironment *RR,void *tPtr,const void *data,unsigned int len,uint64_t now)
{
if (RR->node->putPacket(_localAddress,address(),data,len)) {
if (RR->node->putPacket(tPtr,_localAddress,address(),data,len)) {
_lastOut = now;
return true;
}

View File

@ -186,12 +186,13 @@ public:
* Send a packet via this path (last out time is also updated)
*
* @param RR Runtime environment
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param data Packet data
* @param len Packet length
* @param now Current time
* @return True if transport reported success
*/
bool send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now);
bool send(const RuntimeEnvironment *RR,void *tPtr,const void *data,unsigned int len,uint64_t now);
/**
* Manually update last sent time

View File

@ -68,6 +68,7 @@ Peer::Peer(const RuntimeEnvironment *renv,const Identity &myIdentity,const Ident
}
void Peer::received(
void *tPtr,
const SharedPtr<Path> &path,
const unsigned int hops,
const uint64_t packetId,
@ -161,7 +162,7 @@ void Peer::received(
}
}
if ( (!pathIsConfirmed) && (RR->node->shouldUsePathForZeroTierTraffic(_id.address(),path->localAddress(),path->address())) ) {
if ( (!pathIsConfirmed) && (RR->node->shouldUsePathForZeroTierTraffic(tPtr,_id.address(),path->localAddress(),path->address())) ) {
if (verb == Packet::VERB_OK) {
Mutex::Lock _l(_paths_m);
@ -206,7 +207,7 @@ void Peer::received(
#endif
} else {
TRACE("got %s via unknown path %s(%s), confirming...",Packet::verbString(verb),_id.address().toString().c_str(),path->address().toString().c_str());
attemptToContactAt(path->localAddress(),path->address(),now,true,path->nextOutgoingCounter());
attemptToContactAt(tPtr,path->localAddress(),path->address(),now,true,path->nextOutgoingCounter());
path->sent(now);
}
}
@ -281,7 +282,7 @@ void Peer::received(
if (count) {
outp.setAt(ZT_PACKET_IDX_PAYLOAD,(uint16_t)count);
outp.armor(_key,true,path->nextOutgoingCounter());
path->send(RR,outp.data(),outp.size(),now);
path->send(RR,tPtr,outp.data(),outp.size(),now);
}
}
}
@ -299,7 +300,7 @@ bool Peer::hasActivePathTo(uint64_t now,const InetAddress &addr) const
return false;
}
bool Peer::sendDirect(const void *data,unsigned int len,uint64_t now,bool forceEvenIfDead)
bool Peer::sendDirect(void *tPtr,const void *data,unsigned int len,uint64_t now,bool forceEvenIfDead)
{
Mutex::Lock _l(_paths_m);
@ -316,7 +317,7 @@ bool Peer::sendDirect(const void *data,unsigned int len,uint64_t now,bool forceE
}
if (bestp >= 0) {
return _paths[bestp].path->send(RR,data,len,now);
return _paths[bestp].path->send(RR,tPtr,data,len,now);
} else {
return false;
}
@ -345,7 +346,7 @@ SharedPtr<Path> Peer::getBestPath(uint64_t now,bool includeExpired)
}
}
void Peer::sendHELLO(const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,unsigned int counter)
void Peer::sendHELLO(void *tPtr,const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,unsigned int counter)
{
Packet outp(_id.address(),RR->identity.address(),Packet::VERB_HELLO);
@ -387,35 +388,35 @@ void Peer::sendHELLO(const InetAddress &localAddr,const InetAddress &atAddress,u
if (atAddress) {
outp.armor(_key,false,counter); // false == don't encrypt full payload, but add MAC
RR->node->putPacket(localAddr,atAddress,outp.data(),outp.size());
RR->node->putPacket(tPtr,localAddr,atAddress,outp.data(),outp.size());
} else {
RR->sw->send(outp,false); // false == don't encrypt full payload, but add MAC
RR->sw->send(tPtr,outp,false); // false == don't encrypt full payload, but add MAC
}
}
void Peer::attemptToContactAt(const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,bool sendFullHello,unsigned int counter)
void Peer::attemptToContactAt(void *tPtr,const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,bool sendFullHello,unsigned int counter)
{
if ( (!sendFullHello) && (_vProto >= 5) && (!((_vMajor == 1)&&(_vMinor == 1)&&(_vRevision == 0))) ) {
Packet outp(_id.address(),RR->identity.address(),Packet::VERB_ECHO);
RR->node->expectReplyTo(outp.packetId());
outp.armor(_key,true,counter);
RR->node->putPacket(localAddr,atAddress,outp.data(),outp.size());
RR->node->putPacket(tPtr,localAddr,atAddress,outp.data(),outp.size());
} else {
sendHELLO(localAddr,atAddress,now,counter);
sendHELLO(tPtr,localAddr,atAddress,now,counter);
}
}
void Peer::tryMemorizedPath(uint64_t now)
void Peer::tryMemorizedPath(void *tPtr,uint64_t now)
{
if ((now - _lastTriedMemorizedPath) >= ZT_TRY_MEMORIZED_PATH_INTERVAL) {
_lastTriedMemorizedPath = now;
InetAddress mp;
if (RR->node->externalPathLookup(_id.address(),-1,mp))
attemptToContactAt(InetAddress(),mp,now,true,0);
if (RR->node->externalPathLookup(tPtr,_id.address(),-1,mp))
attemptToContactAt(tPtr,InetAddress(),mp,now,true,0);
}
}
bool Peer::doPingAndKeepalive(uint64_t now,int inetAddressFamily)
bool Peer::doPingAndKeepalive(void *tPtr,uint64_t now,int inetAddressFamily)
{
Mutex::Lock _l(_paths_m);
@ -433,7 +434,7 @@ bool Peer::doPingAndKeepalive(uint64_t now,int inetAddressFamily)
if (bestp >= 0) {
if ( ((now - _paths[bestp].lastReceive) >= ZT_PEER_PING_PERIOD) || (_paths[bestp].path->needsHeartbeat(now)) ) {
attemptToContactAt(_paths[bestp].path->localAddress(),_paths[bestp].path->address(),now,false,_paths[bestp].path->nextOutgoingCounter());
attemptToContactAt(tPtr,_paths[bestp].path->localAddress(),_paths[bestp].path->address(),now,false,_paths[bestp].path->nextOutgoingCounter());
_paths[bestp].path->sent(now);
}
return true;
@ -452,12 +453,12 @@ bool Peer::hasActiveDirectPath(uint64_t now) const
return false;
}
void Peer::resetWithinScope(InetAddress::IpScope scope,int inetAddressFamily,uint64_t now)
void Peer::resetWithinScope(void *tPtr,InetAddress::IpScope scope,int inetAddressFamily,uint64_t now)
{
Mutex::Lock _l(_paths_m);
for(unsigned int p=0;p<_numPaths;++p) {
if ( (_paths[p].path->address().ss_family == inetAddressFamily) && (_paths[p].path->address().ipScope() == scope) ) {
attemptToContactAt(_paths[p].path->localAddress(),_paths[p].path->address(),now,false,_paths[p].path->nextOutgoingCounter());
attemptToContactAt(tPtr,_paths[p].path->localAddress(),_paths[p].path->address(),now,false,_paths[p].path->nextOutgoingCounter());
_paths[p].path->sent(now);
_paths[p].lastReceive = 0; // path will not be used unless it speaks again
}

View File

@ -84,6 +84,7 @@ public:
* This is called by the decode pipe when a packet is proven to be authentic
* and appears to be valid.
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param path Path over which packet was received
* @param hops ZeroTier (not IP) hops
* @param packetId Packet ID
@ -93,6 +94,7 @@ public:
* @param trustEstablished If true, some form of non-trivial trust (like allowed in network) has been established
*/
void received(
void *tPtr,
const SharedPtr<Path> &path,
const unsigned int hops,
const uint64_t packetId,
@ -125,13 +127,14 @@ public:
/**
* Send via best direct path
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param data Packet data
* @param len Packet length
* @param now Current time
* @param forceEvenIfDead If true, send even if the path is not 'alive'
* @return True if we actually sent something
*/
bool sendDirect(const void *data,unsigned int len,uint64_t now,bool forceEvenIfDead);
bool sendDirect(void *tPtr,const void *data,unsigned int len,uint64_t now,bool forceEvenIfDead);
/**
* Get the best current direct path
@ -147,41 +150,47 @@ public:
*
* No statistics or sent times are updated here.
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param localAddr Local address
* @param atAddress Destination address
* @param now Current time
* @param counter Outgoing packet counter
*/
void sendHELLO(const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,unsigned int counter);
void sendHELLO(void *tPtr,const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,unsigned int counter);
/**
* Send ECHO (or HELLO for older peers) to this peer at the given address
*
* No statistics or sent times are updated here.
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param localAddr Local address
* @param atAddress Destination address
* @param now Current time
* @param sendFullHello If true, always send a full HELLO instead of just an ECHO
* @param counter Outgoing packet counter
*/
void attemptToContactAt(const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,bool sendFullHello,unsigned int counter);
void attemptToContactAt(void *tPtr,const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,bool sendFullHello,unsigned int counter);
/**
* Try a memorized or statically defined path if any are known
*
* Under the hood this is done periodically based on ZT_TRY_MEMORIZED_PATH_INTERVAL.
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param now Current time
*/
void tryMemorizedPath(uint64_t now);
void tryMemorizedPath(void *tPtr,uint64_t now);
/**
* Send pings or keepalives depending on configured timeouts
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param now Current time
* @param inetAddressFamily Keep this address family alive, or -1 for any
* @return True if we have at least one direct path of the given family (or any if family is -1)
*/
bool doPingAndKeepalive(uint64_t now,int inetAddressFamily);
bool doPingAndKeepalive(void *tPtr,uint64_t now,int inetAddressFamily);
/**
* @param now Current time
@ -195,11 +204,12 @@ public:
* Resetting a path involves sending an ECHO to it and then deactivating
* it until or unless it responds.
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param scope IP scope
* @param inetAddressFamily Family e.g. AF_INET
* @param now Current time
*/
void resetWithinScope(InetAddress::IpScope scope,int inetAddressFamily,uint64_t now);
void resetWithinScope(void *tPtr,InetAddress::IpScope scope,int inetAddressFamily,uint64_t now);
/**
* Get most recently active path addresses for IPv4 and/or IPv6

View File

@ -25,13 +25,13 @@
namespace ZeroTier {
int Revocation::verify(const RuntimeEnvironment *RR) const
int Revocation::verify(const RuntimeEnvironment *RR,void *tPtr) const
{
if ((!_signedBy)||(_signedBy != Network::controllerFor(_networkId)))
return -1;
const Identity id(RR->topology->getIdentity(_signedBy));
const Identity id(RR->topology->getIdentity(tPtr,_signedBy));
if (!id) {
RR->sw->requestWhois(_signedBy);
RR->sw->requestWhois(tPtr,_signedBy);
return 1;
}
try {

View File

@ -113,9 +113,10 @@ public:
* Verify this revocation's signature
*
* @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
* @return 0 == OK, 1 == waiting for WHOIS, -1 == BAD signature or chain
*/
int verify(const RuntimeEnvironment *RR) const;
int verify(const RuntimeEnvironment *RR,void *tPtr) const;
template<unsigned int C>
inline void serialize(Buffer<C> &b,const bool forSign = false) const

View File

@ -40,15 +40,17 @@ namespace ZeroTier {
class _ResetWithinScope
{
public:
_ResetWithinScope(uint64_t now,int inetAddressFamily,InetAddress::IpScope scope) :
_ResetWithinScope(void *tPtr,uint64_t now,int inetAddressFamily,InetAddress::IpScope scope) :
_now(now),
_tPtr(tPtr),
_family(inetAddressFamily),
_scope(scope) {}
inline void operator()(Topology &t,const SharedPtr<Peer> &p) { p->resetWithinScope(_scope,_family,_now); }
inline void operator()(Topology &t,const SharedPtr<Peer> &p) { p->resetWithinScope(_tPtr,_scope,_family,_now); }
private:
uint64_t _now;
void *_tPtr;
int _family;
InetAddress::IpScope _scope;
};
@ -59,7 +61,7 @@ SelfAwareness::SelfAwareness(const RuntimeEnvironment *renv) :
{
}
void SelfAwareness::iam(const Address &reporter,const InetAddress &receivedOnLocalAddress,const InetAddress &reporterPhysicalAddress,const InetAddress &myPhysicalAddress,bool trusted,uint64_t now)
void SelfAwareness::iam(void *tPtr,const Address &reporter,const InetAddress &receivedOnLocalAddress,const InetAddress &reporterPhysicalAddress,const InetAddress &myPhysicalAddress,bool trusted,uint64_t now)
{
const InetAddress::IpScope scope = myPhysicalAddress.ipScope();
@ -91,7 +93,7 @@ void SelfAwareness::iam(const Address &reporter,const InetAddress &receivedOnLoc
}
// Reset all paths within this scope and address family
_ResetWithinScope rset(now,myPhysicalAddress.ss_family,(InetAddress::IpScope)scope);
_ResetWithinScope rset(tPtr,now,myPhysicalAddress.ss_family,(InetAddress::IpScope)scope);
RR->topology->eachPeer<_ResetWithinScope &>(rset);
} else {
// Otherwise just update DB to use to determine external surface info

View File

@ -47,7 +47,7 @@ public:
* @param trusted True if this peer is trusted as an authority to inform us of external address changes
* @param now Current time
*/
void iam(const Address &reporter,const InetAddress &receivedOnLocalAddress,const InetAddress &reporterPhysicalAddress,const InetAddress &myPhysicalAddress,bool trusted,uint64_t now);
void iam(void *tPtr,const Address &reporter,const InetAddress &receivedOnLocalAddress,const InetAddress &reporterPhysicalAddress,const InetAddress &myPhysicalAddress,bool trusted,uint64_t now);
/**
* Clean up database periodically

View File

@ -64,7 +64,7 @@ Switch::Switch(const RuntimeEnvironment *renv) :
{
}
void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &fromAddr,const void *data,unsigned int len)
void Switch::onRemotePacket(void *tPtr,const InetAddress &localAddr,const InetAddress &fromAddr,const void *data,unsigned int len)
{
try {
const uint64_t now = RR->node->now();
@ -81,15 +81,15 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from
const Address beaconAddr(reinterpret_cast<const char *>(data) + 8,5);
if (beaconAddr == RR->identity.address())
return;
if (!RR->node->shouldUsePathForZeroTierTraffic(beaconAddr,localAddr,fromAddr))
if (!RR->node->shouldUsePathForZeroTierTraffic(tPtr,beaconAddr,localAddr,fromAddr))
return;
const SharedPtr<Peer> peer(RR->topology->getPeer(beaconAddr));
const SharedPtr<Peer> peer(RR->topology->getPeer(tPtr,beaconAddr));
if (peer) { // we'll only respond to beacons from known peers
if ((now - _lastBeaconResponse) >= 2500) { // limit rate of responses
_lastBeaconResponse = now;
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NOP);
outp.armor(peer->key(),true,path->nextOutgoingCounter());
path->send(RR,outp.data(),outp.size(),now);
path->send(RR,tPtr,outp.data(),outp.size(),now);
}
}
@ -115,8 +115,8 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from
// Note: we don't bother initiating NAT-t for fragments, since heads will set that off.
// It wouldn't hurt anything, just redundant and unnecessary.
SharedPtr<Peer> relayTo = RR->topology->getPeer(destination);
if ((!relayTo)||(!relayTo->sendDirect(fragment.data(),fragment.size(),now,false))) {
SharedPtr<Peer> relayTo = RR->topology->getPeer(tPtr,destination);
if ((!relayTo)||(!relayTo->sendDirect(tPtr,fragment.data(),fragment.size(),now,false))) {
#ifdef ZT_ENABLE_CLUSTER
if ((RR->cluster)&&(!isClusterFrontplane)) {
RR->cluster->relayViaCluster(Address(),destination,fragment.data(),fragment.size(),false);
@ -127,7 +127,7 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from
// Don't know peer or no direct path -- so relay via someone upstream
relayTo = RR->topology->getUpstreamPeer();
if (relayTo)
relayTo->sendDirect(fragment.data(),fragment.size(),now,true);
relayTo->sendDirect(tPtr,fragment.data(),fragment.size(),now,true);
}
} else {
TRACE("dropped relay [fragment](%s) -> %s, max hops exceeded",fromAddr.toString().c_str(),destination.toString().c_str());
@ -171,7 +171,7 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from
for(unsigned int f=1;f<totalFragments;++f)
rq->frag0.append(rq->frags[f - 1].payload(),rq->frags[f - 1].payloadLength());
if (rq->frag0.tryDecode(RR)) {
if (rq->frag0.tryDecode(RR,tPtr)) {
rq->timestamp = 0; // packet decoded, free entry
} else {
rq->complete = true; // set complete flag but leave entry since it probably needs WHOIS or something
@ -212,8 +212,8 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from
packet.incrementHops();
#endif
SharedPtr<Peer> relayTo = RR->topology->getPeer(destination);
if ((relayTo)&&(relayTo->sendDirect(packet.data(),packet.size(),now,false))) {
SharedPtr<Peer> relayTo = RR->topology->getPeer(tPtr,destination);
if ((relayTo)&&(relayTo->sendDirect(tPtr,packet.data(),packet.size(),now,false))) {
if ((source != RR->identity.address())&&(_shouldUnite(now,source,destination))) { // don't send RENDEZVOUS for cluster frontplane relays
const InetAddress *hintToSource = (InetAddress *)0;
const InetAddress *hintToDest = (InetAddress *)0;
@ -222,7 +222,7 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from
InetAddress sourceV4,sourceV6;
relayTo->getRendezvousAddresses(now,destV4,destV6);
const SharedPtr<Peer> sourcePeer(RR->topology->getPeer(source));
const SharedPtr<Peer> sourcePeer(RR->topology->getPeer(tPtr,source));
if (sourcePeer) {
sourcePeer->getRendezvousAddresses(now,sourceV4,sourceV6);
if ((destV6)&&(sourceV6)) {
@ -249,7 +249,7 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from
outp.append((uint8_t)4);
outp.append(hintToSource->rawIpData(),4);
}
send(outp,true);
send(tPtr,outp,true);
} else {
Packet outp(destination,RR->identity.address(),Packet::VERB_RENDEZVOUS);
outp.append((uint8_t)0);
@ -262,7 +262,7 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from
outp.append((uint8_t)4);
outp.append(hintToDest->rawIpData(),4);
}
send(outp,true);
send(tPtr,outp,true);
}
++alt;
}
@ -278,7 +278,7 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from
#endif
relayTo = RR->topology->getUpstreamPeer(&source,1,true);
if (relayTo)
relayTo->sendDirect(packet.data(),packet.size(),now,true);
relayTo->sendDirect(tPtr,packet.data(),packet.size(),now,true);
}
} else {
TRACE("dropped relay %s(%s) -> %s, max hops exceeded",packet.source().toString().c_str(),fromAddr.toString().c_str(),destination.toString().c_str());
@ -321,7 +321,7 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from
for(unsigned int f=1;f<rq->totalFragments;++f)
rq->frag0.append(rq->frags[f - 1].payload(),rq->frags[f - 1].payloadLength());
if (rq->frag0.tryDecode(RR)) {
if (rq->frag0.tryDecode(RR,tPtr)) {
rq->timestamp = 0; // packet decoded, free entry
} else {
rq->complete = true; // set complete flag but leave entry since it probably needs WHOIS or something
@ -334,7 +334,7 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from
} else {
// Packet is unfragmented, so just process it
IncomingPacket packet(data,len,path,now);
if (!packet.tryDecode(RR)) {
if (!packet.tryDecode(RR,tPtr)) {
Mutex::Lock _l(_rxQueue_m);
RXQueueEntry *rq = &(_rxQueue[ZT_RX_QUEUE_SIZE - 1]);
unsigned long i = ZT_RX_QUEUE_SIZE - 1;
@ -362,7 +362,7 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from
}
}
void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
{
if (!network->hasConfig())
return;
@ -474,7 +474,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
adv[42] = (checksum >> 8) & 0xff;
adv[43] = checksum & 0xff;
RR->node->putFrame(network->id(),network->userPtr(),peerMac,from,ZT_ETHERTYPE_IPV6,0,adv,72);
RR->node->putFrame(tPtr,network->id(),network->userPtr(),peerMac,from,ZT_ETHERTYPE_IPV6,0,adv,72);
return; // NDP emulation done. We have forged a "fake" reply, so no need to send actual NDP query.
} // else no NDP emulation
} // else no NDP emulation
@ -491,17 +491,18 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
* multicast addresses on bridge interfaces and subscribing each slave.
* But in that case this does no harm, as the sets are just merged. */
if (fromBridged)
network->learnBridgedMulticastGroup(multicastGroup,RR->node->now());
network->learnBridgedMulticastGroup(tPtr,multicastGroup,RR->node->now());
//TRACE("%.16llx: MULTICAST %s -> %s %s %u",network->id(),from.toString().c_str(),multicastGroup.toString().c_str(),etherTypeName(etherType),len);
// First pass sets noTee to false, but noTee is set to true in OutboundMulticast to prevent duplicates.
if (!network->filterOutgoingPacket(false,RR->identity.address(),Address(),from,to,(const uint8_t *)data,len,etherType,vlanId)) {
if (!network->filterOutgoingPacket(tPtr,false,RR->identity.address(),Address(),from,to,(const uint8_t *)data,len,etherType,vlanId)) {
TRACE("%.16llx: %s -> %s %s packet not sent: filterOutgoingPacket() returned false",network->id(),from.toString().c_str(),to.toString().c_str(),etherTypeName(etherType));
return;
}
RR->mc->send(
tPtr,
network->config().multicastLimit,
RR->node->now(),
network->id(),
@ -514,14 +515,14 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
len);
} else if (to == network->mac()) {
// Destination is this node, so just reinject it
RR->node->putFrame(network->id(),network->userPtr(),from,to,etherType,vlanId,data,len);
RR->node->putFrame(tPtr,network->id(),network->userPtr(),from,to,etherType,vlanId,data,len);
} else if (to[0] == MAC::firstOctetForNetwork(network->id())) {
// Destination is another ZeroTier peer on the same network
Address toZT(to.toAddress(network->id())); // since in-network MACs are derived from addresses and network IDs, we can reverse this
SharedPtr<Peer> toPeer(RR->topology->getPeer(toZT));
SharedPtr<Peer> toPeer(RR->topology->getPeer(tPtr,toZT));
if (!network->filterOutgoingPacket(false,RR->identity.address(),toZT,from,to,(const uint8_t *)data,len,etherType,vlanId)) {
if (!network->filterOutgoingPacket(tPtr,false,RR->identity.address(),toZT,from,to,(const uint8_t *)data,len,etherType,vlanId)) {
TRACE("%.16llx: %s -> %s %s packet not sent: filterOutgoingPacket() returned false",network->id(),from.toString().c_str(),to.toString().c_str(),etherTypeName(etherType));
return;
}
@ -536,7 +537,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
outp.append(data,len);
if (!network->config().disableCompression())
outp.compress();
send(outp,true);
send(tPtr,outp,true);
} else {
Packet outp(toZT,RR->identity.address(),Packet::VERB_FRAME);
outp.append(network->id());
@ -544,7 +545,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
outp.append(data,len);
if (!network->config().disableCompression())
outp.compress();
send(outp,true);
send(tPtr,outp,true);
}
//TRACE("%.16llx: UNICAST: %s -> %s etherType==%s(%.4x) vlanId==%u len==%u fromBridged==%d includeCom==%d",network->id(),from.toString().c_str(),to.toString().c_str(),etherTypeName(etherType),etherType,vlanId,len,(int)fromBridged,(int)includeCom);
@ -554,7 +555,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
// We filter with a NULL destination ZeroTier address first. Filtrations
// for each ZT destination are also done below. This is the same rationale
// and design as for multicast.
if (!network->filterOutgoingPacket(false,RR->identity.address(),Address(),from,to,(const uint8_t *)data,len,etherType,vlanId)) {
if (!network->filterOutgoingPacket(tPtr,false,RR->identity.address(),Address(),from,to,(const uint8_t *)data,len,etherType,vlanId)) {
TRACE("%.16llx: %s -> %s %s packet not sent: filterOutgoingPacket() returned false",network->id(),from.toString().c_str(),to.toString().c_str(),etherTypeName(etherType));
return;
}
@ -592,7 +593,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
}
for(unsigned int b=0;b<numBridges;++b) {
if (network->filterOutgoingPacket(true,RR->identity.address(),bridges[b],from,to,(const uint8_t *)data,len,etherType,vlanId)) {
if (network->filterOutgoingPacket(tPtr,true,RR->identity.address(),bridges[b],from,to,(const uint8_t *)data,len,etherType,vlanId)) {
Packet outp(bridges[b],RR->identity.address(),Packet::VERB_EXT_FRAME);
outp.append(network->id());
outp.append((uint8_t)0x00);
@ -602,7 +603,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
outp.append(data,len);
if (!network->config().disableCompression())
outp.compress();
send(outp,true);
send(tPtr,outp,true);
} else {
TRACE("%.16llx: %s -> %s %s packet not sent: filterOutgoingPacket() returned false",network->id(),from.toString().c_str(),to.toString().c_str(),etherTypeName(etherType));
}
@ -610,20 +611,20 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
}
}
void Switch::send(Packet &packet,bool encrypt)
void Switch::send(void *tPtr,Packet &packet,bool encrypt)
{
if (packet.destination() == RR->identity.address()) {
TRACE("BUG: caught attempt to send() to self, ignored");
return;
}
if (!_trySend(packet,encrypt)) {
if (!_trySend(tPtr,packet,encrypt)) {
Mutex::Lock _l(_txQueue_m);
_txQueue.push_back(TXQueueEntry(packet.destination(),RR->node->now(),packet,encrypt));
}
}
void Switch::requestWhois(const Address &addr)
void Switch::requestWhois(void *tPtr,const Address &addr)
{
#ifdef ZT_TRACE
if (addr == RR->identity.address()) {
@ -644,10 +645,10 @@ void Switch::requestWhois(const Address &addr)
}
}
if (inserted)
_sendWhoisRequest(addr,(const Address *)0,0);
_sendWhoisRequest(tPtr,addr,(const Address *)0,0);
}
void Switch::doAnythingWaitingForPeer(const SharedPtr<Peer> &peer)
void Switch::doAnythingWaitingForPeer(void *tPtr,const SharedPtr<Peer> &peer)
{
{ // cancel pending WHOIS since we now know this peer
Mutex::Lock _l(_outstandingWhoisRequests_m);
@ -660,7 +661,7 @@ void Switch::doAnythingWaitingForPeer(const SharedPtr<Peer> &peer)
while (i) {
RXQueueEntry *rq = &(_rxQueue[--i]);
if ((rq->timestamp)&&(rq->complete)) {
if (rq->frag0.tryDecode(RR))
if (rq->frag0.tryDecode(RR,tPtr))
rq->timestamp = 0;
}
}
@ -670,7 +671,7 @@ void Switch::doAnythingWaitingForPeer(const SharedPtr<Peer> &peer)
Mutex::Lock _l(_txQueue_m);
for(std::list< TXQueueEntry >::iterator txi(_txQueue.begin());txi!=_txQueue.end();) {
if (txi->dest == peer->address()) {
if (_trySend(txi->packet,txi->encrypt))
if (_trySend(tPtr,txi->packet,txi->encrypt))
_txQueue.erase(txi++);
else ++txi;
} else ++txi;
@ -678,7 +679,7 @@ void Switch::doAnythingWaitingForPeer(const SharedPtr<Peer> &peer)
}
}
unsigned long Switch::doTimerTasks(uint64_t now)
unsigned long Switch::doTimerTasks(void *tPtr,uint64_t now)
{
unsigned long nextDelay = 0xffffffff; // ceiling delay, caller will cap to minimum
@ -695,7 +696,7 @@ unsigned long Switch::doTimerTasks(uint64_t now)
_outstandingWhoisRequests.erase(*a);
} else {
r->lastSent = now;
r->peersConsulted[r->retries] = _sendWhoisRequest(*a,r->peersConsulted,(r->retries > 1) ? r->retries : 0);
r->peersConsulted[r->retries] = _sendWhoisRequest(tPtr,*a,r->peersConsulted,(r->retries > 1) ? r->retries : 0);
TRACE("WHOIS %s (retry %u)",a->toString().c_str(),r->retries);
++r->retries;
nextDelay = std::min(nextDelay,(unsigned long)ZT_WHOIS_RETRY_DELAY);
@ -709,7 +710,7 @@ unsigned long Switch::doTimerTasks(uint64_t now)
{ // Time out TX queue packets that never got WHOIS lookups or other info.
Mutex::Lock _l(_txQueue_m);
for(std::list< TXQueueEntry >::iterator txi(_txQueue.begin());txi!=_txQueue.end();) {
if (_trySend(txi->packet,txi->encrypt))
if (_trySend(tPtr,txi->packet,txi->encrypt))
_txQueue.erase(txi++);
else if ((now - txi->creationTime) > ZT_TRANSMIT_QUEUE_TIMEOUT) {
TRACE("TX %s -> %s timed out",txi->packet.source().toString().c_str(),txi->packet.destination().toString().c_str());
@ -743,19 +744,19 @@ bool Switch::_shouldUnite(const uint64_t now,const Address &source,const Address
return false;
}
Address Switch::_sendWhoisRequest(const Address &addr,const Address *peersAlreadyConsulted,unsigned int numPeersAlreadyConsulted)
Address Switch::_sendWhoisRequest(void *tPtr,const Address &addr,const Address *peersAlreadyConsulted,unsigned int numPeersAlreadyConsulted)
{
SharedPtr<Peer> upstream(RR->topology->getUpstreamPeer(peersAlreadyConsulted,numPeersAlreadyConsulted,false));
if (upstream) {
Packet outp(upstream->address(),RR->identity.address(),Packet::VERB_WHOIS);
addr.appendTo(outp);
RR->node->expectReplyTo(outp.packetId());
send(outp,true);
send(tPtr,outp,true);
}
return Address();
}
bool Switch::_trySend(Packet &packet,bool encrypt)
bool Switch::_trySend(void *tPtr,Packet &packet,bool encrypt)
{
SharedPtr<Path> viaPath;
const uint64_t now = RR->node->now();
@ -769,7 +770,7 @@ bool Switch::_trySend(Packet &packet,bool encrypt)
clusterMostRecentMemberId = RR->cluster->checkSendViaCluster(destination,clusterMostRecentTs,clusterPeerSecret);
#endif
const SharedPtr<Peer> peer(RR->topology->getPeer(destination));
const SharedPtr<Peer> peer(RR->topology->getPeer(tPtr,destination));
if (peer) {
/* First get the best path, and if it's dead (and this is not a root)
* we attempt to re-activate that path but this packet will flow
@ -784,7 +785,7 @@ bool Switch::_trySend(Packet &packet,bool encrypt)
if ((clusterMostRecentMemberId < 0)||(viaPath->lastIn() > clusterMostRecentTs)) {
#endif
if ((now - viaPath->lastOut()) > std::max((now - viaPath->lastIn()) * 4,(uint64_t)ZT_PATH_MIN_REACTIVATE_INTERVAL)) {
peer->attemptToContactAt(viaPath->localAddress(),viaPath->address(),now,false,viaPath->nextOutgoingCounter());
peer->attemptToContactAt(tPtr,viaPath->localAddress(),viaPath->address(),now,false,viaPath->nextOutgoingCounter());
viaPath->sent(now);
}
#ifdef ZT_ENABLE_CLUSTER
@ -801,7 +802,7 @@ bool Switch::_trySend(Packet &packet,bool encrypt)
#else
if (!viaPath) {
#endif
peer->tryMemorizedPath(now); // periodically attempt memorized or statically defined paths, if any are known
peer->tryMemorizedPath(tPtr,now); // periodically attempt memorized or statically defined paths, if any are known
const SharedPtr<Peer> relay(RR->topology->getUpstreamPeer());
if ( (!relay) || (!(viaPath = relay->getBestPath(now,false))) ) {
if (!(viaPath = peer->getBestPath(now,true)))
@ -816,7 +817,7 @@ bool Switch::_trySend(Packet &packet,bool encrypt)
#ifdef ZT_ENABLE_CLUSTER
if (clusterMostRecentMemberId < 0) {
#else
requestWhois(destination);
requestWhois(tPtr,destination);
return false; // if we are not in cluster mode, there is no way we can send without knowing the peer directly
#endif
#ifdef ZT_ENABLE_CLUSTER
@ -844,9 +845,9 @@ bool Switch::_trySend(Packet &packet,bool encrypt)
#endif
#ifdef ZT_ENABLE_CLUSTER
if ( ((viaPath)&&(viaPath->send(RR,packet.data(),chunkSize,now))) || ((clusterMostRecentMemberId >= 0)&&(RR->cluster->sendViaCluster(clusterMostRecentMemberId,destination,packet.data(),chunkSize))) ) {
if ( ((viaPath)&&(viaPath->send(RR,tPtr,packet.data(),chunkSize,now))) || ((clusterMostRecentMemberId >= 0)&&(RR->cluster->sendViaCluster(clusterMostRecentMemberId,destination,packet.data(),chunkSize))) ) {
#else
if (viaPath->send(RR,packet.data(),chunkSize,now)) {
if (viaPath->send(RR,tPtr,packet.data(),chunkSize,now)) {
#endif
if (chunkSize < packet.size()) {
// Too big for one packet, fragment the rest
@ -866,7 +867,7 @@ bool Switch::_trySend(Packet &packet,bool encrypt)
else if (clusterMostRecentMemberId >= 0)
RR->cluster->sendViaCluster(clusterMostRecentMemberId,destination,frag.data(),frag.size());
#else
viaPath->send(RR,frag.data(),frag.size(),now);
viaPath->send(RR,tPtr,frag.data(),frag.size(),now);
#endif
fragStart += chunkSize;
remaining -= chunkSize;

View File

@ -59,16 +59,18 @@ public:
/**
* Called when a packet is received from the real network
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param localAddr Local interface address
* @param fromAddr Internet IP address of origin
* @param data Packet data
* @param len Packet length
*/
void onRemotePacket(const InetAddress &localAddr,const InetAddress &fromAddr,const void *data,unsigned int len);
void onRemotePacket(void *tPtr,const InetAddress &localAddr,const InetAddress &fromAddr,const void *data,unsigned int len);
/**
* Called when a packet comes from a local Ethernet tap
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param network Which network's TAP did this packet come from?
* @param from Originating MAC address
* @param to Destination MAC address
@ -77,7 +79,7 @@ public:
* @param data Ethernet payload
* @param len Frame length
*/
void onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len);
void onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len);
/**
* Send a packet to a ZeroTier address (destination in packet)
@ -91,26 +93,29 @@ public:
* Needless to say, the packet's source must be this node. Otherwise it
* won't be encrypted right. (This is not used for relaying.)
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param packet Packet to send (buffer may be modified)
* @param encrypt Encrypt packet payload? (always true except for HELLO)
*/
void send(Packet &packet,bool encrypt);
void send(void *tPtr,Packet &packet,bool encrypt);
/**
* Request WHOIS on a given address
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param addr Address to look up
*/
void requestWhois(const Address &addr);
void requestWhois(void *tPtr,const Address &addr);
/**
* Run any processes that are waiting for this peer's identity
*
* Called when we learn of a peer's identity from HELLO, OK(WHOIS), etc.
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param peer New peer
*/
void doAnythingWaitingForPeer(const SharedPtr<Peer> &peer);
void doAnythingWaitingForPeer(void *tPtr,const SharedPtr<Peer> &peer);
/**
* Perform retries and other periodic timer tasks
@ -118,15 +123,16 @@ public:
* This can return a very long delay if there are no pending timer
* tasks. The caller should cap this comparatively vs. other values.
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param now Current time
* @return Number of milliseconds until doTimerTasks() should be run again
*/
unsigned long doTimerTasks(uint64_t now);
unsigned long doTimerTasks(void *tPtr,uint64_t now);
private:
bool _shouldUnite(const uint64_t now,const Address &source,const Address &destination);
Address _sendWhoisRequest(const Address &addr,const Address *peersAlreadyConsulted,unsigned int numPeersAlreadyConsulted);
bool _trySend(Packet &packet,bool encrypt); // packet is modified if return is true
Address _sendWhoisRequest(void *tPtr,const Address &addr,const Address *peersAlreadyConsulted,unsigned int numPeersAlreadyConsulted);
bool _trySend(void *tPtr,Packet &packet,bool encrypt); // packet is modified if return is true
const RuntimeEnvironment *const RR;
uint64_t _lastBeaconResponse;

View File

@ -25,13 +25,13 @@
namespace ZeroTier {
int Tag::verify(const RuntimeEnvironment *RR) const
int Tag::verify(const RuntimeEnvironment *RR,void *tPtr) const
{
if ((!_signedBy)||(_signedBy != Network::controllerFor(_networkId)))
return -1;
const Identity id(RR->topology->getIdentity(_signedBy));
const Identity id(RR->topology->getIdentity(tPtr,_signedBy));
if (!id) {
RR->sw->requestWhois(_signedBy);
RR->sw->requestWhois(tPtr,_signedBy);
return 1;
}
try {

View File

@ -105,9 +105,10 @@ public:
* Check this tag's signature
*
* @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
* @return 0 == OK, 1 == waiting for WHOIS, -1 == BAD signature or tag
*/
int verify(const RuntimeEnvironment *RR) const;
int verify(const RuntimeEnvironment *RR,void *tPtr) const;
template<unsigned int C>
inline void serialize(Buffer<C> &b,const bool forSign = false) const

View File

@ -55,19 +55,19 @@ namespace ZeroTier {
#define ZT_DEFAULT_WORLD_LENGTH 634
static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = {0x01,0x00,0x00,0x00,0x00,0x08,0xea,0xc9,0x0a,0x00,0x00,0x01,0x52,0x3c,0x32,0x50,0x1a,0xb8,0xb3,0x88,0xa4,0x69,0x22,0x14,0x91,0xaa,0x9a,0xcd,0x66,0xcc,0x76,0x4c,0xde,0xfd,0x56,0x03,0x9f,0x10,0x67,0xae,0x15,0xe6,0x9c,0x6f,0xb4,0x2d,0x7b,0x55,0x33,0x0e,0x3f,0xda,0xac,0x52,0x9c,0x07,0x92,0xfd,0x73,0x40,0xa6,0xaa,0x21,0xab,0xa8,0xa4,0x89,0xfd,0xae,0xa4,0x4a,0x39,0xbf,0x2d,0x00,0x65,0x9a,0xc9,0xc8,0x18,0xeb,0x4a,0xf7,0x86,0xa8,0x40,0xd6,0x52,0xea,0xae,0x9e,0x7a,0xbf,0x4c,0x97,0x66,0xab,0x2d,0x6f,0xaf,0xc9,0x2b,0x3a,0xff,0xed,0xd6,0x30,0x3e,0xc4,0x6a,0x65,0xf2,0xbd,0x83,0x52,0xf5,0x40,0xe9,0xcc,0x0d,0x6e,0x89,0x3f,0x9a,0xa0,0xb8,0xdf,0x42,0xd2,0x2f,0x84,0xe6,0x03,0x26,0x0f,0xa8,0xe3,0xcc,0x05,0x05,0x03,0xef,0x12,0x80,0x0d,0xce,0x3e,0xb6,0x58,0x3b,0x1f,0xa8,0xad,0xc7,0x25,0xf9,0x43,0x71,0xa7,0x5c,0x9a,0xc7,0xe1,0xa3,0xb8,0x88,0xd0,0x71,0x6c,0x94,0x99,0x73,0x41,0x0b,0x1b,0x48,0x84,0x02,0x9d,0x21,0x90,0x39,0xf3,0x00,0x01,0xf0,0x92,0x2a,0x98,0xe3,0xb3,0x4e,0xbc,0xbf,0xf3,0x33,0x26,0x9d,0xc2,0x65,0xd7,0xa0,0x20,0xaa,0xb6,0x9d,0x72,0xbe,0x4d,0x4a,0xcc,0x9c,0x8c,0x92,0x94,0x78,0x57,0x71,0x25,0x6c,0xd1,0xd9,0x42,0xa9,0x0d,0x1b,0xd1,0xd2,0xdc,0xa3,0xea,0x84,0xef,0x7d,0x85,0xaf,0xe6,0x61,0x1f,0xb4,0x3f,0xf0,0xb7,0x41,0x26,0xd9,0x0a,0x6e,0x00,0x0c,0x04,0xbc,0xa6,0x5e,0xb1,0x27,0x09,0x06,0x2a,0x03,0xb0,0xc0,0x00,0x02,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x7d,0x00,0x01,0x27,0x09,0x04,0x9a,0x42,0xc5,0x21,0x27,0x09,0x06,0x2c,0x0f,0xf8,0x50,0x01,0x54,0x01,0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x27,0x09,0x04,0x9f,0xcb,0x61,0xab,0x27,0x09,0x06,0x26,0x04,0xa8,0x80,0x08,0x00,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,0x54,0x60,0x01,0x27,0x09,0x04,0xa9,0x39,0x8f,0x68,0x27,0x09,0x06,0x26,0x07,0xf0,0xd0,0x1d,0x01,0x00,0x57,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x27,0x09,0x04,0x6b,0xaa,0xc5,0x0e,0x27,0x09,0x06,0x26,0x04,0xa8,0x80,0x00,0x01,0x00,0x20,0x00,0x00,0x00,0x00,0x02,0x00,0xe0,0x01,0x27,0x09,0x04,0x80,0xc7,0xc5,0xd9,0x27,0x09,0x06,0x24,0x00,0x61,0x80,0x00,0x00,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0xb7,0x40,0x01,0x27,0x09,0x88,0x41,0x40,0x8a,0x2e,0x00,0xbb,0x1d,0x31,0xf2,0xc3,0x23,0xe2,0x64,0xe9,0xe6,0x41,0x72,0xc1,0xa7,0x4f,0x77,0x89,0x95,0x55,0xed,0x10,0x75,0x1c,0xd5,0x6e,0x86,0x40,0x5c,0xde,0x11,0x8d,0x02,0xdf,0xfe,0x55,0x5d,0x46,0x2c,0xcf,0x6a,0x85,0xb5,0x63,0x1c,0x12,0x35,0x0c,0x8d,0x5d,0xc4,0x09,0xba,0x10,0xb9,0x02,0x5d,0x0f,0x44,0x5c,0xf4,0x49,0xd9,0x2b,0x1c,0x00,0x0c,0x04,0x2d,0x20,0xc6,0x82,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x64,0x00,0x81,0xc3,0x54,0x00,0x00,0xff,0xfe,0x18,0x1d,0x61,0x27,0x09,0x04,0x2e,0x65,0xa0,0xf9,0x27,0x09,0x06,0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x6a,0x30,0x01,0x27,0x09,0x04,0x6b,0xbf,0x2e,0xd2,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x68,0x00,0x83,0xa4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x64,0x27,0x09,0x04,0x2d,0x20,0xf6,0xb3,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x58,0x00,0x8b,0xf8,0x54,0x00,0x00,0xff,0xfe,0x15,0xb3,0x9a,0x27,0x09,0x04,0x2d,0x20,0xf8,0x57,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x70,0x00,0x9b,0xc9,0x54,0x00,0x00,0xff,0xfe,0x15,0xc4,0xf5,0x27,0x09,0x04,0x9f,0xcb,0x02,0x9a,0x27,0x09,0x06,0x26,0x04,0xa8,0x80,0x0c,0xad,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x26,0x70,0x01,0x27,0x09};
Topology::Topology(const RuntimeEnvironment *renv) :
Topology::Topology(const RuntimeEnvironment *renv,void *tPtr) :
RR(renv),
_trustedPathCount(0),
_amRoot(false)
{
try {
World cachedPlanet;
std::string buf(RR->node->dataStoreGet("planet"));
std::string buf(RR->node->dataStoreGet(tPtr,"planet"));
if (buf.length() > 0) {
Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> dswtmp(buf.data(),(unsigned int)buf.length());
cachedPlanet.deserialize(dswtmp,0);
}
addWorld(cachedPlanet,false);
addWorld(tPtr,cachedPlanet,false);
} catch ( ... ) {}
World defaultPlanet;
@ -75,10 +75,10 @@ Topology::Topology(const RuntimeEnvironment *renv) :
Buffer<ZT_DEFAULT_WORLD_LENGTH> wtmp(ZT_DEFAULT_WORLD,ZT_DEFAULT_WORLD_LENGTH);
defaultPlanet.deserialize(wtmp,0); // throws on error, which would indicate a bad static variable up top
}
addWorld(defaultPlanet,false);
addWorld(tPtr,defaultPlanet,false);
}
SharedPtr<Peer> Topology::addPeer(const SharedPtr<Peer> &peer)
SharedPtr<Peer> Topology::addPeer(void *tPtr,const SharedPtr<Peer> &peer)
{
#ifdef ZT_TRACE
if ((!peer)||(peer->address() == RR->identity.address())) {
@ -98,12 +98,12 @@ SharedPtr<Peer> Topology::addPeer(const SharedPtr<Peer> &peer)
np = hp;
}
saveIdentity(np->identity());
saveIdentity(tPtr,np->identity());
return np;
}
SharedPtr<Peer> Topology::getPeer(const Address &zta)
SharedPtr<Peer> Topology::getPeer(void *tPtr,const Address &zta)
{
if (zta == RR->identity.address()) {
TRACE("BUG: ignored attempt to getPeer() for self, returned NULL");
@ -118,7 +118,7 @@ SharedPtr<Peer> Topology::getPeer(const Address &zta)
}
try {
Identity id(_getIdentity(zta));
Identity id(_getIdentity(tPtr,zta));
if (id) {
SharedPtr<Peer> np(new Peer(RR,RR->identity,id));
{
@ -134,7 +134,7 @@ SharedPtr<Peer> Topology::getPeer(const Address &zta)
return SharedPtr<Peer>();
}
Identity Topology::getIdentity(const Address &zta)
Identity Topology::getIdentity(void *tPtr,const Address &zta)
{
if (zta == RR->identity.address()) {
return RR->identity;
@ -144,15 +144,15 @@ Identity Topology::getIdentity(const Address &zta)
if (ap)
return (*ap)->identity();
}
return _getIdentity(zta);
return _getIdentity(tPtr,zta);
}
void Topology::saveIdentity(const Identity &id)
void Topology::saveIdentity(void *tPtr,const Identity &id)
{
if (id) {
char p[128];
Utils::snprintf(p,sizeof(p),"iddb.d/%.10llx",(unsigned long long)id.address().toInt());
RR->node->dataStorePut(p,id.toString(false),false);
RR->node->dataStorePut(tPtr,p,id.toString(false),false);
}
}
@ -264,7 +264,7 @@ bool Topology::isProhibitedEndpoint(const Address &ztaddr,const InetAddress &ipa
return false;
}
bool Topology::addWorld(const World &newWorld,bool alwaysAcceptNew)
bool Topology::addWorld(void *tPtr,const World &newWorld,bool alwaysAcceptNew)
{
if ((newWorld.type() != World::TYPE_PLANET)&&(newWorld.type() != World::TYPE_MOON))
return false;
@ -328,29 +328,29 @@ bool Topology::addWorld(const World &newWorld,bool alwaysAcceptNew)
try {
Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> dswtmp;
existing->serialize(dswtmp,false);
RR->node->dataStorePut(savePath,dswtmp.data(),dswtmp.size(),false);
RR->node->dataStorePut(tPtr,savePath,dswtmp.data(),dswtmp.size(),false);
} catch ( ... ) {
RR->node->dataStoreDelete(savePath);
RR->node->dataStoreDelete(tPtr,savePath);
}
_memoizeUpstreams();
_memoizeUpstreams(tPtr);
return true;
}
void Topology::addMoon(const uint64_t id,const Address &seed)
void Topology::addMoon(void *tPtr,const uint64_t id,const Address &seed)
{
char savePath[64];
Utils::snprintf(savePath,sizeof(savePath),"moons.d/%.16llx.moon",id);
try {
std::string moonBin(RR->node->dataStoreGet(savePath));
std::string moonBin(RR->node->dataStoreGet(tPtr,savePath));
if (moonBin.length() > 1) {
Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> wtmp(moonBin.data(),(unsigned int)moonBin.length());
World w;
w.deserialize(wtmp);
if ((w.type() == World::TYPE_MOON)&&(w.id() == id)) {
addWorld(w,true);
addWorld(tPtr,w,true);
return;
}
}
@ -363,7 +363,7 @@ void Topology::addMoon(const uint64_t id,const Address &seed)
}
}
void Topology::removeMoon(const uint64_t id)
void Topology::removeMoon(void *tPtr,const uint64_t id)
{
Mutex::Lock _l1(_upstreams_m);
Mutex::Lock _l2(_peers_m);
@ -375,7 +375,7 @@ void Topology::removeMoon(const uint64_t id)
} else {
char savePath[64];
Utils::snprintf(savePath,sizeof(savePath),"moons.d/%.16llx.moon",id);
RR->node->dataStoreDelete(savePath);
RR->node->dataStoreDelete(tPtr,savePath);
}
}
_moons.swap(nm);
@ -387,7 +387,7 @@ void Topology::removeMoon(const uint64_t id)
}
_moonSeeds.swap(cm);
_memoizeUpstreams();
_memoizeUpstreams(tPtr);
}
void Topology::clean(uint64_t now)
@ -415,11 +415,11 @@ void Topology::clean(uint64_t now)
}
}
Identity Topology::_getIdentity(const Address &zta)
Identity Topology::_getIdentity(void *tPtr,const Address &zta)
{
char p[128];
Utils::snprintf(p,sizeof(p),"iddb.d/%.10llx",(unsigned long long)zta.toInt());
std::string ids(RR->node->dataStoreGet(p));
std::string ids(RR->node->dataStoreGet(tPtr,p));
if (ids.length() > 0) {
try {
return Identity(ids);
@ -428,7 +428,7 @@ Identity Topology::_getIdentity(const Address &zta)
return Identity();
}
void Topology::_memoizeUpstreams()
void Topology::_memoizeUpstreams(void *tPtr)
{
// assumes _upstreams_m and _peers_m are locked
_upstreamAddresses.clear();
@ -442,7 +442,7 @@ void Topology::_memoizeUpstreams()
SharedPtr<Peer> &hp = _peers[i->identity.address()];
if (!hp) {
hp = new Peer(RR,RR->identity,i->identity);
saveIdentity(i->identity);
saveIdentity(tPtr,i->identity);
}
}
}
@ -456,7 +456,7 @@ void Topology::_memoizeUpstreams()
SharedPtr<Peer> &hp = _peers[i->identity.address()];
if (!hp) {
hp = new Peer(RR,RR->identity,i->identity);
saveIdentity(i->identity);
saveIdentity(tPtr,i->identity);
}
}
}

View File

@ -50,7 +50,7 @@ class RuntimeEnvironment;
class Topology
{
public:
Topology(const RuntimeEnvironment *renv);
Topology(const RuntimeEnvironment *renv,void *tPtr);
/**
* Add a peer to database
@ -58,18 +58,20 @@ public:
* This will not replace existing peers. In that case the existing peer
* record is returned.
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param peer Peer to add
* @return New or existing peer (should replace 'peer')
*/
SharedPtr<Peer> addPeer(const SharedPtr<Peer> &peer);
SharedPtr<Peer> addPeer(void *tPtr,const SharedPtr<Peer> &peer);
/**
* Get a peer from its address
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param zta ZeroTier address of peer
* @return Peer or NULL if not found
*/
SharedPtr<Peer> getPeer(const Address &zta);
SharedPtr<Peer> getPeer(void *tPtr,const Address &zta);
/**
* Get a peer only if it is presently in memory (no disk cache)
@ -109,10 +111,11 @@ public:
/**
* Get the identity of a peer
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param zta ZeroTier address of peer
* @return Identity or NULL Identity if not found
*/
Identity getIdentity(const Address &zta);
Identity getIdentity(void *tPtr,const Address &zta);
/**
* Cache an identity
@ -120,9 +123,10 @@ public:
* This is done automatically on addPeer(), and so is only useful for
* cluster identity replication.
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param id Identity to cache
*/
void saveIdentity(const Identity &id);
void saveIdentity(void *tPtr,const Identity &id);
/**
* Get the current best upstream peer
@ -267,11 +271,12 @@ public:
/**
* Validate new world and update if newer and signature is okay
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param newWorld A new or updated planet or moon to learn
* @param alwaysAcceptNew If true, always accept new moons even if we're not waiting for one
* @return True if it was valid and newer than current (or totally new for moons)
*/
bool addWorld(const World &newWorld,bool alwaysAcceptNew);
bool addWorld(void *tPtr,const World &newWorld,bool alwaysAcceptNew);
/**
* Add a moon
@ -282,14 +287,15 @@ public:
* @param id Moon ID
* @param seed If non-NULL, an address of any member of the moon to contact
*/
void addMoon(const uint64_t id,const Address &seed);
void addMoon(void *tPtr,const uint64_t id,const Address &seed);
/**
* Remove a moon
*
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param id Moon's world ID
*/
void removeMoon(const uint64_t id);
void removeMoon(void *tPtr,const uint64_t id);
/**
* Clean and flush database
@ -420,8 +426,8 @@ public:
}
private:
Identity _getIdentity(const Address &zta);
void _memoizeUpstreams();
Identity _getIdentity(void *tPtr,const Address &zta);
void _memoizeUpstreams(void *tPtr);
const RuntimeEnvironment *const RR;

View File

@ -71,7 +71,7 @@ BSDEthernetTap::BSDEthernetTap(
unsigned int metric,
uint64_t nwid,
const char *friendlyName,
void (*handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int),
void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int),
void *arg) :
_handler(handler),
_arg(arg),
@ -460,8 +460,7 @@ void BSDEthernetTap::threadMain()
to.setTo(getBuf,6);
from.setTo(getBuf + 6,6);
unsigned int etherType = ntohs(((const uint16_t *)getBuf)[6]);
// TODO: VLAN support
_handler(_arg,_nwid,from,to,etherType,0,(const void *)(getBuf + 14),r - 14);
_handler(_arg,(void *)0,_nwid,from,to,etherType,0,(const void *)(getBuf + 14),r - 14);
}
r = 0;

View File

@ -43,7 +43,7 @@ public:
unsigned int metric,
uint64_t nwid,
const char *friendlyName,
void (*handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int),
void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int),
void *arg);
~BSDEthernetTap();
@ -62,7 +62,7 @@ public:
throw();
private:
void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int);
void (*_handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int);
void *_arg;
uint64_t _nwid;
Thread _thread;

View File

@ -62,7 +62,7 @@ LinuxEthernetTap::LinuxEthernetTap(
unsigned int metric,
uint64_t nwid,
const char *friendlyName,
void (*handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int),
void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int),
void *arg) :
_handler(handler),
_arg(arg),
@ -470,7 +470,7 @@ void LinuxEthernetTap::threadMain()
from.setTo(getBuf + 6,6);
unsigned int etherType = ntohs(((const uint16_t *)getBuf)[6]);
// TODO: VLAN support
_handler(_arg,_nwid,from,to,etherType,0,(const void *)(getBuf + 14),r - 14);
_handler(_arg,(void *)0,_nwid,from,to,etherType,0,(const void *)(getBuf + 14),r - 14);
}
r = 0;

View File

@ -44,7 +44,7 @@ public:
unsigned int metric,
uint64_t nwid,
const char *friendlyName,
void (*handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int),
void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int),
void *arg);
~LinuxEthernetTap();
@ -66,7 +66,7 @@ public:
throw();
private:
void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int);
void (*_handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int);
void *_arg;
uint64_t _nwid;
Thread _thread;

View File

@ -314,7 +314,7 @@ OSXEthernetTap::OSXEthernetTap(
unsigned int metric,
uint64_t nwid,
const char *friendlyName,
void (*handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *data,unsigned int len),
void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *data,unsigned int len),
void *arg) :
_handler(handler),
_arg(arg),
@ -646,7 +646,7 @@ void OSXEthernetTap::threadMain()
from.setTo(getBuf + 6,6);
unsigned int etherType = ntohs(((const uint16_t *)getBuf)[6]);
// TODO: VLAN support
_handler(_arg,_nwid,from,to,etherType,0,(const void *)(getBuf + 14),r - 14);
_handler(_arg,(void *)0,_nwid,from,to,etherType,0,(const void *)(getBuf + 14),r - 14);
}
r = 0;

View File

@ -48,7 +48,7 @@ public:
unsigned int metric,
uint64_t nwid,
const char *friendlyName,
void (*handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int),
void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int),
void *arg);
~OSXEthernetTap();
@ -67,7 +67,7 @@ public:
throw();
private:
void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int);
void (*_handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int);
void *_arg;
uint64_t _nwid;
Thread _thread;

View File

@ -456,7 +456,7 @@ WindowsEthernetTap::WindowsEthernetTap(
unsigned int metric,
uint64_t nwid,
const char *friendlyName,
void (*handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int),
void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int),
void *arg) :
_handler(handler),
_arg(arg),
@ -1058,8 +1058,7 @@ void WindowsEthernetTap::threadMain()
MAC from(tapReadBuf + 6,6);
unsigned int etherType = ((((unsigned int)tapReadBuf[12]) & 0xff) << 8) | (((unsigned int)tapReadBuf[13]) & 0xff);
try {
// TODO: decode vlans
_handler(_arg,_nwid,from,to,etherType,0,tapReadBuf + 14,bytesRead - 14);
_handler(_arg,(void *)0,_nwid,from,to,etherType,0,tapReadBuf + 14,bytesRead - 14);
} catch ( ... ) {} // handlers should not throw
}
}

View File

@ -87,7 +87,7 @@ public:
unsigned int metric,
uint64_t nwid,
const char *friendlyName,
void (*handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int),
void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int),
void *arg);
~WindowsEthernetTap();
@ -118,7 +118,7 @@ private:
void _setRegistryIPv4Value(const char *regKey,const std::vector<std::string> &value);
void _syncIps();
void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int);
void (*_handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int);
void *_arg;
MAC _mac;
uint64_t _nwid;

View File

@ -291,21 +291,21 @@ static void _moonToJson(nlohmann::json &mj,const World &world)
class OneServiceImpl;
static int SnodeVirtualNetworkConfigFunction(ZT_Node *node,void *uptr,uint64_t nwid,void **nuptr,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwconf);
static void SnodeEventCallback(ZT_Node *node,void *uptr,enum ZT_Event event,const void *metaData);
static long SnodeDataStoreGetFunction(ZT_Node *node,void *uptr,const char *name,void *buf,unsigned long bufSize,unsigned long readIndex,unsigned long *totalSize);
static int SnodeDataStorePutFunction(ZT_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure);
static int SnodeWirePacketSendFunction(ZT_Node *node,void *uptr,const struct sockaddr_storage *localAddr,const struct sockaddr_storage *addr,const void *data,unsigned int len,unsigned int ttl);
static void SnodeVirtualNetworkFrameFunction(ZT_Node *node,void *uptr,uint64_t nwid,void **nuptr,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len);
static int SnodePathCheckFunction(ZT_Node *node,void *uptr,uint64_t ztaddr,const struct sockaddr_storage *localAddr,const struct sockaddr_storage *remoteAddr);
static int SnodePathLookupFunction(ZT_Node *node,void *uptr,uint64_t ztaddr,int family,struct sockaddr_storage *result);
static int SnodeVirtualNetworkConfigFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t nwid,void **nuptr,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwconf);
static void SnodeEventCallback(ZT_Node *node,void *uptr,void *tptr,enum ZT_Event event,const void *metaData);
static long SnodeDataStoreGetFunction(ZT_Node *node,void *uptr,void *tptr,const char *name,void *buf,unsigned long bufSize,unsigned long readIndex,unsigned long *totalSize);
static int SnodeDataStorePutFunction(ZT_Node *node,void *uptr,void *tptr,const char *name,const void *data,unsigned long len,int secure);
static int SnodeWirePacketSendFunction(ZT_Node *node,void *uptr,void *tptr,const struct sockaddr_storage *localAddr,const struct sockaddr_storage *addr,const void *data,unsigned int len,unsigned int ttl);
static void SnodeVirtualNetworkFrameFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t nwid,void **nuptr,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len);
static int SnodePathCheckFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t ztaddr,const struct sockaddr_storage *localAddr,const struct sockaddr_storage *remoteAddr);
static int SnodePathLookupFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t ztaddr,int family,struct sockaddr_storage *result);
#ifdef ZT_ENABLE_CLUSTER
static void SclusterSendFunction(void *uptr,unsigned int toMemberId,const void *data,unsigned int len);
static int SclusterGeoIpFunction(void *uptr,const struct sockaddr_storage *addr,int *x,int *y,int *z);
#endif
static void StapFrameHandler(void *uptr,uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len);
static void StapFrameHandler(void *uptr,void *tptr,uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len);
static int ShttpOnMessageBegin(http_parser *parser);
static int ShttpOnUrl(http_parser *parser,const char *ptr,size_t length);
@ -573,7 +573,7 @@ public:
cb.eventCallback = SnodeEventCallback;
cb.pathCheckFunction = SnodePathCheckFunction;
cb.pathLookupFunction = SnodePathLookupFunction;
_node = new Node(this,&cb,OSUtils::now());
_node = new Node(this,(void *)0,&cb,OSUtils::now());
}
// Read local configuration
@ -804,7 +804,7 @@ public:
for(std::vector<std::string>::iterator f(networksDotD.begin());f!=networksDotD.end();++f) {
std::size_t dot = f->find_last_of('.');
if ((dot == 16)&&(f->substr(16) == ".conf"))
_node->join(Utils::hexStrToU64(f->substr(0,dot).c_str()),(void *)0);
_node->join(Utils::hexStrToU64(f->substr(0,dot).c_str()),(void *)0,(void *)0);
}
}
{ // Load existing moons
@ -812,7 +812,7 @@ public:
for(std::vector<std::string>::iterator f(moonsDotD.begin());f!=moonsDotD.end();++f) {
std::size_t dot = f->find_last_of('.');
if ((dot == 16)&&(f->substr(16) == ".moon"))
_node->orbit(Utils::hexStrToU64(f->substr(0,dot).c_str()),0);
_node->orbit((void *)0,Utils::hexStrToU64(f->substr(0,dot).c_str()),0);
}
}
@ -877,7 +877,7 @@ public:
uint64_t dl = _nextBackgroundTaskDeadline;
if (dl <= now) {
_node->processBackgroundTasks(now,&_nextBackgroundTaskDeadline);
_node->processBackgroundTasks((void *)0,now,&_nextBackgroundTaskDeadline);
dl = _nextBackgroundTaskDeadline;
}
@ -892,7 +892,7 @@ public:
std::vector<MulticastGroup> added,removed;
n->second.tap->scanMulticastGroups(added,removed);
for(std::vector<MulticastGroup>::iterator m(added.begin());m!=added.end();++m)
_node->multicastSubscribe(n->first,m->mac().toInt(),m->adi());
_node->multicastSubscribe((void *)0,n->first,m->mac().toInt(),m->adi());
for(std::vector<MulticastGroup>::iterator m(removed.begin());m!=removed.end();++m)
_node->multicastUnsubscribe(n->first,m->mac().toInt(),m->adi());
}
@ -1306,7 +1306,7 @@ public:
res["signature"] = json();
res["updatesMustBeSignedBy"] = json();
res["waiting"] = true;
_node->orbit(id,seed);
_node->orbit((void *)0,id,seed);
scode = 200;
}
@ -1315,7 +1315,7 @@ public:
if (ps.size() == 2) {
uint64_t wantnw = Utils::hexStrToU64(ps[1].c_str());
_node->join(wantnw,(void *)0); // does nothing if we are a member
_node->join(wantnw,(void *)0,(void *)0); // does nothing if we are a member
ZT_VirtualNetworkList *nws = _node->networks();
if (nws) {
for(unsigned long i=0;i<nws->networkCount;++i) {
@ -1360,7 +1360,7 @@ public:
if (ps[0] == "moon") {
if (ps.size() == 2) {
_node->deorbit(Utils::hexStrToU64(ps[1].c_str()));
_node->deorbit((void *)0,Utils::hexStrToU64(ps[1].c_str()));
res["result"] = true;
scode = 200;
} // else 404
@ -1371,7 +1371,7 @@ public:
uint64_t wantnw = Utils::hexStrToU64(ps[1].c_str());
for(unsigned long i=0;i<nws->networkCount;++i) {
if (nws->networks[i].nwid == wantnw) {
_node->leave(wantnw,(void **)0);
_node->leave(wantnw,(void **)0,(void *)0);
res["result"] = true;
scode = 200;
break;
@ -1693,6 +1693,7 @@ public:
_lastDirectReceiveFromGlobal = OSUtils::now();
const ZT_ResultCode rc = _node->processWirePacket(
(void *)0,
OSUtils::now(),
reinterpret_cast<const struct sockaddr_storage *>(localAddr),
(const struct sockaddr_storage *)from, // Phy<> uses sockaddr_storage, so it'll always be that big
@ -1845,6 +1846,7 @@ public:
if (from) {
InetAddress fakeTcpLocalInterfaceAddress((uint32_t)0xffffffff,0xffff);
const ZT_ResultCode rc = _node->processWirePacket(
(void *)0,
OSUtils::now(),
reinterpret_cast<struct sockaddr_storage *>(&fakeTcpLocalInterfaceAddress),
reinterpret_cast<struct sockaddr_storage *>(&from),
@ -2255,7 +2257,7 @@ public:
inline void tapFrameHandler(uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
{
_node->processVirtualNetworkFrame(OSUtils::now(),nwid,from.toInt(),to.toInt(),etherType,vlanId,data,len,&_nextBackgroundTaskDeadline);
_node->processVirtualNetworkFrame((void *)0,OSUtils::now(),nwid,from.toInt(),to.toInt(),etherType,vlanId,data,len,&_nextBackgroundTaskDeadline);
}
inline void onHttpRequestToServer(TcpConnection *tc)
@ -2426,21 +2428,21 @@ public:
}
};
static int SnodeVirtualNetworkConfigFunction(ZT_Node *node,void *uptr,uint64_t nwid,void **nuptr,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwconf)
static int SnodeVirtualNetworkConfigFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t nwid,void **nuptr,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwconf)
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodeVirtualNetworkConfigFunction(nwid,nuptr,op,nwconf); }
static void SnodeEventCallback(ZT_Node *node,void *uptr,enum ZT_Event event,const void *metaData)
static void SnodeEventCallback(ZT_Node *node,void *uptr,void *tptr,enum ZT_Event event,const void *metaData)
{ reinterpret_cast<OneServiceImpl *>(uptr)->nodeEventCallback(event,metaData); }
static long SnodeDataStoreGetFunction(ZT_Node *node,void *uptr,const char *name,void *buf,unsigned long bufSize,unsigned long readIndex,unsigned long *totalSize)
static long SnodeDataStoreGetFunction(ZT_Node *node,void *uptr,void *tptr,const char *name,void *buf,unsigned long bufSize,unsigned long readIndex,unsigned long *totalSize)
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodeDataStoreGetFunction(name,buf,bufSize,readIndex,totalSize); }
static int SnodeDataStorePutFunction(ZT_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure)
static int SnodeDataStorePutFunction(ZT_Node *node,void *uptr,void *tptr,const char *name,const void *data,unsigned long len,int secure)
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodeDataStorePutFunction(name,data,len,secure); }
static int SnodeWirePacketSendFunction(ZT_Node *node,void *uptr,const struct sockaddr_storage *localAddr,const struct sockaddr_storage *addr,const void *data,unsigned int len,unsigned int ttl)
static int SnodeWirePacketSendFunction(ZT_Node *node,void *uptr,void *tptr,const struct sockaddr_storage *localAddr,const struct sockaddr_storage *addr,const void *data,unsigned int len,unsigned int ttl)
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodeWirePacketSendFunction(localAddr,addr,data,len,ttl); }
static void SnodeVirtualNetworkFrameFunction(ZT_Node *node,void *uptr,uint64_t nwid,void **nuptr,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
static void SnodeVirtualNetworkFrameFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t nwid,void **nuptr,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
{ reinterpret_cast<OneServiceImpl *>(uptr)->nodeVirtualNetworkFrameFunction(nwid,nuptr,sourceMac,destMac,etherType,vlanId,data,len); }
static int SnodePathCheckFunction(ZT_Node *node,void *uptr,uint64_t ztaddr,const struct sockaddr_storage *localAddr,const struct sockaddr_storage *remoteAddr)
static int SnodePathCheckFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t ztaddr,const struct sockaddr_storage *localAddr,const struct sockaddr_storage *remoteAddr)
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodePathCheckFunction(ztaddr,localAddr,remoteAddr); }
static int SnodePathLookupFunction(ZT_Node *node,void *uptr,uint64_t ztaddr,int family,struct sockaddr_storage *result)
static int SnodePathLookupFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t ztaddr,int family,struct sockaddr_storage *result)
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodePathLookupFunction(ztaddr,family,result); }
#ifdef ZT_ENABLE_CLUSTER
@ -2458,7 +2460,7 @@ static int SclusterGeoIpFunction(void *uptr,const struct sockaddr_storage *addr,
}
#endif
static void StapFrameHandler(void *uptr,uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
static void StapFrameHandler(void *uptr,void *tptr,uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
{ reinterpret_cast<OneServiceImpl *>(uptr)->tapFrameHandler(nwid,from,to,etherType,vlanId,data,len); }
static int ShttpOnMessageBegin(http_parser *parser)

View File

@ -175,7 +175,7 @@ void SoftwareUpdater::handleSoftwareUpdateUserMessage(uint64_t origin,const void
std::string lj;
lj.push_back((char)VERB_LATEST);
lj.append(OSUtils::jsonDump(*latest));
_node.sendUserMessage(origin,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,lj.data(),(unsigned int)lj.length());
_node.sendUserMessage((void *)0,origin,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,lj.data(),(unsigned int)lj.length());
if (_distLog) {
fprintf(_distLog,"%.10llx GET_LATEST %u.%u.%u_%u platform %u arch %u vendor %u channel %s -> LATEST %u.%u.%u_%u" ZT_EOL_S,(unsigned long long)origin,rvMaj,rvMin,rvRev,rvBld,rvPlatform,rvArch,rvVendor,rvChannel.c_str(),bestVMaj,bestVMin,bestVRev,bestVBld);
fflush(_distLog);
@ -205,7 +205,7 @@ void SoftwareUpdater::handleSoftwareUpdateUserMessage(uint64_t origin,const void
gd.append((uint8_t)VERB_GET_DATA);
gd.append(_downloadHashPrefix.data,16);
gd.append((uint32_t)_download.length());
_node.sendUserMessage(ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,gd.data(),gd.size());
_node.sendUserMessage((void *)0,ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,gd.data(),gd.size());
//printf(">> GET_DATA @%u\n",(unsigned int)_download.length());
}
}
@ -229,7 +229,7 @@ void SoftwareUpdater::handleSoftwareUpdateUserMessage(uint64_t origin,const void
buf.append(reinterpret_cast<const uint8_t *>(data) + 1,16);
buf.append((uint32_t)idx);
buf.append(d->second.bin.data() + idx,std::min((unsigned long)ZT_SOFTWARE_UPDATE_CHUNK_SIZE,(unsigned long)(d->second.bin.length() - idx)));
_node.sendUserMessage(origin,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,buf.data(),buf.size());
_node.sendUserMessage((void *)0,origin,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,buf.data(),buf.size());
//printf(">> DATA @%u\n",(unsigned int)idx);
}
}
@ -249,7 +249,7 @@ void SoftwareUpdater::handleSoftwareUpdateUserMessage(uint64_t origin,const void
gd.append((uint8_t)VERB_GET_DATA);
gd.append(_downloadHashPrefix.data,16);
gd.append((uint32_t)_download.length());
_node.sendUserMessage(ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,gd.data(),gd.size());
_node.sendUserMessage((void *)0,ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,gd.data(),gd.size());
//printf(">> GET_DATA @%u\n",(unsigned int)_download.length());
}
}
@ -296,7 +296,7 @@ bool SoftwareUpdater::check(const uint64_t now)
ZT_BUILD_ARCHITECTURE,
(int)ZT_VENDOR_ZEROTIER,
_channel.c_str());
_node.sendUserMessage(ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,tmp,len);
_node.sendUserMessage((void *)0,ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,tmp,len);
//printf(">> GET_LATEST\n");
}
@ -343,7 +343,7 @@ bool SoftwareUpdater::check(const uint64_t now)
gd.append((uint8_t)VERB_GET_DATA);
gd.append(_downloadHashPrefix.data,16);
gd.append((uint32_t)_download.length());
_node.sendUserMessage(ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,gd.data(),gd.size());
_node.sendUserMessage((void *)0,ZT_SOFTWARE_UPDATE_SERVICE,ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE,gd.data(),gd.size());
//printf(">> GET_DATA @%u\n",(unsigned int)_download.length());
}
}