[Openvpn-devel] Fix unit test of test_pkt on little endian Linux

Message ID 20221207140259.1083577-1-arne@rfc2549.org
State Accepted
Headers show
Series [Openvpn-devel] Fix unit test of test_pkt on little endian Linux | expand

Commit Message

Arne Schwabe Dec. 7, 2022, 2:02 p.m. UTC
This surprising breakage results from the fact that Linux basically uses
a different structure from the *BSD:

For exmaple, macOS has:

struct sockaddr_in {
    __uint8_t       sin_len;
    sa_family_t     sin_family;
    in_port_t       sin_port;
    struct  in_addr sin_addr;
    char            sin_zero[8];

with sa_family_t also uint8_t

and Linux has stupidly complex definition that boils down to:

struct sockaddr_in
    uint16_t sin_family;
    in_port_t sin_port;
    struct in_addr sin_addr
    char sin_zero[8];

So Linux basically has a 16 bit uint16 instead of two uint8_t. Because
s390x is big endian, this happens to be same in memory layout as on all
BSDs with first byte being 0 and second byte being the family.

Introduce a second array to check against, if we are on little endian Linux.
This is a bit fragile but this is also just a unit test.

This also fixes compiling test_pkt with windows.

Signed-off-by: Arne Schwabe <arne@rfc2549.org>
 tests/unit_tests/openvpn/test_pkt.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)


Gert Doering Dec. 7, 2022, 6:43 p.m. UTC | #1
Acked-by: Gert Doering <gert@greenie.muc.de>

Fed this to Github actions, our buildbot army AND tested this on 
AIX and Linux. And FreeBSD.

Your patch has been applied to the master branch.

commit 0f904615bd2eac9d246055ff1ca4e4da95586f86 (master)
commit 9c923ef3b435f058a3f898691e3d0613a0357fe5 (release/2.6)
Author: Arne Schwabe
Date:   Wed Dec 7 15:02:59 2022 +0100

     Fix unit test of test_pkt on little endian Linux

     Signed-off-by: Arne Schwabe <arne@rfc2549.org>
     Acked-by: Gert Doering <gert@greenie.muc.de>
     Message-Id: <20221207140259.1083577-1-arne@rfc2549.org>
     URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg25633.html
     Signed-off-by: Gert Doering <gert@greenie.muc.de>

kind regards,

Gert Doering


diff --git a/tests/unit_tests/openvpn/test_pkt.c b/tests/unit_tests/openvpn/test_pkt.c
index 615d26c55..e94b2852e 100644
--- a/tests/unit_tests/openvpn/test_pkt.c
+++ b/tests/unit_tests/openvpn/test_pkt.c
@@ -71,6 +71,14 @@  print_link_socket_actual(const struct link_socket_actual *act, struct gc_arena *
     return "dummy print_link_socket_actual from unit test";
+#ifdef _WIN32
+openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned int flags)
+    ASSERT(0);
 struct test_pkt_context {
     struct tls_auth_standalone tas_tls_auth;
     struct tls_auth_standalone tas_crypt;
@@ -501,7 +509,18 @@  test_calc_session_id_hmac_static(void **ut_state)
     now = 1005;
     struct session_id server_id = calculate_session_id_hmac(client_id, &addr, hmac, handwindow, 0);
-    struct session_id expected_server_id = { {0x84, 0x73, 0x52, 0x2b, 0x5b, 0xa9, 0x2a, 0x70 }};
+    struct session_id expected_server_id = {{0x84, 0x73, 0x52, 0x2b, 0x5b, 0xa9, 0x2a, 0x70}};
+    /* We have to deal with different structs here annoyingly */
+    /* Linux has an unsigned short int as family_t and this is field is always
+     * stored in host endianness even though the rest of the struct isn't...,
+     * so Linux little endian differs from all BSD and Linux big endian */
+    if (sizeof(addr.addr.in4.sin_family) == sizeof(unsigned short int)
+        && ntohs(AF_INET) != AF_INET)
+    {
+        struct session_id linuxle = {{0x8b, 0xeb, 0x3d, 0x20, 0x14, 0x53, 0xbe, 0x0a }};
+        expected_server_id = linuxle;
+    }
     assert_memory_equal(expected_server_id.id, server_id.id, SID_SIZE);
     struct session_id server_id_m1 = calculate_session_id_hmac(client_id, &addr, hmac, handwindow, -1);