From d25c95dfc3b3206b98c622a07dd9ecb3c6f091ac Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Thu, 5 Mar 2009 12:15:07 +0000 Subject: fixed daemonizing and boost::thread problem (workaround) fixed signalController --- src/anytun.cpp | 44 +++++++++++++++++++------------------------- src/daemon.hpp | 20 ++++++++++++++++---- src/resolver.cpp | 17 ++++++++++++++--- src/signalController.cpp | 18 +++++++++++------- src/signalController.h | 1 + 5 files changed, 61 insertions(+), 39 deletions(-) diff --git a/src/anytun.cpp b/src/anytun.cpp index 335ce43..a299a7b 100644 --- a/src/anytun.cpp +++ b/src/anytun.cpp @@ -399,26 +399,24 @@ int main(int argc, char* argv[]) cLog.msg(Log::PRIO_NOTICE) << "anytun started..."; gOpt.parse_post(); // print warnings -#ifndef NO_SIGNALCONTROLLER - // this has to be called before the first thread is started - gSignalController.init(); -#endif - gResolver.init(); + // daemonizing has to done before any thread gets started #ifndef NO_DAEMON #ifndef NO_PRIVDROP PrivInfo privs(gOpt.getUsername(), gOpt.getGroupname()); #endif - - std::ofstream pidFile; - if(gOpt.getPidFile() != "") { - pidFile.open(gOpt.getPidFile().c_str()); - if(!pidFile.is_open()) { - std::cout << "can't open pid file" << std::endl; - } + if(gOpt.getDaemonize()) { + daemonize(); + daemonized = true; } #endif - + +#ifndef NO_SIGNALCONTROLLER + // this has to be called before the first thread is started + gSignalController.init(); +#endif + gResolver.init(); + #ifndef NO_CRYPT if(gOpt.getAnytun02Compat()) cLog.msg(Log::PRIO_NOTICE) << "enabling anytun 0.2.x crypto compatiblity mode"; @@ -477,21 +475,17 @@ int main(int argc, char* argv[]) #endif #ifndef NO_DAEMON - if(gOpt.getChrootDir() != "") - do_chroot(gOpt.getChrootDir()); + if(gOpt.getChrootDir() != "") { + try { + do_chroot(gOpt.getChrootDir()); + } + catch(const std::runtime_error& e) { + cLog.msg(Log::PRIO_WARNING) << "ignroing chroot error: " << e.what(); + } + } #ifndef NO_PRIVDROP privs.drop(); #endif - if(gOpt.getDaemonize()) { - daemonize(); - daemonized = true; - } - - if(pidFile.is_open()) { - pid_t pid = getpid(); - pidFile << pid; - pidFile.close(); - } #endif boost::thread senderThread(boost::bind(sender, &dev, src)); diff --git a/src/daemon.hpp b/src/daemon.hpp index 7f0cf0b..b62da17 100644 --- a/src/daemon.hpp +++ b/src/daemon.hpp @@ -109,6 +109,13 @@ void do_chroot(std::string const& chrootdir) void daemonize() { + std::ofstream pidFile; + if(gOpt.getPidFile() != "") { + pidFile.open(gOpt.getPidFile().c_str()); + if(!pidFile.is_open()) + AnytunError::throwErr() << "can't open pid file (" << gOpt.getPidFile() << "): " << AnytunErrno(errno); + } + pid_t pid; pid = fork(); @@ -139,14 +146,19 @@ void daemonize() close(fd); fd = open("/dev/null",O_RDWR); // stdin if(fd == -1) - cLog.msg(Log::PRIO_WARNING) << "can't open stdin (chroot and no link to /dev/null?)"; + cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stdin"; else { if(dup(fd) == -1) // stdout - cLog.msg(Log::PRIO_WARNING) << "can't open stdout"; + cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stdout"; if(dup(fd) == -1) // stderr - cLog.msg(Log::PRIO_WARNING) << "can't open stderr"; + cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stderr"; + } + + if(pidFile.is_open()) { + pid_t pid = getpid(); + pidFile << pid; + pidFile.close(); } - umask(027); } #endif #endif diff --git a/src/resolver.cpp b/src/resolver.cpp index d599a96..6d5c777 100644 --- a/src/resolver.cpp +++ b/src/resolver.cpp @@ -58,6 +58,7 @@ void waitAndEnqueue(u_int32_t s, const std::string& addr, const std::string& por gResolver.resolveTcp(addr, port, onResolve, r); } + template ResolveHandler::ResolveHandler(const std::string& addr, const std::string& port, boost::function)> const& onResolve, ResolvAddrType r) : addr_(addr), port_(port), callback_(onResolve), resolv_addr_type_(r) { @@ -109,9 +110,19 @@ void Resolver::run() cLog.msg(Log::PRIO_DEBUG) << "Resolver Thread started"; while(1) { - io_service_.run(); - io_service_.reset(); - boost::this_thread::sleep(boost::posix_time::milliseconds(250)); + try { + io_service_.run(); + io_service_.reset(); + boost::this_thread::sleep(boost::posix_time::milliseconds(250)); + } + catch(const std::runtime_error& e) + { + cLog.msg(Log::PRIO_ERROR) << "resolver caught runtime error, restarting: " << e.what(); + } + catch(const std::exception& e) + { + cLog.msg(Log::PRIO_ERROR) << "resolver caught exception, restarting: " << e.what(); + } } } diff --git a/src/signalController.cpp b/src/signalController.cpp index 12893ca..2ae5791 100644 --- a/src/signalController.cpp +++ b/src/signalController.cpp @@ -160,18 +160,13 @@ void SignalController::handle() { sigfillset(&signal_set); sigwait(&signal_set, &sigNum); - { - Lock lock(sigQueueMutex); - sigQueue.push(sigNum); - } - sigQueueSem.up(); + inject(sigNum); } } #else bool SignalController::handle(DWORD ctrlType) { - gSignalController.sigQueue.push(ctrlType); - gSignalController.sigQueueSem.up(); + gSignalController.inject(ctrlType); return true; } #endif @@ -213,6 +208,15 @@ void SignalController::init() #endif } +void SignalController::inject(int sig) +{ + { + Lock lock(sigQueueMutex); + sigQueue.push(sig); + } + sigQueueSem.up(); +} + int SignalController::run() { while(1) { diff --git a/src/signalController.h b/src/signalController.h index 835e0fe..1f9cae3 100644 --- a/src/signalController.h +++ b/src/signalController.h @@ -151,6 +151,7 @@ public: void init(); int run(); + void inject(int sig); private: typedef std::map HandlerMap; -- cgit v1.2.3