Merge pull request #1237 from tie/systemd

nfqws: add support for systemd readiness notifications
This commit is contained in:
bol-van 2025-03-12 12:50:02 +03:00 committed by GitHub
commit 0eec445af0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 119 additions and 12 deletions

View File

@ -15,6 +15,19 @@ all: clean
done \ done \
done done
systemd: clean
@mkdir -p "$(TGT)"; \
for dir in $(DIRS); do \
find "$$dir" -type f \( -name "*.c" -o -name "*.h" -o -name "*akefile" \) -exec chmod -x {} \; ; \
$(MAKE) -C "$$dir" systemd || exit; \
for exe in "$$dir/"*; do \
if [ -f "$$exe" ] && [ -x "$$exe" ]; then \
mv -f "$$exe" "${TGT}" ; \
ln -fs "../${TGT}/$$(basename "$$exe")" "$$exe" ; \
fi \
done \
done
android: clean android: clean
@mkdir -p "$(TGT)"; \ @mkdir -p "$(TGT)"; \
for dir in $(DIRS); do \ for dir in $(DIRS); do \

View File

@ -0,0 +1,48 @@
# Example systemd service unit for nfqws. Adjust for your installation.
[Unit]
After=network.target
[Service]
Type=notify
Restart=on-failure
ExecSearchPath=/opt/zapret/binaries/my
ExecStart=nfqws @${CONFIG_FILE}
Environment=CONFIG_FILE=/etc/zapret/nfqws.config
StateDirectory=nfqws
StateDirectoryMode=0700
WorkingDirectory=%S/nfqws
DynamicUser=true
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW
RestrictAddressFamilies=AF_NETLINK AF_UNIX AF_INET6 AF_INET
LockPersonality=true
MemoryDenyWriteExecute=true
PrivateDevices=true
PrivateMounts=true
PrivateTmp=true
ProcSubset=pid
ProtectClock=true
ProtectControlGroups=true
ProtectHome=true
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectProc=invisible
ProtectSystem=strict
RemoveIPC=true
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
SystemCallArchitectures=native
SystemCallFilter=@system-service
SystemCallFilter=~@resources @privileged
UMask=0077
[Install]
WantedBy=multi-user.target

View File

@ -11,6 +11,8 @@ all: ip2net
ip2net: $(SRC_FILES) ip2net: $(SRC_FILES)
$(CC) -s $(CFLAGS) -o ip2net $(SRC_FILES) $(LIBS) $(LDFLAGS) $(CC) -s $(CFLAGS) -o ip2net $(SRC_FILES) $(LIBS) $(LDFLAGS)
systemd: ip2net
android: ip2net android: ip2net
bsd: $(SRC_FILES) bsd: $(SRC_FILES)

View File

@ -12,6 +12,8 @@ all: mdig
mdig: $(SRC_FILES) mdig: $(SRC_FILES)
$(CC) -s $(CFLAGS) -o mdig $(SRC_FILES) $(LIBS) $(LDFLAGS) $(CC) -s $(CFLAGS) -o mdig $(SRC_FILES) $(LIBS) $(LDFLAGS)
systemd: mdig
android: $(SRC_FILES) android: $(SRC_FILES)
$(CC) -s $(CFLAGS) -o mdig $(SRC_FILES) $(LIBS_ANDROID) $(LDFLAGS) $(CC) -s $(CFLAGS) -o mdig $(SRC_FILES) $(LIBS_ANDROID) $(LDFLAGS)

View File

@ -1,8 +1,10 @@
CC ?= gcc CC ?= gcc
CFLAGS += -std=gnu99 -Os -flto=auto CFLAGS += -std=gnu99 -Os -flto=auto
CFLAGS_SYSTEMD = -DUSE_SYSTEMD
CFLAGS_BSD = -Wno-address-of-packed-member CFLAGS_BSD = -Wno-address-of-packed-member
CFLAGS_CYGWIN = -Wno-address-of-packed-member -static CFLAGS_CYGWIN = -Wno-address-of-packed-member -static
LIBS_LINUX = -lnetfilter_queue -lnfnetlink -lz LIBS_LINUX = -lnetfilter_queue -lnfnetlink -lz
LIBS_SYSTEMD = -lsystemd
LIBS_BSD = -lz LIBS_BSD = -lz
LIBS_CYGWIN = -lz -Lwindows/windivert -Iwindows -lwlanapi -lole32 -loleaut32 LIBS_CYGWIN = -lz -Lwindows/windivert -Iwindows -lwlanapi -lole32 -loleaut32
LIBS_CYGWIN32 = -lwindivert32 LIBS_CYGWIN32 = -lwindivert32
@ -16,6 +18,9 @@ all: nfqws
nfqws: $(SRC_FILES) nfqws: $(SRC_FILES)
$(CC) -s $(CFLAGS) -o nfqws $(SRC_FILES) $(LIBS_LINUX) $(LDFLAGS) $(CC) -s $(CFLAGS) -o nfqws $(SRC_FILES) $(LIBS_LINUX) $(LDFLAGS)
systemd: $(SRC_FILES)
$(CC) -s $(CFLAGS) $(CFLAGS_SYSTEMD) -o nfqws $(SRC_FILES) $(LIBS_LINUX) $(LIBS_SYSTEMD) $(LDFLAGS)
android: nfqws android: nfqws
bsd: $(SRC_FILES) bsd: $(SRC_FILES)

