]> git.ipfire.org Git - thirdparty/strongswan.git/blobdiff - src/charon-svc/charon-svc.c
ike: Float to port 4500 if either port is 500
[thirdparty/strongswan.git] / src / charon-svc / charon-svc.c
index d4fc83c48b44e7bc25b3384205d25670bc02d329..7201fae0208f098cddf78efda53ec60cc00e8fc0 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 #include <library.h>
-#include <hydra.h>
 #include <daemon.h>
 
 #include <utils/backtrace.h>
@@ -45,6 +44,12 @@ static HANDLE event;
  */
 extern void (*dbg) (debug_t group, level_t level, char *fmt, ...);
 
+/**
+ * Forward declaration
+ */
+static DWORD WINAPI service_handler(DWORD dwControl, DWORD dwEventType,
+                                                                       LPVOID lpEventData, LPVOID lpContext);
+
 /**
  * Logging hook for library logs, using stderr output
  */
@@ -103,9 +108,99 @@ static void update_status(DWORD state)
 }
 
 /**
- * Initialize and run charon
+ * Control handler for console
  */
-static void init_and_run(DWORD dwArgc, LPTSTR *lpszArgv)
+static BOOL WINAPI console_handler(DWORD dwCtrlType)
+{
+       switch (dwCtrlType)
+       {
+               case CTRL_C_EVENT:
+               case CTRL_BREAK_EVENT:
+               case CTRL_CLOSE_EVENT:
+                       DBG1(DBG_DMN, "application is stopping, cleaning up");
+                       if (status.dwCurrentState == SERVICE_RUNNING)
+                       {
+                               charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL,
+                                                                  dwCtrlType);
+                       }
+                       /* signal main thread to clean up */
+                       SetEvent(event);
+                       return TRUE;
+               default:
+                       return FALSE;
+       }
+}
+
+/**
+ * Service handler function
+ */
+static DWORD WINAPI service_handler(DWORD dwControl, DWORD dwEventType,
+                                                                       LPVOID lpEventData, LPVOID lpContext)
+{
+       switch (dwControl)
+       {
+               case SERVICE_CONTROL_STOP:
+               case SERVICE_CONTROL_SHUTDOWN:
+                       DBG1(DBG_DMN, "service is stopping, cleaning up");
+                       if (status.dwCurrentState == SERVICE_RUNNING)
+                       {
+                               charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL,
+                                                                  dwControl);
+                       }
+                       /* signal main thread to clean up */
+                       SetEvent(event);
+                       return NO_ERROR;
+               case SERVICE_CONTROL_INTERROGATE:
+                       return NO_ERROR;
+               default:
+                       return ERROR_CALL_NOT_IMPLEMENTED;
+       }
+}
+
+/**
+ * Wait for console program shutdown
+ */
+static int console_wait()
+{
+       update_status(SERVICE_RUNNING);
+
+       if (WaitForSingleObjectEx(event, INFINITE, TRUE) != WAIT_OBJECT_0)
+       {
+               return 2;
+       }
+       return 0;
+}
+
+/**
+ * Wait for service shutdown
+ */
+static int service_wait()
+{
+       /* service is initialized, we now accept control requests */
+       status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
+       update_status(SERVICE_RUNNING);
+       status.dwControlsAccepted = 0;
+
+       if (WaitForSingleObjectEx(event, INFINITE, TRUE) != WAIT_OBJECT_0)
+       {
+               return 2;
+       }
+       return 0;
+}
+
+/**
+ * Add namespace alias
+ */
+static void __attribute__ ((constructor))register_namespace()
+{
+       /* inherit settings from charon */
+       library_add_namespace("charon");
+}
+
+/**
+ * Initialize and run charon using a wait function
+ */
+static void init_and_run(DWORD dwArgc, LPTSTR *lpszArgv, int (*wait)())
 {
        level_t levels[DBG_MAX];
        int i;
@@ -123,32 +218,23 @@ static void init_and_run(DWORD dwArgc, LPTSTR *lpszArgv)
                if (library_init(NULL, SERVICE_NAME))
                {
                        update_status(SERVICE_START_PENDING);
-                       if (libhydra_init())
+                       if (libcharon_init())
                        {
+                               charon->set_default_loggers(charon, levels, TRUE);
+                               charon->load_loggers(charon);
+                               print_version();
                                update_status(SERVICE_START_PENDING);
-                               if (libcharon_init())
+                               if (charon->initialize(charon, PLUGINS))
                                {
-                                       charon->load_loggers(charon, levels, TRUE);
-                                       print_version();
                                        update_status(SERVICE_START_PENDING);
-                                       if (charon->initialize(charon, PLUGINS))
-                                       {
-                                               update_status(SERVICE_START_PENDING);
-                                               lib->plugins->status(lib->plugins, LEVEL_CTRL);
-
-                                               charon->start(charon);
+                                       lib->plugins->status(lib->plugins, LEVEL_CTRL);
 
-                                               status.dwWin32ExitCode = 0;
-                                               update_status(SERVICE_RUNNING);
+                                       charon->start(charon);
 
-                                               /* main thread goes to sleep */
-                                               WaitForSingleObjectEx(event, INFINITE, TRUE);
-                                       }
-                                       update_status(SERVICE_STOP_PENDING);
-                                       libcharon_deinit();
+                                       status.dwWin32ExitCode = wait();
                                }
                                update_status(SERVICE_STOP_PENDING);
-                               libhydra_deinit();
+                               libcharon_deinit();
                        }
                        update_status(SERVICE_STOP_PENDING);
                        library_deinit();
@@ -159,30 +245,6 @@ static void init_and_run(DWORD dwArgc, LPTSTR *lpszArgv)
        update_status(SERVICE_STOPPED);
 }
 
-/**
- * Control handler for console
- */
-static BOOL console_handler(DWORD dwCtrlType)
-{
-       switch (dwCtrlType)
-       {
-               case CTRL_C_EVENT:
-               case CTRL_BREAK_EVENT:
-               case CTRL_CLOSE_EVENT:
-                       DBG1(DBG_DMN, "application is stopping, cleaning up");
-                       if (status.dwCurrentState == SERVICE_RUNNING)
-                       {
-                               charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL,
-                                                                  dwCtrlType);
-                       }
-                       /* signal main thread to clean up */
-                       SetEvent(event);
-                       return TRUE;
-               default:
-                       return FALSE;
-       }
-}
-
 /**
  * Main routine when running from console
  */
