Browse code

Add new unit test module test_socket

With a first UT that tests add_in6_addr() (and
print_in6_addr implicitly).

Change-Id: If546f64a4554b292623bfcfe9ee53bac17dfa803
Signed-off-by: Frank Lichtenheld <frank@lichtenheld.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20250831151133.25684-1-gert@greenie.muc.de>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg32723.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Frank Lichtenheld authored on 2025/09/01 00:11:26
Showing 4 changed files
... ...
@@ -628,9 +628,11 @@ if (NOT WIN32)
628 628
     target_compile_options(openvpn PRIVATE -DPLUGIN_LIBDIR=\"${PLUGIN_DIR}\")
629 629
 
630 630
     find_library(resolv resolv)
631
-    # some platform like BSDs already include resolver functionality in the libc and not have an extra resolv library
631
+    # some platform like BSDs already include resolver functionality in the libc
632
+    # and do not have an extra resolv library
632 633
     if (${resolv} OR APPLE)
633
-        target_link_libraries(openvpn PUBLIC -lresolv)
634
+        set(RESOLV_LIBRARIES resolv)
635
+        target_link_libraries(openvpn PUBLIC ${RESOLV_LIBRARIES})
634 636
     endif ()
635 637
 endif ()
636 638
 
... ...
@@ -653,6 +655,7 @@ if (BUILD_TESTING)
653 653
         "test_packet_id"
654 654
         "test_pkt"
655 655
         "test_provider"
656
+        "test_socket"
656 657
         "test_ssl"
657 658
         "test_user_pass"
658 659
         "test_push_update_msg"
... ...
@@ -849,6 +852,16 @@ if (BUILD_TESTING)
849 849
         src/openvpn/base64.c
850 850
         )
851 851
 
852
+    target_link_libraries(test_socket PUBLIC ${RESOLV_LIBRARIES})
853
+    target_sources(test_socket PRIVATE
854
+        tests/unit_tests/openvpn/mock_get_random.c
855
+        tests/unit_tests/openvpn/mock_management.c
856
+        tests/unit_tests/openvpn/mock_win32_execve.c
857
+        src/openvpn/env_set.c
858
+        src/openvpn/run_command.c
859
+        src/openvpn/socket_util.c
860
+        )
861
+
852 862
     target_sources(test_user_pass PRIVATE
853 863
         tests/unit_tests/openvpn/mock_get_random.c
854 864
         tests/unit_tests/openvpn/mock_win32_execve.c
... ...
@@ -4,23 +4,17 @@ EXTRA_DIST = input
4 4
 
5 5
 AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING) Unit-Tests'
6 6
 
7
-test_binaries=
7
+test_binaries = crypto_testdriver packet_id_testdriver auth_token_testdriver \
8
+	ncp_testdriver misc_testdriver pkt_testdriver ssl_testdriver \
9
+	user_pass_testdriver push_update_msg_testdriver provider_testdriver socket_testdriver
8 10
 
9 11
 if HAVE_LD_WRAP_SUPPORT
10 12
 test_binaries += argv_testdriver buffer_testdriver
11
-endif
12
-
13
-test_binaries += crypto_testdriver packet_id_testdriver auth_token_testdriver ncp_testdriver misc_testdriver \
14
-	pkt_testdriver ssl_testdriver user_pass_testdriver push_update_msg_testdriver
15
-
16
-if HAVE_LD_WRAP_SUPPORT
17 13
 if !WIN32
18 14
 test_binaries += tls_crypt_testdriver
19 15
 endif
20 16
 endif
21 17
 
22
-test_binaries += provider_testdriver
23
-
24 18
 if WIN32
25 19
 test_binaries += cryptoapi_testdriver
26 20
 LDADD = -lws2_32
... ...
@@ -343,4 +337,21 @@ push_update_msg_testdriver_SOURCES = test_push_update_msg.c \
343 343
 	$(top_srcdir)/src/openvpn/platform.c \
344 344
 	$(top_srcdir)/src/openvpn/push_util.c \
345 345
 	$(top_srcdir)/src/openvpn/options_util.c \