View File

@ -391,6 +391,12 @@ void fill_random_az09(uint8_t *p,size_t sz)
} }
} }
void disable_console_io_buffering(void)
{
setvbuf(stdout, NULL, _IOLBF, 0);
setvbuf(stderr, NULL, _IOLBF, 0);
}
bool set_env_exedir(const char *argv0) bool set_env_exedir(const char *argv0)
{ {
char *s,*d; char *s,*d;

View File

@ -92,6 +92,7 @@ void fill_random_bytes(uint8_t *p,size_t sz);
void fill_random_az(uint8_t *p,size_t sz); void fill_random_az(uint8_t *p,size_t sz);
void fill_random_az09(uint8_t *p,size_t sz); void fill_random_az09(uint8_t *p,size_t sz);
void disable_console_io_buffering(void);
bool set_env_exedir(const char *argv0); bool set_env_exedir(const char *argv0);

View File

@ -35,6 +35,10 @@
#include "win.h" #include "win.h"
#endif #endif
#ifdef USE_SYSTEMD
#include <systemd/sd-daemon.h>
#endif
#ifdef __linux__ #ifdef __linux__
#include <libnetfilter_queue/libnetfilter_queue.h> #include <libnetfilter_queue/libnetfilter_queue.h>
#define NF_DROP 0 #define NF_DROP 0
@ -271,6 +275,15 @@ exiterr:
return false; return false;
} }
static void notify_ready(void)
{
#ifdef USE_SYSTEMD
int r = sd_notify(0, "READY=1");
if (r < 0)
DLOG_ERR("sd_notify: %s\n", strerror(-r));
#endif
}
static int nfq_main(void) static int nfq_main(void)
{ {
uint8_t buf[16384] __attribute__((aligned)); uint8_t buf[16384] __attribute__((aligned));
@ -291,6 +304,8 @@ static int nfq_main(void)
if (!nfq_init(&h,&qh)) if (!nfq_init(&h,&qh))
return 1; return 1;
notify_ready();
fd = nfq_fd(h); fd = nfq_fd(h);
do do
{ {
@ -484,7 +499,6 @@ static int win_main(const char *windivert_filter)
if (!logical_net_filter_match()) if (!logical_net_filter_match())
{ {
DLOG_CONDUP("logical network is not present. waiting it to appear.\n"); DLOG_CONDUP("logical network is not present. waiting it to appear.\n");
fflush(stdout);
do do
{ {
if (bQuit) if (bQuit)
@ -497,7 +511,6 @@ static int win_main(const char *windivert_filter)
} }
while (!logical_net_filter_match()); while (!logical_net_filter_match());
DLOG_CONDUP("logical network now present\n"); DLOG_CONDUP("logical network now present\n");
fflush(stdout);
} }
if (!windivert_init(windivert_filter)) if (!windivert_init(windivert_filter))
@ -508,10 +521,6 @@ static int win_main(const char *windivert_filter)
DLOG_CONDUP("windivert initialized. capture is started.\n"); DLOG_CONDUP("windivert initialized. capture is started.\n");
// cygwin auto flush fails when piping
fflush(stdout);
fflush(stderr);
for (id=0;;id++) for (id=0;;id++)
{ {
len = sizeof(packet); len = sizeof(packet);
@ -574,10 +583,6 @@ static int win_main(const char *windivert_filter)
default: default:
DLOG("packet: id=%u drop\n", id); DLOG("packet: id=%u drop\n", id);
} }
// cygwin auto flush fails when piping
fflush(stdout);
fflush(stderr);
} }
} }
win_dark_deinit(); win_dark_deinit();
@ -1409,6 +1414,7 @@ void check_dp(const struct desync_profile *dp)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
disable_console_io_buffering();
set_env_exedir(argv[0]); set_env_exedir(argv[0]);
#ifdef __CYGWIN__ #ifdef __CYGWIN__

View File

