]> git.proxmox.com Git - pve-firewall.git/blobdiff - src/pvefw-logger.c
generate_ipset: skip undefined ipsets
[pve-firewall.git] / src / pvefw-logger.c
index 31218a29f91d56d7d06bd59474e96532e857bc59..578d1aaebf482ecee01114c1edd4c44e79758586 100644 (file)
@@ -29,6 +29,7 @@
 #include <stdarg.h>
 #include <string.h>
 #include <signal.h>
+#include <sys/signalfd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <syslog.h>
 
 #include <glib.h>
-#include <glib-unix.h>
 
 static struct nflog_handle *logh = NULL;
 static struct nlif_handle *nlifh = NULL;
 GMainLoop *main_loop;
 
+gboolean foreground = FALSE;
+gboolean debug = FALSE;
+
 /*
 
 LOG FORMAT:
@@ -73,7 +76,7 @@ Example:
 #define PIDFILE "/var/run/pvefw-logger.pid"
 
 #define LQ_LEN 512
-#define LE_MAX (512 - 16) // try to fit into 512 bytes
+#define LE_MAX (512 - 4) // try to fit into 512 bytes
 
 #define MAX_CHAIN_LEN 28
 
@@ -82,6 +85,11 @@ struct log_entry {
     char buf[LE_MAX];
 };
 
+#define STATIC_ASSERT(cond) \
+    extern void pve_static_assert(int test[(cond) ? 1 : -1])
+
+STATIC_ASSERT(sizeof(struct log_entry) == 512);
+
 int outfd = -1;
 
 gboolean terminate_threads = FALSE;
@@ -123,6 +131,8 @@ log_writer_thread(gpointer data)
             continue;
         }
 
+        if (debug) fputs(le->buf, stdout);
+
         int res = safe_write(outfd, le->buf, le->len);
 
         g_free(le);
@@ -617,38 +627,74 @@ nlif_read_cb(GIOChannel *source,
 }
 
 static gboolean
-terminate_request(gpointer data)
+signal_read_cb(GIOChannel *source,
+               GIOCondition condition,
+               gpointer data)
 {
-    terminate_threads = TRUE;
+    int rv = 0;
+    struct signalfd_siginfo si;
 
-    log_status_message(5, "received terminate request (signal)");
+    int fd =  g_io_channel_unix_get_fd(source);
 
-    g_main_loop_quit(main_loop);
+    if ((rv = read(fd, &si, sizeof(si))) && rv >= 0) {
+        terminate_threads = TRUE;
+        log_status_message(5, "received terminate request (signal)");
+        g_main_loop_quit(main_loop);
+    }
 
     return TRUE;
 }
 
-
 int
 main(int argc, char *argv[])
 {
     int lockfd = -1;
-    gboolean foreground = FALSE;
+    int sigfd = -1;
+
     gboolean wrote_pidfile = FALSE;
 
     g_thread_init(NULL);
 
     openlog("pvepw-logger", LOG_CONS|LOG_PID, LOG_DAEMON);
 
+    GOptionContext *context;
+
+    GOptionEntry entries[] = {
+        { "debug", 'd', 0, G_OPTION_ARG_NONE, &debug, "Turn on debug messages", NULL },
+        { "foreground", 'f', 0, G_OPTION_ARG_NONE, &foreground, "Do not daemonize server", NULL },
+        { NULL },
+    };
+
+    context = g_option_context_new("");
+    g_option_context_add_main_entries (context, entries, NULL);
+
+    GError *err = NULL;
+    if (!g_option_context_parse (context, &argc, &argv, &err)) {
+        fprintf(stderr, "error: %s\n", err->message);
+        fprintf(stderr, "%s", g_option_context_get_help(context, FALSE, NULL));
+        g_error_free (err);
+        exit(-1);
+    }
+
+    if (optind < argc) {
+        fprintf(stderr, "error: too many arguments\n");
+        fprintf(stderr, "%s", g_option_context_get_help(context, FALSE, NULL));
+        exit(-1);
+    }
+
+    g_option_context_free(context);
+
+    if (debug) foreground = TRUE;
+
     if ((lockfd = open(LOCKFILE, O_RDWR|O_CREAT|O_APPEND, 0644)) == -1) {
-        fprintf(stderr, "unable to create lock '%s': %s", LOCKFILE, strerror (errno) );
+        fprintf(stderr, "unable to create lock '%s': %s\n", LOCKFILE, strerror (errno) );
         exit(-1);
     }
 
     for (int i = 10; i >= 0; i--) {
         if (flock(lockfd, LOCK_EX|LOCK_NB) != 0) {
             if (!i) {
-                fprintf(stderr, "unable to aquire lock '%s': %s", LOCKFILE, strerror (errno));
+                fprintf(stderr, "unable to aquire lock '%s': %s\n", LOCKFILE, strerror (errno));
                 exit(-1);
             }
             if (i == 10)
@@ -659,7 +705,7 @@ main(int argc, char *argv[])
     }
 
     if ((outfd = open(LOGFILE, O_WRONLY|O_CREAT|O_APPEND, 0644)) == -1) {
-        fprintf(stderr, "unable to open file '%s': %s", LOGFILE, strerror (errno));
+        fprintf(stderr, "unable to open file '%s': %s\n", LOGFILE, strerror (errno));
         exit(-1);
     }
 
@@ -687,7 +733,7 @@ main(int argc, char *argv[])
 
     struct nflog_g_handle *qh = nflog_bind_group(logh, 0);
     if (!qh) {
-        fprintf(stderr, "no handle for group 1\n");
+        fprintf(stderr, "no nflog handle for group 0\n");
         exit(-1);
     }
 
@@ -701,6 +747,18 @@ main(int argc, char *argv[])
         exit(-1);
     }
 
+    sigset_t mask;
+    sigemptyset(&mask);
+    sigaddset(&mask, SIGINT);
+    sigaddset(&mask, SIGTERM);
+    
+    sigprocmask(SIG_BLOCK, &mask, NULL);
+
+    if ((sigfd = signalfd(-1, &mask, SFD_NONBLOCK)) < 0) {
+        fprintf(stderr, "unable to open signalfd: %s\n", strerror (errno));
+        exit(-1);
+    }
+
     if (!foreground) {
         pid_t cpid = fork();
 
@@ -748,13 +806,16 @@ main(int argc, char *argv[])
 
     g_io_add_watch(nflog_ch, G_IO_IN, nflog_read_cb, NULL);
 
+    GIOChannel *sig_ch = g_io_channel_unix_new(sigfd);
+    printf("TEST0: %p %d\n", sig_ch, sigfd);
+    if (!g_io_add_watch(sig_ch, G_IO_IN, signal_read_cb, NULL)) {
+        printf("TEST1\n"); exit(-1);
+    }
+
     GThread *wthread = g_thread_new("log_writer_thread", log_writer_thread, NULL);
 
     main_loop = g_main_loop_new(NULL, TRUE);
 
-    g_unix_signal_add(SIGINT, terminate_request, NULL);
-    g_unix_signal_add(SIGTERM, terminate_request, NULL);
-
     g_main_loop_run(main_loop);
 
     log_status_message(5, "stopping pvefw logger");