Przeglądaj źródła

Merge branch 'edge' into multipath

Joseph Henry 6 lat temu
rodzic
commit
258b1c8b55

+ 7 - 0
RELEASE-NOTES.md

@@ -1,6 +1,13 @@
 ZeroTier Release Notes
 ======
 
+# 2018-07-27 -- Version 1.2.12
+
+ * Fixed a bug that caused exits to take a long time on Mac due to huge numbers of redundant attempts to delete managed routes.
+ * Fixed a socket limit problem on Windows that caused the ZeroTier service to run out of sockets, causing the UI and CLI to be unable to access the API.
+ * Fixed a threading bug in the ZeroTier Core, albeit one that never manifested on the regular ZeroTier One service/client.
+ * Fixed a bug that could cause the service to crash if an authorized local client accessed an invalid URL via the control API. (Not exploitable since you needed admin access anyway.)
+
 # 2018-05-08 -- Version 1.2.10
 
  * Fix bug loading `moons.d/` files for federated root operation.

+ 3 - 3
attic/world/mkworld.cpp

@@ -81,7 +81,7 @@ int main(int argc,char **argv)
 	std::vector<World::Root> roots;
 
 	const uint64_t id = ZT_WORLD_ID_EARTH;
-	const uint64_t ts = 1452708876314ULL; // January 13th, 2016
+	const uint64_t ts = 1532555817048ULL; // July 25th, 2018
 
 	// Alice
 	roots.push_back(World::Root());
@@ -92,8 +92,8 @@ int main(int argc,char **argv)
 	roots.back().stableEndpoints.push_back(InetAddress("2c0f:f850:154:197::33/9993")); // Johannesburg
 	roots.back().stableEndpoints.push_back(InetAddress("159.203.97.171/9993")); // New York
 	roots.back().stableEndpoints.push_back(InetAddress("2604:a880:800:a1::54:6001/9993")); // New York
-	roots.back().stableEndpoints.push_back(InetAddress("169.57.143.104/9993")); // Sao Paolo
-	roots.back().stableEndpoints.push_back(InetAddress("2607:f0d0:1d01:57::2/9993")); // Sao Paolo
+	roots.back().stableEndpoints.push_back(InetAddress("131.255.6.16/9993")); // Buenos Aires
+	roots.back().stableEndpoints.push_back(InetAddress("2803:eb80:0:e::2/9993")); // Buenos Aires
 	roots.back().stableEndpoints.push_back(InetAddress("107.170.197.14/9993")); // San Francisco
 	roots.back().stableEndpoints.push_back(InetAddress("2604:a880:1:20::200:e001/9993")); // San Francisco
 	roots.back().stableEndpoints.push_back(InetAddress("128.199.197.217/9993")); // Singapore

+ 0 - 0
attic/world/earth-2016-01-13.bin → attic/world/old/earth-2016-01-13.bin


BIN
attic/world/world.bin


Plik diff jest za duży
+ 2 - 0
attic/world/world.c


+ 0 - 136
controller/DB.cpp

@@ -324,109 +324,6 @@ void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool pu
 		}
 	}
 
-	/*
-	if (old.is_object()) {
-		json &config = old["config"];
-		if (config.is_object()) {
-			memberId = OSUtils::jsonIntHex(config["id"],0ULL);
-			networkId = OSUtils::jsonIntHex(config["nwid"],0ULL);
-			if ((memberId)&&(networkId)) {
-				{
-					std::lock_guard<std::mutex> l(_networks_l);
-					auto nw2 = _networks.find(networkId);
-					if (nw2 != _networks.end())
-						nw = nw2->second;
-				}
-				if (nw) {
-					std::lock_guard<std::mutex> l(nw->lock);
-					if (OSUtils::jsonBool(config["activeBridge"],false))
-						nw->activeBridgeMembers.erase(memberId);
-					wasAuth = OSUtils::jsonBool(config["authorized"],false);
-					if (wasAuth)
-						nw->authorizedMembers.erase(memberId);
-					json &ips = config["ipAssignments"];
-					if (ips.is_array()) {
-						for(unsigned long i=0;i<ips.size();++i) {
-							json &ipj = ips[i];
-							if (ipj.is_string()) {
-								const std::string ips = ipj;
-								InetAddress ipa(ips.c_str());
-								ipa.setPort(0);
-								nw->allocatedIps.erase(ipa);
-							}
-						}
-					}
-				}
-			}
-		}
-	}
-
-	if (member.is_object()) {
-		json &config = member["config"];
-		if (config.is_object()) {
-			if (!nw) {
-				memberId = OSUtils::jsonIntHex(config["id"],0ULL);
-				networkId = OSUtils::jsonIntHex(config["nwid"],0ULL);
-				if ((!memberId)||(!networkId))
-					return;
-				std::lock_guard<std::mutex> l(_networks_l);
-				std::shared_ptr<_Network> &nw2 = _networks[networkId];
-				if (!nw2)
-					nw2.reset(new _Network);
-				nw = nw2;
-			}
-
-			{
-				std::lock_guard<std::mutex> l(nw->lock);
-
-				nw->members[memberId] = config;
-
-				if (OSUtils::jsonBool(config["activeBridge"],false))
-					nw->activeBridgeMembers.insert(memberId);
-				isAuth = OSUtils::jsonBool(config["authorized"],false);
-				if (isAuth)
-					nw->authorizedMembers.insert(memberId);
-				json &ips = config["ipAssignments"];
-				if (ips.is_array()) {
-					for(unsigned long i=0;i<ips.size();++i) {
-						json &ipj = ips[i];
-						if (ipj.is_string()) {
-							const std::string ips = ipj;
-							InetAddress ipa(ips.c_str());
-							ipa.setPort(0);
-							nw->allocatedIps.insert(ipa);
-						}
-					}
-				}
-
-				if (!isAuth) {
-					const int64_t ldt = (int64_t)OSUtils::jsonInt(config["lastDeauthorizedTime"],0ULL);
-					if (ldt > nw->mostRecentDeauthTime)
-						nw->mostRecentDeauthTime = ldt;
-				}
-			}
-
-			if (push)
-				_controller->onNetworkMemberUpdate(networkId,memberId);
-		}
-	} else if (memberId) {
-		if (nw) {
-			std::lock_guard<std::mutex> l(nw->lock);
-			nw->members.erase(memberId);
-		}
-		if (networkId) {
-			std::lock_guard<std::mutex> l(_networks_l);
-			auto er = _networkByMember.equal_range(memberId);
-			for(auto i=er.first;i!=er.second;++i) {
-				if (i->second == networkId) {
-					_networkByMember.erase(i);
-					break;
-				}
-			}
-		}
-	}
-	*/
-
 	if ((push)&&((wasAuth)&&(!isAuth)&&(networkId)&&(memberId)))
 		_controller->onNetworkMemberDeauthorize(networkId,memberId);
 }
@@ -460,39 +357,6 @@ void DB::_networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool
 			_networks.erase(id);
 		}
 	}
-
-	/*
-	if (network.is_object()) {
-		json &config = network["config"];
-		if (networkConfig.is_object()) {
-			const std::string ids = config["id"];
-			const uint64_t id = Utils::hexStrToU64(ids.c_str());
-			if (id) {
-				std::shared_ptr<_Network> nw;
-				{
-					std::lock_guard<std::mutex> l(_networks_l);
-					std::shared_ptr<_Network> &nw2 = _networks[id];
-					if (!nw2)
-						nw2.reset(new _Network);
-					nw = nw2;
-				}
-				{
-					std::lock_guard<std::mutex> l2(nw->lock);
-					nw->config = config;
-				}
-				if (push)
-					_controller->onNetworkUpdate(id);
-			}
-		}
-	} else if (old.is_object()) {
-		const std::string ids = old["id"];
-		const uint64_t id = Utils::hexStrToU64(ids.c_str());
-		if (id) {
-			std::lock_guard<std::mutex> l(_networks_l);
-			_networks.erase(id);
-		}
-	}
-	*/
 }
 
 void DB::_fillSummaryInfo(const std::shared_ptr<_Network> &nw,NetworkSummaryInfo &info)

+ 1 - 0
controller/DB.hpp

@@ -82,6 +82,7 @@ public:
 	virtual ~DB();
 
 	virtual bool waitForReady() = 0;
