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

@ -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);
}
}