Просмотр исходного кода

Some Mac feth tap changes to hopefully fix slow-leave problem.

Adam Ierymenko 4 лет назад
Родитель
Сommit
fe5aad3cef
3 измененных файлов с 52 добавлено и 11 удалено
  1. 47 7
      osdep/MacEthernetTap.cpp
  2. 1 0
      osdep/MacEthernetTap.hpp
  3. 4 4
      osdep/MacEthernetTapAgent.c

+ 47 - 7
osdep/MacEthernetTap.cpp

@@ -79,6 +79,7 @@ MacEthernetTap::MacEthernetTap(
 	_homePath(homePath),
 	_mtu(mtu),
 	_metric(metric),
+	_devNo(0),
 	_agentStdin(-1),
 	_agentStdout(-1),
 	_agentStderr(-1),
@@ -97,7 +98,7 @@ MacEthernetTap::MacEthernetTap(
 	agentPath.push_back(ZT_PATH_SEPARATOR);
 	agentPath.append("MacEthernetTapAgent");
 	if (!OSUtils::fileExists(agentPath.c_str()))
-		throw std::runtime_error("MacEthernetTapAgent not installed in ZeroTier home");
+		throw std::runtime_error("MacEthernetTapAgent not present in ZeroTier home");
 
 	Mutex::Lock _gl(globalTapCreateLock); // only make one at a time
 
@@ -112,7 +113,7 @@ MacEthernetTap::MacEthernetTap(
 			while (p) {
 				int nameLen = (int)strlen(p->ifa_name);
 				// Delete feth# from feth0 to feth9999, but don't touch >10000.
-				if ((!strncmp(p->ifa_name,"feth",4))&&(nameLen >= 5)&&(nameLen < 9)&&(deleted.count(std::string(p->ifa_name)) == 0)) {
+				if ((!strncmp(p->ifa_name,"feth",4))&&(nameLen >= 5)&&(nameLen <= 8)&&(deleted.count(std::string(p->ifa_name)) == 0)) {
 					deleted.insert(std::string(p->ifa_name));
 					const char *args[4];
 					args[0] = "/sbin/ifconfig";
@@ -156,10 +157,11 @@ MacEthernetTap::MacEthernetTap(
 			if (devNo < 100)
 				devNo = 100;
 		} else {
+			_dev = devstr;
+			_devNo = devNo;
 			break;
 		}
 	}
-	_dev = devstr;
 
 	if (::pipe(_shutdownSignalPipe))
 		throw std::runtime_error("pipe creation failed");
@@ -204,22 +206,60 @@ MacEthernetTap::MacEthernetTap(
 
 MacEthernetTap::~MacEthernetTap()
 {
+	char tmp[64];
+	const char *args[4];
+	pid_t pid0,pid1;
+
 	MacDNSHelper::removeDNS(_nwid);
-	
+
 	Mutex::Lock _gl(globalTapCreateLock);
 	::write(_shutdownSignalPipe[1],"\0",1); // causes thread to exit
-	Thread::join(_thread);
 	::close(_shutdownSignalPipe[0]);
 	::close(_shutdownSignalPipe[1]);
+
 	int ec = 0;
-	::kill(_agentPid,SIGTERM);
-	::waitpid(_agentPid,&ec,0);
+	::kill(_agentPid,SIGKILL);
+
 	::close(_agentStdin);
 	::close(_agentStdout);
 	::close(_agentStderr);
 	::close(_agentStdin2);
 	::close(_agentStdout2);
 	::close(_agentStderr2);
+
+	::waitpid(_agentPid,&ec,0);
+
+	args[0] = "/sbin/ifconfig";
+	args[1] = _dev.c_str();
+	args[2] = "destroy";
+	args[3] = (char *)0;
+	pid0 = vfork();
+	if (pid0 == 0) {
+		execv(args[0],const_cast<char **>(args));
+		_exit(-1);
+	}
+
+	snprintf(tmp,sizeof(tmp),"feth%u",_devNo + 5000);
+	//args[0] = "/sbin/ifconfig";
+	args[1] = tmp;
+	//args[2] = "destroy";
+	//args[3] = (char *)0;
+	pid1 = vfork();
+	if (pid1 == 0) {
+		execv(args[0],const_cast<char **>(args));
+		_exit(-1);
+	}
+
+	if (pid0 > 0) {
+		int rv = 0;
+		waitpid(pid0,&rv,0);
+	}
+	if (pid1 > 0) {
+		int rv = 0;
+		waitpid(pid1,&rv,0);
+	}
+
+	Thread::join(_thread);
 }
 
 void MacEthernetTap::setEnabled(bool en) { _enabled = en; }

+ 1 - 0
osdep/MacEthernetTap.hpp

@@ -72,6 +72,7 @@ private:
 	Mutex _putLock;
 	unsigned int _mtu;
 	unsigned int _metric;
+	unsigned int _devNo;
 	int _shutdownSignalPipe[2];
 	int _agentStdin,_agentStdout,_agentStderr,_agentStdin2,_agentStdout2,_agentStderr2;
 	long _agentPid;

+ 4 - 4
osdep/MacEthernetTapAgent.c

@@ -29,13 +29,13 @@
  * is limited to 2048. AF_NDRV packet injection is required to inject
  * ZeroTier's large MTU frames.
  *
- * Benchmarks show that this performs similarly to the old tap.kext driver,
- * and a kext is no longer required. Splitting it off into an agent will
- * also make it easier to have zerotier-one itself drop permissions.
- *
  * All this stuff is basically undocumented. A lot of tracing through
  * the Darwin/XNU kernel source was required to figure out how to make
  * this actually work.
+ * 
+ * We hope to develop a DriverKit-based driver in the near-mid future to
+ * replace this weird hack, but it works for now through Big Sur in our
+ * testing.
  *
  * See also:
  *