From 668750c022a02cc54756316907f1cbbf7d673025 Mon Sep 17 00:00:00 2001 From: Kirill Isakov Date: Thu, 21 Apr 2022 13:12:47 +0600 Subject: [PATCH] connection_t: split compression_level/log_level into two fields compression_level is reused as a place to store log_level when piping logs to tincctl. Since it was being compared directly with a log level, it felt like a wrong field is being used by mistake. Wrap it in union to avoid wasting additional memory. --- src/connection.h | 8 +++++++- src/control.c | 7 +++++-- src/dropin.h | 2 ++ src/logger.c | 2 +- src/tincctl.c | 4 ++-- test/unit/meson.build | 3 +++ test/unit/test_dropin.c | 44 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 test/unit/test_dropin.c diff --git a/src/connection.h b/src/connection.h index 98177448..9ca1e8da 100644 --- a/src/connection.h +++ b/src/connection.h @@ -27,6 +27,7 @@ #include "rsa.h" #include "list.h" #include "sptps.h" +#include "logger.h" #define OPTION_INDIRECT 0x0001 #define OPTION_TCPONLY 0x0002 @@ -59,6 +60,7 @@ typedef union connection_status_t { #include "edge.h" #include "net.h" #include "node.h" +#include "compression.h" #ifndef DISABLE_LEGACY typedef struct legacy_crypto_t { @@ -107,7 +109,11 @@ typedef struct connection_t { sptps_t sptps; int outmaclength; - int outcompression; /* compression level from compression_level_t */ + + union { + compression_level_t outcompression; + debug_t log_level; // used for REQ_LOG + }; uint8_t *hischallenge; /* The challenge we sent to him */ uint8_t *mychallenge; /* The challenge we received */ diff --git a/src/control.c b/src/control.c index c0895393..6e8580a4 100644 --- a/src/control.c +++ b/src/control.c @@ -130,11 +130,14 @@ bool control_h(connection_t *c, const char *request) { pcap = true; return true; - case REQ_LOG: - sscanf(request, "%*d %*d %d", &c->outcompression); + case REQ_LOG: { + int level = 0; + sscanf(request, "%*d %*d %d", &level); + c->log_level = CLAMP(level, DEBUG_UNSET, DEBUG_SCARY_THINGS); c->status.log = true; logcontrol = true; return true; + } default: return send_request(c, "%d %d", CONTROL, REQ_INVALID); diff --git a/src/dropin.h b/src/dropin.h index 384b4dbf..f161c13d 100644 --- a/src/dropin.h +++ b/src/dropin.h @@ -71,6 +71,8 @@ extern int gettimeofday(struct timeval *, void *); #define MAX(a,b) (((a)>(b))?(a):(b)) #endif +#define CLAMP(val, min, max) MIN((max), MAX((min), (val))) + #ifdef _MSC_VER #define PATH_MAX MAX_PATH diff --git a/src/logger.c b/src/logger.c index f8e82090..026a1202 100644 --- a/src/logger.c +++ b/src/logger.c @@ -110,7 +110,7 @@ static void real_logger(debug_t level, int priority, const char *message) { logcontrol = true; - if(level > (c->outcompression >= COMPRESS_NONE ? c->outcompression : debug_level)) { + if(level > (c->log_level != DEBUG_UNSET ? c->log_level : debug_level)) { continue; } diff --git a/src/tincctl.c b/src/tincctl.c index 4a3682f3..9b39f2ce 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -612,7 +612,7 @@ static void pcap(int fd, FILE *out, uint32_t snaplen) { } } -static void logcontrol(int fd, FILE *out, int level) { +static void log_control(int fd, FILE *out, int level) { sendline(fd, "%d %d %d", CONTROL, REQ_LOG, level); char data[1024]; char line[32]; @@ -1518,7 +1518,7 @@ static int cmd_log(int argc, char *argv[]) { signal(SIGINT, sigint_handler); #endif - logcontrol(fd, stdout, argc > 1 ? atoi(argv[1]) : -1); + log_control(fd, stdout, argc > 1 ? atoi(argv[1]) : DEBUG_UNSET); #ifdef SIGINT signal(SIGINT, SIG_DFL); diff --git a/test/unit/meson.build b/test/unit/meson.build index 70a02d2e..bebd0937 100644 --- a/test/unit/meson.build +++ b/test/unit/meson.build @@ -21,6 +21,9 @@ link_tincd = { 'lib': lib_tincd, 'dep': deps_tincd } # } tests = { + 'dropin': { + 'code': 'test_dropin.c', + }, 'random': { 'code': 'test_random.c', }, diff --git a/test/unit/test_dropin.c b/test/unit/test_dropin.c new file mode 100644 index 00000000..538e633d --- /dev/null +++ b/test/unit/test_dropin.c @@ -0,0 +1,44 @@ +#include "unittest.h" + +static const char buf[3]; + +static void test_min(void **state) { + (void)state; + + assert_int_equal(-1, MIN(1, -1)); + assert_int_equal(-2, MIN(1 + 2 * 3, 3 - 2 * 5 / 2)); + + assert_ptr_equal(buf[0], MIN(buf[1], buf[0])); +} + +static void test_max(void **state) { + (void)state; + + assert_int_equal(1, MAX(1, -1)); + assert_int_equal(4, MAX(1 + 3 - 3 / 4 * 5, 10 / 5 + 2 - 2)); + + assert_ptr_equal(buf[1], MAX(buf[1], buf[0])); +} + +static void test_clamp(void **state) { + (void)state; + + assert_int_equal(10, CLAMP(INT_MAX, -10, 10)); + assert_int_equal(-10, CLAMP(INT_MIN, -10, 10)); + assert_int_equal(7, CLAMP(3 + 4, 6, 8)); + + assert_int_equal(5, CLAMP(-1000, 5, 5)); + assert_int_equal(5, CLAMP(0, 5, 5)); + assert_int_equal(5, CLAMP(1000, 5, 5)); + + assert_ptr_equal(buf[1], CLAMP(buf[2], buf[0], buf[1])); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_min), + cmocka_unit_test(test_max), + cmocka_unit_test(test_clamp), + }; + return cmocka_run_group_tests(tests, NULL, NULL); +} -- 2.20.1