]> git.ipfire.org Git - people/jschlag/network.git/commitdiff
libnetwork: Add logging infrastructure
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 2 Feb 2018 12:47:41 +0000 (12:47 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 2 Feb 2018 12:47:41 +0000 (12:47 +0000)
Fixes #11610

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
configure.ac
src/libnetwork/libnetwork.c
src/libnetwork/network/libnetwork.h
src/libnetwork/network/logging.h [new file with mode: 0644]

index e59995cf91cff3f8bec23bae2414bb7f5dba7f91..f05805c1269d108bec893663d7a1c591555ea4b1 100644 (file)
@@ -245,7 +245,8 @@ LIBNETWORK_REVISION=0
 LIBNETWORK_AGE=0
 
 pkginclude_HEADERS = \
-       src/libnetwork/network/libnetwork.h
+       src/libnetwork/network/libnetwork.h \
+       src/libnetwork/network/logging.h
 
 lib_LTLIBRARIES = \
        src/libnetwork.la
@@ -254,6 +255,11 @@ src_libnetwork_la_SOURCES = \
        src/libnetwork/libnetwork-private.h \
        src/libnetwork/libnetwork.c
 
+src_libnetwork_la_CPPFLAGS = \
+       $(AM_CPPFLAGS) \
+       -D_GNU_SOURCE \
+       -DNETWORK_PRIVATE
+
 src_libnetwork_la_LDFLAGS = \
        $(AM_LDFLAGS) \
        -version-info $(LIBNETWORK_CURRENT):$(LIBNETWORK_REVISION):$(LIBNETWORK_AGE) \
index e9384872e1366d4b0129e8bd5418b13dd00f6f1c..309ff79e8580f89404d4a635916812976f603d5a 100644 (file)
@@ -96,8 +96,18 @@ AC_SUBST([OUR_LDFLAGS], $with_ldflags)
 # ------------------------------------------------------------------------------
 
 AC_CHECK_HEADERS_ONCE([
+       ctype.h
        errno.h
+       stdarg.h
+       stdio.h
        stdlib.h
+       string.h
+       syslog.h
+])
+
+AC_CHECK_FUNCS([ \
+       __secure_getenv \
+       secure_getenv \
 ])
 
 # ------------------------------------------------------------------------------
index 6793fd5251aa646ad25a45035ed1c996cfe0c7b3..09651a066537c9c81630d57043a97d91b2626a49 100644 (file)
 #                                                                             #
 #############################################################################*/
 
+#include <ctype.h>
 #include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
 
 #include <network/libnetwork.h>
+#include <network/logging.h>
 #include "libnetwork-private.h"
 
 struct network_ctx {
        int refcount;
+
+       // Logging
+       void (*log_fn)(struct network_ctx* ctx,
+               int priority, const char *file, int line, const char *fn,
+               const char *format, va_list args);
+       int log_priority;
 };
 
+void network_log(struct network_ctx* ctx,
+               int priority, const char* file, int line, const char* fn,
+               const char* format, ...) {
+       va_list args;
+
+       va_start(args, format);
+       ctx->log_fn(ctx, priority, file, line, fn, format, args);
+       va_end(args);
+}
+
+static void log_stderr(struct network_ctx* ctx,
+               int priority, const char* file, int line, const char* fn,
+               const char* format, va_list args) {
+       fprintf(stderr, "libnetwork: %s: ", fn);
+       vfprintf(stderr, format, args);
+}
+
+static int log_priority(const char* priority) {
+       char *endptr;
+
+       int prio = strtol(priority, &endptr, 10);
+
+       if (endptr[0] == '\0' || isspace(endptr[0]))
+               return prio;
+
+       if (strncmp(priority, "err", 3) == 0)
+               return LOG_ERR;
+
+       if (strncmp(priority, "info", 4) == 0)
+               return LOG_INFO;
+
+       if (strncmp(priority, "debug", 5) == 0)
+               return LOG_DEBUG;
+
+       return 0;
+}
+
 NETWORK_EXPORT int network_new(struct network_ctx** ctx) {
        struct network_ctx* c = calloc(1, sizeof(*c));
        if (!c)
@@ -36,6 +85,17 @@ NETWORK_EXPORT int network_new(struct network_ctx** ctx) {
        // Initialise basic variables
        c->refcount = 1;
 
+       // Initialise logging
+       c->log_fn = log_stderr;
+       c->log_priority = LOG_ERR;
+
+       const char* env = secure_getenv("NETWORK_LOG");
+       if (env)
+               network_set_log_priority(c, log_priority(env));
+
+       INFO(c, "network ctx %p created\n", c);
+       DEBUG(c, "log_priority=%d\n", c->log_priority);
+
        *ctx = c;
        return 0;
 }
@@ -49,7 +109,7 @@ NETWORK_EXPORT struct network_ctx* network_ref(struct network_ctx* ctx) {
 }
 
 static void network_free(struct network_ctx* ctx) {
-       // Nothing to do, yet
+       DEBUG(ctx, "network ctx %p released\n", ctx);
 }
 
 NETWORK_EXPORT struct network_ctx* network_unref(struct network_ctx* ctx) {
@@ -63,6 +123,21 @@ NETWORK_EXPORT struct network_ctx* network_unref(struct network_ctx* ctx) {
        return NULL;
 }
 
+NETWORK_EXPORT void network_set_log_fn(struct network_ctx* ctx,
+               void (*log_fn)(struct network_ctx* ctx, int priority, const char* file,
+               int line, const char* fn, const char* format, va_list args)) {
+       ctx->log_fn = log_fn;
+       INFO(ctx, "custom logging function %p registered\n", log_fn);
+}
+
+NETWORK_EXPORT int network_get_log_priority(struct network_ctx* ctx) {
+       return ctx->log_priority;
+}
+
+NETWORK_EXPORT void network_set_log_priority(struct network_ctx* ctx, int priority) {
+       ctx->log_priority = priority;
+}
+
 NETWORK_EXPORT const char* network_version() {
        return "network " VERSION;
 }
index 48f7e68ccd19a070ad7f16faa0c287c32d2a5eb1..20ba1636ce3a12e0af8d7b26c03e4a2d9d385903 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef LIBNETWORK_H
 #define LIBNETWORK_H
 
+#include <stdarg.h>
+
 // Central context for all network operations
 struct network_ctx;
 
@@ -28,6 +30,12 @@ int network_new(struct network_ctx** ctx);
 struct network_ctx* network_ref(struct network_ctx* ctx);
 struct network_ctx* network_unref(struct network_ctx* ctx);
 
+void network_set_log_fn(struct network_ctx* ctx,
+       void (*log_fn)(struct network_ctx* ctx, int priority, const char* file,
+       int line, const char* fn, const char* format, va_list args));
+int network_get_log_priority(struct network_ctx* ctx);
+void network_set_log_priority(struct network_ctx* ctx, int priority);
+
 const char* network_version();
 
 #endif
diff --git a/src/libnetwork/network/logging.h b/src/libnetwork/network/logging.h
new file mode 100644 (file)
index 0000000..96492fe
--- /dev/null
@@ -0,0 +1,57 @@
+/*#############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2018 IPFire Network Development Team                          #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#ifndef NETWORK_LOGGING_H
+#define NETWORK_LOGGING_H
+
+#ifdef NETWORK_PRIVATE
+
+#include <stdlib.h>
+#include <syslog.h>
+
+static inline void __attribute__((always_inline, format(printf, 2, 3)))
+    network_log_null(struct network_ctx* ctx, const char* format, ...) {}
+
+#define network_log_cond(ctx, prio, arg...) \
+    do { \
+        if (network_get_log_priority(ctx) >= prio) \
+            network_log(ctx, prio, __FILE__, __LINE__, __FUNCTION__, ## arg); \
+    } while (0)
+
+#ifdef ENABLE_DEBUG
+#  define DEBUG(ctx, arg...) network_log_cond(ctx, LOG_DEBUG, ## arg)
+#else
+#  define DEBUG(ctx, arg...) network_log_null(ctx, ## arg)
+#endif
+
+#define INFO(ctx, arg...) network_log_cond(ctx, LOG_INFO, ## arg)
+#define ERROR(ctx, arg...) network_log_cond(ctx, LOG_ERR, ## arg)
+
+#ifndef HAVE_SECURE_GETENV
+#  ifdef HAVE___SECURE_GETENV
+#    define secure_getenv __secure_getenv
+#  else
+#    error neither secure_getenv nor __secure_getenv is available
+#  endif
+#endif
+
+#endif
+
+#endif /* NETWORK_LOGGING_H */