summaryrefslogtreecommitdiff
path: root/osdep
diff options
context:
space:
mode:
Diffstat (limited to 'osdep')
-rw-r--r--osdep/BlockingQueue.hpp28
-rw-r--r--osdep/MacEthernetTap.cpp15
-rw-r--r--osdep/MacEthernetTap.hpp2
-rw-r--r--osdep/MacEthernetTapAgent.c16
4 files changed, 41 insertions, 20 deletions
diff --git a/osdep/BlockingQueue.hpp b/osdep/BlockingQueue.hpp
index 351a095a..9e2f73cb 100644
--- a/osdep/BlockingQueue.hpp
+++ b/osdep/BlockingQueue.hpp
@@ -32,6 +32,8 @@
#include <condition_variable>
#include <chrono>
+#include "Thread.hpp"
+
namespace ZeroTier {
/**
@@ -52,11 +54,27 @@ public:
c.notify_one();
}
+ inline void postLimit(T t,const unsigned long limit)
+ {
+ std::unique_lock<std::mutex> lock(m);
+ for(;;) {
+ if (q.size() < limit) {
+ q.push(t);
+ c.notify_one();
+ break;
+ }
+ if (!r)
+ break;
+ gc.wait(lock);
+ }
+ }
+
inline void stop(void)
{
std::lock_guard<std::mutex> lock(m);
r = false;
c.notify_all();
+ gc.notify_all();
}
inline bool get(T &value)
@@ -65,10 +83,14 @@ public:
if (!r) return false;
while (q.empty()) {
c.wait(lock);
- if (!r) return false;
+ if (!r) {
+ gc.notify_all();
+ return false;
+ }
}
value = q.front();
q.pop();
+ gc.notify_all();
return true;
}
@@ -98,8 +120,8 @@ public:
private:
volatile bool r;
std::queue<T> q;
- std::mutex m;
- std::condition_variable c;
+ mutable std::mutex m;
+ mutable std::condition_variable c,gc;
};
} // namespace ZeroTier
diff --git a/osdep/MacEthernetTap.cpp b/osdep/MacEthernetTap.cpp
index 92df2f31..fb3e3a75 100644
--- a/osdep/MacEthernetTap.cpp
+++ b/osdep/MacEthernetTap.cpp
@@ -147,7 +147,7 @@ MacEthernetTap::MacEthernetTap(
_agentStdin2 = agentStdin[0];
_agentStdout2 = agentStdout[1];
_agentStderr2 = agentStderr[1];
- long apid = (long)vfork();
+ long apid = (long)fork();
if (apid < 0) {
throw std::runtime_error("fork failed");
} else if (apid == 0) {
@@ -155,10 +155,13 @@ MacEthernetTap::MacEthernetTap(
::dup2(agentStdout[1],STDOUT_FILENO);
::dup2(agentStderr[1],STDERR_FILENO);
::close(agentStdin[0]);
+ ::close(agentStdin[1]);
+ ::close(agentStdout[0]);
::close(agentStdout[1]);
+ ::close(agentStderr[0]);
::close(agentStderr[1]);
::execl(agentPath.c_str(),agentPath.c_str(),devnostr,ethaddr,mtustr,metricstr,(char *)0);
- ::exit(-1);
+ ::_exit(-1);
} else {
_agentPid = apid;
}
@@ -284,7 +287,9 @@ void MacEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,co
iov[1].iov_len = 15;
iov[2].iov_base = const_cast<void *>(data);
iov[2].iov_len = len;
+ _putLock.lock();
writev(_agentStdin,iov,3);
+ _putLock.unlock();
}
}
@@ -356,8 +361,8 @@ void MacEthernetTap::threadMain()
const int nfds = std::max(std::max(_shutdownSignalPipe[0],_agentStdout),_agentStderr) + 1;
long agentReadPtr = 0;
- fcntl(_agentStdout,F_SETFL,O_NONBLOCK);
- fcntl(_agentStderr,F_SETFL,O_NONBLOCK);
+ fcntl(_agentStdout,F_SETFL,fcntl(_agentStdout,F_GETFL)|O_NONBLOCK);
+ fcntl(_agentStderr,F_SETFL,fcntl(_agentStderr,F_GETFL)|O_NONBLOCK);
FD_ZERO(&readfds);
FD_ZERO(&nullfds);
@@ -393,8 +398,6 @@ void MacEthernetTap::threadMain()
break;
}
}
- } else {
- break;
}
}
if (FD_ISSET(_agentStderr,&readfds)) {
diff --git a/osdep/MacEthernetTap.hpp b/osdep/MacEthernetTap.hpp
index 4b3ac019..eaf131a7 100644
--- a/osdep/MacEthernetTap.hpp
+++ b/osdep/MacEthernetTap.hpp
@@ -38,6 +38,7 @@
#include "../node/MAC.hpp"
#include "../node/InetAddress.hpp"
#include "../node/MulticastGroup.hpp"
+#include "../node/Mutex.hpp"
#include "Thread.hpp"
@@ -80,6 +81,7 @@ private:
std::string _homePath;
std::string _dev;
std::vector<MulticastGroup> _multicastGroups;
+ Mutex _putLock;
unsigned int _mtu;
unsigned int _metric;
int _shutdownSignalPipe[2];
diff --git a/osdep/MacEthernetTapAgent.c b/osdep/MacEthernetTapAgent.c
index ca1f7a4e..a595e154 100644
--- a/osdep/MacEthernetTapAgent.c
+++ b/osdep/MacEthernetTapAgent.c
@@ -175,7 +175,7 @@ static int run(const char *path,...)
} else if (pid == 0) {
dup2(STDERR_FILENO,STDOUT_FILENO);
execv(args[0],args);
- exit(-1);
+ _exit(-1);
}
int rv = 0;
waitpid(pid,&rv,0);
@@ -322,10 +322,6 @@ int main(int argc,char **argv)
return ZT_MACETHERNETTAPAGENT_EXIT_CODE_UNABLE_TO_CREATE;
}
- fcntl(STDIN_FILENO,F_SETFL,fcntl(STDIN_FILENO,F_GETFL)|O_NONBLOCK);
- fcntl(s_ndrvfd,F_SETFL,fcntl(s_ndrvfd,F_GETFL)|O_NONBLOCK);
- fcntl(s_bpffd,F_SETFL,fcntl(s_bpffd,F_GETFL)|O_NONBLOCK);
-
fprintf(stderr,"I %s %s %d.%d.%d.%d\n",s_deviceName,s_peerDeviceName,ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION,ZEROTIER_ONE_VERSION_BUILD);
FD_ZERO(&rfds);
@@ -358,8 +354,6 @@ int main(int argc,char **argv)
}
p += BPF_WORDALIGN(h->bh_hdrlen + h->bh_caplen);
}
- } else {
- return ZT_MACETHERNETTAPAGENT_EXIT_CODE_READ_ERROR;
}
}
@@ -381,6 +375,7 @@ int main(int argc,char **argv)
}
}
break;
+
case ZT_MACETHERNETTAPAGENT_STDIN_CMD_IFCONFIG: {
char *args[16];
args[0] = P_IFCONFIG;
@@ -404,18 +399,19 @@ int main(int argc,char **argv)
}
args[argNo] = (char *)0;
if (argNo > 2) {
- pid_t pid = vfork();
+ pid_t pid = fork();
if (pid < 0) {
return -1;
} else if (pid == 0) {
dup2(STDERR_FILENO,STDOUT_FILENO);
execv(args[0],args);
- exit(-1);
+ _exit(-1);
}
int rv = 0;
waitpid(pid,&rv,0);
}
} break;
+
case ZT_MACETHERNETTAPAGENT_STDIN_CMD_EXIT:
return ZT_MACETHERNETTAPAGENT_EXIT_CODE_SUCCESS;
}
@@ -430,8 +426,6 @@ int main(int argc,char **argv)
break;
}
}
- } else {
- return ZT_MACETHERNETTAPAGENT_EXIT_CODE_READ_ERROR;
}
}
}