From d6f0f1a82ad78c033d2a772b3a1655b9c6c48e3c Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 12 Jan 2016 11:34:22 -0800 Subject: [PATCH] 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); }