@@ -192,37 +254,11 @@ static void console_main(DWORD dwArgc, LPTSTR *lpszArgv)
 
        if (SetConsoleCtrlHandler(console_handler, TRUE))
        {
-               init_and_run(dwArgc, lpszArgv);
+               init_and_run(dwArgc, lpszArgv, console_wait);
                SetConsoleCtrlHandler(console_handler, FALSE);
        }
 }
 
-/**
- * Service handler function
- */
-static DWORD service_handler(DWORD dwControl, DWORD dwEventType,
-                                                        LPVOID lpEventData, LPVOID lpContext)
-{
-       switch (dwControl)
-       {
-               case SERVICE_CONTROL_STOP:
-               case SERVICE_CONTROL_SHUTDOWN:
-                       DBG1(DBG_DMN, "service is stopping, cleaning up");
-                       if (status.dwCurrentState == SERVICE_RUNNING)
-                       {
-                               charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL,
-                                                                  dwControl);
-                       }
-                       /* signal main thread to clean up */
-                       SetEvent(event);
-                       return NO_ERROR;
-               case SERVICE_CONTROL_INTERROGATE:
-                       return NO_ERROR;
-               default:
-                       return ERROR_CALL_NOT_IMPLEMENTED;
-       }
-}
-
 /**
  * Switch the working directory to the executable directory
  */
@@ -252,11 +288,10 @@ static bool switch_workingdir()
 /**
  * Service main routine when running as service
  */
-static void service_main(DWORD dwArgc, LPTSTR *lpszArgv)
+static void WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv)
 {
        memset(&status, 0, sizeof(status));
        status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
-       status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
        status.dwWin32ExitCode = 1;
 
        handle = RegisterServiceCtrlHandlerEx(SERVICE_NAME, service_handler, NULL);
@@ -264,7 +299,7 @@ static void service_main(DWORD dwArgc, LPTSTR *lpszArgv)
        {
                if (switch_workingdir())
                {
-                       init_and_run(dwArgc, lpszArgv);
+                       init_and_run(dwArgc, lpszArgv, service_wait);
                }
        }
 }