diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2013-12-27 21:56:02 -0800 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2013-12-27 21:56:02 -0800 |
commit | a6dc4caecf219bcb1c47e9842f2bea1fc024b482 (patch) | |
tree | 83eb58e3ed7f3d805a9f5ce4f673f05a28a0de20 /node | |
parent | a5b3747c01ed2321f04ee74a23c23be6c5d0eddc (diff) | |
download | infinitytier-a6dc4caecf219bcb1c47e9842f2bea1fc024b482.tar.gz infinitytier-a6dc4caecf219bcb1c47e9842f2bea1fc024b482.zip |
Unload the mac kext on exit.
Diffstat (limited to 'node')
-rw-r--r-- | node/EthernetTap.cpp | 32 |
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__ |