Unload the mac kext on exit.

This commit is contained in:
Adam Ierymenko 2013-12-27 21:56:02 -08:00
parent a5b3747c01
commit a6dc4caecf

View File

@ -69,6 +69,7 @@ static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC
#define ZT_UNIX_IFCONFIG_COMMAND 2 #define ZT_UNIX_IFCONFIG_COMMAND 2
#define ZT_MAC_KEXTLOAD_COMMAND 3 #define ZT_MAC_KEXTLOAD_COMMAND 3
#define ZT_MAC_IPCONFIG_COMMAND 4 #define ZT_MAC_IPCONFIG_COMMAND 4
#define ZT_MAC_KEXTUNLOAD_COMMAND 5
// Finds external commands on startup // Finds external commands on startup
class _CommandFinder class _CommandFinder
@ -83,6 +84,7 @@ public:
#ifdef __APPLE__ #ifdef __APPLE__
_findCmd(ZT_MAC_KEXTLOAD_COMMAND,"kextload"); _findCmd(ZT_MAC_KEXTLOAD_COMMAND,"kextload");
_findCmd(ZT_MAC_IPCONFIG_COMMAND,"ipconfig"); _findCmd(ZT_MAC_IPCONFIG_COMMAND,"ipconfig");
_findCmd(ZT_MAC_KEXTUNLOAD_COMMAND,"kextunload");
#endif #endif
} }
@ -139,6 +141,9 @@ static const _CommandFinder UNIX_COMMANDS;
#include <net/route.h> #include <net/route.h>
#include <net/if_dl.h> #include <net/if_dl.h>
#include <ifaddrs.h> #include <ifaddrs.h>
static volatile int EthernetTap_instances = 0;
static ZeroTier::Mutex EthernetTap_instances_m;
#endif // __APPLE__ #endif // __APPLE__
namespace ZeroTier { namespace ZeroTier {
@ -337,6 +342,10 @@ EthernetTap::EthernetTap(
::pipe(_shutdownSignalPipe); ::pipe(_shutdownSignalPipe);
_thread = Thread::start(this); _thread = Thread::start(this);
EthernetTap_instances_m.lock();
++EthernetTap_instances;
EthernetTap_instances_m.unlock();
} }
#endif // __APPLE__ #endif // __APPLE__
@ -345,6 +354,29 @@ EthernetTap::~EthernetTap()
::write(_shutdownSignalPipe[1],"\0",1); // causes thread to exit ::write(_shutdownSignalPipe[1],"\0",1); // causes thread to exit
Thread::join(_thread); Thread::join(_thread);
::close(_fd); ::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__ #ifdef __APPLE__