diff --git a/doc/userguide/manpages/suricata.rst b/doc/userguide/manpages/suricata.rst index a85795c01a..17de1f9f6a 100644 --- a/doc/userguide/manpages/suricata.rst +++ b/doc/userguide/manpages/suricata.rst @@ -45,8 +45,8 @@ SIGHUP used to re-open log files after they may have been moved away by log rotation utilities. -On Windows, when running as a service, the service control code 128 is the -equivalent of SIGUSR2. +On Windows, when running as a service, the service control codes 128 and +129 are the equivalent of SIGUSR2 and SIGHUP respectively. FILES AND DIRECTORIES --------------------- diff --git a/doc/userguide/output/log-rotation.rst b/doc/userguide/output/log-rotation.rst index d6f00932fc..250f743a28 100644 --- a/doc/userguide/output/log-rotation.rst +++ b/doc/userguide/output/log-rotation.rst @@ -44,3 +44,20 @@ include: - :ref:`Eve ` - :ref:`PCAP log ` + +Windows +------- + +Windows does not support SIGHUP. Instead, when Suricata is running as a +Windows service, it can be told to re-open its log files by sending the +service the user-defined control code ``129``:: + + sc.exe control Suricata 129 + +As with SIGHUP, an external tool is responsible for renaming the log files +before sending the control code. Suricata opens log files on Windows with +shared delete access so they can be renamed while open. See +:ref:`rule-reload-windows-service` for who may send control codes. + +.. note:: In PowerShell, ``sc`` is an alias for ``Set-Content``, so + ``sc.exe`` must be used. diff --git a/src/suricata.c b/src/suricata.c index 0da0dac37e..e9a377421d 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -3042,8 +3042,13 @@ void SuricataMainLoop(void) #ifdef OS_WIN32 /* Service control requests are handled like their signal equivalents, - * SC_SERVICE_REQUEST_RELOAD_RULES like SIGUSR2. */ + * SC_SERVICE_REQUEST_RELOAD_RULES like SIGUSR2 and + * SC_SERVICE_REQUEST_REOPEN_LOG_FILES like SIGHUP. */ uint32_t requests = SCServiceTakeRequests(); + if (requests & SC_SERVICE_REQUEST_REOPEN_LOG_FILES) { + SCLogNotice("Reopen of log files requested by service control"); + sighup_count = 1; + } if (requests & SC_SERVICE_REQUEST_RELOAD_RULES) { SCLogNotice("Rule reload requested by service control"); if (DetectEngineEnabled() && sigusr2_count < 2) { diff --git a/src/win32-service.c b/src/win32-service.c index c3b3d64930..25caa36f7a 100644 --- a/src/win32-service.c +++ b/src/win32-service.c @@ -209,6 +209,12 @@ static DWORD WINAPI SCServiceCtrlHandlerEx(DWORD code, DWORD etype, LPVOID edata return NO_ERROR; } + if (code == SC_SERVICE_CONTROL_REOPEN_LOG_FILES) { + /* Defer logging to the main loop, after logging initialization. */ + SC_ATOMIC_OR(service_requests, SC_SERVICE_REQUEST_REOPEN_LOG_FILES); + return NO_ERROR; + } + if (code == SERVICE_CONTROL_SHUTDOWN || code == SERVICE_CONTROL_STOP) { SERVICE_STATUS status = { SERVICE_WIN32, diff --git a/src/win32-service.h b/src/win32-service.h index bb808fe85a..afcc5ce754 100644 --- a/src/win32-service.h +++ b/src/win32-service.h @@ -26,10 +26,12 @@ #ifdef OS_WIN32 /* User-defined service control codes, must be in the range 128-255. */ -#define SC_SERVICE_CONTROL_RELOAD_RULES 128 +#define SC_SERVICE_CONTROL_RELOAD_RULES 128 +#define SC_SERVICE_CONTROL_REOPEN_LOG_FILES 129 /* Requests returned by SCServiceTakeRequests(). */ -#define SC_SERVICE_REQUEST_RELOAD_RULES BIT_U32(0) +#define SC_SERVICE_REQUEST_RELOAD_RULES BIT_U32(0) +#define SC_SERVICE_REQUEST_REOPEN_LOG_FILES BIT_U32(1) uint32_t SCServiceTakeRequests(void); int SCRunningAsService(void);