+	virtual bool isReady() = 0;
 
 	inline bool hasNetwork(const uint64_t networkId) const
 	{

+ 4 - 3
controller/EmbeddedNetworkController.cpp

@@ -551,7 +551,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpGET(
 							for(auto member=members.begin();member!=members.end();++member) {
 								mid = (*member)["id"];
 								char tmp[128];
-								OSUtils::ztsnprintf(tmp,sizeof(tmp),"%s\"%s\":%llu",(responseBody.length() > 1) ? ",\"" : "\"",mid.c_str(),(unsigned long long)OSUtils::jsonInt((*member)["revision"],0));
+								OSUtils::ztsnprintf(tmp,sizeof(tmp),"%s\"%s\":%llu",(responseBody.length() > 1) ? "," : "",mid.c_str(),(unsigned long long)OSUtils::jsonInt((*member)["revision"],0));
 								responseBody.append(tmp);
 							}
 						}
@@ -596,10 +596,11 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpGET(
 		// Controller status
 
 		char tmp[4096];
-		OSUtils::ztsnprintf(tmp,sizeof(tmp),"{\n\t\"controller\": true,\n\t\"apiVersion\": %d,\n\t\"clock\": %llu\n}\n",ZT_NETCONF_CONTROLLER_API_VERSION,(unsigned long long)OSUtils::now());
+		const bool dbOk = _db->isReady();
+		OSUtils::ztsnprintf(tmp,sizeof(tmp),"{\n\t\"controller\": true,\n\t\"apiVersion\": %d,\n\t\"clock\": %llu,\n\t\"databaseReady\": %s\n}\n",ZT_NETCONF_CONTROLLER_API_VERSION,(unsigned long long)OSUtils::now(),dbOk ? "true" : "false");
 		responseBody = tmp;
 		responseContentType = "application/json";
-		return 200;
+		return dbOk ? 200 : 503;
 
 	}
 

+ 25 - 23
controller/FileDB.cpp

@@ -63,14 +63,10 @@ FileDB::FileDB(EmbeddedNetworkController *const nc,const Identity &myId,const ch
 	}
 }
 
-FileDB::~FileDB()
-{
-}
+FileDB::~FileDB() {}
 
-bool FileDB::waitForReady()
-{
-	return true;
-}
+bool FileDB::waitForReady() { return true; }
+bool FileDB::isReady() { return true; }
 
 void FileDB::save(nlohmann::json *orig,nlohmann::json &record)
 {
@@ -91,13 +87,15 @@ void FileDB::save(nlohmann::json *orig,nlohmann::json &record)
 				nlohmann::json old;
 				get(nwid,old);
 
-				OSUtils::ztsnprintf(p1,sizeof(p1),"%s" ZT_PATH_SEPARATOR_S "%.16llx.json.new",_networksPath.c_str(),nwid);
-				OSUtils::ztsnprintf(p2,sizeof(p2),"%s" ZT_PATH_SEPARATOR_S "%.16llx.json",_networksPath.c_str(),nwid);
-				if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1)))
-					fprintf(stderr,"WARNING: controller unable to write to path: %s" ZT_EOL_S,p1);
-				OSUtils::rename(p1,p2);
+				if ((!old.is_object())||(old != record)) {
+					OSUtils::ztsnprintf(p1,sizeof(p1),"%s" ZT_PATH_SEPARATOR_S "%.16llx.json.new",_networksPath.c_str(),nwid);
+					OSUtils::ztsnprintf(p2,sizeof(p2),"%s" ZT_PATH_SEPARATOR_S "%.16llx.json",_networksPath.c_str(),nwid);
+					if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1)))
+						fprintf(stderr,"WARNING: controller unable to write to path: %s" ZT_EOL_S,p1);
+					OSUtils::rename(p1,p2);
 
-				_networkChanged(old,record,true);
+					_networkChanged(old,record,true);
+				}
 			}
 		} else if (objtype == "member") {
 			const uint64_t id = OSUtils::jsonIntHex(record["id"],0ULL);
@@ -106,17 +104,21 @@ void FileDB::save(nlohmann::json *orig,nlohmann::json &record)
 				nlohmann::json network,old;
 				get(nwid,network,id,old);
 
-				OSUtils::ztsnprintf(pb,sizeof(pb),"%s" ZT_PATH_SEPARATOR_S "%.16llx" ZT_PATH_SEPARATOR_S "member",_networksPath.c_str(),(unsigned long long)nwid);
-				OSUtils::ztsnprintf(p1,sizeof(p1),"%s" ZT_PATH_SEPARATOR_S "%.10llx.json.new",pb,(unsigned long long)id);
-				OSUtils::ztsnprintf(p2,sizeof(p2),"%s" ZT_PATH_SEPARATOR_S "%.10llx.json",pb,(unsigned long long)id);
-				if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1))) {
-					OSUtils::mkdir(pb);
-					if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1)))
-						fprintf(stderr,"WARNING: controller unable to write to path: %s" ZT_EOL_S,p1);
-				}
-				OSUtils::rename(p1,p2);
+				if ((!old.is_object())||(old != record)) {
+					OSUtils::ztsnprintf(pb,sizeof(pb),"%s" ZT_PATH_SEPARATOR_S "%.16llx" ZT_PATH_SEPARATOR_S "member",_networksPath.c_str(),(unsigned long long)nwid);
+					OSUtils::ztsnprintf(p1,sizeof(p1),"%s" ZT_PATH_SEPARATOR_S "%.10llx.json.new",pb,(unsigned long long)id);
+					if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1))) {
+						OSUtils::ztsnprintf(p2,sizeof(p2),"%s" ZT_PATH_SEPARATOR_S "%.16llx",_networksPath.c_str(),(unsigned long long)nwid);
+						OSUtils::mkdir(p2);
+						OSUtils::mkdir(pb);
+						if (!OSUtils::writeFile(p1,OSUtils::jsonDump(record,-1)))
+							fprintf(stderr,"WARNING: controller unable to write to path: %s" ZT_EOL_S,p1);
+					}
+					OSUtils::ztsnprintf(p2,sizeof(p2),"%s" ZT_PATH_SEPARATOR_S "%.10llx.json",pb,(unsigned long long)id);
+					OSUtils::rename(p1,p2);
 
