From bbcc3304a0e917bfa74cd098f3137fbb03078741 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 11 Jan 2016 15:57:58 -0800 Subject: [PATCH 1/6] Check shouldUsePathForZeroTierTraffic in legacy beacon responder. --- node/Switch.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/node/Switch.cpp b/node/Switch.cpp index 9ef8611aa..d7d29f937 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -89,6 +89,8 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from Address beaconAddr(reinterpret_cast(data) + 8,5); if (beaconAddr == RR->identity.address()) return; + if (!RR->node->shouldUsePathForZeroTierTraffic(localAddr,fromAddr)) + return; SharedPtr peer(RR->topology->getPeer(beaconAddr)); if (peer) { // we'll only respond to beacons from known peers const uint64_t now = RR->node->now(); From 21656ba01502842f92f23e94dcd624a658363482 Mon Sep 17 00:00:00 2001 From: Ren Jie Date: Tue, 12 Jan 2016 22:51:08 +0800 Subject: [PATCH 2/6] Update controller README.md Sync make parameter with code. --- controller/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controller/README.md b/controller/README.md index 612dba7b8..6989e98d9 100644 --- a/controller/README.md +++ b/controller/README.md @@ -5,7 +5,7 @@ This folder contains code implementing the node/NetworkController.hpp interface ### Building -By default this code is not built or included in the client. To build on Linux, BSD, or Mac add ZT\_ENABLE\_NETCONF\_MASTER=1 to the make command line. You'll need the development headers for Sqlite3 installed. They ship as part of OSX and Xcode. On Linux or BSD you'll probably need to install a package. +By default this code is not built or included in the client. To build on Linux, BSD, or Mac add ZT_\ENABLE_\NETWORK_\CONTROLLER=1 to the make command line. You'll need the development headers for Sqlite3 installed. They ship as part of OSX and Xcode. On Linux or BSD you'll probably need to install a package. ### Running From 704205c5f7583527f9c9398261f1206c59f1b812 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 12 Jan 2016 09:33:14 -0800 Subject: [PATCH 3/6] Dead code removal. --- node/Switch.cpp | 6 ------ node/Switch.hpp | 9 +-------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/node/Switch.cpp b/node/Switch.cpp index d7d29f937..c17b8d1b1 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -451,12 +451,6 @@ void Switch::requestWhois(const Address &addr) _sendWhoisRequest(addr,(const Address *)0,0); } -void Switch::cancelWhoisRequest(const Address &addr) -{ - Mutex::Lock _l(_outstandingWhoisRequests_m); - _outstandingWhoisRequests.erase(addr); -} - void Switch::doAnythingWaitingForPeer(const SharedPtr &peer) { { // cancel pending WHOIS since we now know this peer diff --git a/node/Switch.hpp b/node/Switch.hpp index 1964d1eea..a63ec1bbd 100644 --- a/node/Switch.hpp +++ b/node/Switch.hpp @@ -138,13 +138,6 @@ public: */ void requestWhois(const Address &addr); - /** - * Cancel WHOIS for an address - * - * @param addr Address to cancel - */ - void cancelWhoisRequest(const Address &addr); - /** * Run any processes that are waiting for this peer's identity * @@ -174,7 +167,7 @@ private: const RuntimeEnvironment *const RR; uint64_t _lastBeaconResponse; - // Outsanding WHOIS requests and how many retries they've undergone + // Outstanding WHOIS requests and how many retries they've undergone struct WhoisRequest { WhoisRequest() : lastSent(0),retries(0) {} From 83ef98a9dc4fb3c40a15a7fe2b5642355e4c4142 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 12 Jan 2016 11:04:35 -0800 Subject: [PATCH 4/6] Add a network-associated user ptr in API. --- include/ZeroTierOne.h | 39 +++++++++++++++++++++++---------------- node/IncomingPacket.cpp | 6 +++--- node/Network.cpp | 13 +++++++------ node/Network.hpp | 9 ++++++++- node/Node.cpp | 20 ++++++++++++-------- node/Node.hpp | 11 +++++++---- node/Switch.cpp | 2 +- service/ControlPlane.cpp | 4 ++-- service/OneService.cpp | 10 +++++----- 9 files changed, 68 insertions(+), 46 deletions(-) diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index e087904f5..e10b2c04e 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -978,11 +978,12 @@ typedef void ZT_Node; * PORT_ERROR state. */ typedef int (*ZT_VirtualNetworkConfigFunction)( - ZT_Node *, - void *, - uint64_t, - enum ZT_VirtualNetworkConfigOperation, - const ZT_VirtualNetworkConfig *); + ZT_Node *, /* Node */ + void *, /* User ptr */ + uint64_t, /* Network ID */ + void *, /* Network user ptr (set w/join) */ + enum ZT_VirtualNetworkConfigOperation, /* Config operation */ + const ZT_VirtualNetworkConfig *); /* Network configuration */ /** * Function to send a frame out to a virtual network port @@ -992,15 +993,16 @@ typedef int (*ZT_VirtualNetworkConfigFunction)( * (9) frame length. */ typedef void (*ZT_VirtualNetworkFrameFunction)( - ZT_Node *, - void *, - uint64_t, - uint64_t, - uint64_t, - unsigned int, - unsigned int, - const void *, - unsigned int); + ZT_Node *, /* Node */ + void *, /* User ptr */ + uint64_t, /* Network ID */ + void *, /* Network user PTR (set w/join) */ + uint64_t, /* Source MAC */ + uint64_t, /* Destination MAC */ + unsigned int, /* Ethernet type */ + unsigned int, /* VLAN ID (0 for none) */ + const void *, /* Frame data */ + unsigned int); /* Frame length */ /** * Callback for events @@ -1245,9 +1247,10 @@ enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,uint64_t now,vol * * @param node Node instance * @param nwid 64-bit ZeroTier network ID + * @param uptr An arbitrary pointer to associate with this network * @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); +enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *uptr); /** * Leave a network @@ -1256,11 +1259,15 @@ enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid); * to the port config callback with a NULL second parameter to indicate that * the port is now deleted. * + * The uptr parameter is optional and is NULL by default. If it is not NULL, + * the pointer it points to is set to this network's uptr on success. + * * @param node Node instance * @param nwid 64-bit network ID + * @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); +enum ZT_ResultCode ZT_Node_leave(ZT_Node *node,uint64_t nwid,void **uptr = (void **)0); /** * Subscribe to an Ethernet multicast group diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index c63d70b76..6616783ad 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -548,7 +548,7 @@ bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,const SharedPtr } const unsigned int payloadLen = size() - ZT_PROTO_VERB_FRAME_IDX_PAYLOAD; - RR->node->putFrame(network->id(),MAC(peer->address(),network->id()),network->mac(),etherType,0,field(ZT_PROTO_VERB_FRAME_IDX_PAYLOAD,payloadLen),payloadLen); + RR->node->putFrame(network->id(),network->userPtr(),MAC(peer->address(),network->id()),network->mac(),etherType,0,field(ZT_PROTO_VERB_FRAME_IDX_PAYLOAD,payloadLen),payloadLen); } peer->received(_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_FRAME,0,Packet::VERB_NOP); @@ -619,7 +619,7 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr

node->putFrame(network->id(),from,to,etherType,0,field(comLen + ZT_PROTO_VERB_EXT_FRAME_IDX_PAYLOAD,payloadLen),payloadLen); + RR->node->putFrame(network->id(),network->userPtr(),from,to,etherType,0,field(comLen + ZT_PROTO_VERB_EXT_FRAME_IDX_PAYLOAD,payloadLen),payloadLen); } peer->received(_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_EXT_FRAME,0,Packet::VERB_NOP); @@ -888,7 +888,7 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share } } - RR->node->putFrame(network->id(),from,to.mac(),etherType,0,field(offset + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME,payloadLen),payloadLen); + RR->node->putFrame(network->id(),network->userPtr(),from,to.mac(),etherType,0,field(offset + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME,payloadLen),payloadLen); } if (gatherLimit) { diff --git a/node/Network.cpp b/node/Network.cpp index afbe10740..5c980e5e3 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -45,8 +45,9 @@ namespace ZeroTier { const ZeroTier::MulticastGroup Network::BROADCAST(ZeroTier::MAC(0xffffffffffffULL),0); -Network::Network(const RuntimeEnvironment *renv,uint64_t nwid) : +Network::Network(const RuntimeEnvironment *renv,uint64_t nwid,void *uptr) : RR(renv), + _uptr(uptr), _id(nwid), _mac(renv->identity.address(),nwid), _enabled(true), @@ -88,7 +89,7 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid) : if (!_portInitialized) { ZT_VirtualNetworkConfig ctmp; _externalConfig(&ctmp); - _portError = RR->node->configureVirtualNetworkPort(_id,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp); + _portError = RR->node->configureVirtualNetworkPort(_id,_uptr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp); _portInitialized = true; } } @@ -100,11 +101,11 @@ Network::~Network() char n[128]; if (_destroyed) { - RR->node->configureVirtualNetworkPort(_id,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp); + RR->node->configureVirtualNetworkPort(_id,_uptr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp); Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.conf",_id); RR->node->dataStoreDelete(n); } else { - RR->node->configureVirtualNetworkPort(_id,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN,&ctmp); + RR->node->configureVirtualNetworkPort(_id,_uptr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN,&ctmp); } } @@ -173,7 +174,7 @@ bool Network::applyConfiguration(const SharedPtr &conf) portInitialized = _portInitialized; _portInitialized = true; } - _portError = RR->node->configureVirtualNetworkPort(_id,(portInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp); + _portError = RR->node->configureVirtualNetworkPort(_id,_uptr,(portInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp); return true; } else { TRACE("ignored invalid configuration for network %.16llx (configuration contains mismatched network ID or issued-to address)",(unsigned long long)_id); @@ -331,7 +332,7 @@ void Network::setEnabled(bool enabled) _enabled = enabled; ZT_VirtualNetworkConfig ctmp; _externalConfig(&ctmp); - _portError = RR->node->configureVirtualNetworkPort(_id,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE,&ctmp); + _portError = RR->node->configureVirtualNetworkPort(_id,_uptr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE,&ctmp); } } diff --git a/node/Network.hpp b/node/Network.hpp index 0effa8e20..2bd6a7c77 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -80,8 +80,9 @@ public: * * @param renv Runtime environment * @param nwid Network ID + * @param uptr Arbitrary pointer used by externally-facing API (for user use) */ - Network(const RuntimeEnvironment *renv,uint64_t nwid); + Network(const RuntimeEnvironment *renv,uint64_t nwid,void *uptr); ~Network(); @@ -331,6 +332,11 @@ public: */ void destroy(); + /** + * @return User ptr + */ + inline void *userPtr() const throw() { return _uptr; } + inline bool operator==(const Network &n) const throw() { return (_id == n._id); } inline bool operator!=(const Network &n) const throw() { return (_id != n._id); } inline bool operator<(const Network &n) const throw() { return (_id < n._id); } @@ -348,6 +354,7 @@ private: std::vector _allMulticastGroups() const; const RuntimeEnvironment *RR; + void *_uptr; uint64_t _id; MAC _mac; // local MAC address volatile bool _enabled; diff --git a/node/Node.cpp b/node/Node.cpp index f65aa8433..b322b64e6 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -358,24 +358,28 @@ ZT_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *nextB return ZT_RESULT_OK; } -ZT_ResultCode Node::join(uint64_t nwid) +ZT_ResultCode Node::join(uint64_t nwid,void *uptr) { Mutex::Lock _l(_networks_m); SharedPtr nw = _network(nwid); if(!nw) - _networks.push_back(std::pair< uint64_t,SharedPtr >(nwid,SharedPtr(new Network(RR,nwid)))); + _networks.push_back(std::pair< uint64_t,SharedPtr >(nwid,SharedPtr(new Network(RR,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) +ZT_ResultCode Node::leave(uint64_t nwid,void **uptr) { std::vector< std::pair< uint64_t,SharedPtr > > newn; Mutex::Lock _l(_networks_m); for(std::vector< std::pair< uint64_t,SharedPtr > >::const_iterator n(_networks.begin());n!=_networks.end();++n) { if (n->first != nwid) newn.push_back(*n); - else n->second->destroy(); + else { + if (uptr) + *uptr = n->second->userPtr(); + n->second->destroy(); + } } _networks.swap(newn); return ZT_RESULT_OK; @@ -839,10 +843,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) +enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *uptr) { try { - return reinterpret_cast(node)->join(nwid); + return reinterpret_cast(node)->join(nwid,uptr); } catch (std::bad_alloc &exc) { return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY; } catch ( ... ) { @@ -850,10 +854,10 @@ enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid) } } -enum ZT_ResultCode ZT_Node_leave(ZT_Node *node,uint64_t nwid) +enum ZT_ResultCode ZT_Node_leave(ZT_Node *node,uint64_t nwid,void **uptr) { try { - return reinterpret_cast(node)->leave(nwid); + return reinterpret_cast(node)->leave(nwid,uptr); } catch (std::bad_alloc &exc) { return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY; } catch ( ... ) { diff --git a/node/Node.hpp b/node/Node.hpp index b6b323633..45e80057d 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -96,8 +96,8 @@ public: unsigned int frameLength, volatile uint64_t *nextBackgroundTaskDeadline); ZT_ResultCode processBackgroundTasks(uint64_t now,volatile uint64_t *nextBackgroundTaskDeadline); - ZT_ResultCode join(uint64_t nwid); - ZT_ResultCode leave(uint64_t nwid); + 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 multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi); uint64_t address() const; @@ -169,6 +169,7 @@ public: * Enqueue a frame to be injected into a tap device (port) * * @param nwid Network ID + * @param nuptr Network user ptr * @param source Source MAC * @param dest Destination MAC * @param etherType 16-bit ethernet type @@ -176,12 +177,13 @@ public: * @param data Frame data * @param len Frame length */ - inline void putFrame(uint64_t nwid,const MAC &source,const MAC &dest,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) + 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) { _virtualNetworkFrameFunction( reinterpret_cast(this), _uPtr, nwid, + nuptr, source.toInt(), dest.toInt(), etherType, @@ -249,10 +251,11 @@ public: * Update virtual network port configuration * * @param nwid Network ID + * @param nuptr Network user ptr * @param op Configuration operation * @param nc Network configuration */ - inline int configureVirtualNetworkPort(uint64_t nwid,ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nc) { return _virtualNetworkConfigFunction(reinterpret_cast(this),_uPtr,nwid,op,nc); } + inline int configureVirtualNetworkPort(uint64_t nwid,void *nuptr,ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nc) { return _virtualNetworkConfigFunction(reinterpret_cast(this),_uPtr,nwid,nuptr,op,nc); } /** * @return True if we appear to be online diff --git a/node/Switch.cpp b/node/Switch.cpp index c17b8d1b1..23c534bea 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -216,7 +216,7 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c adv[42] = (checksum >> 8) & 0xff; adv[43] = checksum & 0xff; - RR->node->putFrame(network->id(),atPeerMac,from,ZT_ETHERTYPE_IPV6,0,adv,72); + RR->node->putFrame(network->id(),network->userPtr(),atPeerMac,from,ZT_ETHERTYPE_IPV6,0,adv,72); return; // stop processing: we have handled this frame with a spoofed local reply so no need to send it anywhere } } diff --git a/service/ControlPlane.cpp b/service/ControlPlane.cpp index 4978a91d2..3f41c76a7 100644 --- a/service/ControlPlane.cpp +++ b/service/ControlPlane.cpp @@ -506,7 +506,7 @@ unsigned int ControlPlane::handleRequest( } else if (ps[0] == "network") { if (ps.size() == 2) { uint64_t wantnw = Utils::hexStrToU64(ps[1].c_str()); - _node->join(wantnw); // does nothing if we are a member + _node->join(wantnw,(void *)0); // does nothing if we are a member ZT_VirtualNetworkList *nws = _node->networks(); if (nws) { for(unsigned long i=0;inetworkCount;++i) { @@ -546,7 +546,7 @@ unsigned int ControlPlane::handleRequest( uint64_t wantnw = Utils::hexStrToU64(ps[1].c_str()); for(unsigned long i=0;inetworkCount;++i) { if (nws->networks[i].nwid == wantnw) { - _node->leave(wantnw); + _node->leave(wantnw,(void **)0); responseBody = "true"; responseContentType = "application/json"; scode = 200; diff --git a/service/OneService.cpp b/service/OneService.cpp index 84ebdd875..b343ee34f 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -391,12 +391,12 @@ static std::string _trimString(const std::string &s) class OneServiceImpl; -static int SnodeVirtualNetworkConfigFunction(ZT_Node *node,void *uptr,uint64_t nwid,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwconf); +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,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,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,const struct sockaddr_storage *localAddr,const struct sockaddr_storage *remoteAddr); #ifdef ZT_ENABLE_CLUSTER @@ -695,7 +695,7 @@ public: for(std::vector::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())); + _node->join(Utils::hexStrToU64(f->substr(0,dot).c_str()),(void *)0); } } @@ -1533,7 +1533,7 @@ public: Mutex _run_m; }; -static int SnodeVirtualNetworkConfigFunction(ZT_Node *node,void *uptr,uint64_t nwid,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwconf) +static int SnodeVirtualNetworkConfigFunction(ZT_Node *node,void *uptr,uint64_t nwid,void *nuptr,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwconf) { return reinterpret_cast(uptr)->nodeVirtualNetworkConfigFunction(nwid,op,nwconf); } static void SnodeEventCallback(ZT_Node *node,void *uptr,enum ZT_Event event,const void *metaData) { reinterpret_cast(uptr)->nodeEventCallback(event,metaData); } @@ -1543,7 +1543,7 @@ static int SnodeDataStorePutFunction(ZT_Node *node,void *uptr,const char *name,c { return reinterpret_cast(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) { return reinterpret_cast(uptr)->nodeWirePacketSendFunction(localAddr,addr,data,len,ttl); } -static void SnodeVirtualNetworkFrameFunction(ZT_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 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) { reinterpret_cast(uptr)->nodeVirtualNetworkFrameFunction(nwid,sourceMac,destMac,etherType,vlanId,data,len); } static int SnodePathCheckFunction(ZT_Node *node,void *uptr,const struct sockaddr_storage *localAddr,const struct sockaddr_storage *remoteAddr) { return reinterpret_cast(uptr)->nodePathCheckFunction(localAddr,remoteAddr); } From d6f0f1a82ad78c033d2a772b3a1655b9c6c48e3c Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 12 Jan 2016 11:34:22 -0800 Subject: [PATCH 5/6] Use network user ptr in lookup for Ethernet frame handling to eliminate map lookup. --- include/ZeroTierOne.h | 8 ++++---- node/Network.cpp | 10 +++++----- node/Network.hpp | 4 ++-- node/Node.hpp | 4 ++-- service/OneService.cpp | 26 ++++++++++++++------------ 5 files changed, 27 insertions(+), 25 deletions(-) diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index e10b2c04e..cfbecf161 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -981,7 +981,7 @@ typedef int (*ZT_VirtualNetworkConfigFunction)( ZT_Node *, /* Node */ void *, /* User ptr */ uint64_t, /* Network ID */ - void *, /* Network user ptr (set w/join) */ + void **, /* Modifiable network user PTR */ enum ZT_VirtualNetworkConfigOperation, /* Config operation */ const ZT_VirtualNetworkConfig *); /* Network configuration */ @@ -996,7 +996,7 @@ typedef void (*ZT_VirtualNetworkFrameFunction)( ZT_Node *, /* Node */ void *, /* User ptr */ uint64_t, /* Network ID */ - void *, /* Network user PTR (set w/join) */ + void **, /* Modifiable network user PTR */ uint64_t, /* Source MAC */ uint64_t, /* Destination MAC */ unsigned int, /* Ethernet type */ @@ -1247,10 +1247,10 @@ enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,uint64_t now,vol * * @param node Node instance * @param nwid 64-bit ZeroTier network ID - * @param uptr An arbitrary pointer to associate with this network + * @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 *)0); /** * Leave a network diff --git a/node/Network.cpp b/node/Network.cpp index 5c980e5e3..7a4a187d4 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -89,7 +89,7 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid,void *uptr) : if (!_portInitialized) { ZT_VirtualNetworkConfig ctmp; _externalConfig(&ctmp); - _portError = RR->node->configureVirtualNetworkPort(_id,_uptr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp); + _portError = RR->node->configureVirtualNetworkPort(_id,&_uptr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp); _portInitialized = true; } } @@ -101,11 +101,11 @@ Network::~Network() char n[128]; if (_destroyed) { - RR->node->configureVirtualNetworkPort(_id,_uptr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp); + RR->node->configureVirtualNetworkPort(_id,&_uptr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp); Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.conf",_id); RR->node->dataStoreDelete(n); } else { - RR->node->configureVirtualNetworkPort(_id,_uptr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN,&ctmp); + RR->node->configureVirtualNetworkPort(_id,&_uptr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN,&ctmp); } } @@ -174,7 +174,7 @@ bool Network::applyConfiguration(const SharedPtr &conf) portInitialized = _portInitialized; _portInitialized = true; } - _portError = RR->node->configureVirtualNetworkPort(_id,_uptr,(portInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp); + _portError = RR->node->configureVirtualNetworkPort(_id,&_uptr,(portInitialized) ? ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE : ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp); return true; } else { TRACE("ignored invalid configuration for network %.16llx (configuration contains mismatched network ID or issued-to address)",(unsigned long long)_id); @@ -332,7 +332,7 @@ void Network::setEnabled(bool enabled) _enabled = enabled; ZT_VirtualNetworkConfig ctmp; _externalConfig(&ctmp); - _portError = RR->node->configureVirtualNetworkPort(_id,_uptr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE,&ctmp); + _portError = RR->node->configureVirtualNetworkPort(_id,&_uptr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE,&ctmp); } } diff --git a/node/Network.hpp b/node/Network.hpp index 2bd6a7c77..cb696d12b 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -333,9 +333,9 @@ public: void destroy(); /** - * @return User ptr + * @return Pointer to user PTR (modifiable user ptr used in API) */ - inline void *userPtr() const throw() { return _uptr; } + inline void **userPtr() throw() { return &_uptr; } inline bool operator==(const Network &n) const throw() { return (_id == n._id); } inline bool operator!=(const Network &n) const throw() { return (_id != n._id); } diff --git a/node/Node.hpp b/node/Node.hpp index 45e80057d..7eda8b05b 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -177,7 +177,7 @@ public: * @param data Frame data * @param len Frame length */ - 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(uint64_t nwid,void **nuptr,const MAC &source,const MAC &dest,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) { _virtualNetworkFrameFunction( reinterpret_cast(this), @@ -255,7 +255,7 @@ public: * @param op Configuration operation * @param nc Network configuration */ - inline int configureVirtualNetworkPort(uint64_t nwid,void *nuptr,ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nc) { return _virtualNetworkConfigFunction(reinterpret_cast(this),_uPtr,nwid,nuptr,op,nc); } + inline int configureVirtualNetworkPort(uint64_t nwid,void **nuptr,ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nc) { return _virtualNetworkConfigFunction(reinterpret_cast(this),_uPtr,nwid,nuptr,op,nc); } /** * @return True if we appear to be online diff --git a/service/OneService.cpp b/service/OneService.cpp index b343ee34f..407871e68 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -391,12 +391,12 @@ static std::string _trimString(const std::string &s) class OneServiceImpl; -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,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 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,const struct sockaddr_storage *localAddr,const struct sockaddr_storage *remoteAddr); #ifdef ZT_ENABLE_CLUSTER @@ -1131,7 +1131,7 @@ public: inline void phyOnUnixData(PhySocket *sock,void **uptr,void *data,unsigned long len) {} inline void phyOnUnixWritable(PhySocket *sock,void **uptr) {} - inline int nodeVirtualNetworkConfigFunction(uint64_t nwid,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwc) + inline int nodeVirtualNetworkConfigFunction(uint64_t nwid,void **nuptr,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwc) { Mutex::Lock _l(_taps_m); std::map< uint64_t,EthernetTap * >::iterator t(_taps.find(nwid)); @@ -1150,6 +1150,7 @@ public: friendlyName, StapFrameHandler, (void *)this))).first; + *nuptr = (void *)t->second; } catch (std::exception &exc) { #ifdef __WINDOWS__ FILE *tapFailLog = fopen((_homePath + ZT_PATH_SEPARATOR_S"port_error_log.txt").c_str(),"a"); @@ -1197,6 +1198,7 @@ public: #ifdef __WINDOWS__ std::string winInstanceId(t->second->instanceId()); #endif + *nuptr = (void *)0; delete t->second; _taps.erase(t); _tapAssignedIps.erase(nwid); @@ -1387,12 +1389,12 @@ public: return result; } - inline void nodeVirtualNetworkFrameFunction(uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) + inline void nodeVirtualNetworkFrameFunction(uint64_t nwid,void **nuptr,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) { - Mutex::Lock _l(_taps_m); - std::map< uint64_t,EthernetTap * >::const_iterator t(_taps.find(nwid)); - if (t != _taps.end()) - t->second->put(MAC(sourceMac),MAC(destMac),etherType,data,len); + EthernetTap *tap = reinterpret_cast(*nuptr); + if (!tap) + return; + tap->put(MAC(sourceMac),MAC(destMac),etherType,data,len); } inline int nodePathCheckFunction(const struct sockaddr_storage *localAddr,const struct sockaddr_storage *remoteAddr) @@ -1533,8 +1535,8 @@ public: Mutex _run_m; }; -static int SnodeVirtualNetworkConfigFunction(ZT_Node *node,void *uptr,uint64_t nwid,void *nuptr,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwconf) -{ return reinterpret_cast(uptr)->nodeVirtualNetworkConfigFunction(nwid,op,nwconf); } +static int SnodeVirtualNetworkConfigFunction(ZT_Node *node,void *uptr,uint64_t nwid,void **nuptr,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwconf) +{ return reinterpret_cast(uptr)->nodeVirtualNetworkConfigFunction(nwid,nuptr,op,nwconf); } static void SnodeEventCallback(ZT_Node *node,void *uptr,enum ZT_Event event,const void *metaData) { reinterpret_cast(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) @@ -1543,8 +1545,8 @@ static int SnodeDataStorePutFunction(ZT_Node *node,void *uptr,const char *name,c { return reinterpret_cast(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) { return reinterpret_cast(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) -{ reinterpret_cast(uptr)->nodeVirtualNetworkFrameFunction(nwid,sourceMac,destMac,etherType,vlanId,data,len); } +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) +{ reinterpret_cast(uptr)->nodeVirtualNetworkFrameFunction(nwid,nuptr,sourceMac,destMac,etherType,vlanId,data,len); } static int SnodePathCheckFunction(ZT_Node *node,void *uptr,const struct sockaddr_storage *localAddr,const struct sockaddr_storage *remoteAddr) { return reinterpret_cast(uptr)->nodePathCheckFunction(localAddr,remoteAddr); } From 740eb6ebc4c4af19f9d40ed03e75ba0a0021dc37 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 12 Jan 2016 12:12:25 -0800 Subject: [PATCH 6/6] Simplify Peer locking to eliminate deadlock with new path recursion check code (and also probably improve performance). --- node/Peer.cpp | 185 ++++++++++++++++++++++---------------------------- node/Peer.hpp | 15 +--- 2 files changed, 85 insertions(+), 115 deletions(-) diff --git a/node/Peer.cpp b/node/Peer.cpp index c75a3e46a..bcfda7229 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -126,87 +126,77 @@ void Peer::received( #endif const uint64_t now = RR->node->now(); - bool needMulticastGroupAnnounce = false; + _lastReceive = now; + if ((verb == Packet::VERB_FRAME)||(verb == Packet::VERB_EXT_FRAME)) + _lastUnicastFrame = now; + else if (verb == Packet::VERB_MULTICAST_FRAME) + _lastMulticastFrame = now; - { // begin _lock - Mutex::Lock _l(_lock); - - _lastReceive = now; - if ((verb == Packet::VERB_FRAME)||(verb == Packet::VERB_EXT_FRAME)) - _lastUnicastFrame = now; - else if (verb == Packet::VERB_MULTICAST_FRAME) - _lastMulticastFrame = now; - - if ((now - _lastAnnouncedTo) >= ((ZT_MULTICAST_LIKE_EXPIRE / 2) - 1000)) { - _lastAnnouncedTo = now; - needMulticastGroupAnnounce = true; + if (hops == 0) { + bool pathIsConfirmed = false; + unsigned int np = _numPaths; + for(unsigned int p=0;pnode->shouldUsePathForZeroTierTraffic(localAddr,remoteAddr))) { + if (verb == Packet::VERB_OK) { - if ((!pathIsConfirmed)&&(RR->node->shouldUsePathForZeroTierTraffic(localAddr,remoteAddr))) { - if (verb == Packet::VERB_OK) { - - Path *slot = (Path *)0; - if (np < ZT_MAX_PEER_NETWORK_PATHS) { - slot = &(_paths[np++]); - } else { - uint64_t slotLRmin = 0xffffffffffffffffULL; - for(unsigned int p=0;preceived(now); -#ifdef ZT_ENABLE_CLUSTER - slot->setClusterSuboptimal(suboptimalPath); -#endif - _numPaths = np; - } - -#ifdef ZT_ENABLE_CLUSTER - if (RR->cluster) - RR->cluster->broadcastHavePeer(_id); -#endif - - } else { - - TRACE("got %s via unknown path %s(%s), confirming...",Packet::verbString(verb),_id.address().toString().c_str(),remoteAddr.toString().c_str()); - - if ( (_vProto >= 5) && ( !((_vMajor == 1)&&(_vMinor == 1)&&(_vRevision == 0)) ) ) { - // 1.1.1 and newer nodes support ECHO, which is smaller -- but 1.1.0 has a bug so use HELLO there too - Packet outp(_id.address(),RR->identity.address(),Packet::VERB_ECHO); - outp.armor(_key,true); - RR->node->putPacket(localAddr,remoteAddr,outp.data(),outp.size()); - } else { - sendHELLO(localAddr,remoteAddr,now); - } - } + if (slot) { + *slot = Path(localAddr,remoteAddr); + slot->received(now); +#ifdef ZT_ENABLE_CLUSTER + slot->setClusterSuboptimal(suboptimalPath); +#endif + _numPaths = np; + } + +#ifdef ZT_ENABLE_CLUSTER + if (RR->cluster) + RR->cluster->broadcastHavePeer(_id); +#endif + + } else { + + TRACE("got %s via unknown path %s(%s), confirming...",Packet::verbString(verb),_id.address().toString().c_str(),remoteAddr.toString().c_str()); + + if ( (_vProto >= 5) && ( !((_vMajor == 1)&&(_vMinor == 1)&&(_vRevision == 0)) ) ) { + // 1.1.1 and newer nodes support ECHO, which is smaller -- but 1.1.0 has a bug so use HELLO there too + Packet outp(_id.address(),RR->identity.address(),Packet::VERB_ECHO); + outp.armor(_key,true); + RR->node->putPacket(localAddr,remoteAddr,outp.data(),outp.size()); + } else { + sendHELLO(localAddr,remoteAddr,now); + } + } } - } // end _lock + } - if (needMulticastGroupAnnounce) { + if ((now - _lastAnnouncedTo) >= ((ZT_MULTICAST_LIKE_EXPIRE / 2) - 1000)) { + _lastAnnouncedTo = now; const std::vector< SharedPtr > networks(RR->node->allNetworks()); for(std::vector< SharedPtr >::const_iterator n(networks.begin());n!=networks.end();++n) (*n)->tryAnnounceMulticastGroupsTo(SharedPtr(this)); @@ -215,8 +205,6 @@ void Peer::received( void Peer::sendHELLO(const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,unsigned int ttl) { - // _lock not required here since _id is immutable and nothing else is accessed - Packet outp(_id.address(),RR->identity.address(),Packet::VERB_HELLO); outp.append((unsigned char)ZT_PROTO_VERSION); outp.append((unsigned char)ZEROTIER_ONE_VERSION_MAJOR); @@ -236,7 +224,6 @@ bool Peer::doPingAndKeepalive(uint64_t now,int inetAddressFamily) { Path *p = (Path *)0; - Mutex::Lock _l(_lock); if (inetAddressFamily != 0) { p = _getBestPath(now,inetAddressFamily); } else { @@ -271,8 +258,6 @@ void Peer::pushDirectPaths(Path *path,uint64_t now,bool force) return; #endif - Mutex::Lock _l(_lock); - if (((now - _lastDirectPathPushSent) >= ZT_DIRECT_PATH_PUSH_INTERVAL)||(force)) { _lastDirectPathPushSent = now; @@ -333,7 +318,6 @@ void Peer::pushDirectPaths(Path *path,uint64_t now,bool force) bool Peer::resetWithinScope(InetAddress::IpScope scope,uint64_t now) { - Mutex::Lock _l(_lock); unsigned int np = _numPaths; unsigned int x = 0; unsigned int y = 0; @@ -353,7 +337,6 @@ bool Peer::resetWithinScope(InetAddress::IpScope scope,uint64_t now) void Peer::getBestActiveAddresses(uint64_t now,InetAddress &v4,InetAddress &v6) const { - Mutex::Lock _l(_lock); uint64_t bestV4 = 0,bestV6 = 0; for(unsigned int p=0,np=_numPaths;pcom.agreesWith(com); @@ -392,7 +375,7 @@ bool Peer::validateAndSetNetworkMembershipCertificate(uint64_t nwid,const Certif // Return true if we already have this *exact* COM { - Mutex::Lock _l(_lock); + Mutex::Lock _l(_networkComs_m); _NetworkCom *ourCom = _networkComs.get(nwid); if ((ourCom)&&(ourCom->com == com)) return true; @@ -432,7 +415,7 @@ bool Peer::validateAndSetNetworkMembershipCertificate(uint64_t nwid,const Certif // If we made it past all those checks, add or update cert in our cert info store { - Mutex::Lock _l(_lock); + Mutex::Lock _l(_networkComs_m); _networkComs.set(nwid,_NetworkCom(RR->node->now(),com)); } @@ -441,7 +424,7 @@ bool Peer::validateAndSetNetworkMembershipCertificate(uint64_t nwid,const Certif bool Peer::needsOurNetworkMembershipCertificate(uint64_t nwid,uint64_t now,bool updateLastPushedTime) { - Mutex::Lock _l(_lock); + Mutex::Lock _l(_networkComs_m); uint64_t &lastPushed = _lastPushedComs[nwid]; const uint64_t tmp = lastPushed; if (updateLastPushedTime) @@ -451,8 +434,6 @@ bool Peer::needsOurNetworkMembershipCertificate(uint64_t nwid,uint64_t now,bool void Peer::clean(uint64_t now) { - Mutex::Lock _l(_lock); - { unsigned int np = _numPaths; unsigned int x = 0; @@ -466,30 +447,30 @@ void Peer::clean(uint64_t now) } { - uint64_t *k = (uint64_t *)0; - _NetworkCom *v = (_NetworkCom *)0; - Hashtable< uint64_t,_NetworkCom >::Iterator i(_networkComs); - while (i.next(k,v)) { - if ( (!RR->node->belongsToNetwork(*k)) && ((now - v->ts) >= ZT_PEER_NETWORK_COM_EXPIRATION) ) - _networkComs.erase(*k); + Mutex::Lock _l(_networkComs_m); + { + uint64_t *k = (uint64_t *)0; + _NetworkCom *v = (_NetworkCom *)0; + Hashtable< uint64_t,_NetworkCom >::Iterator i(_networkComs); + while (i.next(k,v)) { + if ( (!RR->node->belongsToNetwork(*k)) && ((now - v->ts) >= ZT_PEER_NETWORK_COM_EXPIRATION) ) + _networkComs.erase(*k); + } } - } - - { - uint64_t *k = (uint64_t *)0; - uint64_t *v = (uint64_t *)0; - Hashtable< uint64_t,uint64_t >::Iterator i(_lastPushedComs); - while (i.next(k,v)) { - if ((now - *v) > (ZT_NETWORK_AUTOCONF_DELAY * 2)) - _lastPushedComs.erase(*k); + { + uint64_t *k = (uint64_t *)0; + uint64_t *v = (uint64_t *)0; + Hashtable< uint64_t,uint64_t >::Iterator i(_lastPushedComs); + while (i.next(k,v)) { + if ((now - *v) > (ZT_NETWORK_AUTOCONF_DELAY * 2)) + _lastPushedComs.erase(*k); + } } } } bool Peer::_checkPath(Path &p,const uint64_t now) { - // assumes _lock is locked - if (!p.active(now)) return false; @@ -536,7 +517,6 @@ bool Peer::_checkPath(Path &p,const uint64_t now) Path *Peer::_getBestPath(const uint64_t now) { - // assumes _lock is locked Path *bestPath = (Path *)0; uint64_t bestPathScore = 0; for(unsigned int i=0;i<_numPaths;++i) { @@ -551,7 +531,6 @@ Path *Peer::_getBestPath(const uint64_t now) Path *Peer::_getBestPath(const uint64_t now,int inetAddressFamily) { - // assumes _lock is locked Path *bestPath = (Path *)0; uint64_t bestPathScore = 0; for(unsigned int i=0;i<_numPaths;++i) { diff --git a/node/Peer.hpp b/node/Peer.hpp index 079640dbc..e40f576a9 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -134,11 +134,7 @@ public: * @param now Current time * @return Best path or NULL if there are no active direct paths */ - inline Path *getBestPath(uint64_t now) - { - Mutex::Lock _l(_lock); - return _getBestPath(now); - } + inline Path *getBestPath(uint64_t now) { return _getBestPath(now); } /** * Send via best path @@ -195,7 +191,6 @@ public: inline std::vector paths() const { std::vector pp; - Mutex::Lock _l(_lock); for(unsigned int p=0,np=_numPaths;p inline void serialize(Buffer &b) const { - Mutex::Lock _l(_lock); + Mutex::Lock _l(_networkComs_m); const unsigned int recSizePos = b.size(); b.addSize(4); // space for uint32_t field length @@ -599,8 +590,8 @@ private: }; Hashtable _networkComs; Hashtable _lastPushedComs; + Mutex _networkComs_m; - Mutex _lock; AtomicCounter __refCount; };