diff options
Diffstat (limited to 'osdep')
-rw-r--r-- | osdep/BlockingQueue.hpp | 28 | ||||
-rw-r--r-- | osdep/MacEthernetTap.cpp | 15 | ||||
-rw-r--r-- | osdep/MacEthernetTap.hpp | 2 | ||||
-rw-r--r-- | osdep/MacEthernetTapAgent.c | 16 |
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; } } } |