From 6f4814dbcfb2c920cb79d69492ebdb4e3ecdf0e0 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Fri, 2 Feb 2018 12:47:41 +0000 Subject: [PATCH] libnetwork: Add logging infrastructure Fixes #11610 Signed-off-by: Michael Tremer --- Makefile.am | 8 ++- configure.ac | 10 ++++ src/libnetwork/libnetwork.c | 77 ++++++++++++++++++++++++++++- src/libnetwork/network/libnetwork.h | 8 +++ src/libnetwork/network/logging.h | 57 +++++++++++++++++++++ 5 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 src/libnetwork/network/logging.h diff --git a/Makefile.am b/Makefile.am index e59995c..f05805c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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) \ diff --git a/configure.ac b/configure.ac index e938487..309ff79 100644 --- a/configure.ac +++ b/configure.ac @@ -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 \ ]) # ------------------------------------------------------------------------------ diff --git a/src/libnetwork/libnetwork.c b/src/libnetwork/libnetwork.c index 6793fd5..09651a0 100644 --- a/src/libnetwork/libnetwork.c +++ b/src/libnetwork/libnetwork.c @@ -18,16 +18,65 @@ # # #############################################################################*/ +#include #include +#include +#include #include +#include +#include #include +#include #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; } diff --git a/src/libnetwork/network/libnetwork.h b/src/libnetwork/network/libnetwork.h index 48f7e68..20ba163 100644 --- a/src/libnetwork/network/libnetwork.h +++ b/src/libnetwork/network/libnetwork.h @@ -21,6 +21,8 @@ #ifndef LIBNETWORK_H #define LIBNETWORK_H +#include + // 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 index 0000000..96492fe --- /dev/null +++ b/src/libnetwork/network/logging.h @@ -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 . # +# # +#############################################################################*/ + +#ifndef NETWORK_LOGGING_H +#define NETWORK_LOGGING_H + +#ifdef NETWORK_PRIVATE + +#include +#include + +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 */ -- 2.47.3