-				_memberChanged(old,record,true);
+					_memberChanged(old,record,true);
+				}
 			}
 		} else if (objtype == "trace") {
 			const std::string id = record["id"];

+ 1 - 0
controller/FileDB.hpp

@@ -31,6 +31,7 @@ public:
 	virtual ~FileDB();
 
 	virtual bool waitForReady();
+	virtual bool isReady();
 	virtual void save(nlohmann::json *orig,nlohmann::json &record);
 	virtual void eraseNetwork(const uint64_t networkId);
 	virtual void eraseMember(const uint64_t networkId,const uint64_t memberId);

+ 10 - 1
controller/RethinkDB.cpp

@@ -263,9 +263,13 @@ RethinkDB::RethinkDB(EmbeddedNetworkController *const nc,const Identity &myId,co
 			std::unique_ptr<R::Connection> rdb;
 			while (_run == 1) {
 				try {
-					if (!rdb)
+					if (!rdb) {
+						_connected = 0;
 						rdb = R::connect(this->_host,this->_port,this->_auth);
+					}
+
 					if (rdb) {
+						_connected = 1;
 						R::Array batch;
 						R::Object tmpobj;
 
@@ -434,6 +438,11 @@ bool RethinkDB::waitForReady()
 	return true;
 }
 
+bool RethinkDB::isReady()
+{
+	return ((_ready)&&(_connected));
+}
+
 void RethinkDB::save(nlohmann::json *orig,nlohmann::json &record)
 {
 	if (!record.is_object()) // sanity check

+ 2 - 2
controller/RethinkDB.hpp

@@ -41,6 +41,7 @@ public:
 	virtual ~RethinkDB();
 
 	virtual bool waitForReady();
+	virtual bool isReady();
 	virtual void save(nlohmann::json *orig,nlohmann::json &record);
 	virtual void eraseNetwork(const uint64_t networkId);
 	virtual void eraseMember(const uint64_t networkId,const uint64_t memberId);
@@ -72,8 +73,7 @@ protected:
 	std::thread _heartbeatThread;
 
 	mutable std::mutex _readyLock; // locked until ready
-	std::atomic<int> _ready;
-	std::atomic<int> _run;
+	std::atomic<int> _ready,_connected,_run;
 	mutable volatile bool _waitNoticePrinted;
 };
 

+ 6 - 0
debian/changelog

@@ -1,3 +1,9 @@
+zerotier-one (1.2.12) unstable; urgency=medium
+
+  * See https://github.com/zerotier/ZeroTierOne for release notes.
+
+ -- Adam Ierymenko <[email protected]>  Tue, 25 Jul 2018 01:00:00 -0700
+
 zerotier-one (1.2.10) unstable; urgency=medium
 
   * See https://github.com/zerotier/ZeroTierOne for release notes.

+ 4 - 0
debian/ufw-zerotier-one

@@ -0,0 +1,4 @@
+[zerotier-one]
+title=ZeroTier One
+description=A planetary Ethernet switch
+ports=9993/udp

+ 2 - 1
debian/zerotier-one.service

@@ -1,6 +1,7 @@
 [Unit]
 Description=ZeroTier One
-After=network.target
+After=network-online.target
+Wants=network-online.target
 
 [Service]
 ExecStart=/usr/sbin/zerotier-one

+ 1 - 1
ext/installfiles/mac/ZeroTier One.pkgproj

@@ -664,7 +664,7 @@
 			<key>USE_HFS+_COMPRESSION</key>
 			<false/>
 			<key>VERSION</key>
-			<string>1.2.10</string>
+			<string>1.2.12</string>
 		</dict>
 		<key>PROJECT_COMMENTS</key>
 		<dict>

+ 4 - 4
ext/installfiles/windows/ZeroTier One.aip

@@ -27,10 +27,10 @@
     <ROW Property="CTRLS" Value="2"/>
     <ROW Property="MSIFASTINSTALL" MultiBuildValue="DefaultBuild:2"/>
     <ROW Property="Manufacturer" Value="ZeroTier, Inc."/>
-    <ROW Property="ProductCode" Value="1033:{A400C1B3-BF08-4CCE-A13A-60B98FA41CD2} " Type="16"/>
+    <ROW Property="ProductCode" Value="1033:{855E8629-580C-4BDF-8B59-B9290C7E7BA5} " Type="16"/>
     <ROW Property="ProductLanguage" Value="1033"/>
     <ROW Property="ProductName" Value="ZeroTier One"/>
-    <ROW Property="ProductVersion" Value="1.2.10" Type="32"/>
+    <ROW Property="ProductVersion" Value="1.2.12" Type="32"/>
     <ROW Property="REBOOT" MultiBuildValue="DefaultBuild:ReallySuppress"/>
     <ROW Property="RUNAPPLICATION" Value="1" Type="4"/>
     <ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND;AI_SETUPEXEPATH;SETUPEXEDIR"/>
@@ -64,7 +64,7 @@
     <ROW Directory="x86_Dir" Directory_Parent="tapwindows_Dir" DefaultDir="x86"/>
   </COMPONENT>
   <COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent">
-    <ROW Component="AI_CustomARPName" ComponentId="{58E98F1B-5626-4810-A5A2-AD71DCF3FC09}" Directory_="APPDIR" Attributes="4" KeyPath="DisplayName" Options="1"/>
+    <ROW Component="AI_CustomARPName" ComponentId="{92D9A995-E340-41B2-98F5-F2DB3F6E8AD8}" Directory_="APPDIR" Attributes="4" KeyPath="DisplayName" Options="1"/>
     <ROW Component="AI_DisableModify" ComponentId="{020DCABD-5D56-49B9-AF48-F07F0B55E590}" Directory_="APPDIR" Attributes="4" KeyPath="NoModify" Options="1"/>
     <ROW Component="AI_ExePath" ComponentId="{8E02B36C-7A19-429B-A93E-77A9261AC918}" Directory_="APPDIR" Attributes="4" KeyPath="AI_ExePath"/>
     <ROW Component="Hardcodet.Wpf.TaskbarNotification.dll" ComponentId="{BEA825AF-2555-44AF-BE40-47FFC16DCBA6}" Directory_="APPDIR" Attributes="0" KeyPath="Hardcodet.Wpf.TaskbarNotification.dll"/>
@@ -454,7 +454,7 @@
     <ROW XmlAttribute="xsischemaLocation" XmlElement="swidsoftware_identification_tag" Name="xsi:schemaLocation" Flags="14" Order="3" Value="http://standards.iso.org/iso/19770/-2/2008/schema.xsd software_identification_tag.xsd"/>
   </COMPONENT>
   <COMPONENT cid="caphyon.advinst.msicomp.XmlElementComponent">
-    <ROW XmlElement="swidbuild" ParentElement="swidnumeric" Name="swid:build" Condition="1" Order="2" Flags="14" Text="10"/>
+    <ROW XmlElement="swidbuild" ParentElement="swidnumeric" Name="swid:build" Condition="1" Order="2" Flags="14" Text="12"/>
     <ROW XmlElement="swidentitlement_required_indicator" ParentElement="swidsoftware_identification_tag" Name="swid:entitlement_required_indicator" Condition="1" Order="0" Flags="14" Text="false"/>
     <ROW XmlElement="swidmajor" ParentElement="swidnumeric" Name="swid:major" Condition="1" Order="0" Flags="14" Text="1"/>
     <ROW XmlElement="swidminor" ParentElement="swidnumeric" Name="swid:minor" Condition="1" Order="1" Flags="14" Text="2"/>

+ 1 - 1
ext/installfiles/windows/chocolatey/zerotier-one/zerotier-one.nuspec

@@ -26,7 +26,7 @@ This is a nuspec. It mostly adheres to https://docs.nuget.org/create/Nuspec-Refe
     <!-- version should MATCH as closely as possible with the underlying software -->
     <!-- Is the version a prerelease of a version? https://docs.nuget.org/create/versioning#creating-prerelease-packages -->
     <!-- Note that unstable versions like 0.0.1 can be considered a released version, but it's possible that one can release a 0.0.1-beta before you release a 0.0.1 version. If the version number is final, that is considered a released version and not a prerelease. -->
-    <version>1.2.10</version>
+    <version>1.2.12</version>
     <!-- <packageSourceUrl>Where is this Chocolatey package located (think GitHub)? packageSourceUrl is highly recommended for the community feed</packageSourceUrl>-->
     <!-- owners is a poor name for maintainers of the package. It sticks around by this name for compatibility reasons. It basically means you. -->
     <!--<owners>ZeroTier, Inc.</owners>-->

+ 8 - 0
node/Constants.hpp

@@ -193,6 +193,14 @@
  */
 #define ZT_RX_QUEUE_SIZE 64
 
+/**
+ * Size of TX queue
+ *
+ * This is about 2mb, and can be decreased for small devices. A queue smaller
+ * than about 4 is probably going to cause a lot of lost packets.
+ */
+#define ZT_TX_QUEUE_SIZE 64
+
 /**
  * Length of secret key in bytes -- 256-bit -- do not change
  */

+ 1 - 1
node/Packet.cpp

@@ -332,7 +332,7 @@ static const int LZ4_minLength = (MFLIMIT+1);
 
 #define LZ4_STATIC_ASSERT(c)    { enum { LZ4_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
 
-static inline unsigned LZ4_NbCommonBytes (register reg_t val)
+static inline unsigned LZ4_NbCommonBytes (reg_t val)
 {
 	if (LZ4_isLittleEndian()) {
 	    if (sizeof(val)==8) {

+ 8 - 0
node/Switch.cpp

@@ -121,6 +121,7 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
 						// seeing a Packet::Fragment?
 
 						RXQueueEntry *const rq = _findRXQueueEntry(fragmentPacketId);
+						Mutex::Lock rql(rq->lock);
 						if (rq->packetId != fragmentPacketId) {
 							// No packet found, so we received a fragment without its head.
 
@@ -203,6 +204,7 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
 					);
 
 					RXQueueEntry *const rq = _findRXQueueEntry(packetId);
+					Mutex::Lock rql(rq->lock);
 					if (rq->packetId != packetId) {
 						// If we have no other fragments yet, create an entry and save the head
 
@@ -237,6 +239,7 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
 					IncomingPacket packet(data,len,path,now);
 					if (!packet.tryDecode(RR,tPtr)) {
 						RXQueueEntry *const rq = _nextRXQueueEntry();
+						Mutex::Lock rql(rq->lock);
 						rq->timestamp = now;
 						rq->packetId = packet.packetId();
 						rq->frag0 = packet;
@@ -762,6 +765,9 @@ void Switch::send(void *tPtr,Packet &packet,bool encrypt)
 	if (!_trySend(tPtr,packet,encrypt)) {
 		{
 			Mutex::Lock _l(_txQueue_m);
+			if (_txQueue.size() >= ZT_TX_QUEUE_SIZE) {
+				_txQueue.pop_front();
+			}
 			_txQueue.push_back(TXQueueEntry(dest,RR->node->now(),packet,encrypt));
 		}
 		if (!RR->topology->getPeer(tPtr,dest))
@@ -801,6 +807,7 @@ void Switch::doAnythingWaitingForPeer(void *tPtr,const SharedPtr<Peer> &peer)
 	const int64_t now = RR->node->now();
 	for(unsigned int ptr=0;ptr<ZT_RX_QUEUE_SIZE;++ptr) {
 		RXQueueEntry *const rq = &(_rxQueue[ptr]);
+		Mutex::Lock rql(rq->lock);
 		if ((rq->timestamp)&&(rq->complete)) {
 			if ((rq->frag0.tryDecode(RR,tPtr))||((now - rq->timestamp) > ZT_RECEIVE_QUEUE_TIMEOUT))
 				rq->timestamp = 0;
@@ -852,6 +859,7 @@ unsigned long Switch::doTimerTasks(void *tPtr,int64_t now)
 
 	for(unsigned int ptr=0;ptr<ZT_RX_QUEUE_SIZE;++ptr) {
 		RXQueueEntry *const rq = &(_rxQueue[ptr]);
+		Mutex::Lock rql(rq->lock);
 		if ((rq->timestamp)&&(rq->complete)) {
 			if ((rq->frag0.tryDecode(RR,tPtr))||((now - rq->timestamp) > ZT_RECEIVE_QUEUE_TIMEOUT)) {
 				rq->timestamp = 0;

+ 1 - 0
node/Switch.hpp

@@ -223,6 +223,7 @@ private:
 		unsigned int totalFragments; // 0 if only frag0 received, waiting for frags
 		uint32_t haveFragments; // bit mask, LSB to MSB
 		volatile bool complete; // if true, packet is complete
+		Mutex lock;
 	};
 	RXQueueEntry _rxQueue[ZT_RX_QUEUE_SIZE];
 	AtomicCounter _rxQueuePtr;

Plik diff jest za duży
+ 2 - 2
node/Topology.cpp


+ 2 - 1
osdep/Binder.hpp

@@ -293,7 +293,7 @@ public:
 #else
 			const bool gotViaProc = false;
 #endif
-
+#if !defined(ZT_SDK) || !defined(__ANDROID__) // getifaddrs() freeifaddrs() not available on Android
 			if (!gotViaProc) {
 				struct ifaddrs *ifatbl = (struct ifaddrs *)0;
 				struct ifaddrs *ifa;
@@ -325,6 +325,7 @@ public:
 					interfacesEnumerated = false;
 				}
 			}
+#endif
 
 #endif
 		} else {

+ 25 - 125
osdep/ManagedRoute.cpp

@@ -46,18 +46,13 @@
 #include <sys/wait.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#ifndef ZT_SDK
 #include <net/route.h>
-#ifdef __LINUX__
-#include <sys/ioctl.h>
-#include <asm/types.h>
-#include <linux/rtnetlink.h>
-#include <sys/socket.h>
-#include "../osdep/LinuxNetLink.hpp"
 #endif
+#include <net/if.h>
 #ifdef __BSD__
 #include <net/if_dl.h>
 #include <sys/sysctl.h>
-#include <net/if.h>
 #endif
 #include <ifaddrs.h>
 #endif
@@ -116,6 +111,7 @@ struct _RTE
 #ifdef __BSD__ // ------------------------------------------------------------
 #define ZT_ROUTING_SUPPORT_FOUND 1
 
+#ifndef ZT_SDK
 static std::vector<_RTE> _getRTEs(const InetAddress &target,bool contains)
 {
 	std::vector<_RTE> rtes;
@@ -250,9 +246,11 @@ static std::vector<_RTE> _getRTEs(const InetAddress &target,bool contains)
 
 	return rtes;
 }
+#endif
 
 static void _routeCmd(const char *op,const InetAddress &target,const InetAddress &via,const char *ifscope,const char *localInterface)
 {
+	//char f1[1024],f2[1024]; printf("%s %s %s %s %s\n",op,target.toString(f1),via.toString(f2),ifscope,localInterface);
 	long p = (long)fork();
 	if (p > 0) {
 		int exitcode = -1;
@@ -284,127 +282,27 @@ static void _routeCmd(const char *op,const InetAddress &target,const InetAddress
 #ifdef __LINUX__ // ----------------------------------------------------------
 #define ZT_ROUTING_SUPPORT_FOUND 1
 
-static void _routeCmd(const char *op, const InetAddress &target, const InetAddress &via, const InetAddress &src, const char *localInterface) 
+static void _routeCmd(const char *op,const InetAddress &target,const InetAddress &via,const char *localInterface)
 {
-	char targetStr[64] = {0};
-	char viaStr[64] = {0};
-	InetAddress nmsk = target.netmask();
-	char nmskStr[64] = {0};
-	fprintf(stderr, "Received Route Cmd: %s target: %s via: %s netmask: %s localInterface: %s\n", op, target.toString(targetStr), via.toString(viaStr), nmsk.toString(nmskStr), localInterface);
-
-
-	if ((strcmp(op, "add") == 0 || strcmp(op, "replace") == 0)) {
-		LinuxNetLink::getInstance().addRoute(target, via, src, localInterface);
-	} else if ((strcmp(op, "remove") == 0 || strcmp(op, "del") == 0)) {
-		LinuxNetLink::getInstance().delRoute(target, via, src, localInterface);
-	}
-	return;
-
-	
-	int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);;
-	struct rtentry route = {0};
-
-	if (target.ss_family == AF_INET) {
-		struct sockaddr_in *target_in = (struct sockaddr_in*)&target;
-		struct sockaddr_in *via_in = (struct sockaddr_in*)&via;
-		InetAddress netmask = target.netmask();
-		struct sockaddr_in *netmask_in = (struct sockaddr_in*)&netmask;
-
-		struct sockaddr_in *addr = NULL;
-
-		// set target
-		addr = (struct sockaddr_in *)&route.rt_dst;
-		addr->sin_family = AF_INET;
-		addr->sin_addr = target_in->sin_addr;
-
-		// set netmask
-		addr = (struct sockaddr_in *)&route.rt_genmask;
-		addr->sin_family = AF_INET;
-		addr->sin_addr = netmask_in->sin_addr;
-
-		route.rt_dev = const_cast<char*>(localInterface);
-
-		if (via) {
-			// set the gateway
-			addr = (struct sockaddr_in *)&route.rt_gateway;
-			addr->sin_family = AF_INET;
-			addr->sin_addr = via_in->sin_addr;
-
-			route.rt_flags = RTF_UP | RTF_GATEWAY;
-		} else if ((localInterface)&&(localInterface[0])) {
-			route.rt_flags = RTF_UP;//| RTF_HOST;
-		}
-	}
-	else if (target.ss_family == AF_INET6) 
-	{
-		struct sockaddr_in6 *addr = NULL;
-
-		// set target
-		addr = (struct sockaddr_in6 *)&route.rt_dst;
-		addr->sin6_family = AF_INET6;
-		memcpy(&addr->sin6_addr, &((struct sockaddr_in6*)&target)->sin6_addr, sizeof(struct in6_addr));
-
-		//set netmask
-		addr = (struct sockaddr_in6 *)&route.rt_genmask;
-		addr->sin6_family = AF_INET6;
-		InetAddress netmask = target.netmask();
-		memcpy(&addr->sin6_addr, &((struct sockaddr_in6*)&netmask)->sin6_addr, sizeof(struct in6_addr));
-
+	long p = (long)fork();
+	if (p > 0) {
+		int exitcode = -1;
+		::waitpid(p,&exitcode,0);
+	} else if (p == 0) {
+		::close(STDOUT_FILENO);
+		::close(STDERR_FILENO);
+		char ipbuf[64],ipbuf2[64];
 		if (via) {
-			// set the gateway
-			addr = (struct sockaddr_in6*)&route.rt_gateway;
-			addr->sin6_family = AF_INET;
-			memcpy(&addr->sin6_addr, &((struct sockaddr_in6*)&via)->sin6_addr, sizeof(struct in6_addr));
-
-			route.rt_flags = RTF_UP | RTF_GATEWAY;
+			::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,(target.ss_family == AF_INET6) ? "-6" : "-4","route",op,target.toString(ipbuf),"via",via.toIpString(ipbuf2),(const char *)0);
+			::execl(ZT_LINUX_IP_COMMAND_2,ZT_LINUX_IP_COMMAND_2,(target.ss_family == AF_INET6) ? "-6" : "-4","route",op,target.toString(ipbuf),"via",via.toIpString(ipbuf2),(const char *)0);
 		} else if ((localInterface)&&(localInterface[0])) {
-			route.rt_dev = const_cast<char*>(localInterface);
-			route.rt_flags = RTF_UP;
+			::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,(target.ss_family == AF_INET6) ? "-6" : "-4","route",op,target.toString(ipbuf),"dev",localInterface,(const char *)0);
+			::execl(ZT_LINUX_IP_COMMAND_2,ZT_LINUX_IP_COMMAND_2,(target.ss_family == AF_INET6) ? "-6" : "-4","route",op,target.toString(ipbuf),"dev",localInterface,(const char *)0);
 		}
+		::_exit(-1);
 	}
-
-	unsigned long ctl = -1;
-	if (strcmp(op, "add") == 0 || strcmp(op, "replace") == 0) {
-		ctl = SIOCADDRT;
-	} else if (strcmp(op, "remove") == 0 || strcmp(op, "del") == 0) {
-		ctl = SIOCDELRT;
-	} else {
-		close(fd);
-		return;
-	}
-
-	if ( ioctl(fd, ctl, &route)) {
-		fprintf(stderr, "Error adding route: %s\n", strerror(errno));
-		close(fd);
-		::exit(1);
-	}
-	close(fd);
 }
 
-// static void _routeCmd(const char *op,const InetAddress &target,const InetAddress &via,const char *localInterface)
-// {
-// 	// long p = (long)fork();
-// 	// if (p > 0) {
-// 	// 	int exitcode = -1;
-// 	// 	::waitpid(p,&exitcode,0);
-// 	// } else if (p == 0) {
-// 	// 	::close(STDOUT_FILENO);
-// 	// 	::close(STDERR_FILENO);
-// 		char ipbuf[64],ipbuf2[64];
-
-		
-
-// 		if (via) {
-// 			::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,(target.ss_family == AF_INET6) ? "-6" : "-4","route",op,target.toString(ipbuf),"via",via.toIpString(ipbuf2),(const char *)0);
-// 			::execl(ZT_LINUX_IP_COMMAND_2,ZT_LINUX_IP_COMMAND_2,(target.ss_family == AF_INET6) ? "-6" : "-4","route",op,target.toString(ipbuf),"via",via.toIpString(ipbuf2),(const char *)0);
-// 		} else if ((localInterface)&&(localInterface[0])) {
-// 			::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,(target.ss_family == AF_INET6) ? "-6" : "-4","route",op,target.toString(ipbuf),"dev",localInterface,(const char *)0);
-// 			::execl(ZT_LINUX_IP_COMMAND_2,ZT_LINUX_IP_COMMAND_2,(target.ss_family == AF_INET6) ? "-6" : "-4","route",op,target.toString(ipbuf),"dev",localInterface,(const char *)0);
-// 		}
-// 	// 	::_exit(-1);
-// 	// }
-// }
-
 #endif // __LINUX__ ----------------------------------------------------------
 
 #ifdef __WINDOWS__ // --------------------------------------------------------
@@ -515,6 +413,7 @@ static bool _winHasRoute(const NET_LUID &interfaceLuid, const NET_IFINDEX &inter
  * Linux default route override implies asymmetric routes, which then
  * trigger Linux's "martian packet" filter. */
 
+#ifndef ZT_SDK
 bool ManagedRoute::sync()
 {
 #ifdef __WINDOWS__
@@ -601,11 +500,11 @@ bool ManagedRoute::sync()
 
 	if (!_applied.count(leftt)) {
 		_applied[leftt] = false; // boolean unused
-		_routeCmd("replace",leftt,_via,_src,_device);
+		_routeCmd("replace",leftt,_via,(_via) ? (const char *)0 : _device);
 	}
 	if ((rightt)&&(!_applied.count(rightt))) {
 		_applied[rightt] = false; // boolean unused
-		_routeCmd("replace",rightt,_via,_src,_device);
+		_routeCmd("replace",rightt,_via,(_via) ? (const char *)0 : _device);
 	}
 
 #endif // __LINUX__ ----------------------------------------------------------
@@ -625,6 +524,7 @@ bool ManagedRoute::sync()
 
 	return true;
 }
+#endif
 
 void ManagedRoute::remove()
 {
@@ -652,7 +552,7 @@ void ManagedRoute::remove()
 #endif // __BSD__ ------------------------------------------------------------
 
 #ifdef __LINUX__ // ----------------------------------------------------------
-		_routeCmd("del",r->first,_via,_src,_device);
+		_routeCmd("del",r->first,_via,(_via) ? (const char *)0 : _device);
 #endif // __LINUX__ ----------------------------------------------------------
 
 #ifdef __WINDOWS__ // --------------------------------------------------------
@@ -668,4 +568,4 @@ void ManagedRoute::remove()
 	_applied.clear();
 }
 
-} // namespace ZeroTier
+} // namespace ZeroTier

+ 5 - 1
rule-compiler/rule-compiler.js

@@ -229,12 +229,16 @@ function _cleanMac(m)
 {
 	m = m.toLowerCase();
 	var m2 = '';
+	let charcount = 0;
 	for(let i=0;((i<m.length)&&(m2.length<17));++i) {
 		let c = m.charAt(i);
 		if ("0123456789abcdef".indexOf(c) >= 0) {
 			m2 += c;
-			if ((m2.length > 0)&&(m2.length !== 17)&&((m2.length & 1) === 0))
+			charcount++;
+			if ((m2.length > 0)&&(m2.length !== 17)&&(charcount >= 2) ) {
 				m2 += ':';
+				charcount=0;
+			}
 		}
 	}
 	return m2;

+ 52 - 72
service/OneService.cpp

@@ -161,7 +161,6 @@ namespace ZeroTier { typedef BSDEthernetTap EthernetTap; }
 
 // How often to check for local interface addresses
 #define ZT_LOCAL_INTERFACE_CHECK_INTERVAL 60000
-#define ZT_MULTIPATH_LOCAL_INTERFACE_CHECK_INTERVAL 5000
 
 // Maximum write buffer size for outgoing TCP connections (sanity limit)
 #define ZT_TCP_MAX_WRITEQ_SIZE 33554432
@@ -455,7 +454,7 @@ public:
 	unsigned int _primaryPort;
 	volatile unsigned int _udpPortPickerCounter;
 
-	// Local configuration and memoized information from it
+	// Local configuration and memo-ized information from it
 	json _localConfig;
 	Hashtable< uint64_t,std::vector<InetAddress> > _v4Hints;
 	Hashtable< uint64_t,std::vector<InetAddress> > _v6Hints;
@@ -471,7 +470,7 @@ public:
 	 * To attempt to handle NAT/gateway craziness we use three local UDP ports:
 	 *
 	 * [0] is the normal/default port, usually 9993
-	 * [1] is a port derived from our ZeroTier address
+	 * [1] is a port dervied from our ZeroTier address
 	 * [2] is a port computed from the normal/default for use with uPnP/NAT-PMP mappings
 	 *
 	 * [2] exists because on some gateways trying to do regular NAT-t interferes
@@ -581,7 +580,6 @@ public:
 		_ports[0] = 0;
 		_ports[1] = 0;
 		_ports[2] = 0;
-
 #if ZT_VAULT_SUPPORT
 		curl_global_init(CURL_GLOBAL_DEFAULT);
 #endif
@@ -625,10 +623,25 @@ public:
 				_authToken = _trimString(_authToken);
 			}
 
+			{
+				struct ZT_Node_Callbacks cb;
+				cb.version = 0;
+				cb.stateGetFunction = SnodeStateGetFunction;
+				cb.statePutFunction = SnodeStatePutFunction;
+				cb.wirePacketSendFunction = SnodeWirePacketSendFunction;
+				cb.virtualNetworkFrameFunction = SnodeVirtualNetworkFrameFunction;
+				cb.virtualNetworkConfigFunction = SnodeVirtualNetworkConfigFunction;
+				cb.eventCallback = SnodeEventCallback;
+				cb.pathCheckFunction = SnodePathCheckFunction;
+				cb.pathLookupFunction = SnodePathLookupFunction;
+				_node = new Node(this,(void *)0,&cb,OSUtils::now());
+			}
+
 			// Read local configuration
-			std::map<InetAddress,ZT_PhysicalPathConfiguration> ppc;
 			std::vector<InetAddress> explicitBind;
 			{
+				std::map<InetAddress,ZT_PhysicalPathConfiguration> ppc;
+
 				// LEGACY: support old "trustedpaths" flat file
 				FILE *trustpaths = fopen((_homePath + ZT_PATH_SEPARATOR_S "trustedpaths").c_str(),"r");
 				if (trustpaths) {
@@ -707,35 +720,17 @@ public:
 						}
 					}
 				}
+
+				// Set trusted paths if there are any
+				if (ppc.size() > 0) {
+					for(std::map<InetAddress,ZT_PhysicalPathConfiguration>::iterator i(ppc.begin());i!=ppc.end();++i)
+						_node->setPhysicalPathConfiguration(reinterpret_cast<const struct sockaddr_storage *>(&(i->first)),&(i->second));
+				}
 			}
 
 			// Apply other runtime configuration from local.conf
 			applyLocalConfig();
 
-			{
-				struct ZT_Node_Callbacks cb;
-				cb.version = 0;
-				cb.stateGetFunction = SnodeStateGetFunction;
-				cb.statePutFunction = SnodeStatePutFunction;
-				cb.wirePacketSendFunction = SnodeWirePacketSendFunction;
-				cb.virtualNetworkFrameFunction = SnodeVirtualNetworkFrameFunction;
-				cb.virtualNetworkConfigFunction = SnodeVirtualNetworkConfigFunction;
-				cb.eventCallback = SnodeEventCallback;
-				cb.pathCheckFunction = SnodePathCheckFunction;
-				cb.pathLookupFunction = SnodePathLookupFunction;
-				_node = new Node(this, (void *)0, &cb, OSUtils::now());
-			}
-
-			// Apply software update specific configuration from local.conf
-			applySoftwareUpdateLocalConfig();
-
-			// Set trusted paths if there are any
-			if (ppc.size() > 0) {
-				for(std::map<InetAddress,ZT_PhysicalPathConfiguration>::iterator i(ppc.begin());i!=ppc.end();++i)
-					_node->setPhysicalPathConfiguration(reinterpret_cast<const struct sockaddr_storage *>(&(i->first)),&(i->second));
-			}
-			ppc.clear();
-
 			// Make sure we can use the primary port, and hunt for one if configured to do so
 			const int portTrials = (_primaryPort == 0) ? 256 : 1; // if port is 0, pick random
 			for(int k=0;k<portTrials;++k) {
@@ -853,8 +848,8 @@ public:
 			_lastRestart = clockShouldBe;
 			int64_t lastTapMulticastGroupCheck = 0;
 			int64_t lastBindRefresh = 0;
-			int64_t lastMultipathModeUpdate = 0;
 			int64_t lastUpdateCheck = clockShouldBe;
+			int64_t lastMultipathModeUpdate = 0;
 			int64_t lastCleanedPeersDb = 0;
 			int64_t lastLocalInterfaceAddressCheck = (clockShouldBe - ZT_LOCAL_INTERFACE_CHECK_INTERVAL) + 15000; // do this in 15s to give portmapper time to configure and other things time to settle
 			for(;;) {
@@ -885,10 +880,8 @@ public:
 						_updater->apply();
 				}
 
-				// Refresh bindings
-				// Do this more frequently when multipath bonding is enabled
-				int interfaceRefreshPeriod = _multipathMode ? ZT_MULTIPATH_BINDER_REFRESH_PERIOD : ZT_BINDER_REFRESH_PERIOD;
-				if (((now - lastBindRefresh) >= interfaceRefreshPeriod)||(restarted)) {
+				// Refresh bindings in case device's interfaces have changed, and also sync routes to update any shadow routes (e.g. shadow default)
+				if (((now - lastBindRefresh) >= (_multipathMode ? ZT_BINDER_REFRESH_PERIOD / 8 : ZT_BINDER_REFRESH_PERIOD))||(restarted)) {
 					lastBindRefresh = now;
 					unsigned int p[3];
 					unsigned int pc = 0;
@@ -906,7 +899,7 @@ public:
 					}
 				}
 				// Update multipath mode (if needed)
-				if (((now - lastMultipathModeUpdate) >= interfaceRefreshPeriod)||(restarted)) {
+				if (((now - lastMultipathModeUpdate) >= ZT_BINDER_REFRESH_PERIOD / 8)||(restarted)) {
 					lastMultipathModeUpdate = now;
 					_node->setMultipathMode(_multipathMode);
 				}
@@ -945,8 +938,7 @@ public:
 				}
 
 				// Sync information about physical network interfaces
-				int interfaceAddressCheckInterval = _multipathMode ? ZT_MULTIPATH_LOCAL_INTERFACE_CHECK_INTERVAL : ZT_LOCAL_INTERFACE_CHECK_INTERVAL;
-				if ((now - lastLocalInterfaceAddressCheck) >= interfaceAddressCheckInterval) {
+				if ((now - lastLocalInterfaceAddressCheck) >= (_multipathMode ? ZT_LOCAL_INTERFACE_CHECK_INTERVAL / 8 : ZT_LOCAL_INTERFACE_CHECK_INTERVAL)) {
 					lastLocalInterfaceAddressCheck = now;
 
 					_node->clearLocalInterfaceAddresses();
@@ -1146,6 +1138,8 @@ public:
 					else urlArgs[a->substr(0,eqpos)] = a->substr(eqpos + 1);
 				}
 			}
+		} else {
+			return 404;
 		}
 
 		bool isAuth = false;
@@ -1163,7 +1157,6 @@ public:
 #ifdef __SYNOLOGY__
 		// Authenticate via Synology's built-in cgi script
 		if (!isAuth) {
-			// Parse out url args
 			int synotoken_pos = path.find("SynoToken");
 			int argpos = path.find("?");
 			if(synotoken_pos != std::string::npos && argpos != std::string::npos) {
@@ -1176,7 +1169,6 @@ public:
 				setenv("HTTP_COOKIE", cookie_val.c_str(), true);
 				setenv("HTTP_X_SYNO_TOKEN", synotoken_val.c_str(), true);
 				setenv("REMOTE_ADDR", ah2->second.c_str(),true);
-				// Check Synology web auth
 				char user[256], buf[1024];
 				FILE *fp = NULL;
 				bzero(user, 256);
@@ -1574,6 +1566,22 @@ public:
 		}
 		_portMappingEnabled = OSUtils::jsonBool(settings["portMappingEnabled"],true);
 
+#ifndef ZT_SDK
+		const std::string up(OSUtils::jsonString(settings["softwareUpdate"],ZT_SOFTWARE_UPDATE_DEFAULT));
+		const bool udist = OSUtils::jsonBool(settings["softwareUpdateDist"],false);
+		if (((up == "apply")||(up == "download"))||(udist)) {
+			if (!_updater)
+				_updater = new SoftwareUpdater(*_node,_homePath);
+			_updateAutoApply = (up == "apply");
+			_updater->setUpdateDistribution(udist);
+			_updater->setChannel(OSUtils::jsonString(settings["softwareUpdateChannel"],ZT_SOFTWARE_UPDATE_DEFAULT_CHANNEL));
+		} else {
+			delete _updater;
+			_updater = (SoftwareUpdater *)0;
+			_updateAutoApply = false;
+		}
+#endif
+
 		json &ignoreIfs = settings["interfacePrefixBlacklist"];
 		if (ignoreIfs.is_array()) {
 			for(unsigned long i=0;i<ignoreIfs.size();++i) {
@@ -1591,6 +1599,7 @@ public:
 					_allowManagementFrom.push_back(nw);
 			}
 		}
+	}
 
 #if ZT_VAULT_SUPPORT
 		json &vault = settings["vault"];
@@ -1632,29 +1641,7 @@ public:
 			_vaultEnabled = true;
 		}
 #endif
-	}
 
-	void applySoftwareUpdateLocalConfig()
-	{
-#ifndef ZT_SDK
-		json lc(_localConfig);
-		json &settings = lc["settings"];
-		const std::string up(OSUtils::jsonString(settings["softwareUpdate"],ZT_SOFTWARE_UPDATE_DEFAULT));
-		const bool udist = OSUtils::jsonBool(settings["softwareUpdateDist"],false);
-		if (((up == "apply")||(up == "download"))||(udist)) {
-			if (!_updater)
-				_updater = new SoftwareUpdater(*_node,_homePath);
-			_updateAutoApply = (up == "apply");
-			_updater->setUpdateDistribution(udist);
-			_updater->setChannel(OSUtils::jsonString(settings["softwareUpdateChannel"],ZT_SOFTWARE_UPDATE_DEFAULT_CHANNEL));
-		} else {
-			delete _updater;
-			_updater = (SoftwareUpdater *)0;
-			_updateAutoApply = false;
-		}
-#endif
-	}
-	
 	// Checks if a managed IP or route target is allowed
 	bool checkIfManagedIsAllowed(const NetworkState &n,const InetAddress &target)
 	{
@@ -1747,12 +1734,10 @@ public:
 			// Nuke applied routes that are no longer in n.config.routes[] and/or are not allowed
 			for(std::list< SharedPtr<ManagedRoute> >::iterator mr(n.managedRoutes.begin());mr!=n.managedRoutes.end();) {
 				bool haveRoute = false;
-
 				if ( (checkIfManagedIsAllowed(n,(*mr)->target())) && (((*mr)->via().ss_family != (*mr)->target().ss_family)||(!matchIpOnly(myIps,(*mr)->via()))) ) {
 					for(unsigned int i=0;i<n.config.routeCount;++i) {
 						const InetAddress *const target = reinterpret_cast<const InetAddress *>(&(n.config.routes[i].target));
 						const InetAddress *const via = reinterpret_cast<const InetAddress *>(&(n.config.routes[i].via));
-
 						if ( ((*mr)->target() == *target) && ( ((via->ss_family == target->ss_family)&&((*mr)->via().ipsEqual(*via))) || (strcmp(tapdev,(*mr)->device())==0) ) ) {
 							haveRoute = true;
 							break;
@@ -1770,6 +1755,7 @@ public:
 			for(unsigned int i=0;i<n.config.routeCount;++i) {
 				const InetAddress *const target = reinterpret_cast<const InetAddress *>(&(n.config.routes[i].target));
 				const InetAddress *const via = reinterpret_cast<const InetAddress *>(&(n.config.routes[i].via));
+
 				InetAddress *src = NULL;
 				for (unsigned int j=0; j<n.config.assignedAddressCount; ++j) {
 					const InetAddress *const tmp = reinterpret_cast<const InetAddress *>(&(n.config.assignedAddresses[j]));
@@ -1788,18 +1774,15 @@ public:
 				bool haveRoute = false;
 
 				// Ignore routes implied by local managed IPs since adding the IP adds the route
-				// Commented out to fix ticket #600 (disappearing routes on macOS). Remove this block when we're sure there's no side effects
-				/*
 				for(std::vector<InetAddress>::iterator ip(n.managedIps.begin());ip!=n.managedIps.end();++ip) {
 					if ((target->netmaskBits() == ip->netmaskBits())&&(target->containsAddress(*ip))) {
 						haveRoute = true;
 						break;
 					}
 				}
-				*/
 				if (haveRoute)
 					continue;
-
+#ifndef ZT_SDK
 				// If we've already applied this route, just sync it and continue
 				for(std::list< SharedPtr<ManagedRoute> >::iterator mr(n.managedRoutes.begin());mr!=n.managedRoutes.end();++mr) {
 					if ( ((*mr)->target() == *target) && ( ((via->ss_family == target->ss_family)&&((*mr)->via().ipsEqual(*via))) || (tapdev == (*mr)->device()) ) ) {
@@ -1815,6 +1798,7 @@ public:
 				n.managedRoutes.push_back(SharedPtr<ManagedRoute>(new ManagedRoute(*target,*via,*src,tapdev)));
 				if (!n.managedRoutes.back()->sync())
 					n.managedRoutes.pop_back();
+#endif
 			}
 		}
 	}
@@ -2316,7 +2300,6 @@ public:
 			// else fallback to disk
 		}
 #endif
-
 		char p[1024];
 		FILE *f;
 		bool secure = false;
@@ -2397,8 +2380,7 @@ public:
 			snprintf(token, sizeof(token), "X-Vault-Token: %s", _vaultToken.c_str());
 
 			struct curl_slist *chunk = NULL;
-		  chunk = curl_slist_append(chunk, token);
-			
+			chunk = curl_slist_append(chunk, token);
 			curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
 
 			char url[2048] = { 0 };
@@ -2423,7 +2405,6 @@ public:
 				long response_code = 0;
 				curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
 				if (response_code == 200) {
-					
 					try {
 						json payload = json::parse(response);
 						if (!payload["data"].is_null()) {
@@ -2472,7 +2453,6 @@ public:
 			// else continue file based lookup
 		}
 #endif
-
 		char p[4096];
 		switch(type) {
 			case ZT_STATE_OBJECT_IDENTITY_PUBLIC:

+ 2 - 1
service/README.md

@@ -32,7 +32,8 @@ Settings available in `local.conf` (this is not valid JSON, and JSON does not al
 		"softwareUpdateDist": true|false, /* If true, distribute software updates (only really useful to ZeroTier, Inc. itself, default is false) */
 		"interfacePrefixBlacklist": [ "XXX",... ], /* Array of interface name prefixes (e.g. eth for eth#) to blacklist for ZT traffic */
 		"allowManagementFrom": "NETWORK/bits"|null, /* If non-NULL, allow JSON/HTTP management from this IP network. Default is 127.0.0.1 only. */
-		"bind": [ "ip",... ] /* If present and non-null, bind to these IPs instead of to each interface (wildcard IP allowed) */
+		"bind": [ "ip",... ], /* If present and non-null, bind to these IPs instead of to each interface (wildcard IP allowed) */
+		"allowTcpFallbackRelay": true|false /* Allow or disallow establishment of TCP relay connections (true by default) */
 	}
 }
 ```

+ 1 - 1
version.h

@@ -40,7 +40,7 @@
 /**
  * Revision
  */
-#define ZEROTIER_ONE_VERSION_REVISION 10
+#define ZEROTIER_ONE_VERSION_REVISION 12
 
 /**
  * Build version

+ 2 - 2
windows/WinUI/AboutView.xaml

@@ -19,9 +19,9 @@
                     <Run Text="ZeroTier One"/>
                 </Paragraph>
                 <Paragraph TextAlignment="Center">
-                    <Run FontSize="14" Text="Version 1.2.10"/>
+                    <Run FontSize="14" Text="Version 1.2.12"/>
                     <LineBreak/>
-                    <Run FontSize="14" Text="(c) 2011-2017 ZeroTier, Inc."/>
+                    <Run FontSize="14" Text="(c) 2011-2018 ZeroTier, Inc."/>
                     <LineBreak/>
                     <Run FontSize="14" Text="www.zerotier.com"/>
                 </Paragraph>

+ 1 - 1
windows/WinUI/CentralAPI.cs

@@ -207,7 +207,7 @@ namespace WinUI
 
         public async Task<CentralNetwork> CreateNewNetwork()
         {
-            string networkURL = Central.ServerURL + "/api/network/";
+            string networkURL = Central.ServerURL + "/api/network?easy=1";
             CentralNetwork network = new CentralNetwork();
             network.Config = new CentralNetwork.CentralNetworkConfig();
             network.Config.Name = NetworkNameGenerator.GenerateName();

+ 4 - 1
windows/WinUI/ToolbarItem.xaml

@@ -43,7 +43,10 @@
 							<Separator/>
 							<MenuItem Header="ZeroTier Central"
 												Click="ToolbarItem_CentralClicked"/>
-								
+							<MenuItem Header="Create and Join Network"
+												Click="ToolbarItem_NewNetwork"
+												x:Name="newNetworkItem"/>
+							<Separator/>
 							<MenuItem Header="About..."
                                       Click="ToolbarItem_AboutClicked"/>
 							<MenuItem Header="Preferences..."

+ 37 - 5
windows/WinUI/ToolbarItem.xaml.cs

@@ -120,17 +120,21 @@ namespace WinUI
                 if (shouldShowOnboardProcess)
                 {
                     // TODO: Show onboarding process window (on main thread
-                    Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
-                    {
-                        PageSwitcher ps = new PageSwitcher();
-                        ps.Show();
-                    }));
+                    showOnboardProcess();
 
                     shouldShowOnboardProcess = false;
                 }
             }
         }
 
+        private void showOnboardProcess()
+        {
+            Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
+            {
+                PageSwitcher ps = new PageSwitcher();
+                ps.Show();
+            }));
+        }
         private void updateStatus(ZeroTierStatus status) 
         {
             if (status != null)
@@ -142,6 +146,15 @@ namespace WinUI
                     nodeId = status.Address;
                 }));
             }
+
+            if (CentralAPI.Instance.HasAccessToken())
+            {
+                newNetworkItem.IsEnabled = true;
+            }
+            else
+            {
+                newNetworkItem.IsEnabled = false;
+            }
         }
 
         private void ToolbarItem_NodeIDClicked(object sender, System.Windows.RoutedEventArgs e)
@@ -331,6 +344,25 @@ namespace WinUI
             }
         }
 
+        private async void ToolbarItem_NewNetwork(object sender, System.Windows.RoutedEventArgs e)
+        {
+            if (CentralAPI.Instance.HasAccessToken())
+            {
+                CentralAPI api = CentralAPI.Instance;
+                CentralNetwork newNetwork = await api.CreateNewNetwork();
+
+                APIHandler handler = APIHandler.Instance;
+                handler.JoinNetwork(this.Dispatcher, newNetwork.Id);
+
+                string nodeId = APIHandler.Instance.NodeAddress();
+                bool authorized = await CentralAPI.Instance.AuthorizeNode(nodeId, newNetwork.Id);
+            }   
+            else
+            {
+                showOnboardProcess();
+            }
+        }
+
         private void setWindowPosition(Window w)
         {
             double width = w.ActualWidth;

+ 36 - 26
windows/ZeroTierOne/ZeroTierOne.vcxproj

@@ -48,7 +48,12 @@
     <ClCompile Include="..\..\ext\miniupnpc\upnpdev.c" />
     <ClCompile Include="..\..\ext\miniupnpc\upnperrors.c" />
     <ClCompile Include="..\..\ext\miniupnpc\upnpreplyparse.c" />
-    <ClCompile Include="..\..\node\C25519.cpp" />
+    <ClCompile Include="..\..\node\C25519.cpp">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">MaxSpeed</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Default</BasicRuntimeChecks>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Default</BasicRuntimeChecks>
+    </ClCompile>
     <ClCompile Include="..\..\node\Capability.cpp" />
     <ClCompile Include="..\..\node\CertificateOfMembership.cpp" />
     <ClCompile Include="..\..\node\CertificateOfOwnership.cpp" />
@@ -64,7 +69,12 @@
     <ClCompile Include="..\..\node\Packet.cpp" />
     <ClCompile Include="..\..\node\Path.cpp" />
     <ClCompile Include="..\..\node\Peer.cpp" />
-    <ClCompile Include="..\..\node\Poly1305.cpp" />
+    <ClCompile Include="..\..\node\Poly1305.cpp">
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MaxSpeed</Optimization>
+      <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">MaxSpeed</Optimization>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Default</BasicRuntimeChecks>
+      <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Default</BasicRuntimeChecks>
+    </ClCompile>
     <ClCompile Include="..\..\node\Revocation.cpp" />
     <ClCompile Include="..\..\node\Salsa20.cpp" />
     <ClCompile Include="..\..\node\SelfAwareness.cpp" />
@@ -284,15 +294,15 @@
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
       <SDLCheck>true</SDLCheck>
-      <AdditionalIncludeDirectories>$(ProjectDir)..\..\ext\curl-7.58.0\$(PlatformTarget)\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>ZT_EXPORT;CURL_STATICLIB;ZT_VAULT_SUPPORT=1;NOMINMAX;STATICLIB;WIN32;ZT_TRACE;ZT_USE_MINIUPNPC;MINIUPNP_STATICLIB;ZT_SOFTWARE_UPDATE_DEFAULT="disable";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>
+      </AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZT_EXPORT;FD_SETSIZE=1024;NOMINMAX;STATICLIB;WIN32;ZT_TRACE;ZT_USE_MINIUPNPC;MINIUPNP_STATICLIB;ZT_SOFTWARE_UPDATE_DEFAULT="disable";%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <DisableSpecificWarnings>4996</DisableSpecificWarnings>
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>wsock32.lib;ws2_32.lib;Iphlpapi.lib;Rpcrt4.lib;libcurl_a_debug.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>wsock32.lib;ws2_32.lib;Iphlpapi.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
-      <AdditionalLibraryDirectories>$(ProjectDir)..\..\ext\curl-7.58.0\$(PlatformTarget)\lib\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">
@@ -300,15 +310,15 @@
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
       <SDLCheck>true</SDLCheck>
-      <AdditionalIncludeDirectories>$(ProjectDir)..\..\ext\curl-7.58.0\$(PlatformTarget)\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>ZT_EXPORT;CURL_STATICLIB;ZT_VAULT_SUPPORT=1;NOMINMAX;STATICLIB;WIN32;ZT_TRACE;ZT_USE_MINIUPNPC;MINIUPNP_STATICLIB;ZT_SOFTWARE_UPDATE_DEFAULT="disable";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>
+      </AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZT_EXPORT;FD_SETSIZE=1024;NOMINMAX;STATICLIB;WIN32;ZT_TRACE;ZT_USE_MINIUPNPC;MINIUPNP_STATICLIB;ZT_SOFTWARE_UPDATE_DEFAULT="disable";%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <DisableSpecificWarnings>4996</DisableSpecificWarnings>
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>wsock32.lib;ws2_32.lib;Iphlpapi.lib;Rpcrt4.lib;libcurl_a.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>wsock32.lib;ws2_32.lib;Iphlpapi.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
-      <AdditionalLibraryDirectories>$(ProjectDir)..\..\ext\curl-7.58.0\$(PlatformTarget)\lib\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -316,17 +326,17 @@
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
       <SDLCheck>true</SDLCheck>
-      <AdditionalIncludeDirectories>$(ProjectDir)..\..\ext\curl-7.58.0\$(PlatformTarget)\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>ZT_EXPORT;CURL_STATICLIB;ZT_VAULT_SUPPORT=1;NOMINMAX;STATICLIB;WIN32;ZT_TRACE;ZT_RULES_ENGINE_DEBUGGING;ZT_USE_MINIUPNPC;MINIUPNP_STATICLIB;ZT_SOFTWARE_UPDATE_DEFAULT="disable";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>
+      </AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZT_EXPORT;FD_SETSIZE=1024;NOMINMAX;STATICLIB;WIN32;ZT_TRACE;ZT_RULES_ENGINE_DEBUGGING;ZT_USE_MINIUPNPC;MINIUPNP_STATICLIB;ZT_SOFTWARE_UPDATE_DEFAULT="disable";%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <MultiProcessorCompilation>false</MultiProcessorCompilation>
       <DisableSpecificWarnings>4996</DisableSpecificWarnings>
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>wsock32.lib;ws2_32.lib;Iphlpapi.lib;Rpcrt4.lib;libcurl_a_debug.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>wsock32.lib;ws2_32.lib;Iphlpapi.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
       <AdditionalOptions>"notelemetry.obj" %(AdditionalOptions)</AdditionalOptions>
-      <AdditionalLibraryDirectories>$(ProjectDir)..\..\ext\curl-7.58.0\$(PlatformTarget)\lib\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">
@@ -334,17 +344,17 @@
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
       <SDLCheck>true</SDLCheck>
-      <AdditionalIncludeDirectories>$(ProjectDir)..\..\ext\curl-7.58.0\$(PlatformTarget)\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>ZT_EXPORT;CURL_STATICLIB;ZT_VAULT_SUPPORT=1;NOMINMAX;STATICLIB;WIN32;ZT_USE_MINIUPNPC;MINIUPNP_STATICLIB;ZT_SOFTWARE_UPDATE_DEFAULT="disable";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>
+      </AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZT_EXPORT;FD_SETSIZE=1024;NOMINMAX;STATICLIB;WIN32;ZT_USE_MINIUPNPC;MINIUPNP_STATICLIB;ZT_SOFTWARE_UPDATE_DEFAULT="disable";%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <MultiProcessorCompilation>false</MultiProcessorCompilation>
       <DisableSpecificWarnings>4996</DisableSpecificWarnings>
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>wsock32.lib;ws2_32.lib;Iphlpapi.lib;Rpcrt4.lib;libcurl_a.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>wsock32.lib;ws2_32.lib;Iphlpapi.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
       <AdditionalOptions>"notelemetry.obj" %(AdditionalOptions)</AdditionalOptions>
-      <AdditionalLibraryDirectories>$(ProjectDir)..\..\ext\curl-7.58.0\$(PlatformTarget)\lib\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -354,8 +364,9 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <SDLCheck>true</SDLCheck>
-      <AdditionalIncludeDirectories>$(ProjectDir)..\..\ext\curl-7.58.0\$(PlatformTarget)\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>ZT_EXPORT;CURL_STATICLIB;ZT_VAULT_SUPPORT=1;STATICLIB;ZT_SALSA20_SSE;ZT_USE_MINIUPNPC;MINIUPNP_STATICLIB;WIN32;NOMINMAX;ZT_SOFTWARE_UPDATE_DEFAULT="apply";ZT_BUILD_PLATFORM=2;ZT_BUILD_ARCHITECTURE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>
+      </AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZT_EXPORT;FD_SETSIZE=1024;STATICLIB;ZT_SALSA20_SSE;ZT_USE_MINIUPNPC;MINIUPNP_STATICLIB;WIN32;NOMINMAX;ZT_SOFTWARE_UPDATE_DEFAULT="apply";ZT_BUILD_PLATFORM=2;ZT_BUILD_ARCHITECTURE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
       <StringPooling>true</StringPooling>
@@ -369,9 +380,8 @@
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>wsock32.lib;ws2_32.lib;Iphlpapi.lib;Rpcrt4.lib;libcurl_a.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>wsock32.lib;ws2_32.lib;Iphlpapi.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
-      <AdditionalLibraryDirectories>$(ProjectDir)..\..\ext\curl-7.58.0\$(PlatformTarget)\lib\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -381,8 +391,9 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <SDLCheck>true</SDLCheck>
-      <AdditionalIncludeDirectories>$(ProjectDir)..\..\ext\curl-7.58.0\$(PlatformTarget)\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>ZT_EXPORT;CURL_STATICLIB;ZT_VAULT_SUPPORT=1;STATICLIB;ZT_SOFTWARE_UPDATE_DEFAULT="apply";ZT_SALSA20_SSE;ZT_USE_MINIUPNPC;MINIUPNP_STATICLIB;WIN32;NOMINMAX;ZT_BUILD_PLATFORM=2;ZT_BUILD_ARCHITECTURE=2;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>
+      </AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZT_EXPORT;FD_SETSIZE=1024;STATICLIB;ZT_SOFTWARE_UPDATE_DEFAULT="apply";ZT_SALSA20_SSE;ZT_USE_MINIUPNPC;MINIUPNP_STATICLIB;WIN32;NOMINMAX;ZT_BUILD_PLATFORM=2;ZT_BUILD_ARCHITECTURE=2;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
       <StringPooling>true</StringPooling>
@@ -398,9 +409,8 @@
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>wsock32.lib;ws2_32.lib;Iphlpapi.lib;Rpcrt4.lib;libcurl_a.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>wsock32.lib;ws2_32.lib;Iphlpapi.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
-      <AdditionalLibraryDirectories>$(ProjectDir)..\..\ext\curl-7.58.0\$(PlatformTarget)\lib\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
     </Link>
   </ItemDefinitionGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+ 6 - 6
zerotier-one.spec

@@ -1,5 +1,5 @@
 Name:           zerotier-one
-Version:        1.2.10
+Version:        1.2.12
 Release:        1%{?dist}
 Summary:        ZeroTier One network virtualization service
 
@@ -33,13 +33,13 @@ Requires(pre): /usr/sbin/useradd, /usr/bin/getent
 %description
 ZeroTier is a software defined networking layer for Earth.
 
-It can be used for on-premise network virtualization, as a peer to peer VPN 
-for mobile teams, for hybrid or multi-data-center cloud deployments, or just 
+It can be used for on-premise network virtualization, as a peer to peer VPN
+for mobile teams, for hybrid or multi-data-center cloud deployments, or just
 about anywhere else secure software defined virtual networking is useful.
 
-ZeroTier One is our OS-level client service. It allows Mac, Linux, Windows, 
-FreeBSD, and soon other types of clients to join ZeroTier virtual networks 
-like conventional VPNs or VLANs. It can run on native systems, VMs, or 
+ZeroTier One is our OS-level client service. It allows Mac, Linux, Windows,
+FreeBSD, and soon other types of clients to join ZeroTier virtual networks
+like conventional VPNs or VLANs. It can run on native systems, VMs, or
 containers (Docker, OpenVZ, etc.).
 
 %prep

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików