diff options
-rw-r--r-- | include/ZeroTierOne.h | 18 | ||||
-rw-r--r-- | main.cpp | 43 | ||||
-rw-r--r-- | make-mac.mk | 2 | ||||
-rw-r--r-- | node/IncomingPacket.cpp | 4 | ||||
-rw-r--r-- | node/InetAddress.hpp | 13 | ||||
-rw-r--r-- | node/Node.cpp | 11 | ||||
-rw-r--r-- | node/Switch.cpp | 6 | ||||
-rw-r--r-- | objects.mk | 1 | ||||
-rw-r--r-- | osdep/HttpClient.cpp | 3 | ||||
-rw-r--r-- | osdep/OSUtils.hpp | 11 | ||||
-rw-r--r-- | service/One.cpp | 57 | ||||
-rw-r--r-- | service/One.hpp | 4 |
12 files changed, 140 insertions, 33 deletions
diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index 5441b180..4fa45780 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -614,6 +614,15 @@ typedef void ZT1_Node; typedef int (*ZT1_VirtualNetworkConfigFunction)(ZT1_Node *,void *,uint64_t,enum ZT1_VirtualNetworkConfigOperation,const ZT1_VirtualNetworkConfig *); /** + * Function to send a frame out to a virtual network port + * + * Parameters: (1) node, (2) user ptr, (3) network ID, (4) source MAC, + * (5) destination MAC, (6) ethertype, (7) VLAN ID, (8) frame data, + * (9) frame length. + */ +typedef void (*ZT1_VirtualNetworkFrameFunction)(ZT1_Node *,void *,uint64_t,uint64_t,uint64_t,unsigned int,unsigned int,const void *,unsigned int); + +/** * Callback for events * * Events are generated when the node's status changes in a significant way @@ -676,15 +685,6 @@ typedef int (*ZT1_DataStorePutFunction)(ZT1_Node *,void *,const char *,const voi */ typedef int (*ZT1_WirePacketSendFunction)(ZT1_Node *,void *,const struct sockaddr_storage *,unsigned int,const void *,unsigned int); -/** - * Function to send a frame out to a virtual network port - * - * Parameters: (1) node, (2) user ptr, (3) network ID, (4) source MAC, - * (5) destination MAC, (6) ethertype, (7) VLAN ID, (8) frame data, - * (9) frame length. - */ -typedef void (*ZT1_VirtualNetworkFrameFunction)(ZT1_Node *,void *,uint64_t,uint64_t,uint64_t,unsigned int,unsigned int,const void *,unsigned int); - /****************************************************************************/ /* C Node API */ /****************************************************************************/ @@ -0,0 +1,43 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> + +#include "service/One.hpp" + +using namespace ZeroTier; + +int main(int argc,char **argv) +{ + One *one = One::newInstance("/tmp/foo",12345); + one->waitForTermination(); + printf("termination reason: %d, message: %s\n",(int)one->reasonForTermination(),one->fatalErrorMessage().c_str()); + return 0; +} diff --git a/make-mac.mk b/make-mac.mk index 673641f2..22b6a823 100644 --- a/make-mac.mk +++ b/make-mac.mk @@ -38,7 +38,7 @@ endif DEFS+=-DZT_SALSA20_SSE ifeq ($(ZT_DEBUG),1) -# DEFS+=-DZT_TRACE + DEFS+=-DZT_TRACE CFLAGS=-Wall -g -pthread $(INCLUDES) $(DEFS) STRIP=echo # The following line enables optimization for the crypto code, since diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 690c2c9d..aadef3c2 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -304,9 +304,9 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) outp.armor(peer->key(),true); RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation); } catch (std::exception &ex) { - TRACE("dropped HELLO from %s(%s): %s",id.address().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); + TRACE("dropped HELLO from %s(%s): %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); } catch ( ... ) { - TRACE("dropped HELLO from %s(%s): unexpected exception",id.address().toString().c_str(),_remoteAddress.toString().c_str()); + TRACE("dropped HELLO from %s(%s): unexpected exception",source().toString().c_str(),_remoteAddress.toString().c_str()); } return true; } diff --git a/node/InetAddress.hpp b/node/InetAddress.hpp index 43fcc333..5e4dbfd8 100644 --- a/node/InetAddress.hpp +++ b/node/InetAddress.hpp @@ -354,6 +354,19 @@ struct InetAddress : public sockaddr_storage } /** + * @param a InetAddress to compare again + * @return True if only IP portions are equal (false for non-IP or null addresses) + */ + inline bool ipsEqual(const InetAddress &a) const + { + switch(ss_family) { + case AF_INET: return (reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr == reinterpret_cast<const struct sockaddr_in *>(&a)->sin_addr.s_addr); + case AF_INET6: return (memcmp(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr,reinterpret_cast<const struct sockaddr_in6 *>(&a)->sin6_addr.s6_addr,16) == 0); + } + return false; + } + + /** * Set to null/zero */ inline void zero() throw() { memset(this,0,sizeof(InetAddress)); } diff --git a/node/Node.cpp b/node/Node.cpp index e6f73879..0192c49a 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -82,6 +82,7 @@ Node::Node( std::string idtmp(dataStoreGet("identity.secret")); if ((!idtmp.length())||(!RR->identity.fromString(idtmp))||(!RR->identity.hasPrivate())) { + TRACE("identity.secret not found, generating..."); RR->identity.generate(); idtmp = RR->identity.toString(true); if (!dataStorePut("identity.secret",idtmp,true)) { @@ -444,10 +445,16 @@ void Node::postTrace(const char *module,unsigned int line,const char *fmt,...) #ifdef __WINDOWS__ ctime_s(tmp3,sizeof(tmp3),&now); - const char *nowstr = tmp3; + char *nowstr = tmp3; #else - const char *nowstr = ctime_r(&now,tmp3); + time_t now = (time_t)(_now / 1000ULL); + char *nowstr = ctime_r(&now,tmp3); #endif + unsigned long nowstrlen = strlen(nowstr); + if (nowstr[nowstrlen-1] == '\n') + nowstr[--nowstrlen] = (char)0; + if (nowstr[nowstrlen-1] == '\r') + nowstr[--nowstrlen] = (char)0; va_start(ap,fmt); vsnprintf(tmp2,sizeof(tmp2),fmt,ap); diff --git a/node/Switch.cpp b/node/Switch.cpp index a73c354e..caeb3e3a 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -92,7 +92,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c * still happen because Windows likes to send broadcasts over interfaces that have little * to do with their intended target audience. :P */ if (!RR->antiRec->checkEthernetFrame(data,len)) { - TRACE("%.16llx: rejected recursively addressed ZeroTier packet by tail match (type %s, length: %u)",network->id(),etherTypeName(etherType),data.size()); + TRACE("%.16llx: rejected recursively addressed ZeroTier packet by tail match (type %s, length: %u)",network->id(),etherTypeName(etherType),len); return; } @@ -149,11 +149,11 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c // Check multicast/broadcast bandwidth quotas and reject if quota exceeded if (!network->updateAndCheckMulticastBalance(mg,len)) { - TRACE("%.16llx: didn't multicast %d bytes, quota exceeded for multicast group %s",network->id(),(int)data.size(),mg.toString().c_str()); + TRACE("%.16llx: didn't multicast %u bytes, quota exceeded for multicast group %s",network->id(),len,mg.toString().c_str()); return; } - TRACE("%.16llx: MULTICAST %s -> %s %s %d",network->id(),from.toString().c_str(),mg.toString().c_str(),etherTypeName(etherType),(int)data.size()); + //TRACE("%.16llx: MULTICAST %s -> %s %s %u",network->id(),from.toString().c_str(),mg.toString().c_str(),etherTypeName(etherType),len); RR->mc->send( ((!nconf->isPublic())&&(nconf->com())) ? &(nconf->com()) : (const CertificateOfMembership *)0, @@ -17,6 +17,7 @@ OBJS=\ node/Peer.o \ node/Poly1305.o \ node/Salsa20.o \ + node/SelfAwareness.o \ node/SHA512.o \ node/Switch.o \ node/Topology.o \ diff --git a/osdep/HttpClient.cpp b/osdep/HttpClient.cpp index 251320ab..1cf78204 100644 --- a/osdep/HttpClient.cpp +++ b/osdep/HttpClient.cpp @@ -57,6 +57,7 @@ #include "HttpClient.hpp" #include "Thread.hpp" #include "OSUtils.hpp" +#include "../node/Utils.hpp" namespace ZeroTier { @@ -281,7 +282,7 @@ public: return; } ++scPos; - unsigned int rcode = OSUtils::strToUInt(headers.front().substr(scPos,3).c_str()); + unsigned int rcode = Utils::strToUInt(headers.front().substr(scPos,3).c_str()); if ((!rcode)||(rcode > 999)) { _doH(_arg,-1,_url,"invalid HTTP response (invalid response code)"); delete this; diff --git a/osdep/OSUtils.hpp b/osdep/OSUtils.hpp index 2f7499ba..a0cb1067 100644 --- a/osdep/OSUtils.hpp +++ b/osdep/OSUtils.hpp @@ -46,7 +46,9 @@ #include <Windows.h> #else #include <unistd.h> +#include <errno.h> #include <sys/time.h> +#include <sys/stat.h> #include <arpa/inet.h> #endif @@ -90,6 +92,15 @@ public: } static inline bool rm(const std::string &path) throw() { return rm(path.c_str()); } + static inline bool mkdir(const char *path) + throw() + { + if (::mkdir(path,0755) != 0) + return (errno == EEXIST); + return true; + } + static inline bool mkdir(const std::string &path) throw() { return OSUtils::mkdir(path.c_str()); } + /** * List a directory's contents * diff --git a/service/One.cpp b/service/One.cpp index 4d8a2d48..2ebfd285 100644 --- a/service/One.cpp +++ b/service/One.cpp @@ -76,6 +76,22 @@ public: struct sockaddr_in in4; struct sockaddr_in6 in6; + if (*hp) { + std::vector<std::string> hpsp(Utils::split(hp,ZT_PATH_SEPARATOR_S,"","")); + std::string ptmp; + if (*hp == '/') + ptmp.push_back('/'); + for(std::vector<std::string>::iterator pi(hpsp.begin());pi!=hpsp.end();++pi) { + if (ptmp.length() > 0) + ptmp.push_back(ZT_PATH_SEPARATOR); + ptmp.append(*pi); + if ((*pi != ".")&&(*pi != "..")) { + if (!OSUtils::mkdir(ptmp)) + throw std::runtime_error("home path does not exist, and could not create"); + } + } + } + ::memset((void *)&in4,0,sizeof(in4)); in4.sin_family = AF_INET; in4.sin_port = Utils::hton(port); @@ -141,7 +157,7 @@ public: { ZT1_ResultCode rc = _node->processWirePacket( OSUtils::now(), - (const struct sockaddr_storage *)&from, // Phy<> uses sockaddr_storage, so it'll always be that big + (const struct sockaddr_storage *)from, // Phy<> uses sockaddr_storage, so it'll always be that big 0, data, len, @@ -178,6 +194,7 @@ public: inline int nodeVirtualNetworkConfigFunction(uint64_t nwid,enum ZT1_VirtualNetworkConfigOperation op,const ZT1_VirtualNetworkConfig *nwconf) { + return 0; } inline void nodeEventCallback(enum ZT1_Event event,const void *metaData) @@ -259,8 +276,10 @@ public: FILE *f = fopen(p.c_str(),"wb"); if (!f) return -1; - if (fwrite(data,len,1,f) != 1) { + if (fwrite(data,len,1,f) == 1) { fclose(f); + if (secure) + OSUtils::lockDownFile(p.c_str(),false); return 0; } else { fclose(f); @@ -274,25 +293,26 @@ public: switch(addr->ss_family) { case AF_INET: if (_v4UdpSocket) - _phy.udpSend(_v4UdpSocket,(const struct sockaddr *)addr,data,len); + return (_phy.udpSend(_v4UdpSocket,(const struct sockaddr *)addr,data,len) ? 0 : -1); break; case AF_INET6: if (_v6UdpSocket) - _phy.udpSend(_v6UdpSocket,(const struct sockaddr *)addr,data,len); + return (_phy.udpSend(_v6UdpSocket,(const struct sockaddr *)addr,data,len) ? 0 : -1); break; } + return -1; } inline void nodeVirtualNetworkFrameFunction(uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) { - fprintf(stderr,"VIRTUAL NETWORK FRAME from %.16llx : %.12llx -> %.12llx %.4x %u bytes",nwid,sourceMac,destMac,etherType,len); + fprintf(stderr,"VIRTUAL NETWORK FRAME from %.16llx : %.12llx -> %.12llx %.4x %u bytes\n",nwid,sourceMac,destMac,etherType,len); fflush(stderr); } void threadMain() throw() { - _nextBackgroundTaskDeadline = OSUtils::now(); + _nextBackgroundTaskDeadline = 0; try { _node = new Node( OSUtils::now(), @@ -315,9 +335,16 @@ public: break; } else _run_m.unlock(); - const uint64_t dl = _nextBackgroundTaskDeadline; - const uint64_t now = OSUtils::now(); - _phy.poll((dl > now) ? (unsigned long)(dl - now) : 500); + uint64_t dl = _nextBackgroundTaskDeadline; + uint64_t now = OSUtils::now(); + + if (dl <= now) { + _node->processBackgroundTasks(now,const_cast<uint64_t *>(&_nextBackgroundTaskDeadline)); + dl = _nextBackgroundTaskDeadline; + now = OSUtils::now(); + } + + _phy.poll((dl > now) ? (unsigned long)(dl - now) : 100); } } catch (std::exception &exc) { Mutex::Lock _l(_termReason_m); @@ -366,15 +393,15 @@ static void SphyOnTcpWritableFunction(PhySocket *sock,void **uptr) { reinterpret_cast<OneImpl *>(*uptr)->phyOnTcpWritableFunction(sock); } static int SnodeVirtualNetworkConfigFunction(ZT1_Node *node,void *uptr,uint64_t nwid,enum ZT1_VirtualNetworkConfigOperation op,const ZT1_VirtualNetworkConfig *nwconf) -{ reinterpret_cast<OneImpl *>(uptr)->nodeVirtualNetworkConfigFunction(nwid,op,nwconf); } +{ return reinterpret_cast<OneImpl *>(uptr)->nodeVirtualNetworkConfigFunction(nwid,op,nwconf); } static void SnodeEventCallback(ZT1_Node *node,void *uptr,enum ZT1_Event event,const void *metaData) { reinterpret_cast<OneImpl *>(uptr)->nodeEventCallback(event,metaData); } static long SnodeDataStoreGetFunction(ZT1_Node *node,void *uptr,const char *name,void *buf,unsigned long bufSize,unsigned long readIndex,unsigned long *totalSize) -{ reinterpret_cast<OneImpl *>(uptr)->nodeDataStoreGetFunction(name,buf,bufSize,readIndex,totalSize); } +{ return reinterpret_cast<OneImpl *>(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) -{ reinterpret_cast<OneImpl *>(uptr)->nodeDataStorePutFunction(name,data,len,secure); } +{ return reinterpret_cast<OneImpl *>(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) -{ reinterpret_cast<OneImpl *>(uptr)->nodeWirePacketSendFunction(addr,desperation,data,len); } +{ return reinterpret_cast<OneImpl *>(uptr)->nodeWirePacketSendFunction(addr,desperation,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<OneImpl *>(uptr)->nodeVirtualNetworkFrameFunction(nwid,sourceMac,destMac,etherType,vlanId,data,len); } @@ -406,7 +433,9 @@ std::string One::platformDefaultHomePath() return (std::string(buf) + "\\ZeroTier\\One"); else return std::string("C:\\ZeroTier\\One"); #else -#error Unknown platform, please define a default home path! + + return std::string(); // UNKNOWN PLATFORM + #endif #endif // __UNIX_LIKE__ or not... diff --git a/service/One.hpp b/service/One.hpp index 29dec67f..26071656 100644 --- a/service/One.hpp +++ b/service/One.hpp @@ -28,6 +28,8 @@ #ifndef ZT_ONE_HPP #define ZT_ONE_HPP +#include <string> + namespace ZeroTier { class NetworkConfigMaster; @@ -68,7 +70,7 @@ public: }; /** - * @return Platform default home path + * @return Platform default home path or empty string if this platform doesn't have one */ static std::string platformDefaultHomePath(); |