346
-	$(top_srcdir)/src/openvpn/otime.c
347 346
\ No newline at end of file
347
+	$(top_srcdir)/src/openvpn/otime.c
348
+
349
+socket_testdriver_CFLAGS  = \
350
+	-I$(top_srcdir)/include -I$(top_srcdir)/src/compat -I$(top_srcdir)/src/openvpn \
351
+	-DSOURCEDIR=\"$(top_srcdir)\" @TEST_CFLAGS@
352
+
353
+socket_testdriver_LDFLAGS = @TEST_LDFLAGS@ $(SOCKETS_LIBS)
354
+
355
+socket_testdriver_SOURCES = test_socket.c \
356
+	mock_msg.c test_common.h  \
357
+	mock_get_random.c \
358
+	mock_management.c \
359
+	$(top_srcdir)/src/openvpn/buffer.c \
360
+	$(top_srcdir)/src/openvpn/win32-util.c \
361
+	$(top_srcdir)/src/openvpn/platform.c \
362
+	$(top_srcdir)/src/openvpn/env_set.c \
363
+	$(top_srcdir)/src/openvpn/run_command.c \
364
+	$(top_srcdir)/src/openvpn/socket_util.c
... ...
@@ -46,4 +46,18 @@ management_query_pk_sig(struct management *man, const char *b64_data, const char
46 46
 {
47 47
     return NULL;
48 48
 }
49
+
50
+void
51
+management_set_state(struct management *man, const int state, const char *detail,
52
+                     const in_addr_t *tun_local_ip, const struct in6_addr *tun_local_ip6,
53
+                     const struct openvpn_sockaddr *local_addr,
54
+                     const struct openvpn_sockaddr *remote_addr)
55
+{
56
+}
57
+
49 58
 #endif
59
+
60
+void
61
+management_sleep(const int n)
62
+{
63
+}
50 64
new file mode 100644
... ...
@@ -0,0 +1,126 @@
0
+/*
1
+ *  OpenVPN -- An application to securely tunnel IP networks
2
+ *             over a single UDP port, with support for SSL/TLS-based
3
+ *             session authentication and key exchange,
4
+ *             packet encryption, packet authentication, and
5
+ *             packet compression.
6
+ *
7
+ *  Copyright (C) 2021-2025 Arne Schwabe <arne@rfc2549.org>
8
+ *
9
+ *  This program is free software; you can redistribute it and/or modify
10
+ *  it under the terms of the GNU General Public License version 2
11
+ *  as published by the Free Software Foundation.
12
+ *
13
+ *  This program is distributed in the hope that it will be useful,
14
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ *  GNU General Public License for more details.
17
+ *
18
+ *  You should have received a copy of the GNU General Public License along
19
+ *  with this program; if not, see <https://www.gnu.org/licenses/>.
20
+ */
21
+
22
+#ifdef HAVE_CONFIG_H
23
+#include "config.h"
24
+#endif
25
+
26
+#include "syshead.h"
27
+
28
+#include <stdio.h>
29
+#include <stdlib.h>
30
+#include <stdarg.h>
31
+#include <string.h>
32
+#include <setjmp.h>
33
+#include <cmocka.h>
34
+
35
+#include "socket.h"
36
+#include "win32.h"
37
+
38
+/* stubs for some unused functions instead of pulling in too many dependencies */
39
+struct signal_info siginfo_static; /* GLOBAL */
40
+
41
+int
42
+signal_reset(struct signal_info *si, int signum)
43
+{
44
+    assert_true(0);
45
+    return 0;
46
+}
47
+
48
+#ifdef _WIN32
49
+struct win32_signal win32_signal; /* GLOBAL */
50
+
51
+int
52
+win32_signal_get(struct win32_signal *ws)
53
+{
54
+    assert_true(0);
55
+    return 0;
56
+}
57
+#endif
58
+
59
+int
60
+parse_line(const char *line, char **p, const int n, const char *file, const int line_num,
61
+           int msglevel, struct gc_arena *gc)
62
+{
63
+    assert_true(0);
64
+    return 0;
65
+}
66
+
67
+static void
68
+test_add_in6_addr_tc(const char *orig_str, uint32_t add, const char *expect_str)
69
+{
70
+    struct in6_addr orig, result, expected;
71
+    struct gc_arena gc = gc_new();
72
+    assert_int_equal(inet_pton(AF_INET6, orig_str, &orig), 1);
73
+    assert_int_equal(inet_pton(AF_INET6, expect_str, &expected), 1);
74
+    result = add_in6_addr(orig, add);
75
+    const char *result_str = print_in6_addr(result, 0, &gc);
76
+    assert_string_equal(result_str, expect_str);
77
+    assert_memory_equal(&result, &expected, sizeof(struct in6_addr));
78
+    gc_free(&gc);
79
+}
80
+
81
+static bool
82
+check_mapped_ipv4_address(void)
83
+{
84
+    struct gc_arena gc = gc_new();
85
+    const char *ipv4_output = "::255.255.255.255";
86
+    struct in6_addr addr;
87
+    assert_int_equal(inet_pton(AF_INET6, ipv4_output, &addr), 1);
88
+    const char *test_output = print_in6_addr(addr, 0, &gc);
89
+    bool ret = strcmp(test_output, ipv4_output) == 0;
90
+    gc_free(&gc);
91
+    return ret;
92
+}
93
+
94
+static void
95
+test_add_in6_addr(void **state)
96
+{
97
+    /* Note that some of the result strings need to account for
98
+       print_in6_addr formatting the addresses potentially as IPv4 */
99
+    bool mapped_ipv4 = check_mapped_ipv4_address();
100
+    test_add_in6_addr_tc("::", 1, "::1");
101
+    test_add_in6_addr_tc("::ff", 1, "::100");
102
+    test_add_in6_addr_tc("::ffff", 1, mapped_ipv4 ? "::0.1.0.0" : "::1:0");
103
+    test_add_in6_addr_tc("ffff::ffff", 1, "ffff::1:0");
104
+    test_add_in6_addr_tc("::ffff:ffff", 1, "::1:0:0");
105
+    test_add_in6_addr_tc("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 1, "::");
106
+    test_add_in6_addr_tc("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 2, "::1");
107
+
108
+    test_add_in6_addr_tc("::", UINT32_MAX, mapped_ipv4 ? "::255.255.255.255" : "::ffff:ffff");
109
+    test_add_in6_addr_tc("::1", UINT32_MAX, "::1:0:0");
110
+    test_add_in6_addr_tc("::ffff", UINT32_MAX, "::1:0:fffe");
111
+    test_add_in6_addr_tc("ffff::ffff", UINT32_MAX, "ffff::1:0:fffe");
112
+    test_add_in6_addr_tc("::ffff:ffff", UINT32_MAX, "::1:ffff:fffe");
113
+    test_add_in6_addr_tc("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", UINT32_MAX,
114
+                         mapped_ipv4 ? "::255.255.255.254" : "::ffff:fffe");
115
+}
116
+
117
+const struct CMUnitTest socket_tests[] = {
118
+    cmocka_unit_test(test_add_in6_addr)
119
+};
120
+
121
+int
122
+main(void)
123
+{
124
+    return cmocka_run_group_tests(socket_tests, NULL, NULL);
125
+}