connection_t: split compression_level/log_level into two fields
authorKirill Isakov <bootctl@gmail.com>
Thu, 21 Apr 2022 07:12:47 +0000 (13:12 +0600)
committerGuus Sliepen <guus@tinc-vpn.org>
Thu, 21 Apr 2022 18:34:57 +0000 (20:34 +0200)
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
src/control.c
src/dropin.h
src/logger.c
src/tincctl.c
test/unit/meson.build
test/unit/test_dropin.c [new file with mode: 0644]

index 9817744..9ca1e8d 100644 (file)
@@ -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 */
index c089539..6e8580a 100644 (file)
@@ -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);
index 384b4db..f161c13 100644 (file)
@@ -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
index f8e8209..026a120 100644 (file)
@@ -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;
                        }
 
index 4a3682f..9b39f2c 100644 (file)
@@ -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);
index 70a02d2..bebd093 100644 (file)
@@ -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 (file)
index 0000000..538e633
--- /dev/null
@@ -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);
+}