@ -1,7 +1,9 @@
CC ?= gcc CC ?= gcc
CFLAGS += -std=gnu99 -Os -flto=auto CFLAGS += -std=gnu99 -Os -flto=auto
CFLAGS_SYSTEMD = -DUSE_SYSTEMD
CFLAGS_BSD = -Wno-address-of-packed-member CFLAGS_BSD = -Wno-address-of-packed-member
LIBS = -lz -lpthread LIBS = -lz -lpthread
LIBS_SYSTEMD = -lz -lsystemd
LIBS_ANDROID = -lz LIBS_ANDROID = -lz
SRC_FILES = *.c SRC_FILES = *.c
SRC_FILES_ANDROID = $(SRC_FILES) andr/*.c SRC_FILES_ANDROID = $(SRC_FILES) andr/*.c
@ -11,6 +13,9 @@ all: tpws
tpws: $(SRC_FILES) tpws: $(SRC_FILES)
$(CC) -s $(CFLAGS) -o tpws $(SRC_FILES) $(LIBS) $(LDFLAGS) $(CC) -s $(CFLAGS) -o tpws $(SRC_FILES) $(LIBS) $(LDFLAGS)
systemd: $(SRC_FILES)
$(CC) -s $(CFLAGS) $(CFLAGS_SYSTEMD) -o tpws $(SRC_FILES) $(LIBS_SYSTEMD) $(LDFLAGS)
android: $(SRC_FILES) android: $(SRC_FILES)
$(CC) -s $(CFLAGS) -o tpws $(SRC_FILES_ANDROID) $(LIBS_ANDROID) $(LDFLAGS) $(CC) -s $(CFLAGS) -o tpws $(SRC_FILES_ANDROID) $(LIBS_ANDROID) $(LDFLAGS)

View File

@ -383,6 +383,11 @@ bool pf_is_empty(const port_filter *pf)
return !pf->neg && !pf->from && !pf->to; return !pf->neg && !pf->from && !pf->to;
} }
void disable_console_io_buffering(void)
{
setvbuf(stdout, NULL, _IOLBF, 0);
setvbuf(stderr, NULL, _IOLBF, 0);
}
bool set_env_exedir(const char *argv0) bool set_env_exedir(const char *argv0)
{ {

View File

@ -82,6 +82,7 @@ bool pf_in_range(uint16_t port, const port_filter *pf);
bool pf_parse(const char *s, port_filter *pf); bool pf_parse(const char *s, port_filter *pf);
bool pf_is_empty(const port_filter *pf); bool pf_is_empty(const port_filter *pf);
void disable_console_io_buffering(void);
bool set_env_exedir(const char *argv0); bool set_env_exedir(const char *argv0);
#ifndef IN_LOOPBACK #ifndef IN_LOOPBACK

View File

@ -30,6 +30,10 @@
#include <ifaddrs.h> #include <ifaddrs.h>
#endif #endif
#ifdef USE_SYSTEMD
#include <systemd/sd-daemon.h>
#endif
#include "tpws.h" #include "tpws.h"
#ifdef BSD #ifdef BSD
@ -1688,12 +1692,22 @@ static const char *bindll_s[] = { "unwanted","no","prefer","force" };
#define PRINT_VER printf("self-built version %s %s\n\n", __DATE__, __TIME__) #define PRINT_VER printf("self-built version %s %s\n\n", __DATE__, __TIME__)
#endif #endif
static void notify_ready(void)
{
#ifdef USE_SYSTEMD
int r = sd_notify(0, "READY=1");
if (r < 0)
DLOG_ERR("sd_notify: %s\n", strerror(-r));
#endif
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int i, listen_fd[MAX_BINDS], yes = 1, retval = 0, if_index, exit_v=EXIT_FAILURE; int i, listen_fd[MAX_BINDS], yes = 1, retval = 0, if_index, exit_v=EXIT_FAILURE;
struct salisten_s list[MAX_BINDS]; struct salisten_s list[MAX_BINDS];
char ip_port[48]; char ip_port[48];
disable_console_io_buffering();
set_env_exedir(argv[0]); set_env_exedir(argv[0]);
srand(time(NULL)); srand(time(NULL));
mask_from_preflen6_prepare(); mask_from_preflen6_prepare();
@ -1964,6 +1978,7 @@ int main(int argc, char *argv[])
signal(SIGHUP, onhup); signal(SIGHUP, onhup);
signal(SIGUSR2, onusr2); signal(SIGUSR2, onusr2);
notify_ready();
retval = event_loop(listen_fd,params.binds_last+1); retval = event_loop(listen_fd,params.binds_last+1);
exit_v = retval < 0 ? EXIT_FAILURE : EXIT_SUCCESS; exit_v = retval < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
DLOG_CONDUP("Exiting\n"); DLOG_CONDUP("Exiting\n");

View File

@ -1755,8 +1755,6 @@ int event_loop(const int *listen_fd, size_t listen_fd_ct)
// at least one leg was removed. recount legs // at least one leg was removed. recount legs
print_legs(); print_legs();
} }
fflush(stderr); fflush(stdout); // for console messages
} }
ex: ex: