diff --git a/test/bio_addr_test.c b/test/bio_addr_test.c new file mode 100644 index 0000000000..a985d03b14 --- /dev/null +++ b/test/bio_addr_test.c @@ -0,0 +1,164 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/e_os.h" +#include "internal/sockets.h" +#include "testutil.h" + +static int families[] = { + AF_INET, +#if OPENSSL_USE_IPV6 + AF_INET6, +#endif +#ifndef OPENSSL_NO_UNIX_SOCK + AF_UNIX +#endif +}; + +static BIO_ADDR *make_dummy_addr(int family) +{ + BIO_ADDR *addr; + union { + struct sockaddr_in sin; +#if OPENSSL_USE_IPV6 + struct sockaddr_in6 sin6; +#endif +#ifndef OPENSSL_NO_UNIX_SOCK + struct sockaddr_un sun; +#endif + } sa; + void *where; + size_t wherelen; + + /* Fill with a dummy address */ + switch(family) { + case AF_INET: + where = &(sa.sin.sin_addr); + wherelen = sizeof(sa.sin.sin_addr); + break; +#if OPENSSL_USE_IPV6 + case AF_INET6: + where = &(sa.sin6.sin6_addr); + wherelen = sizeof(sa.sin6.sin6_addr); + break; +#endif +#ifndef OPENSSL_NO_UNIX_SOCK + case AF_UNIX: + where = &(sa.sun.sun_path); + /* BIO_ADDR_rawmake needs an extra byte for a NUL-terminator*/ + wherelen = sizeof(sa.sun.sun_path) - 1; + break; +#endif + default: + TEST_error("Unsupported address family"); + return 0; + } + /* + * Could be any data, but we make it printable because BIO_ADDR_rawmake + * expects the AF_UNIX address to be a string. + */ + memset(where, 'a', wherelen); + + addr = BIO_ADDR_new(); + if (!TEST_ptr(addr)) + return NULL; + + if (!TEST_true(BIO_ADDR_rawmake(addr, family, where, wherelen, 1000))) { + BIO_ADDR_free(addr); + return NULL; + } + + return addr; +} + +static int bio_addr_is_eq(const BIO_ADDR *a, const BIO_ADDR *b) +{ + struct sockaddr_storage adata, bdata; + size_t alen, blen; + + /* True even if a and b are NULL */ + if (a == b) + return 1; + + /* If one is NULL the other cannot be due to the test above */ + if (a == NULL || b == NULL) + return 0; + + if (BIO_ADDR_family(a) != BIO_ADDR_family(b)) + return 0; + + /* Works even with AF_UNIX/AF_UNSPEC which just returns 0 */ + if (BIO_ADDR_rawport(a) != BIO_ADDR_rawport(b)) + return 0; + + if (!BIO_ADDR_rawaddress(a, NULL, &alen) + || alen > sizeof(adata) + || !BIO_ADDR_rawaddress(a, &adata, &alen)) + return 0; + + if (!BIO_ADDR_rawaddress(a, NULL, &blen) + || blen > sizeof(bdata) + || !BIO_ADDR_rawaddress(a, &bdata, &blen)) + return 0; + + if (alen != blen) + return 0; + + if (alen == 0) + return 1; + + return memcmp(&adata, &bdata, alen) == 0; +} + +static int test_bio_addr_copy_dup(int idx) +{ + BIO_ADDR *src = NULL, *dst = NULL; + int ret = 0; + int docopy = idx & 1; + + idx >>= 1; + + src = make_dummy_addr(families[idx]); + if (!TEST_ptr(src)) + return 0; + + if (docopy) { + dst = BIO_ADDR_new(); + if (!TEST_ptr(dst)) + goto err; + + if (!TEST_true(BIO_ADDR_copy(dst, src))) + goto err; + } else { + dst = BIO_ADDR_dup(src); + if (!TEST_ptr(dst)) + goto err; + } + + if (!TEST_true(bio_addr_is_eq(src, dst))) + goto err; + + ret = 1; + err: + BIO_ADDR_free(src); + BIO_ADDR_free(dst); + return ret; +} + +int setup_tests(void) +{ + if (!test_skip_common_options()) { + TEST_error("Error parsing test options\n"); + return 0; + } + + ADD_ALL_TESTS(test_bio_addr_copy_dup, OSSL_NELEM(families) * 2); + return 1; +} diff --git a/test/build.info b/test/build.info index 4c81a2b779..73f8de1f7a 100644 --- a/test/build.info +++ b/test/build.info @@ -522,6 +522,12 @@ IF[{- !$disabled{tests} -}] INCLUDE[http_test]=../include ../apps/include DEPEND[http_test]=../libcrypto libtestutil.a ENDIF + + PROGRAMS{noinst}=bio_addr_test + + SOURCE[bio_addr_test]=bio_addr_test.c + INCLUDE[bio_addr_test]=../include ../apps/include + DEPEND[bio_addr_test]=../libcrypto libtestutil.a ENDIF SOURCE[dtlstest]=dtlstest.c helpers/ssltestlib.c diff --git a/test/recipes/61-test_bio_addr.t b/test/recipes/61-test_bio_addr.t new file mode 100644 index 0000000000..bd4c23a71f --- /dev/null +++ b/test/recipes/61-test_bio_addr.t @@ -0,0 +1,20 @@ +#! /usr/bin/env perl +# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + + +use OpenSSL::Test; +use OpenSSL::Test::Utils; + +setup("test_bio_addr"); + +plan skip_all => "No sockets in this configuration" + if disabled("sock"); + +plan tests => 1; + +ok(run(test(["bio_addr_test"])), "running bio_addr_test");