summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2013-12-27 21:56:02 -0800
committerAdam Ierymenko <adam.ierymenko@gmail.com>2013-12-27 21:56:02 -0800
commita6dc4caecf219bcb1c47e9842f2bea1fc024b482 (patch)
tree83eb58e3ed7f3d805a9f5ce4f673f05a28a0de20 /node
parenta5b3747c01ed2321f04ee74a23c23be6c5d0eddc (diff)
downloadinfinitytier-a6dc4caecf219bcb1c47e9842f2bea1fc024b482.tar.gz
infinitytier-a6dc4caecf219bcb1c47e9842f2bea1fc024b482.zip
Unload the mac kext on exit.
Diffstat (limited to 'node')
-rw-r--r--node/EthernetTap.cpp32
1 files changed, 32 insertions, 0 deletions
diff --git a/node/EthernetTap.cpp b/node/EthernetTap.cpp
index 44118c2a..d8de55d2 100644
--- a/node/EthernetTap.cpp
+++ b/node/EthernetTap.cpp
@@ -69,6 +69,7 @@ static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC
#define ZT_UNIX_IFCONFIG_COMMAND 2
#define ZT_MAC_KEXTLOAD_COMMAND 3
#define ZT_MAC_IPCONFIG_COMMAND 4
+#define ZT_MAC_KEXTUNLOAD_COMMAND 5
// Finds external commands on startup
class _CommandFinder
@@ -83,6 +84,7 @@ public:
#ifdef __APPLE__
_findCmd(ZT_MAC_KEXTLOAD_COMMAND,"kextload");
_findCmd(ZT_MAC_IPCONFIG_COMMAND,"ipconfig");
+ _findCmd(ZT_MAC_KEXTUNLOAD_COMMAND,"kextunload");
#endif
}
@@ -139,6 +141,9 @@ static const _CommandFinder UNIX_COMMANDS;
#include <net/route.h>
#include <net/if_dl.h>
#include <ifaddrs.h>
+
+static volatile int EthernetTap_instances = 0;
+static ZeroTier::Mutex EthernetTap_instances_m;
#endif // __APPLE__
namespace ZeroTier {
@@ -337,6 +342,10 @@ EthernetTap::EthernetTap(
::pipe(_shutdownSignalPipe);
_thread = Thread::start(this);
+
+ EthernetTap_instances_m.lock();
+ ++EthernetTap_instances;
+ EthernetTap_instances_m.unlock();
}
#endif // __APPLE__
@@ -345,6 +354,29 @@ EthernetTap::~EthernetTap()
::write(_shutdownSignalPipe[1],"\0",1); // causes thread to exit
Thread::join(_thread);
::close(_fd);
+
+#ifdef __APPLE__
+ EthernetTap_instances_m.lock();
+ int instances = --EthernetTap_instances;
+ EthernetTap_instances_m.unlock();
+ if (instances <= 0) {
+ // Unload OSX kernel extension on the deletion of the last EthernetTap
+ // instance.
+ const char *kextunload = UNIX_COMMANDS[ZT_MAC_KEXTUNLOAD_COMMAND];
+ if (kextunload) {
+ long kextpid;
+ char tmp[4096];
+ sprintf(tmp,"%s/tap.kext",_r->homePath.c_str());
+ if ((kextpid = (long)vfork()) == 0) {
+ execl(kextunload,kextunload,tmp,(const char *)0);
+ _exit(-1);
+ } else if (kextpid > 0) {
+ int exitcode = -1;
+ waitpid(kextpid,&exitcode,0);
+ }
+ }
+ }
+#endif // __APPLE__
}
#ifdef __APPLE__