diff --git a/.gitignore b/.gitignore index fba7c321b..3d12d5d2a 100755 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,9 @@ mac-tap/tuntap/tap.kext /ZeroTierOne.v11.suo /vsprojects/SelfTest/Debug /vsprojects/SelfTest/Release +/vsprojects/ZeroTierOne/Debug +/vsprojects/ZeroTierOne/Release +/vsprojects/ZeroTierOne/x64 /vsprojects/TapDriver/Win32 /vsprojects/TapDriver/x64 /Build/* @@ -18,5 +21,6 @@ mac-tap/tuntap/tap.kext *.opensdf *.user *.cache - +*.obj +*.tlog /vsprojects/SelfTest/SelfTest.aps diff --git a/ZeroTierOne.sln b/ZeroTierOne.sln index 008cb65ef..aba9d0f83 100644 --- a/ZeroTierOne.sln +++ b/ZeroTierOne.sln @@ -10,6 +10,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TapDriver Package", "vsproj {689210B1-467C-4850-BB7D-2E10D5B4A3DA} = {689210B1-467C-4850-BB7D-2E10D5B4A3DA} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZeroTierOne", "vsprojects\ZeroTierOne\ZeroTierOne.vcxproj", "{B00A4957-5977-4AC1-9EF4-571DC27EADA2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -156,6 +158,39 @@ Global {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|x64.ActiveCfg = Win8 Release|x64 {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|x64.Build.0 = Win8 Release|x64 {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|x64.Deploy.0 = Win8 Release|x64 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|Win32.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|Win32.Build.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|Win32.Deploy.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|x64.ActiveCfg = Debug|x64 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|x64.Build.0 = Debug|x64 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|Win32.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|Win32.Build.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|Win32.Deploy.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|x64.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|Win32.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|Win32.Build.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|Win32.Deploy.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|x64.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|Win32.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|Win32.Build.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|Win32.Deploy.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|x64.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|Win32.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|Win32.Build.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|Win32.Deploy.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|x64.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|Win32.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|Win32.Build.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|Win32.Deploy.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|x64.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|Win32.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|Win32.Build.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|Win32.Deploy.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|x64.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|Win32.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|Win32.Build.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|Win32.Deploy.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ext/kissdb/kissdb.c b/ext/kissdb/kissdb.c index 28346a474..e5ee99795 100644 --- a/ext/kissdb/kissdb.c +++ b/ext/kissdb/kissdb.c @@ -179,7 +179,7 @@ int KISSDB_get(KISSDB *db,const void *key,void *vbuf) kptr = (const uint8_t *)key; klen = db->key_size; while (klen) { - n = fread(tmp,1,(klen > sizeof(tmp)) ? sizeof(tmp) : klen,db->f); + n = (long)fread(tmp,1,(klen > sizeof(tmp)) ? sizeof(tmp) : klen,db->f); if (n > 0) { if (memcmp(kptr,tmp,n)) goto get_no_match_next_hash_table; @@ -224,7 +224,7 @@ int KISSDB_put(KISSDB *db,const void *key,const void *value) kptr = (const uint8_t *)key; klen = db->key_size; while (klen) { - n = fread(tmp,1,(klen > sizeof(tmp)) ? sizeof(tmp) : klen,db->f); + n = (long)fread(tmp,1,(klen > sizeof(tmp)) ? sizeof(tmp) : klen,db->f); if (n > 0) { if (memcmp(kptr,tmp,n)) goto put_no_match_next_hash_table; diff --git a/launcher.h b/launcher.h index 7056231eb..d99eadc88 100644 --- a/launcher.h +++ b/launcher.h @@ -32,17 +32,6 @@ #define ZT_LAUNCHER_VERSION_MINOR 0 #define ZT_LAUNCHER_VERSION_REVISION 1 -/* Default locations of data directories on operating systems */ -#ifdef __APPLE__ /* MacOS likes purdy paths, none of this 1970s /var stuff */ -#define ZT_DEFAULT_HOME "/Library/Application Support/ZeroTier/One" -#else -#ifdef _WIN32 /* Winbloze */ -need windoze; -#else /* Unix/Linux */ -#define ZT_DEFAULT_HOME "/var/lib/zerotier-one" -#endif -#endif - /** * Normal termination * diff --git a/main.cpp b/main.cpp index ed1ca19cf..b0713da88 100644 --- a/main.cpp +++ b/main.cpp @@ -30,14 +30,17 @@ #include #include #include + #include #include -#include #include "node/Constants.hpp" #ifdef __WINDOWS__ +#include #include +#include +#include #else #include #include @@ -48,8 +51,10 @@ #include -#include "node/Node.hpp" +#include "node/Constants.hpp" +#include "node/Defaults.hpp" #include "node/Utils.hpp" +#include "node/Node.hpp" #include "launcher.h" @@ -89,10 +94,10 @@ static Node *node = (Node *)0; static void printHelp(const char *cn,FILE *out) { - fprintf(out,"ZeroTier One version %d.%d.%d\n(c)2012-2013 ZeroTier Networks LLC\nLicensed under the GNU General Public License v3\n\nUsage: %s \n",Node::versionMajor(),Node::versionMinor(),Node::versionRevision(),cn); + fprintf(out,"ZeroTier One version %d.%d.%d"ZT_EOL_S"(c)2012-2013 ZeroTier Networks LLC"ZT_EOL_S"Licensed under the GNU General Public License v3"ZT_EOL_S""ZT_EOL_S"Usage: %s [home directory]"ZT_EOL_S,Node::versionMajor(),Node::versionMinor(),Node::versionRevision(),cn); } -#ifndef _WIN32 +#ifdef __UNIX_LIKE__ static void sighandlerQuit(int sig) { Node *n = node; @@ -102,9 +107,13 @@ static void sighandlerQuit(int sig) } #endif +#ifdef __WINDOWS__ +int _tmain(int argc, _TCHAR* argv[]) +#else int main(int argc,char **argv) +#endif { -#ifndef _WIN32 +#ifdef __UNIX_LIKE__ signal(SIGHUP,SIG_IGN); signal(SIGPIPE,SIG_IGN); signal(SIGUSR1,SIG_IGN); @@ -115,17 +124,19 @@ int main(int argc,char **argv) signal(SIGQUIT,&sighandlerQuit); #endif - _initLibCrypto(); +#ifdef __WINDOWS__ + WSADATA wsaData; + WSAStartup(MAKEWORD(2,2),&wsaData); +#endif - if (argc < 2) { - printHelp(argv[0],stderr); - return ZT_EXEC_RETURN_VALUE_NORMAL_TERMINATION; - } + _initLibCrypto(); const char *homeDir = (const char *)0; for(int i=1;ifirst.data(),kv->first.length(),s); + _appendEsc(kv->first.data(),(unsigned int)kv->first.length(),s); s.push_back('='); - _appendEsc(kv->second.data(),kv->second.length(),s); + _appendEsc(kv->second.data(),(unsigned int)kv->second.length(),s); s.append(ZT_EOL_S); } diff --git a/node/EllipticCurveKey.hpp b/node/EllipticCurveKey.hpp index 5a3a60c48..c3439c624 100644 --- a/node/EllipticCurveKey.hpp +++ b/node/EllipticCurveKey.hpp @@ -78,7 +78,7 @@ public: EllipticCurveKey(const std::string &data) throw(std::out_of_range) { - set(data.data(),data.length()); + set(data.data(),(unsigned int)data.length()); } inline void set(const void *data,unsigned int len) diff --git a/node/EllipticCurveKeyPair.cpp b/node/EllipticCurveKeyPair.cpp index 047b2b4fb..dd95d9a7d 100644 --- a/node/EllipticCurveKeyPair.cpp +++ b/node/EllipticCurveKeyPair.cpp @@ -153,7 +153,7 @@ bool EllipticCurveKeyPair::generate() } memset(_priv._key,0,sizeof(_priv._key)); - len = BN_num_bytes(EC_KEY_get0_private_key(key)); + len = (int)BN_num_bytes(EC_KEY_get0_private_key(key)); if ((len > ZT_EC_PRIME_BYTES)||(len < 0)) { EC_KEY_free(key); return false; @@ -162,7 +162,7 @@ bool EllipticCurveKeyPair::generate() _priv._bytes = ZT_EC_PRIME_BYTES; memset(_pub._key,0,sizeof(_pub._key)); - len = EC_POINT_point2oct(ZT_EC_GROUP.g,EC_KEY_get0_public_key(key),POINT_CONVERSION_COMPRESSED,_pub._key,sizeof(_pub._key),0); + len = (int)EC_POINT_point2oct(ZT_EC_GROUP.g,EC_KEY_get0_public_key(key),POINT_CONVERSION_COMPRESSED,_pub._key,sizeof(_pub._key),0); if (len != ZT_EC_PUBLIC_KEY_BYTES) { EC_KEY_free(key); return false; diff --git a/node/EthernetTap.cpp b/node/EthernetTap.cpp index 48e93a34f..745b8c8e0 100644 --- a/node/EthernetTap.cpp +++ b/node/EthernetTap.cpp @@ -693,11 +693,37 @@ void EthernetTap::threadMain() #include #include #include +#include +#include #include "..\vsprojects\TapDriver\tap-windows.h" namespace ZeroTier { +// Helper function to get an adapter's LUID and index from its GUID. The LUID is +// constant but the index can change, so go ahead and just look them both up by +// the GUID which is constant. (The GUID is the instance ID in the registry.) +static inline std::pair _findAdapterByGuid(const GUID &guid) + throw(std::runtime_error) +{ + MIB_IF_TABLE2 *ift = (MIB_IF_TABLE2 *)0; + + if (GetIfTable2Ex(MibIfTableRaw,&ift) != NO_ERROR) + throw std::runtime_error("GetIfTable2Ex() failed"); + + for(ULONG i=0;iNumEntries;++i) { + if (ift->Table[i].InterfaceGuid == guid) { + std::pair tmp(ift->Table[i].InterfaceLuid,ift->Table[i].InterfaceIndex); + FreeMibTable(&ift); + return tmp; + } + } + + FreeMibTable(&ift); + + throw std::runtime_error("interface not found"); +} + static Mutex _systemTapInitLock; EthernetTap::EthernetTap( @@ -721,6 +747,9 @@ EthernetTap::EthernetTap( char subkeyClass[4096]; char data[4096]; + if (mtu > ZT_IF_MTU) + throw std::runtime_error("MTU too large for Windows tap"); + Mutex::Lock _l(_systemTapInitLock); // only init one tap at a time, process-wide HKEY nwAdapters; @@ -813,7 +842,7 @@ EthernetTap::EthernetTap( dataLen = sizeof(data); if (RegGetValueA(nwAdapters,subkeyName,"NetCfgInstanceId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) { if (existingDeviceInstances.count(std::string(data,dataLen)) == 0) { - RegSetKeyValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",REG_SZ,tag,strlen(tag)+1); + RegSetKeyValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",REG_SZ,tag,(DWORD)(strlen(tag)+1)); _myDeviceInstanceId.assign(data,dataLen); mySubkeyName = subkeyName; subkeyIndex = -1; // break outer loop @@ -842,8 +871,27 @@ EthernetTap::EthernetTap( if (_myDeviceInstanceId.length() == 0) throw std::runtime_error("unable to create new tap adapter"); + { + char nobraces[128]; + const char *nbtmp1 = _myDeviceInstanceId.c_str(); + char *nbtmp2 = nobraces; + while (*nbtmp1) { + if ((*nbtmp1 != '{')&&(*nbtmp1 != '}')) + *nbtmp2++ = *nbtmp1; + ++nbtmp1; + } + *nbtmp2 = (char)0; + if (UuidFromStringA((RPC_CSTR)nobraces,&_deviceGuid) != RPC_S_OK) + throw std::runtime_error("unable to convert instance ID GUID to native GUID (invalid NetCfgInstanceId in registry?)"); + } + +#ifdef UNICODE wchar_t tapPath[4096]; swprintf_s(tapPath,L"\\\\.\\Global\\%S.tap",_myDeviceInstanceId.c_str()); +#else + char tapPath[4096]; + sprintf_s(tapPath,"\\\\.\\Global\\%s.tap",_myDeviceInstanceId.c_str()); +#endif _tap = CreateFile(tapPath,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM|FILE_FLAG_OVERLAPPED,NULL); if (_tap == INVALID_HANDLE_VALUE) throw std::runtime_error("unable to open tap in \\\\.\\Global\\ namespace"); @@ -878,14 +926,104 @@ void EthernetTap::whack() bool EthernetTap::addIP(const InetAddress &ip) { + Mutex::Lock _l(_ips_m); + + if (_ips.count(ip)) + return true; + + if (!ip.port()) + return false; + + try { + std::pair ifidx = _findAdapterByGuid(_deviceGuid); + MIB_UNICASTIPADDRESS_ROW ipr; + + InitializeUnicastIpAddressEntry(&ipr); + if (ip.isV4()) { + ipr.Address.Ipv4.sin_family = AF_INET; + ipr.Address.Ipv4.sin_addr.S_un.S_addr = *((const uint32_t *)ip.rawIpData()); + ipr.OnLinkPrefixLength = ip.port(); + } else if (ip.isV6()) { + } else return false; + + ipr.PrefixOrigin = IpPrefixOriginManual; + ipr.SuffixOrigin = IpSuffixOriginManual; + ipr.ValidLifetime = 0xffffffff; + ipr.PreferredLifetime = 0xffffffff; + + ipr.InterfaceLuid = ifidx.first; + ipr.InterfaceIndex = ifidx.second; + + if (CreateUnicastIpAddressEntry(&ipr) == NO_ERROR) { + _ips.insert(ip); + return true; + } + } catch ( ... ) {} + return false; } bool EthernetTap::removeIP(const InetAddress &ip) { + try { + MIB_UNICASTIPADDRESS_TABLE *ipt = (MIB_UNICASTIPADDRESS_TABLE *)0; + std::pair ifidx = _findAdapterByGuid(_deviceGuid); + + if (GetUnicastIpAddressTable(AF_UNSPEC,&ipt) == NO_ERROR) { + for(DWORD i=0;iNumEntries;++i) { + if ((ipt->Table[i].InterfaceLuid.Value == ifidx.first.Value)&&(ipt->Table[i].InterfaceIndex == ifidx.second)) { + InetAddress addr; + switch(ipt->Table[i].Address.si_family) { + case AF_INET: + addr.set(&(ipt->Table[i].Address.Ipv4.sin_addr.S_un.S_addr),4,ipt->Table[i].OnLinkPrefixLength); + break; + case AF_INET6: + addr.set(ipt->Table[i].Address.Ipv6.sin6_addr.u.Byte,16,ipt->Table[i].OnLinkPrefixLength); + break; + } + if (addr == ip) { + DeleteUnicastIpAddressEntry(&(ipt->Table[i])); + FreeMibTable(&ipt); + Mutex::Lock _l(_ips_m); + _ips.erase(ip); + return true; + } + } + } + FreeMibTable(&ipt); + } + } catch ( ... ) {} return false; } +std::set EthernetTap::allIps() const +{ + std::set addrs; + + try { + MIB_UNICASTIPADDRESS_TABLE *ipt = (MIB_UNICASTIPADDRESS_TABLE *)0; + std::pair ifidx = _findAdapterByGuid(_deviceGuid); + + if (GetUnicastIpAddressTable(AF_UNSPEC,&ipt) == NO_ERROR) { + for(DWORD i=0;iNumEntries;++i) { + if ((ipt->Table[i].InterfaceLuid.Value == ifidx.first.Value)&&(ipt->Table[i].InterfaceIndex == ifidx.second)) { + switch(ipt->Table[i].Address.si_family) { + case AF_INET: + addrs.insert(InetAddress(&(ipt->Table[i].Address.Ipv4.sin_addr.S_un.S_addr),4,ipt->Table[i].OnLinkPrefixLength)); + break; + case AF_INET6: + addrs.insert(InetAddress(ipt->Table[i].Address.Ipv6.sin6_addr.u.Byte,16,ipt->Table[i].OnLinkPrefixLength)); + break; + } + } + } + FreeMibTable(&ipt); + } + } catch ( ... ) {} + + return addrs; +} + void EthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) { if (len > (ZT_IF_MTU)) @@ -939,8 +1077,8 @@ void EthernetTap::threadMain() MAC from(_tapReadBuf + 6); unsigned int etherType = Utils::ntoh(*((const uint16_t *)(_tapReadBuf + 12))); Buffer<4096> tmp(_tapReadBuf + 14,bytesRead - 14); - printf("GOT FRAME: %u bytes: %s\r\n",(unsigned int)bytesRead,Utils::hex(_tapReadBuf,bytesRead).c_str()); - //_handler(_arg,from,to,etherType,tmp); + //printf("GOT FRAME: %u bytes: %s\r\n",(unsigned int)bytesRead,Utils::hex(_tapReadBuf,bytesRead).c_str()); + _handler(_arg,from,to,etherType,tmp); } } ReadFile(_tap,_tapReadBuf,sizeof(_tapReadBuf),NULL,&_tapOvlRead); diff --git a/node/EthernetTap.hpp b/node/EthernetTap.hpp index cff0953be..b4128abd3 100644 --- a/node/EthernetTap.hpp +++ b/node/EthernetTap.hpp @@ -134,6 +134,11 @@ public: return _ips; } + /** + * @return Set of IP addresses / netmasks included any we did not assign, link-local, etc. + */ + std::set allIps() const; + /** * Set this tap's IP addresses to exactly this set of IPs * @@ -213,6 +218,7 @@ private: OVERLAPPED _tapOvlRead,_tapOvlWrite; char _tapReadBuf[ZT_IF_MTU + 32]; HANDLE _injectSemaphore; + GUID _deviceGuid; std::string _myDeviceInstanceId; std::queue< std::pair< Array,unsigned int > > _injectPending; Mutex _injectPending_m; diff --git a/node/Filter.hpp b/node/Filter.hpp index 8b86b48fd..ac493b288 100644 --- a/node/Filter.hpp +++ b/node/Filter.hpp @@ -298,7 +298,7 @@ public: throw() { Mutex::Lock _l(_chain_m); - return _chain.size(); + return (unsigned int)_chain.size(); } /** diff --git a/node/Identity.cpp b/node/Identity.cpp index 66ddae04b..391b436ee 100644 --- a/node/Identity.cpp +++ b/node/Identity.cpp @@ -88,7 +88,7 @@ bool Identity::locallyValidate(bool doAddressDerivationCheck) const SHA256_Update(&sha,&zero,1); SHA256_Final(dig,&sha); - return ((EllipticCurveKeyPair::verify(dig,_publicKey,_signature.data(),_signature.length()))&&((!doAddressDerivationCheck)||(deriveAddress(_publicKey.data(),_publicKey.size()) == _address))); + return ((EllipticCurveKeyPair::verify(dig,_publicKey,_signature.data(),(unsigned int)_signature.length()))&&((!doAddressDerivationCheck)||(deriveAddress(_publicKey.data(),_publicKey.size()) == _address))); } std::string Identity::toString(bool includePrivate) const @@ -98,7 +98,7 @@ std::string Identity::toString(bool includePrivate) const r.append(":1:"); // 1 == IDENTITY_TYPE_NIST_P_521 r.append(Utils::base64Encode(_publicKey.data(),_publicKey.size())); r.push_back(':'); - r.append(Utils::base64Encode(_signature.data(),_signature.length())); + r.append(Utils::base64Encode(_signature.data(),(unsigned int)_signature.length())); if ((includePrivate)&&(_keyPair)) { r.push_back(':'); r.append(Utils::base64Encode(_keyPair->priv().data(),_keyPair->priv().size())); @@ -127,7 +127,7 @@ bool Identity::fromString(const char *str) b = Utils::base64Decode(fields[2]); if ((!b.length())||(b.length() > ZT_EC_MAX_BYTES)) return false; - _publicKey.set(b.data(),b.length()); + _publicKey.set(b.data(),(unsigned int)b.length()); _signature = Utils::base64Decode(fields[3]); if (!_signature.length()) @@ -137,7 +137,7 @@ bool Identity::fromString(const char *str) b = Utils::base64Decode(fields[4]); if ((!b.length())||(b.length() > ZT_EC_MAX_BYTES)) return false; - _keyPair = new EllipticCurveKeyPair(_publicKey,EllipticCurveKey(b.data(),b.length())); + _keyPair = new EllipticCurveKeyPair(_publicKey,EllipticCurveKey(b.data(),(unsigned int)b.length())); } return true; diff --git a/node/Logger.cpp b/node/Logger.cpp index 71b4893d5..7084ba6ce 100644 --- a/node/Logger.cpp +++ b/node/Logger.cpp @@ -107,7 +107,12 @@ void Logger::trace(const char *module,unsigned int line,const char *fmt,...) if (_log) { time_t now = time(0); +#ifdef __WINDOWS__ + ctime_s(tmp,sizeof(tmp),&now); + char *nowstr = tmp; +#else char *nowstr = ctime_r(&now,tmp); +#endif for(char *c=nowstr;*c;++c) { if (*c == '\n') *c = '\0'; diff --git a/node/Node.cpp b/node/Node.cpp index 1884f9ce4..c9aef8a5c 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -258,7 +258,7 @@ Node::Node(const char *hp) { _NodeImpl *impl = (_NodeImpl *)_impl; - if (hp) + if ((hp)&&(strlen(hp) > 0)) impl->renv.homePath = hp; else impl->renv.homePath = ZT_DEFAULTS.defaultHomePath; impl->reasonForTermination = Node::NODE_RUNNING; @@ -382,10 +382,10 @@ Node::ReasonForTermination Node::run() _r->sysEnv = new SysEnv(_r); try { _r->nc = new NodeConfig(_r,configAuthToken.c_str()); - } catch ( ... ) { + } catch (std::exception &exc) { // An exception here currently means that another instance of ZeroTier // One is running. - return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"another instance of ZeroTier One appears to be running, or local control UDP port cannot be bound"); + return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,(std::string("another instance of ZeroTier One appears to be running, or local control UDP port cannot be bound: ") + exc.what()).c_str()); } // TODO: make configurable @@ -618,3 +618,27 @@ const unsigned char EMBEDDED_VERSION_STAMP[20] = { }; } // namespace ZeroTier + +extern "C" { + +ZeroTier::Node *zeroTierCreateNode(const char *hp) +{ + return new ZeroTier::Node(hp); +} + +void zeroTierDeleteNode(ZeroTier::Node *n) +{ + delete n; +} + +ZeroTier::Node::LocalClient *zeroTierCreateLocalClient(const char *authToken,void (*resultHandler)(void *,unsigned long,const char *),void *arg) +{ + return new ZeroTier::Node::LocalClient(authToken,resultHandler,arg); +} + +void zeroTierDeleteLocalClient(ZeroTier::Node::LocalClient *lc) +{ + delete lc; +} + +} // extern "C" diff --git a/node/Node.hpp b/node/Node.hpp index b716b556f..9fb4666d2 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -163,5 +163,17 @@ extern const unsigned char EMBEDDED_VERSION_STAMP[20]; } // namespace ZeroTier -#endif +extern "C" { +// Functions with C-style linkage for easy DLL symbol table +// lookup. These just create instances of Node and LocalClient. + +ZeroTier::Node *zeroTierCreateNode(const char *hp); +void zeroTierDeleteNode(ZeroTier::Node *n); + +ZeroTier::Node::LocalClient *zeroTierCreateLocalClient(const char *authToken,void (*resultHandler)(void *,unsigned long,const char *),void *arg); +void zeroTierDeleteLocalClient(ZeroTier::Node::LocalClient *lc); + +} // extern "C" + +#endif diff --git a/node/Switch.cpp b/node/Switch.cpp index aed37307e..9370522e7 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -142,7 +142,7 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c outpTmpl.append((uint16_t)data.size()); outpTmpl.append((uint16_t)signature.length()); outpTmpl.append(data.data(),data.size()); - outpTmpl.append(signature.data(),signature.length()); + outpTmpl.append(signature.data(),(unsigned int)signature.length()); outpTmpl.compress(); send(outpTmpl,true); for(unsigned int i=1;i 0) { #ifdef __WINDOWS__ + _sock = INVALID_SOCKET; + if (s != INVALID_SOCKET) { ::shutdown(s,SD_BOTH); ::closesocket(s); + } #else + _sock = 0; + if (s > 0) { ::shutdown(s,SHUT_RDWR); ::close(s); -#endif } +#endif Thread::join(_thread); } diff --git a/node/UdpSocket.hpp b/node/UdpSocket.hpp index 6b7d488ca..d8467f641 100644 --- a/node/UdpSocket.hpp +++ b/node/UdpSocket.hpp @@ -35,6 +35,10 @@ #include "InetAddress.hpp" #include "Mutex.hpp" +#ifdef __WINDOWS__ +#include +#endif + namespace ZeroTier { /** @@ -100,7 +104,11 @@ private: void (*_packetHandler)(UdpSocket *,void *,const InetAddress &,const void *,unsigned int); void *_arg; int _localPort; +#ifdef __WINDOWS__ + volatile SOCKET _sock; +#else volatile int _sock; +#endif bool _v6; Mutex _sendLock; }; diff --git a/node/Utils.cpp b/node/Utils.cpp index 32cfe2d16..94f66c118 100644 --- a/node/Utils.cpp +++ b/node/Utils.cpp @@ -501,7 +501,7 @@ uint64_t Utils::fromRfc1123(const char *tstr) struct tm t; char wdays[128],mons[128]; - int l = strlen(tstr); + int l = (int)strlen(tstr); if ((l < 29)||(l > 64)) return 0; int assigned = sscanf(tstr,"%3s, %02d %3s %4d %02d:%02d:%02d GMT",wdays,&t.tm_mday,mons,&t.tm_year,&t.tm_hour,&t.tm_min,&t.tm_sec); @@ -620,7 +620,7 @@ std::vector Utils::split(const char *s,const char *const sep,const std::string Utils::trim(const std::string &s) { - unsigned long end = s.length(); + unsigned long end = (unsigned long)s.length(); while (end) { char c = s[end - 1]; if ((c == ' ')||(c == '\r')||(c == '\n')||(!c)||(c == '\t')) diff --git a/node/Utils.hpp b/node/Utils.hpp index ff88124b4..1a3adec68 100644 --- a/node/Utils.hpp +++ b/node/Utils.hpp @@ -102,7 +102,7 @@ public: * @return Hexadecimal string */ static std::string hex(const void *data,unsigned int len); - static inline std::string hex(const std::string &data) { return hex(data.data(),data.length()); } + static inline std::string hex(const std::string &data) { return hex(data.data(),(unsigned int)data.length()); } /** * @param hex Hexadecimal ASCII code (non-hex chars are ignored) @@ -413,7 +413,7 @@ public: */ static inline bool writeFile(const char *path,const std::string &s) { - return writeFile(path,s.data(),s.length()); + return writeFile(path,s.data(),(unsigned int)s.length()); } /** @@ -422,7 +422,7 @@ public: * @return Base64-encoded string */ static std::string base64Encode(const void *data,unsigned int len); - inline static std::string base64Encode(const std::string &data) { return base64Encode(data.data(),data.length()); } + inline static std::string base64Encode(const std::string &data) { return base64Encode(data.data(),(unsigned int)data.length()); } /** * @param data Base64-encoded string @@ -430,7 +430,7 @@ public: * @return Decoded binary date */ static std::string base64Decode(const char *data,unsigned int len); - inline static std::string base64Decode(const std::string &data) { return base64Decode(data.data(),data.length()); } + inline static std::string base64Decode(const std::string &data) { return base64Decode(data.data(),(unsigned int)data.length()); } /** * Split a string by delimiter, with optional escape and quote characters diff --git a/vsprojects/SelfTest/SelfTest.vcxproj b/vsprojects/SelfTest/SelfTest.vcxproj index 0847e783e..db4e163fd 100644 --- a/vsprojects/SelfTest/SelfTest.vcxproj +++ b/vsprojects/SelfTest/SelfTest.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD} @@ -22,6 +30,12 @@ v110 Unicode + + Application + true + v110 + Unicode + Application false @@ -29,23 +43,43 @@ true Unicode + + Application + false + v110 + true + Unicode + + + + + + + true $(SolutionDir)\Build\$(Configuration)\ + + true + false - $(SolutionDir)\Build\$(Configuration)\ + $(SolutionDir)\Build\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\Build\$(Platform)\$(Configuration)\ @@ -62,6 +96,21 @@ $(SolutionDir)\ext\bin\libcrypto\win32-vs2012\libeay32.lib;wsock32.lib;ws2_32.lib;%(AdditionalDependencies) + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir)\ext\bin\libcrypto\include;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\ext\bin\libcrypto\win32-vs2012\libeay32.lib;wsock32.lib;ws2_32.lib;%(AdditionalDependencies) + + Level3 @@ -82,6 +131,26 @@ false + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir)\ext\bin\libcrypto\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + wsock32.lib;ws2_32.lib;iphlpapi.lib;$(SolutionDir)\ext\bin\libcrypto\win64-vs2012\libeay32.lib;%(AdditionalDependencies) + false + + diff --git a/vsprojects/ZeroTierOne/ZeroTierOne.vcxproj b/vsprojects/ZeroTierOne/ZeroTierOne.vcxproj new file mode 100644 index 000000000..2d01154d3 --- /dev/null +++ b/vsprojects/ZeroTierOne/ZeroTierOne.vcxproj @@ -0,0 +1,228 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {B00A4957-5977-4AC1-9EF4-571DC27EADA2} + ZeroTierOne + + + + Application + true + v110 + MultiByte + + + Application + true + v110 + MultiByte + + + Application + false + v110 + true + MultiByte + + + Application + false + v110 + true + MultiByte + + + + + + + + + + + + + + + + + + + .exe + $(SolutionDir)\Build\$(Platform)\$(Configuration)\ + zerotier-one-x86 + + + .exe + $(SolutionDir)\Build\$(Platform)\$(Configuration)\ + zerotier-one-x86 + + + .exe + $(SolutionDir)\Build\$(Platform)\$(Configuration)\ + zerotier-one-x64 + + + .exe + $(SolutionDir)\Build\$(Platform)\$(Configuration)\ + zerotier-one-x64 + + + + Level3 + Disabled + true + $(SolutionDir)\ext\bin\libcrypto\include + ZT_LOG_STDOUT;ZT_TRACE;%(PreprocessorDefinitions) + + + true + wsock32.lib;ws2_32.lib;iphlpapi.lib;rpcrt4.lib;$(SolutionDir)\ext\bin\libcrypto\win32-vs2012\libeay32.lib;%(AdditionalDependencies) + false + + + + + Level3 + Disabled + true + $(SolutionDir)\ext\bin\libcrypto\include + ZT_LOG_STDOUT;ZT_TRACE;%(PreprocessorDefinitions) + + + true + wsock32.lib;ws2_32.lib;iphlpapi.lib;rpcrt4.lib;$(SolutionDir)\ext\bin\libcrypto\win64-vs2012\libeay32.lib;%(AdditionalDependencies) + false + + + + + Level3 + MaxSpeed + true + true + true + $(SolutionDir)\ext\bin\libcrypto\include + ZT_LOG_STDOUT;ZT_TRACE;%(PreprocessorDefinitions) + + + true + true + true + wsock32.lib;ws2_32.lib;iphlpapi.lib;rpcrt4.lib;$(SolutionDir)\ext\bin\libcrypto\win32-vs2012\libeay32.lib;%(AdditionalDependencies) + false + + + + + Level3 + MaxSpeed + true + true + true + $(SolutionDir)\ext\bin\libcrypto\include + ZT_LOG_STDOUT;ZT_TRACE;%(PreprocessorDefinitions) + + + true + true + true + wsock32.lib;ws2_32.lib;iphlpapi.lib;rpcrt4.lib;$(SolutionDir)\ext\bin\libcrypto\win64-vs2012\libeay32.lib;%(AdditionalDependencies) + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vsprojects/ZeroTierOne/ZeroTierOne.vcxproj.filters b/vsprojects/ZeroTierOne/ZeroTierOne.vcxproj.filters new file mode 100644 index 000000000..67e668e1e --- /dev/null +++ b/vsprojects/ZeroTierOne/ZeroTierOne.vcxproj.filters @@ -0,0 +1,228 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file