From 91b4dfa446e352f5d9c7d0ef58da1ceee9ce7b34 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Wed, 20 Jan 2010 07:38:36 +0000 Subject: integrated winservice into signal controller --- src/win32/signalHandler.hpp | 2 +- src/win32/signalServiceHandler.hpp | 47 ++++++++++++++++++++ src/win32/winService.cpp | 88 ++++++++++++-------------------------- src/win32/winService.h | 22 ++-------- 4 files changed, 79 insertions(+), 80 deletions(-) create mode 100644 src/win32/signalServiceHandler.hpp (limited to 'src/win32') diff --git a/src/win32/signalHandler.hpp b/src/win32/signalHandler.hpp index f5b79e1..a961621 100644 --- a/src/win32/signalHandler.hpp +++ b/src/win32/signalHandler.hpp @@ -71,7 +71,7 @@ bool handleSignal(DWORD ctrlType) return true; } -void registerSignalHandler(SignalController& ctrl) +void registerSignalHandler(SignalController& ctrl, DaemonService& /*service*/) { if(!SetConsoleCtrlHandler((PHANDLER_ROUTINE)handleSignal, true)) AnytunError::throwErr() << "Error on SetConsoleCtrlhandler: " << AnytunErrno(GetLastError()); diff --git a/src/win32/signalServiceHandler.hpp b/src/win32/signalServiceHandler.hpp new file mode 100644 index 0000000..3c6be7e --- /dev/null +++ b/src/win32/signalServiceHandler.hpp @@ -0,0 +1,47 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * Anytun is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with anytun. If not, see . + */ + +#ifndef ANYTUN_signalServiceHandler_h_INCLUDED +#define ANYTUN_signalServiceHandler_h_INCLUDED + +#include "winService.h" + +void registerSignalHandler(SignalController& ctrl, WinService& service) +{ + ctrl.handler[SERVICE_CONTROL_STOP] = boost::bind(WinService::handleCtrlSignal, &service, _1, _2); + ctrl.handler[SERVICE_CONTROL_INTERROGATE] = boost::bind(WinService::handleCtrlSignal, &service, _1, _2); + + ctrl.callbacks.insert(SignalController::CallbackMap::value_type(CALLB_RUNNING, boost::bind(&WinService::reportStatus, &service, SERVICE_RUNNING, NO_ERROR))); + ctrl.callbacks.insert(SignalController::CallbackMap::value_type(CALLB_STOPPING, boost::bind(&WinService::reportStatus, &service, SERVICE_STOP_PENDING, NO_ERROR))); +} + +#endif diff --git a/src/win32/winService.cpp b/src/win32/winService.cpp index 1b7c9f8..feb1aab 100644 --- a/src/win32/winService.cpp +++ b/src/win32/winService.cpp @@ -41,26 +41,6 @@ #include "../anytunError.h" #include "../threadUtils.hpp" -WinService* WinService::inst = NULL; -Mutex WinService::instMutex; -WinService& gWinService = WinService::instance(); - -WinService& WinService::instance() -{ - Lock lock(instMutex); - static instanceCleaner c; - if(!inst) - inst = new WinService(); - - return *inst; -} - -WinService::~WinService() -{ - if(started_) - CloseHandle(stop_event_); -} - void WinService::install() { SC_HANDLE schSCManager; @@ -125,75 +105,61 @@ void WinService::start() AnytunError::throwErr() << "Error on StartServiceCtrlDispatcher: " << AnytunErrno(GetLastError()); } -void WinService::waitForStop() -{ - if(!started_) - AnytunError::throwErr() << "Service not started correctly"; - - reportStatus(SERVICE_RUNNING, NO_ERROR); - WaitForSingleObject(stop_event_, INFINITE); - reportStatus(SERVICE_STOP_PENDING, NO_ERROR); - cLog.msg(Log::PRIO_NOTICE) << "WinService received stop signal, exitting"; -} - -void WinService::stop() -{ - if(!started_) - AnytunError::throwErr() << "Service not started correctly"; - - reportStatus(SERVICE_STOPPED, NO_ERROR); -} - -int real_main(int argc, char* argv[]); +int real_main(int argc, char* argv[], WinService& service); VOID WINAPI WinService::main(DWORD dwArgc, LPTSTR *lpszArgv) { - if(gWinService.started_) { - cLog.msg(Log::PRIO_ERROR) << "Service is already running"; - return; - } + WinService service; - gWinService.status_handle_ = RegisterServiceCtrlHandlerA(SVC_NAME, WinService::ctrlHandler); - if(!gWinService.status_handle_) { + service.status_handle_ = RegisterServiceCtrlHandlerA(SVC_NAME, WinService::ctrlHandler); + if(!service.status_handle_) { cLog.msg(Log::PRIO_ERROR) << "Error on RegisterServiceCtrlHandler: " << AnytunErrno(GetLastError()); return; } - gWinService.status_.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - gWinService.status_.dwServiceSpecificExitCode = 0; - gWinService.reportStatus(SERVICE_START_PENDING, NO_ERROR); - gWinService.started_ = true; + service.status_.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + service.status_.dwServiceSpecificExitCode = 0; + service.reportStatus(SERVICE_START_PENDING, NO_ERROR); - gWinService.stop_event_ = CreateEvent(NULL, true, false, NULL); - if(!gWinService.stop_event_) { + service.stop_event_ = CreateEvent(NULL, true, false, NULL); + if(!service.stop_event_) { cLog.msg(Log::PRIO_ERROR) << "WinService Error on CreateEvent: " << AnytunErrno(GetLastError()); - gWinService.reportStatus(SERVICE_STOPPED, -1); + service.reportStatus(SERVICE_STOPPED, -1); return; } - real_main(dwArgc, lpszArgv); + real_main(dwArgc, lpszArgv, service); + + service.reportStatus(SERVICE_STOPPED, NO_ERROR); } VOID WINAPI WinService::ctrlHandler(DWORD dwCtrl) { - switch(dwCtrl) { + gSignalController.inject(ctrlType); + return true; +} + +int handleCtrlSignal(const SigNum& sig, const std::string& msg) +{ + switch(sig) { case SERVICE_CONTROL_STOP: { - gWinService.reportStatus(SERVICE_STOP_PENDING, NO_ERROR); - SetEvent(gWinService.stop_event_); - return; + reportStatus(SERVICE_STOP_PENDING, NO_ERROR); + return 1; } case SERVICE_CONTROL_INTERROGATE: break; default: break; } - gWinService.reportStatus(gWinService.status_.dwCurrentState, NO_ERROR); + reportStatus(gWinService.status_.dwCurrentState, NO_ERROR); + + return 0; } -void WinService::reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint) +void WinService::reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode) { static DWORD dwCheckPoint = 1; status_.dwCurrentState = dwCurrentState; status_.dwWin32ExitCode = dwWin32ExitCode; - status_.dwWaitHint = dwWaitHint; + status_.dwWaitHint = 0; if((dwCurrentState == SERVICE_START_PENDING) || (dwCurrentState == SERVICE_STOP_PENDING)) diff --git a/src/win32/winService.h b/src/win32/winService.h index 6867c7c..e2bab90 100644 --- a/src/win32/winService.h +++ b/src/win32/winService.h @@ -40,39 +40,25 @@ class WinService { public: - static WinService& instance(); #define SVC_NAME "anytun" static void install(); static void uninstall(); static void start(); - void waitForStop(); - void stop(); - static VOID WINAPI main(DWORD dwArgc, LPTSTR *lpszArgv); static VOID WINAPI ctrlHandler(DWORD dwCtrl); + + void reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode); + int handleCtrlSignal(const SigNum& sig, const std::string& msg); + private: WinService() : started_(false) {}; ~WinService(); WinService(const WinService &w); void operator=(const WinService &w); - void reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint=0); - - static WinService* inst; - static Mutex instMutex; - class instanceCleaner { - public: ~instanceCleaner() { - if(WinService::inst != NULL) - delete WinService::inst; - } - }; - friend class instanceCleaner; - - bool started_; SERVICE_STATUS status_; SERVICE_STATUS_HANDLE status_handle_; - HANDLE stop_event_; }; extern WinService& gWinService; -- cgit v1.2.3