4 * The secure anycast tunneling protocol (satp) defines a protocol used
5 * for communication between any combination of unicast and anycast
6 * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
7 * mode and allows tunneling of every ETHER TYPE protocol (e.g.
8 * ethernet, ip, arp ...). satp directly includes cryptography and
9 * message authentication based on the methodes used by SRTP. It is
10 * intended to deliver a generic, scaleable and secure solution for
11 * tunneling and relaying of packets of any protocol.
14 * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl,
15 * Christian Pointner <satp@wirdorange.org>
17 * This file is part of Anytun.
19 * Anytun is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License version 3 as
21 * published by the Free Software Foundation.
23 * Anytun is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with anytun. If not, see <http://www.gnu.org/licenses/>.
35 #include "signalController.h"
37 #include "anytunError.h"
38 #include "threadUtils.hpp"
42 #include <boost/bind.hpp>
47 SignalController* SignalController::inst = NULL;
48 Mutex SignalController::instMutex;
49 SignalController& gSignalController = SignalController::instance();
51 SignalController& SignalController::instance()
54 static instanceCleaner c;
56 inst = new SignalController();
61 int SigErrorHandler::handle(const std::string& msg)
63 AnytunError::throwErr() << msg;
70 int SigIntHandler::handle()
72 cLog.msg(Log::PRIO_NOTICE) << "SIG-Int caught, exiting";
77 int SigQuitHandler::handle()
79 cLog.msg(Log::PRIO_NOTICE) << "SIG-Quit caught, exiting";
84 int SigHupHandler::handle()
86 cLog.msg(Log::PRIO_NOTICE) << "SIG-Hup caught";
91 int SigTermHandler::handle()
93 cLog.msg(Log::PRIO_NOTICE) << "SIG-Term caughtm, exiting";
98 int SigUsr1Handler::handle()
100 cLog.msg(Log::PRIO_NOTICE) << "SIG-Usr1 caught";
105 int SigUsr2Handler::handle()
107 cLog.msg(Log::PRIO_NOTICE) << "SIG-Usr2 caught";
112 int CtrlCHandler::handle()
114 cLog.msg(Log::PRIO_NOTICE) << "CTRL-C Event received, exitting";
119 int CtrlBreakHandler::handle()
121 cLog.msg(Log::PRIO_NOTICE) << "CTRL-Break Event received, ignoring";
126 int CtrlCloseHandler::handle()
128 cLog.msg(Log::PRIO_NOTICE) << "Close Event received, exitting";
133 int CtrlLogoffHandler::handle()
135 cLog.msg(Log::PRIO_NOTICE) << "LogOff Event received, exitting";
140 int CtrlShutdownHandler::handle()
142 cLog.msg(Log::PRIO_NOTICE) << "Shutdown Event received, exitting";
148 SignalController::~SignalController()
150 for(HandlerMap::iterator it = handler.begin(); it != handler.end(); ++it)
154 if(thread) delete thread;
159 void SignalController::handle()
166 sigfillset(&signal_set);
167 sigwait(&signal_set, &sigNum);
172 bool SignalController::handle(DWORD ctrlType)
174 gSignalController.inject(ctrlType);
179 void SignalController::init()
184 sigfillset(&signal_set);
185 sigdelset(&signal_set, SIGCHLD);
186 sigdelset(&signal_set, SIGSEGV);
187 sigdelset(&signal_set, SIGBUS);
188 sigdelset(&signal_set, SIGFPE);
190 #if defined(BOOST_HAS_PTHREADS)
191 pthread_sigmask(SIG_BLOCK, &signal_set, NULL);
193 #error The signalhandler works only with pthreads
196 thread = new boost::thread(boost::bind(&SignalController::handle, this));
198 handler[SIGINT] = new SigIntHandler;
199 handler[SIGQUIT] = new SigQuitHandler;
200 handler[SIGHUP] = new SigHupHandler;
201 handler[SIGTERM] = new SigTermHandler;
202 handler[SIGUSR1] = new SigUsr1Handler;
203 handler[SIGUSR2] = new SigUsr2Handler;
205 if(!SetConsoleCtrlHandler((PHANDLER_ROUTINE)SignalController::handle, true))
206 AnytunError::throwErr() << "Error on SetConsoleCtrlhandler: " << AnytunErrno(GetLastError());
208 handler[CTRL_C_EVENT] = new CtrlCHandler;
209 handler[CTRL_BREAK_EVENT] = new CtrlBreakHandler;
210 handler[CTRL_CLOSE_EVENT] = new CtrlCloseHandler;
211 handler[CTRL_LOGOFF_EVENT] = new CtrlLogoffHandler;
212 handler[CTRL_SHUTDOWN_EVENT] = new CtrlShutdownHandler;
215 handler[SIGERROR] = new SigErrorHandler;
218 void SignalController::inject(int sig, const std::string& msg)
221 Lock lock(sigQueueMutex);
222 sigQueue.push(SigPair(sig, msg));
227 int SignalController::run()
233 Lock lock(sigQueueMutex);
234 sig = sigQueue.front();
238 HandlerMap::iterator it = handler.find(sig.first);
239 if(it != handler.end())
243 ret = it->second->handle();
245 ret = it->second->handle(sig.second);
251 cLog.msg(Log::PRIO_NOTICE) << "SIG " << sig.first << " caught with message '" << sig.second << "'- ignoring";