]> git.proxmox.com Git - pve-firewall.git/blobdiff - src/pvefw-logger.c
factor out IPPROTO switch for reuse
[pve-firewall.git] / src / pvefw-logger.c
index 8c7376fe5c6901eea7c487e0790114724ef1db9a..5b00758239bc75d57c2b58bd6aa42ff8d26630d2 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>
@@ -47,7 +48,6 @@
 #include <syslog.h>
 
 #include <glib.h>
-#include <glib-unix.h>
 
 static struct nflog_handle *logh = NULL;
 static struct nlif_handle *nlifh = NULL;
@@ -175,8 +175,17 @@ queue_log_entry(struct log_entry *le)
 }
 
 
-#define LEPRINTF(format, ...) { if (le->len < LE_MAX) le->len += snprintf(le->buf + le->len, LE_MAX - le->len, format, ##__VA_ARGS__); }
-#define LEPRINTTIME(sec) { time_t tmp_sec = sec; if (le->len < (LE_MAX - 30)) le->len += strftime(le->buf + le->len, LE_MAX - le->len, "%d/%b/%Y:%H:%M:%S %z ", localtime(&tmp_sec)); }
+#define LEPRINTF(format, ...) \
+    do { \
+        if (le->len < LE_MAX) \
+            le->len += snprintf(le->buf + le->len, LE_MAX - le->len, format, ##__VA_ARGS__); \
+    } while (0)
+#define LEPRINTTIME(sec) \
+    do { \
+        time_t tmp_sec = sec; \
+        if (le->len < (LE_MAX - 30)) \
+            le->len += strftime(le->buf + le->len, LE_MAX - le->len, "%d/%b/%Y:%H:%M:%S %z ", localtime(&tmp_sec)); \
+    } while (0)
 
 static void
 log_status_message(guint loglevel, const char *fmt, ...)
@@ -309,6 +318,37 @@ print_sctp(struct log_entry *le, struct sctphdr *h, int payload_len)
     return 0;
 }
 
+static int
+print_ipproto(struct log_entry *le, char * nexthdr, int payload_len, u_int8_t proto)
+{
+    switch (proto) {
+    case IPPROTO_TCP:
+        print_tcp(le, (struct tcphdr *)nexthdr, payload_len);
+        break;
+    case IPPROTO_UDP:
+        print_udp(le, (struct udphdr *)nexthdr, payload_len);
+        break;
+    case IPPROTO_ICMP:
+        print_icmp(le, (struct icmphdr *)nexthdr, payload_len);
+        break;
+    case IPPROTO_SCTP:
+        print_sctp(le, (struct sctphdr *)nexthdr, payload_len);
+        break;
+    case IPPROTO_AH:
+        LEPRINTF("PROTO=AH ");
+        break;
+    case IPPROTO_ESP:
+        LEPRINTF("PROTO=ESP ");
+        break;
+    case IPPROTO_IGMP:
+        LEPRINTF("PROTO=IGMP ");
+        break;
+     default:
+        return -1;
+    }
+    return 0;
+}
+
 static int
 print_iphdr(struct log_entry *le, char * payload, int payload_len)
 {
@@ -346,29 +386,7 @@ print_iphdr(struct log_entry *le, char * payload, int payload_len)
     void *nexthdr = (u_int32_t *)h + h->ihl;
     payload_len -= h->ihl * 4;
 
-    switch (h->protocol) {
-    case IPPROTO_TCP:
-        print_tcp(le, (struct tcphdr *)nexthdr, payload_len);
-        break;
-    case IPPROTO_UDP:
-        print_udp(le, (struct udphdr *)nexthdr, payload_len);
-        break;
-    case IPPROTO_ICMP:
-        print_icmp(le, (struct icmphdr *)nexthdr, payload_len);
-        break;
-    case IPPROTO_SCTP:
-        print_sctp(le, (struct sctphdr *)nexthdr, payload_len);
-        break;
-    case IPPROTO_AH:
-        LEPRINTF("PROTO=AH ");
-        break;
-    case IPPROTO_ESP:
-        LEPRINTF("PROTO=ESP ");
-        break;
-    case IPPROTO_IGMP:
-        LEPRINTF("PROTO=IGMP ");
-        break;
-     default:
+    if (print_ipproto(le, nexthdr, payload_len, h->protocol) < 0) {
         LEPRINTF("PROTO=%u ", h->protocol);
     }
 
@@ -627,13 +645,20 @@ 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;
 }
@@ -642,9 +667,9 @@ int
 main(int argc, char *argv[])
 {
     int lockfd = -1;
-    gboolean wrote_pidfile = FALSE;
+    int sigfd = -1;
 
-    g_thread_init(NULL);
+    gboolean wrote_pidfile = FALSE;
 
     openlog("pvepw-logger", LOG_CONS|LOG_PID, LOG_DAEMON);
 
@@ -738,6 +763,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();
 
@@ -785,13 +822,15 @@ 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);
+    if (!g_io_add_watch(sig_ch, G_IO_IN, signal_read_cb, NULL)) {
+        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");