Completely factor out "desperation" from the core. I thought of a significantly simpler way to move all of this logic entirely into the containing service, liberating the core from any concern over the nature of its pipe to the outside world.

This commit is contained in:
Adam Ierymenko 2015-05-21 15:58:26 -07:00
parent 123ff28863
commit d9006712f6
12 changed files with 91 additions and 165 deletions

View File

@ -723,14 +723,14 @@ typedef int (*ZT1_DataStorePutFunction)(ZT1_Node *,void *,const char *,const voi
/**
* Function to send a ZeroTier packet out over the wire
*
* Parameters: (1) node, (2) user ptr, (3) address, (4) link desperation,
* (5) packet data, (6) packet data length.
* Parameters: (1) node, (2) user ptr, (3) address, (4) packet data,
* (5) packet data length.
*
* The function must return zero on success and may return any error code
* on failure. Note that success does not (of course) guarantee packet
* delivery. It only means that the packet appears to have been sent.
*/
typedef int (*ZT1_WirePacketSendFunction)(ZT1_Node *,void *,const struct sockaddr_storage *,unsigned int,const void *,unsigned int);
typedef int (*ZT1_WirePacketSendFunction)(ZT1_Node *,void *,const struct sockaddr_storage *,const void *,unsigned int);
/****************************************************************************/
/* C Node API */
@ -780,7 +780,6 @@ void ZT1_Node_delete(ZT1_Node *node);
* @param node Node instance
* @param now Current clock in milliseconds
* @param remoteAddress Origin of packet
* @param linkDesperation Link desperation metric for link or protocol over which packet arrived
* @param packetData Packet data
* @param packetLength Packet length
* @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks()
@ -790,7 +789,6 @@ enum ZT1_ResultCode ZT1_Node_processWirePacket(
ZT1_Node *node,
uint64_t now,
const struct sockaddr_storage *remoteAddress,
unsigned int linkDesperation,
const void *packetData,
unsigned int packetLength,
volatile uint64_t *nextBackgroundTaskDeadline);

View File

@ -269,11 +269,6 @@
*/
#define ZT_NETWORK_AUTOCONF_DELAY 60000
/**
* Increment core desperation after this multiple of ping checks without responses from upstream peers
*/
#define ZT_CORE_DESPERATION_INCREMENT 2
/**
* Timeout for overall peer activity (measured from last receive)
*/

View File

@ -69,7 +69,7 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR)
switch(verb()) {
//case Packet::VERB_NOP:
default: // ignore unknown verbs, but if they pass auth check they are "received"
peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),verb(),0,Packet::VERB_NOP);
peer->received(RR,_remoteAddress,hops(),packetId(),verb(),0,Packet::VERB_NOP);
return true;
case Packet::VERB_HELLO: return _doHELLO(RR);
case Packet::VERB_ERROR: return _doERROR(RR,peer);
@ -140,7 +140,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer>
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE);
nconf->com().serialize(outp);
outp.armor(peer->key(),true);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
}
}
} break;
@ -158,7 +158,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer>
default: break;
}
peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_ERROR,inRePacketId,inReVerb);
peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_ERROR,inRePacketId,inReVerb);
} catch (std::exception &ex) {
TRACE("dropped ERROR from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what());
} catch ( ... ) {
@ -219,7 +219,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR)
outp.append(packetId());
outp.append((unsigned char)Packet::ERROR_IDENTITY_COLLISION);
outp.armor(key,true);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
} else {
RR->node->postEvent(ZT1_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress);
TRACE("rejected HELLO from %s(%s): packet failed authentication",id.address().toString().c_str(),_remoteAddress.toString().c_str());
@ -264,7 +264,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR)
// VALID -- continues here
peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_HELLO,0,Packet::VERB_NOP);
peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_HELLO,0,Packet::VERB_NOP);
peer->setRemoteVersion(protoVersion,vMajor,vMinor,vRevision);
bool trusted = false;
@ -302,7 +302,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR)
}
outp.armor(peer->key(),true);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
} catch (std::exception &ex) {
TRACE("dropped HELLO from %s(%s): %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what());
} catch ( ... ) {
@ -397,7 +397,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p
outp.append((uint16_t)0); // no meta-data
outp.append((uint64_t)nc->revision());
outp.armor(peer->key(),true);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
}
}
TRACE("got network configuration for network %.16llx from %s",(unsigned long long)nw->id(),source().toString().c_str());
@ -443,7 +443,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p
default: break;
}
peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_OK,inRePacketId,inReVerb);
peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_OK,inRePacketId,inReVerb);
} catch (std::exception &ex) {
TRACE("dropped OK from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what());
} catch ( ... ) {
@ -463,7 +463,7 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr<Peer>
outp.append(packetId());
queried->identity().serialize(outp,false);
outp.armor(peer->key(),true);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
} else {
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR);
outp.append((unsigned char)Packet::VERB_WHOIS);
@ -471,12 +471,12 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr<Peer>
outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND);
outp.append(payload(),ZT_ADDRESS_LENGTH);
outp.armor(peer->key(),true);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
}
} else {
TRACE("dropped WHOIS from %s(%s): missing or invalid address",source().toString().c_str(),_remoteAddress.toString().c_str());
}
peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_WHOIS,0,Packet::VERB_NOP);
peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_WHOIS,0,Packet::VERB_NOP);
} catch ( ... ) {
TRACE("dropped WHOIS from %s(%s): unexpected exception",source().toString().c_str(),_remoteAddress.toString().c_str());
}
@ -508,8 +508,8 @@ bool IncomingPacket::_doRENDEZVOUS(const RuntimeEnvironment *RR,const SharedPtr<
if ((port > 0)&&((addrlen == 4)||(addrlen == 16))) {
InetAddress atAddr(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS,addrlen),addrlen,port);
TRACE("RENDEZVOUS from %s says %s might be at %s, starting NAT-t",peer->address().toString().c_str(),with.toString().c_str(),atAddr.toString().c_str());
peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP);
RR->sw->contact(withPeer,atAddr,_linkDesperation);
peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP);
RR->sw->contact(withPeer,atAddr);
} else {
TRACE("dropped corrupt RENDEZVOUS from %s(%s) (bad address or port)",peer->address().toString().c_str(),_remoteAddress.toString().c_str());
}
@ -549,7 +549,7 @@ bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,const SharedPtr<Peer>
RR->node->putFrame(network->id(),MAC(peer->address(),network->id()),network->mac(),etherType,0,field(ZT_PROTO_VERB_FRAME_IDX_PAYLOAD,payloadLen),payloadLen);
}
peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_FRAME,0,Packet::VERB_NOP);
peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_FRAME,0,Packet::VERB_NOP);
} else {
TRACE("dropped FRAME from %s(%s): we are not connected to network %.16llx",source().toString().c_str(),_remoteAddress.toString().c_str(),at<uint64_t>(ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID));
}
@ -625,7 +625,7 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr<P
RR->node->putFrame(network->id(),from,to,etherType,0,field(comLen + ZT_PROTO_VERB_EXT_FRAME_IDX_PAYLOAD,payloadLen),payloadLen);
}
peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP);
peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP);
} else {
TRACE("dropped EXT_FRAME from %s(%s): we are not connected to network %.16llx",source().toString().c_str(),_remoteAddress.toString().c_str(),at<uint64_t>(ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID));
}
@ -646,7 +646,7 @@ bool IncomingPacket::_doMULTICAST_LIKE(const RuntimeEnvironment *RR,const Shared
for(unsigned int ptr=ZT_PACKET_IDX_PAYLOAD;ptr<size();ptr+=18)
RR->mc->add(now,at<uint64_t>(ptr),MulticastGroup(MAC(field(ptr + 8,6),6),at<uint32_t>(ptr + 14)),peer->address());
peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_MULTICAST_LIKE,0,Packet::VERB_NOP);
peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_LIKE,0,Packet::VERB_NOP);
} catch (std::exception &ex) {
TRACE("dropped MULTICAST_LIKE from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what());
} catch ( ... ) {
@ -670,7 +670,7 @@ bool IncomingPacket::_doNETWORK_MEMBERSHIP_CERTIFICATE(const RuntimeEnvironment
}
}
peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE,0,Packet::VERB_NOP);
peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE,0,Packet::VERB_NOP);
} catch (std::exception &ex) {
TRACE("dropped NETWORK_MEMBERSHIP_CERTIFICATE from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what());
} catch ( ... ) {
@ -689,7 +689,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
const unsigned int h = hops();
const uint64_t pid = packetId();
peer->received(RR,_remoteAddress,_linkDesperation,h,pid,Packet::VERB_NETWORK_CONFIG_REQUEST,0,Packet::VERB_NOP);
peer->received(RR,_remoteAddress,h,pid,Packet::VERB_NETWORK_CONFIG_REQUEST,0,Packet::VERB_NOP);
if (RR->localNetworkController) {
Dictionary netconf;
@ -709,7 +709,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
if (outp.size() > ZT_PROTO_MAX_PACKET_LENGTH) {
TRACE("NETWORK_CONFIG_REQUEST failed: internal error: netconf size %u is too large",(unsigned int)netconfStr.length());
} else {
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
}
}
} break;
@ -722,7 +722,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND);
outp.append(nwid);
outp.armor(peer->key(),true);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
} break;
case NetworkController::NETCONF_QUERY_ACCESS_DENIED: {
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR);
@ -731,7 +731,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
outp.append((unsigned char)Packet::ERROR_NETWORK_ACCESS_DENIED_);
outp.append(nwid);
outp.armor(peer->key(),true);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
} break;
case NetworkController::NETCONF_QUERY_INTERNAL_SERVER_ERROR:
TRACE("NETWORK_CONFIG_REQUEST failed: internal error: %s",netconf.get("error","(unknown)").c_str());
@ -747,7 +747,7 @@ 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);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
}
} catch (std::exception &exc) {
TRACE("dropped NETWORK_CONFIG_REQUEST from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what());
@ -768,7 +768,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REFRESH(const RuntimeEnvironment *RR,cons
nw->requestConfiguration();
ptr += 8;
}
peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_NETWORK_CONFIG_REFRESH,0,Packet::VERB_NOP);
peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_NETWORK_CONFIG_REFRESH,0,Packet::VERB_NOP);
} catch (std::exception &exc) {
TRACE("dropped NETWORK_CONFIG_REFRESH from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what());
} catch ( ... ) {
@ -795,11 +795,11 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,const Shar
outp.append((uint32_t)mg.adi());
if (RR->mc->gather(peer->address(),nwid,mg,outp,gatherLimit)) {
outp.armor(peer->key(),true);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
}
}
peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_MULTICAST_GATHER,0,Packet::VERB_NOP);
peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_GATHER,0,Packet::VERB_NOP);
} catch (std::exception &exc) {
TRACE("dropped MULTICAST_GATHER from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what());
} catch ( ... ) {
@ -886,12 +886,12 @@ 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);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
}
}
} // else ignore -- not a member of this network
peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP);
peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP);
} catch (std::exception &exc) {
TRACE("dropped MULTICAST_FRAME from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),exc.what());
} catch ( ... ) {
@ -908,7 +908,7 @@ void IncomingPacket::_sendErrorNeedCertificate(const RuntimeEnvironment *RR,cons
outp.append((unsigned char)Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE);
outp.append(nwid);
outp.armor(peer->key(),true);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
RR->node->putPacket(_remoteAddress,outp.data(),outp.size());
}
} // namespace ZeroTier

View File

@ -73,15 +73,13 @@ public:
* @param data Packet data
* @param len Packet length
* @param remoteAddress Address from which packet came
* @param linkDesperation Link desperation for link over which packet was received
* @param now Current time
* @throws std::out_of_range Range error processing packet
*/
IncomingPacket(const void *data,unsigned int len,const InetAddress &remoteAddress,unsigned int linkDesperation,uint64_t now) :
IncomingPacket(const void *data,unsigned int len,const InetAddress &remoteAddress,uint64_t now) :
Packet(data,len),
_receiveTime(now),
_remoteAddress(remoteAddress),
_linkDesperation(linkDesperation),
__refCount()
{
}
@ -129,7 +127,6 @@ private:
uint64_t _receiveTime;
InetAddress _remoteAddress;
unsigned int _linkDesperation;
AtomicCounter __refCount;
};

View File

@ -80,8 +80,7 @@ Node::Node(
_startTimeAfterInactivity(0),
_lastPingCheck(0),
_lastHousekeepingRun(0),
_lastBeacon(0),
_coreDesperation(0)
_lastBeacon(0)
{
_newestVersionSeen[0] = ZEROTIER_ONE_VERSION_MAJOR;
_newestVersionSeen[1] = ZEROTIER_ONE_VERSION_MINOR;
@ -155,13 +154,12 @@ Node::~Node()
ZT1_ResultCode Node::processWirePacket(
uint64_t now,
const struct sockaddr_storage *remoteAddress,
unsigned int linkDesperation,
const void *packetData,
unsigned int packetLength,
volatile uint64_t *nextBackgroundTaskDeadline)
{
_now = now;
RR->sw->onRemotePacket(*(reinterpret_cast<const InetAddress *>(remoteAddress)),linkDesperation,packetData,packetLength);
RR->sw->onRemotePacket(*(reinterpret_cast<const InetAddress *>(remoteAddress)),packetData,packetLength);
return ZT1_RESULT_OK;
}
@ -219,8 +217,7 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next
if ((now - _lastPingCheck) >= ZT_PING_CHECK_INVERVAL) {
_lastPingCheck = now;
// This is used as a floor for the desperation and online status
// calculations if we just started up or have been asleep.
// This is used to compute whether we appear to be "online" or not
if ((now - _startTimeAfterInactivity) > (ZT_PING_CHECK_INVERVAL * 3))
_startTimeAfterInactivity = now;
@ -229,7 +226,6 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next
RR->topology->eachPeer<_PingPeersThatNeedPing &>(pfunc);
const uint64_t lastActivityAgo = now - std::max(_startTimeAfterInactivity,pfunc.lastReceiveFromUpstream);
_coreDesperation = (unsigned int)(lastActivityAgo / (ZT_PING_CHECK_INVERVAL * ZT_CORE_DESPERATION_INCREMENT));
bool oldOnline = _online;
_online = (lastActivityAgo < ZT_PEER_ACTIVITY_TIMEOUT);
if (oldOnline != _online)
@ -257,7 +253,7 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next
*(reinterpret_cast<uint32_t *>(p)) = RR->prng->next32();
RR->identity.address().copyTo(beacon + 8,5);
RR->antiRec->logOutgoingZT(beacon,13);
putPacket(ZT_DEFAULTS.v4Broadcast,beacon,13,0);
putPacket(ZT_DEFAULTS.v4Broadcast,beacon,13);
}
}
@ -528,13 +524,12 @@ enum ZT1_ResultCode ZT1_Node_processWirePacket(
ZT1_Node *node,
uint64_t now,
const struct sockaddr_storage *remoteAddress,
unsigned int linkDesperation,
const void *packetData,
unsigned int packetLength,
volatile uint64_t *nextBackgroundTaskDeadline)
{
try {
return reinterpret_cast<ZeroTier::Node *>(node)->processWirePacket(now,remoteAddress,linkDesperation,packetData,packetLength,nextBackgroundTaskDeadline);
return reinterpret_cast<ZeroTier::Node *>(node)->processWirePacket(now,remoteAddress,packetData,packetLength,nextBackgroundTaskDeadline);
} catch (std::bad_alloc &exc) {
return ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
} catch ( ... ) {

View File

@ -79,7 +79,6 @@ public:
ZT1_ResultCode processWirePacket(
uint64_t now,
const struct sockaddr_storage *remoteAddress,
unsigned int linkDesperation,
const void *packetData,
unsigned int packetLength,
volatile uint64_t *nextBackgroundTaskDeadline);
@ -119,16 +118,14 @@ public:
* @param addr Destination address
* @param data Packet data
* @param len Packet length
* @param desperation Link desperation for reaching this address
* @return True if packet appears to have been sent
*/
inline bool putPacket(const InetAddress &addr,const void *data,unsigned int len,unsigned int desperation)
inline bool putPacket(const InetAddress &addr,const void *data,unsigned int len)
{
return (_wirePacketSendFunction(
reinterpret_cast<ZT1_Node *>(this),
_uPtr,
reinterpret_cast<const struct sockaddr_storage *>(&addr),
desperation,
data,
len) == 0);
}
@ -174,23 +171,6 @@ public:
return nw;
}
/**
* Get an overall current level of desperation
*
* The current level of desperation is based on how recently an upstream
* (a.k.a. supernode) peer has spoken to us. As such, it will change and
* return to 0 once something like tunneling (higher desperation link) is
* active. As a result, actual link desperation for outgoing messages
* should be the max of either this or the most recent link desperation
* for an incoming message from a given address. See Path.hpp and Peer.hpp.
*
* In other words think of this as 'the desperation we should try to
* escalate to right now.'
*
* @return Overall system level of desperation
*/
inline unsigned int coreDesperation() const throw() { return _coreDesperation; }
inline bool dataStorePut(const char *name,const void *data,unsigned int len,bool secure) { return (_dataStorePutFunction(reinterpret_cast<ZT1_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) { _dataStorePutFunction(reinterpret_cast<ZT1_Node *>(this),_uPtr,name,(const void *)0,0,0); }
@ -253,7 +233,6 @@ private:
uint64_t _lastPingCheck;
uint64_t _lastHousekeepingRun;
uint64_t _lastBeacon;
unsigned int _coreDesperation;
unsigned int _newestVersionSeen[3]; // major, minor, revision
bool _online;
};

View File

@ -57,7 +57,6 @@ public:
_addr(),
_lastSend(0),
_lastReceived(0),
_lastReceiveDesperation(0),
_fixed(false) {}
Path(const Path &p) throw() { memcpy(this,&p,sizeof(Path)); }
@ -66,7 +65,6 @@ public:
_addr(addr),
_lastSend(0),
_lastReceived(0),
_lastReceiveDesperation(0),
_fixed(fixed) {}
inline void init(const InetAddress &addr,bool fixed)
@ -74,7 +72,6 @@ public:
_addr = addr;
_lastSend = 0;
_lastReceived = 0;
_lastReceiveDesperation = 0;
_fixed = fixed;
}
@ -107,13 +104,11 @@ public:
* Called when a packet is received from this path
*
* @param t Time of receive
* @param d Link desperation of receive
*/
inline void received(uint64_t t,unsigned int d)
inline void received(uint64_t t)
throw()
{
_lastReceived = t;
_lastReceiveDesperation = d;
}
/**
@ -126,11 +121,6 @@ public:
*/
inline void setFixed(bool f) throw() { _fixed = f; }
/**
* @return Last desperation reported via incoming link
*/
inline unsigned int lastReceiveDesperation() const throw() { return _lastReceiveDesperation; }
/**
* @param now Current time
* @return True if this path is fixed or has received data in last ACTIVITY_TIMEOUT ms
@ -152,7 +142,7 @@ public:
*/
inline bool send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now)
{
if (RR->node->putPacket(_addr,data,len,std::max(RR->node->coreDesperation(),_lastReceiveDesperation))) {
if (RR->node->putPacket(_addr,data,len)) {
sent(now);
RR->antiRec->logOutgoingZT(data,len);
return true;
@ -187,7 +177,6 @@ private:
InetAddress _addr;
uint64_t _lastSend;
uint64_t _lastReceived;
unsigned int _lastReceiveDesperation;
bool _fixed;
};

View File

@ -60,7 +60,6 @@ Peer::Peer(const Identity &myIdentity,const Identity &peerIdentity)
void Peer::received(
const RuntimeEnvironment *RR,
const InetAddress &remoteAddr,
int linkDesperation,
unsigned int hops,
uint64_t packetId,
Packet::Verb verb,
@ -78,7 +77,7 @@ void Peer::received(
unsigned int np = _numPaths;
for(unsigned int p=0;p<np;++p) {
if (_paths[p].address() == remoteAddr) {
_paths[p].received(now,linkDesperation);
_paths[p].received(now);
pathIsConfirmed = true;
break;
}
@ -103,7 +102,7 @@ void Peer::received(
}
if (slot) {
slot->init(remoteAddr,false);
slot->received(now,linkDesperation);
slot->received(now);
_numPaths = np;
pathIsConfirmed = true;
}
@ -115,7 +114,7 @@ void Peer::received(
if ((now - _lastPathConfirmationSent) >= ZT_MIN_PATH_CONFIRMATION_INTERVAL) {
_lastPathConfirmationSent = now;
TRACE("got %s via unknown path %s(%s), confirming...",Packet::verbString(verb),_id.address().toString().c_str(),remoteAddr.toString().c_str());
attemptToContactAt(RR,remoteAddr,linkDesperation,now);
attemptToContactAt(RR,remoteAddr,now);
}
}
}
@ -137,7 +136,7 @@ void Peer::received(
for(std::vector<MulticastGroup>::const_iterator mg(mgs.begin());mg!=mgs.end();++mg) {
if ((outp.size() + 18) > ZT_UDP_DEFAULT_PAYLOAD_MTU) {
outp.armor(_key,true);
RR->node->putPacket(remoteAddr,outp.data(),outp.size(),linkDesperation);
RR->node->putPacket(remoteAddr,outp.data(),outp.size());
outp.reset(_id.address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE);
}
@ -150,7 +149,7 @@ void Peer::received(
}
if (outp.size() > ZT_PROTO_MIN_PACKET_LENGTH) {
outp.armor(_key,true);
RR->node->putPacket(remoteAddr,outp.data(),outp.size(),linkDesperation);
RR->node->putPacket(remoteAddr,outp.data(),outp.size());
}
}
}
@ -161,7 +160,7 @@ void Peer::received(
_lastMulticastFrame = now;
}
void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &atAddress,unsigned int linkDesperation,uint64_t now)
void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &atAddress,uint64_t now)
{
Packet outp(_id.address(),RR->identity.address(),Packet::VERB_HELLO);
outp.append((unsigned char)ZT_PROTO_VERSION);
@ -189,26 +188,21 @@ void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &at
}
outp.armor(_key,false); // HELLO is sent in the clear
RR->node->putPacket(atAddress,outp.data(),outp.size(),linkDesperation);
RR->node->putPacket(atAddress,outp.data(),outp.size());
}
void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now)
{
Path *const bestPath = getBestPath(now);
if ((bestPath)&&(bestPath->active(now))) {
const unsigned int desp = std::max(RR->node->coreDesperation(),bestPath->lastReceiveDesperation());
if ((now - bestPath->lastReceived()) >= ZT_PEER_DIRECT_PING_DELAY) {
TRACE("PING %s(%s) desperation == %u",_id.address().toString().c_str(),bestPath->address().toString().c_str(),desp);
attemptToContactAt(RR,bestPath->address(),desp,now);
TRACE("PING %s(%s)",_id.address().toString().c_str(),bestPath->address().toString().c_str());
attemptToContactAt(RR,bestPath->address(),now);
bestPath->sent(now);
} else if ((now - bestPath->lastSend()) >= ZT_NAT_KEEPALIVE_DELAY) {
// We only do keepalive if desperation is zero right now, since higher
// desperation paths involve things like tunneling that do not need it.
if (desp == 0) {
TRACE("NAT keepalive %s(%s)",_id.address().toString().c_str(),bestPath->address().toString().c_str());
RR->node->putPacket(bestPath->address(),"",0,0);
bestPath->sent(now);
}
TRACE("NAT keepalive %s(%s)",_id.address().toString().c_str(),bestPath->address().toString().c_str());
RR->node->putPacket(bestPath->address(),"",0);
bestPath->sent(now);
}
}
}
@ -269,7 +263,7 @@ bool Peer::resetWithinScope(const RuntimeEnvironment *RR,InetAddress::IpScope sc
while (x < np) {
if (_paths[x].address().ipScope() == scope) {
if (_paths[x].fixed()) {
attemptToContactAt(RR,_paths[x].address(),_paths[x].lastReceiveDesperation(),now);
attemptToContactAt(RR,_paths[x].address(),now);
_paths[y++] = _paths[x]; // keep fixed paths
}
} else {
@ -281,11 +275,11 @@ bool Peer::resetWithinScope(const RuntimeEnvironment *RR,InetAddress::IpScope sc
return (y < np);
}
void Peer::getBestActiveAddresses(uint64_t now,InetAddress &v4,InetAddress &v6,unsigned int maxDesperation) const
void Peer::getBestActiveAddresses(uint64_t now,InetAddress &v4,InetAddress &v6) const
{
uint64_t bestV4 = 0,bestV6 = 0;
for(unsigned int p=0,np=_numPaths;p<np;++p) {
if ((_paths[p].active(now))&&(_paths[p].lastReceiveDesperation() <= maxDesperation)) {
if (_paths[p].active(now)) {
uint64_t lr = _paths[p].lastReceived();
if (lr) {
if (_paths[p].address().isV4()) {

View File

@ -109,7 +109,6 @@ public:
*
* @param RR Runtime environment
* @param remoteAddr Internet address of sender
* @param linkDesperation Link desperation level
* @param hops ZeroTier (not IP) hops
* @param packetId Packet ID
* @param verb Packet verb
@ -119,7 +118,6 @@ public:
void received(
const RuntimeEnvironment *RR,
const InetAddress &remoteAddr,
int linkDesperation,
unsigned int hops,
uint64_t packetId,
Packet::Verb verb,
@ -172,10 +170,9 @@ public:
*
* @param RR Runtime environment
* @param atAddress Destination address
* @param linkDesperation Link desperation
* @param now Current time
*/
void attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &atAddress,unsigned int linkDesperation,uint64_t now);
void attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &atAddress,uint64_t now);
/**
* Send pings or keepalives depending on configured timeouts
@ -382,9 +379,8 @@ public:
* @param now Current time
* @param v4 Result parameter to receive active IPv4 address, if any
* @param v6 Result parameter to receive active IPv6 address, if any
* @param maxDesperation Maximum link desperation to consider
*/
void getBestActiveAddresses(uint64_t now,InetAddress &v4,InetAddress &v6,unsigned int maxDesperation) const;
void getBestActiveAddresses(uint64_t now,InetAddress &v4,InetAddress &v6) const;
/**
* Find a common set of addresses by which two peers can link, if any
@ -392,14 +388,13 @@ public:
* @param a Peer A
* @param b Peer B
* @param now Current time
* @param maxDesperation Maximum link desperation to consider
* @return Pair: B's address (to send to A), A's address (to send to B)
*/
static inline std::pair<InetAddress,InetAddress> findCommonGround(const Peer &a,const Peer &b,uint64_t now,unsigned int maxDesperation)
static inline std::pair<InetAddress,InetAddress> findCommonGround(const Peer &a,const Peer &b,uint64_t now)
{
std::pair<InetAddress,InetAddress> v4,v6;
b.getBestActiveAddresses(now,v4.first,v6.first,maxDesperation);
a.getBestActiveAddresses(now,v4.second,v6.second,maxDesperation);
b.getBestActiveAddresses(now,v4.first,v6.first);
a.getBestActiveAddresses(now,v4.second,v6.second);
if ((v6.first)&&(v6.second)) // prefer IPv6 if both have it since NAT-t is (almost) unnecessary
return v6;
else if ((v4.first)&&(v4.second))

View File

@ -58,16 +58,16 @@ Switch::~Switch()
{
}
void Switch::onRemotePacket(const InetAddress &fromAddr,int linkDesperation,const void *data,unsigned int len)
void Switch::onRemotePacket(const InetAddress &fromAddr,const void *data,unsigned int len)
{
try {
if (len == ZT_PROTO_BEACON_LENGTH) {
_handleBeacon(fromAddr,linkDesperation,Buffer<ZT_PROTO_BEACON_LENGTH>(data,len));
_handleBeacon(fromAddr,Buffer<ZT_PROTO_BEACON_LENGTH>(data,len));
} else if (len > ZT_PROTO_MIN_FRAGMENT_LENGTH) {
if (((const unsigned char *)data)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_INDICATOR] == ZT_PACKET_FRAGMENT_INDICATOR) {
_handleRemotePacketFragment(fromAddr,linkDesperation,data,len);
_handleRemotePacketFragment(fromAddr,data,len);
} else if (len >= ZT_PROTO_MIN_PACKET_LENGTH) {
_handleRemotePacketHead(fromAddr,linkDesperation,data,len);
_handleRemotePacketHead(fromAddr,data,len);
}
}
} catch (std::exception &ex) {
@ -291,8 +291,7 @@ bool Switch::unite(const Address &p1,const Address &p2,bool force)
const uint64_t now = RR->node->now();
// Right now we only unite desperation == 0 links, which will be direct
std::pair<InetAddress,InetAddress> cg(Peer::findCommonGround(*p1p,*p2p,now,0));
std::pair<InetAddress,InetAddress> cg(Peer::findCommonGround(*p1p,*p2p,now));
if (!(cg.first))
return false;
@ -369,18 +368,18 @@ bool Switch::unite(const Address &p1,const Address &p2,bool force)
return true;
}
void Switch::contact(const SharedPtr<Peer> &peer,const InetAddress &atAddr,unsigned int maxDesperation)
void Switch::contact(const SharedPtr<Peer> &peer,const InetAddress &atAddr)
{
TRACE("sending NAT-t message to %s(%s)",peer->address().toString().c_str(),atAddr.toString().c_str());
const uint64_t now = RR->node->now();
// Attempt to contact at zero desperation first
peer->attemptToContactAt(RR,atAddr,0,now);
// Attempt to contact directly
peer->attemptToContactAt(RR,atAddr,now);
// If we have not punched through after this timeout, open refreshing can of whupass
{
Mutex::Lock _l(_contactQueue_m);
_contactQueue.push_back(ContactQueueEntry(peer,now + ZT_NAT_T_TACTICAL_ESCALATION_DELAY,atAddr,maxDesperation));
_contactQueue.push_back(ContactQueueEntry(peer,now + ZT_NAT_T_TACTICAL_ESCALATION_DELAY,atAddr));
}
}
@ -450,7 +449,7 @@ unsigned long Switch::doTimerTasks(uint64_t now)
case 0: {
// First strategy: rifle method: direct packet to known port
qi->peer->attemptToContactAt(RR,qi->inaddr,qi->currentDesperation,now);
qi->peer->attemptToContactAt(RR,qi->inaddr,now);
} break;
case 1: {
@ -460,7 +459,7 @@ unsigned long Switch::doTimerTasks(uint64_t now)
for(int i=0;i<9;++i) {
if (++p > 0xffff) break;
tmpaddr.setPort((unsigned int)p);
qi->peer->attemptToContactAt(RR,tmpaddr,qi->currentDesperation,now);
qi->peer->attemptToContactAt(RR,tmpaddr,now);
}
} break;
@ -471,19 +470,12 @@ unsigned long Switch::doTimerTasks(uint64_t now)
for(int i=0;i<3;++i) {
if (--p < 1024) break;
tmpaddr.setPort((unsigned int)p);
qi->peer->attemptToContactAt(RR,tmpaddr,qi->currentDesperation,now);
qi->peer->attemptToContactAt(RR,tmpaddr,now);
}
// Escalate link desperation after all strategies attempted
++qi->currentDesperation;
if (qi->currentDesperation > qi->maxDesperation) {
// We've tried all strategies at all levels of desperation, give up.
_contactQueue.erase(qi++);
continue;
} else {
// Otherwise restart at new link desperation level (e.g. try a tougher transport)
qi->strategyIteration = 0;
}
// We've tried all strategies
_contactQueue.erase(qi++);
continue;
} break;
}
@ -572,7 +564,7 @@ const char *Switch::etherTypeName(const unsigned int etherType)
return "UNKNOWN";
}
void Switch::_handleRemotePacketFragment(const InetAddress &fromAddr,int linkDesperation,const void *data,unsigned int len)
void Switch::_handleRemotePacketFragment(const InetAddress &fromAddr,const void *data,unsigned int len)
{
Packet::Fragment fragment(data,len);
Address destination(fragment.destination());
@ -644,9 +636,9 @@ void Switch::_handleRemotePacketFragment(const InetAddress &fromAddr,int linkDes
}
}
void Switch::_handleRemotePacketHead(const InetAddress &fromAddr,int linkDesperation,const void *data,unsigned int len)
void Switch::_handleRemotePacketHead(const InetAddress &fromAddr,const void *data,unsigned int len)
{
SharedPtr<IncomingPacket> packet(new IncomingPacket(data,len,fromAddr,linkDesperation,RR->node->now()));
SharedPtr<IncomingPacket> packet(new IncomingPacket(data,len,fromAddr,RR->node->now()));
Address source(packet->source());
Address destination(packet->destination());
@ -714,7 +706,7 @@ void Switch::_handleRemotePacketHead(const InetAddress &fromAddr,int linkDespera
}
}
void Switch::_handleBeacon(const InetAddress &fromAddr,int linkDesperation,const Buffer<ZT_PROTO_BEACON_LENGTH> &data)
void Switch::_handleBeacon(const InetAddress &fromAddr,const Buffer<ZT_PROTO_BEACON_LENGTH> &data)
{
Address beaconAddr(data.field(ZT_PROTO_BEACON_IDX_ADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
if (beaconAddr == RR->identity.address())
@ -726,7 +718,7 @@ void Switch::_handleBeacon(const InetAddress &fromAddr,int linkDesperation,const
_lastBeacon = now;
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NOP);
outp.armor(peer->key(),false);
RR->node->putPacket(fromAddr,outp.data(),outp.size(),linkDesperation);
RR->node->putPacket(fromAddr,outp.data(),outp.size());
}
}
}

View File

@ -79,11 +79,10 @@ public:
* Called when a packet is received from the real network
*
* @param fromAddr Internet IP address of origin
* @param linkDesperation Link desperation of path over which packet was received
* @param data Packet data
* @param len Packet length
*/
void onRemotePacket(const InetAddress &fromAddr,int linkDesperation,const void *data,unsigned int len);
void onRemotePacket(const InetAddress &fromAddr,const void *data,unsigned int len);
/**
* Called when a packet comes from a local Ethernet tap
@ -136,9 +135,8 @@ public:
*
* @param peer Peer to contact
* @param atAddr Address of peer
* @param linkDesperation Attempt up to given max desperation
*/
void contact(const SharedPtr<Peer> &peer,const InetAddress &atAddr,unsigned int maxDesperation);
void contact(const SharedPtr<Peer> &peer,const InetAddress &atAddr);
/**
* Request WHOIS on a given address
@ -182,9 +180,9 @@ public:
throw();
private:
void _handleRemotePacketFragment(const InetAddress &fromAddr,int linkDesperation,const void *data,unsigned int len);
void _handleRemotePacketHead(const InetAddress &fromAddr,int linkDesperation,const void *data,unsigned int len);
void _handleBeacon(const InetAddress &fromAddr,int linkDesperation,const Buffer<ZT_PROTO_BEACON_LENGTH> &data);
void _handleRemotePacketFragment(const InetAddress &fromAddr,const void *data,unsigned int len);
void _handleRemotePacketHead(const InetAddress &fromAddr,const void *data,unsigned int len);
void _handleBeacon(const InetAddress &fromAddr,const Buffer<ZT_PROTO_BEACON_LENGTH> &data);
Address _sendWhoisRequest(
const Address &addr,
@ -248,19 +246,15 @@ private:
struct ContactQueueEntry
{
ContactQueueEntry() {}
ContactQueueEntry(const SharedPtr<Peer> &p,uint64_t ft,const InetAddress &a,unsigned int md) :
ContactQueueEntry(const SharedPtr<Peer> &p,uint64_t ft,const InetAddress &a) :
peer(p),
fireAtTime(ft),
inaddr(a),
maxDesperation(md),
currentDesperation(0),
strategyIteration(1) {} // start with 2nd strategy, zero desperation, since we've already tried 0/0
strategyIteration(1) {} // start with 2nd strategy, since first was tried at inception
SharedPtr<Peer> peer;
uint64_t fireAtTime;
InetAddress inaddr;
unsigned int maxDesperation;
unsigned int currentDesperation;
unsigned int strategyIteration;
};
std::list<ContactQueueEntry> _contactQueue;

View File

@ -316,7 +316,7 @@ static int SnodeVirtualNetworkConfigFunction(ZT1_Node *node,void *uptr,uint64_t
static void SnodeEventCallback(ZT1_Node *node,void *uptr,enum ZT1_Event event,const void *metaData);
static long SnodeDataStoreGetFunction(ZT1_Node *node,void *uptr,const char *name,void *buf,unsigned long bufSize,unsigned long readIndex,unsigned long *totalSize);
static int SnodeDataStorePutFunction(ZT1_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure);
static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,const struct sockaddr_storage *addr,unsigned int desperation,const void *data,unsigned int len);
static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,const struct sockaddr_storage *addr,const void *data,unsigned int len);
static void SnodeVirtualNetworkFrameFunction(ZT1_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len);
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);
@ -590,7 +590,6 @@ public:
ZT1_ResultCode rc = _node->processWirePacket(
OSUtils::now(),
(const struct sockaddr_storage *)from, // Phy<> uses sockaddr_storage, so it'll always be that big
0, // desperation == 0, direct UDP
data,
len,
&_nextBackgroundTaskDeadline);
@ -730,7 +729,6 @@ public:
ZT1_ResultCode rc = _node->processWirePacket(
OSUtils::now(),
(const struct sockaddr_storage *)&from, // Phy<> uses sockaddr_storage, so it'll always be that big
1, // desperation == 1, TCP tunnel proxy
data,
plen,
&_nextBackgroundTaskDeadline);
@ -915,7 +913,7 @@ public:
}
}
inline int nodeWirePacketSendFunction(const struct sockaddr_storage *addr,unsigned int desperation,const void *data,unsigned int len)
inline int nodeWirePacketSendFunction(const struct sockaddr_storage *addr,const void *data,unsigned int len)
{
switch(addr->ss_family) {
case AF_INET:
@ -1047,8 +1045,8 @@ static long SnodeDataStoreGetFunction(ZT1_Node *node,void *uptr,const char *name
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodeDataStoreGetFunction(name,buf,bufSize,readIndex,totalSize); }
static int SnodeDataStorePutFunction(ZT1_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure)
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodeDataStorePutFunction(name,data,len,secure); }
static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,const struct sockaddr_storage *addr,unsigned int desperation,const void *data,unsigned int len)
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodeWirePacketSendFunction(addr,desperation,data,len); }
static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,const struct sockaddr_storage *addr,const void *data,unsigned int len)
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodeWirePacketSendFunction(addr,data,len); }
static void SnodeVirtualNetworkFrameFunction(ZT1_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
{ reinterpret_cast<OneServiceImpl *>(uptr)->nodeVirtualNetworkFrameFunction(nwid,sourceMac,destMac,etherType,vlanId,data,len); }