This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
pespin gerrit-no-reply at lists.osmocom.orgpespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/19724 ) Change subject: socket: multiaddr: Support IPv4 + IPv6 addresses in SCTP associations ...................................................................... socket: multiaddr: Support IPv4 + IPv6 addresses in SCTP associations The function is improved to support AF_INET:v4->v4, AF_INET6:v6->v6 and AF_UNSPEC:v4+v6->v4+v6. Unit tests for the function are added to make sure function behaves correctly in several scenarios. Change-Id: I36d8ab85d92bba4d6adb83bc1875eb61094ed2ef --- M src/socket.c M tests/socket/socket_test.c M tests/socket/socket_test.err M tests/socket/socket_test.ok 4 files changed, 294 insertions(+), 66 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/24/19724/1 diff --git a/src/socket.c b/src/socket.c index d92c670..57ff843 100644 --- a/src/socket.c +++ b/src/socket.c @@ -79,7 +79,7 @@ hints.ai_socktype = type; hints.ai_protocol = proto; } - + hints.ai_flags = AI_ADDRCONFIG; if (passive) hints.ai_flags |= AI_PASSIVE; @@ -428,24 +428,62 @@ #ifdef HAVE_LIBSCTP +/* Check whether there's an IPv6 Addr as first option of any addrinfo item in the addrinfo set */ +static void addrinfo_has_v4v6addr(const struct addrinfo **result, int result_count, bool *has_v4, bool *has_v6) { + size_t host_idx; + *has_v4 = false; + *has_v6 = false; + + for (host_idx = 0; host_idx < result_count; host_idx++) { + if (result[host_idx]->ai_family == AF_INET) + *has_v4 = true; + else if (result[host_idx]->ai_family == AF_INET6) + *has_v6 = true; + } +} + +static int socket_helper_multiaddr(uint16_t family, uint16_t type, uint8_t proto, unsigned int flags) +{ + int sfd, on = 1; + + sfd = socket(family, type, proto); + if (sfd == -1) { + LOGP(DLGLOBAL, LOGL_ERROR, + "unable to create socket: %s\n", strerror(errno)); + return sfd; + } + if (flags & OSMO_SOCK_F_NONBLOCK) { + if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) { + LOGP(DLGLOBAL, LOGL_ERROR, + "cannot set this socket unblocking: %s\n", + strerror(errno)); + close(sfd); + sfd = -EINVAL; + } + } + return sfd; +} /* Build array of addresses taking first addrinfo result of the requested family - * for each host in hosts. addrs4 or addrs6 are filled based on family type. */ + * for each host in addrs_buf. */ static int addrinfo_to_sockaddr(uint16_t family, const struct addrinfo **result, const char **hosts, int host_cont, - struct sockaddr_in *addrs4, struct sockaddr_in6 *addrs6) { - size_t host_idx; + uint8_t *addrs_buf, size_t addrs_buf_len) { + size_t host_idx, offset = 0; const struct addrinfo *rp; - OSMO_ASSERT(family == AF_INET || family == AF_INET6); for (host_idx = 0; host_idx < host_cont; host_idx++) { + /* Addresses are ordered based on RFC 3484, see man getaddrinfo */ for (rp = result[host_idx]; rp != NULL; rp = rp->ai_next) { - if (rp->ai_family != family) + if (family != AF_UNSPEC && rp->ai_family != family) continue; - if (family == AF_INET) - memcpy(&addrs4[host_idx], rp->ai_addr, sizeof(addrs4[host_idx])); - else - memcpy(&addrs6[host_idx], rp->ai_addr, sizeof(addrs6[host_idx])); + if (offset + rp->ai_addrlen > addrs_buf_len) { + LOGP(DLGLOBAL, LOGL_ERROR, "output buffer to small: %zu\n", + addrs_buf_len); + return -ENOSPC; + } + memcpy(addrs_buf + offset, rp->ai_addr, rp->ai_addrlen); + offset += rp->ai_addrlen; break; } if (!rp) { /* No addr could be bound for this host! */ @@ -486,25 +524,20 @@ struct addrinfo *res_loc[OSMO_SOCK_MAX_ADDRS], *res_rem[OSMO_SOCK_MAX_ADDRS]; int sfd = -1, rc, on = 1; int i; - struct sockaddr_in addrs4[OSMO_SOCK_MAX_ADDRS]; - struct sockaddr_in6 addrs6[OSMO_SOCK_MAX_ADDRS]; - struct sockaddr *addrs; + bool loc_has_v4addr, rem_has_v4addr; + bool loc_has_v6addr, rem_has_v6addr; + struct sockaddr_in6 addrs_buf[OSMO_SOCK_MAX_ADDRS]; char strbuf[512]; + /* updated later in case of AF_UNSPEC */ + loc_has_v4addr = rem_has_v4addr = (family == AF_INET); + loc_has_v6addr = rem_has_v6addr = (family == AF_INET6); + /* TODO: So far this function is only aimed for SCTP, but could be reused in the future for other protocols with multi-addr support */ if (proto != IPPROTO_SCTP) return -ENOTSUP; - /* TODO: Let's not support AF_UNSPEC for now. sctp_bindx() actually - supports binding both types of addresses on a AF_INET6 soscket, but - that would mean we could get both AF_INET and AF_INET6 addresses for - each host, and makes complexity of this function increase a lot since - we'd need to find out which subsets to use, use v4v6 mapped socket, - etc. */ - if (family == AF_UNSPEC) - return -ENOTSUP; - if ((flags & (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) == 0) { LOGP(DLGLOBAL, LOGL_ERROR, "invalid: you have to specify either " "BIND or CONNECT flags\n"); @@ -523,6 +556,10 @@ local_hosts_cnt, local_port, true); if (rc < 0) return -EINVAL; + /* Figure out if there's any IPV4 or IPv6 addr in the set */ + if (family == AF_UNSPEC) + addrinfo_has_v4v6addr((const struct addrinfo **)res_loc, local_hosts_cnt, + &loc_has_v4addr, &loc_has_v6addr); } /* figure out remote side of socket */ if (flags & OSMO_SOCK_F_CONNECT) { @@ -530,22 +567,27 @@ remote_hosts_cnt, remote_port, false); if (rc < 0) return -EINVAL; + /* Figure out if there's any IPv4 or IPv6 addr in the set */ + if (family == AF_UNSPEC) + addrinfo_has_v4v6addr((const struct addrinfo **)res_rem, remote_hosts_cnt, + &rem_has_v4addr, &rem_has_v6addr); } - /* figure out local side of socket */ + if (((flags & OSMO_SOCK_F_BIND) && (flags & OSMO_SOCK_F_CONNECT)) && + (loc_has_v4addr != rem_has_v4addr || loc_has_v6addr != rem_has_v6addr)) { + LOGP(DLGLOBAL, LOGL_ERROR, "invalid v4 vs v6 in local vs remote addresses\n"); + rc = -EINVAL; + goto ret_freeaddrinfo; + } + + sfd = socket_helper_multiaddr(loc_has_v6addr ? AF_INET6 : AF_INET, + type, proto, flags); + if (sfd < 0) { + rc = sfd; + goto ret_freeaddrinfo; + } + if (flags & OSMO_SOCK_F_BIND) { - - /* Since addrinfo_helper sets ai_family, socktype and - ai_protocol in hints, we know all results will use same - values, so simply pick the first one and pass it to create - the socket: - */ - sfd = socket_helper(res_loc[0], flags); - if (sfd < 0) { - rc = sfd; - goto ret_freeaddrinfo; - } - /* Since so far we only allow IPPROTO_SCTP in this function, no need to check below for "proto != IPPROTO_UDP || flags & OSMO_SOCK_F_UDP_REUSEADDR" */ rc = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, @@ -560,21 +602,20 @@ goto ret_close; } - /* Build array of addresses taking first of same family for each host. + /* Build array of addresses taking first entry for each host. TODO: Ideally we should use backtracking storing last used indexes and trying next combination if connect() fails .*/ + /* We could alternatively use v4v6 mapped addresses and call sctp_bindx once with an array od sockaddr_in6 */ rc = addrinfo_to_sockaddr(family, (const struct addrinfo **)res_loc, - local_hosts, local_hosts_cnt, addrs4, addrs6); + local_hosts, local_hosts_cnt, + (uint8_t*)addrs_buf, sizeof(addrs_buf)); if (rc < 0) { rc = -ENODEV; goto ret_close; } - if (family == AF_INET) - addrs = (struct sockaddr *)addrs4; - else - addrs = (struct sockaddr *)addrs6; - if (sctp_bindx(sfd, addrs, local_hosts_cnt, SCTP_BINDX_ADD_ADDR) == -1) { + rc = sctp_bindx(sfd, (struct sockaddr *)addrs_buf, local_hosts_cnt, SCTP_BINDX_ADD_ADDR); + if (rc == -1) { multiaddr_snprintf(strbuf, sizeof(strbuf), local_hosts, local_hosts_cnt); LOGP(DLGLOBAL, LOGL_NOTICE, "unable to bind socket: %s:%u: %s\n", strbuf, local_port, strerror(errno)); @@ -583,40 +624,19 @@ } } - /* Reached this point, if OSMO_SOCK_F_BIND then sfd is valid (>=0) or it - was already closed and func returned. If OSMO_SOCK_F_BIND is not - set, then sfd = -1 */ - - /* figure out remote side of socket */ if (flags & OSMO_SOCK_F_CONNECT) { - if (sfd < 0) { - /* Since addrinfo_helper sets ai_family, socktype and - ai_protocol in hints, we know all results will use same - values, so simply pick the first one and pass it to create - the socket: - */ - sfd = socket_helper(res_rem[0], flags); - if (sfd < 0) { - rc = sfd; - goto ret_freeaddrinfo; - } - } - /* Build array of addresses taking first of same family for each host. TODO: Ideally we should use backtracking storing last used indexes and trying next combination if connect() fails .*/ rc = addrinfo_to_sockaddr(family, (const struct addrinfo **)res_rem, - remote_hosts, remote_hosts_cnt, addrs4, addrs6); + remote_hosts, remote_hosts_cnt, + (uint8_t*)addrs_buf, sizeof(addrs_buf)); if (rc < 0) { rc = -ENODEV; goto ret_close; } - if (family == AF_INET) - addrs = (struct sockaddr *)addrs4; - else - addrs = (struct sockaddr *)addrs6; - rc = sctp_connectx(sfd, addrs, remote_hosts_cnt, NULL); + rc = sctp_connectx(sfd, (struct sockaddr *)addrs_buf, remote_hosts_cnt, NULL); if (rc != 0 && errno != EINPROGRESS) { multiaddr_snprintf(strbuf, sizeof(strbuf), remote_hosts, remote_hosts_cnt); LOGP(DLGLOBAL, LOGL_ERROR, "unable to connect socket: %s:%u: %s\n", diff --git a/tests/socket/socket_test.c b/tests/socket/socket_test.c index e68243c..1d4253c 100644 --- a/tests/socket/socket_test.c +++ b/tests/socket/socket_test.c @@ -23,6 +23,7 @@ #include <unistd.h> #include <string.h> #include <fcntl.h> +#include <inttypes.h> #include <sys/socket.h> #include <arpa/inet.h> @@ -32,6 +33,7 @@ #include <osmocom/core/utils.h> #include <osmocom/core/socket.h> #include <osmocom/core/logging.h> +#include <osmocom/core/bits.h> #include "../config.h" @@ -146,6 +148,175 @@ return 0; } +#ifdef HAVE_LIBSCTP +static uint16_t sock_get_local_port(int fd, bool is_v6) { + struct sockaddr_storage sa; + struct sockaddr_in *sin = (struct sockaddr_in *)&sa; + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa; + socklen_t len = sizeof(sa); + int local_port; + + OSMO_ASSERT(getsockname(fd, (struct sockaddr*)&sa, &len) == 0); + if(!is_v6) + local_port = osmo_load16be(&sin->sin_port); + else + local_port = osmo_load16be(&sin6->sin6_port); + //printf("Checking osmo_sock_init2_multiaddr() port: %" PRIu16 "\n", listen_port_v4); + return local_port; +} + +/* Test API osmo_sock_init2_multiaddr with 1 local/remote address */ +static int test_sockinit2_multiaddr(const char **addrv4_loc, const char **addrv6_loc, + const char **addrv4_rem, const char **addrv6_rem, + size_t addrv4_size, size_t addrv6_size) +{ + int fd, rc; + int listen_fd_v4, listen_fd_v6; + int listen_port_v4, listen_port_v6; + + printf("Checking osmo_sock_init2_multiaddr() with bind to a random local SCTP IPv4 port\n"); + + listen_fd_v4 = osmo_sock_init2_multiaddr(AF_INET, SOCK_STREAM, IPPROTO_SCTP, + addrv4_loc, addrv4_size, 0, + NULL, 0, 0, OSMO_SOCK_F_BIND); + OSMO_ASSERT(listen_fd_v4 >= 0); + /* expect it to be blocking */ + rc = fcntl(listen_fd_v4, F_GETFL); + OSMO_ASSERT(!(rc & O_NONBLOCK)); + + listen_port_v4 = sock_get_local_port(listen_fd_v4, false); + + printf("Checking osmo_sock_init2_multiaddr() with bind to a random local SCTP IPv6 port\n"); + + listen_fd_v6 = osmo_sock_init2_multiaddr(AF_INET6, SOCK_STREAM, IPPROTO_SCTP, + addrv6_loc, addrv6_size, 0, + NULL, 0, 0, OSMO_SOCK_F_BIND); + OSMO_ASSERT(listen_fd_v6 >= 0); + /* expect it to be blocking */ + rc = fcntl(listen_fd_v6, F_GETFL); + OSMO_ASSERT(!(rc & O_NONBLOCK)); + + listen_port_v6 = sock_get_local_port(listen_fd_v6, true); + + printf("Checking osmo_sock_init2_multiaddr() for OSMO_SOCK_F_NONBLOCK\n"); + fd = osmo_sock_init2_multiaddr(AF_INET, SOCK_STREAM, IPPROTO_SCTP, + addrv4_loc, addrv4_size, 0, + NULL, 0, 0, OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK); + OSMO_ASSERT(fd >= 0); + /* expect it to be blocking */ + rc = fcntl(fd, F_GETFL); + OSMO_ASSERT(rc & O_NONBLOCK); + close(fd); + + printf("Checking osmo_sock_init2_multiaddr() for invalid flags\n"); + fd = osmo_sock_init2_multiaddr(AF_INET, SOCK_STREAM, IPPROTO_SCTP, + addrv4_loc, addrv4_size, 0, + NULL, 0, 0, 0); + OSMO_ASSERT(fd < 0); + + printf("Checking osmo_sock_init2_multiaddr() for combined BIND + CONNECT\n"); + fd = osmo_sock_init2_multiaddr(AF_INET, SOCK_STREAM, IPPROTO_SCTP, + addrv4_rem, addrv4_size, 0, + addrv4_rem, addrv4_size, listen_port_v4, + OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT); + OSMO_ASSERT(fd >= 0); + + printf("Checking osmo_sock_init2_multiaddr(AF_UNSPEC) must fail on mixed IPv4 & IPv6\n"); + fd = osmo_sock_init2_multiaddr(AF_UNSPEC, SOCK_STREAM, IPPROTO_SCTP, + addrv4_rem, addrv4_size, 0, + addrv6_rem, addrv6_size, listen_port_v6, + OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT); + OSMO_ASSERT(fd < 0); + + printf("Checking osmo_sock_init2_multiaddr(AF_UNSPEC) must fail on mixed IPv6 & IPv4\n"); + fd = osmo_sock_init2_multiaddr(AF_UNSPEC, SOCK_STREAM, IPPROTO_SCTP, + addrv6_rem, addrv6_size, 0, + addrv4_rem, addrv4_size, listen_port_v4, + OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT); + OSMO_ASSERT(fd < 0); + + printf("Checking osmo_sock_init2_multiaddr(AF_UNSPEC) BIND + CONNECT on IPv4\n"); + fd = osmo_sock_init2_multiaddr(AF_UNSPEC, SOCK_STREAM, IPPROTO_SCTP, + addrv4_rem, addrv4_size, 0, + addrv4_rem, addrv4_size, listen_port_v4, + OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT); + OSMO_ASSERT(fd >= 0); + + printf("Checking osmo_sock_init2_multiaddr(AF_UNSPEC) BIND + CONNECT on IPv6\n"); + fd = osmo_sock_init2_multiaddr(AF_UNSPEC, SOCK_STREAM, IPPROTO_SCTP, + addrv6_rem, addrv6_size, 0, + addrv6_rem, addrv6_size, listen_port_v6, + OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT); + OSMO_ASSERT(fd >= 0); + + close(listen_fd_v4); + close(listen_fd_v6); + printf("Done\n"); + return 0; +} + +/* Test API osmo_sock_init2_multiaddr with 1 local/remote address */ +static int test_sockinit2_multiaddr_simple(void) +{ + const char *addrv4_loc[] = { "0.0.0.0" }; + const char *addrv6_loc[] = { "::" }; + const char *addrv4_rem[] = { "127.0.0.1" }; + const char *addrv6_rem[] = { "::1" }; + + return test_sockinit2_multiaddr(addrv4_loc, addrv6_loc, + addrv4_rem, addrv6_rem, 1, 1); +} + +/* Test API osmo_sock_init2_multiaddr with several local/remote address */ +static int test_sockinit2_multiaddr_several(void) +{ + const char *addrv4_localhost[] = { "127.0.0.1", "127.0.0.2" }; + const char *addrv6_localhost[] = { "::1" }; + + return test_sockinit2_multiaddr(addrv4_localhost, addrv6_localhost, + addrv4_localhost, addrv6_localhost, 2, 1); +} + +/* Test API osmo_sock_init2_multiaddr with several local/remote address, using both ipv4+v6 */ +static int test_sockinit2_multiaddr_mixed(void) +{ + const char *addr_localhost[] = { "127.0.0.1", "127.0.0.2", "::1" }; + size_t addr_size = ARRAY_SIZE(addr_localhost); + + int listen_fd, listen_port, fd; + + printf("Checking osmo_sock_init2_multiaddr(AF_UNSPEC) BIND on AF_INET IPv4+v6 fails\n"); + listen_fd = osmo_sock_init2_multiaddr(AF_INET, SOCK_STREAM, IPPROTO_SCTP, + addr_localhost, addr_size, 0, + NULL, 0, 0, OSMO_SOCK_F_BIND); + OSMO_ASSERT(listen_fd < 0); + + printf("Checking osmo_sock_init2_multiaddr(AF_UNSPEC) BIND on AF_INET6 IPv4+v6 fails\n"); + listen_fd = osmo_sock_init2_multiaddr(AF_INET6, SOCK_STREAM, IPPROTO_SCTP, + addr_localhost, addr_size, 0, + NULL, 0, 0, OSMO_SOCK_F_BIND); + OSMO_ASSERT(listen_fd < 0); + + printf("Checking osmo_sock_init2_multiaddr(AF_UNSPEC) BIND on AF_UNSPEC IPv4+v6 succeeds\n"); + listen_fd = osmo_sock_init2_multiaddr(AF_UNSPEC, SOCK_STREAM, IPPROTO_SCTP, + addr_localhost, addr_size, 0, + NULL, 0, 0, OSMO_SOCK_F_BIND); + OSMO_ASSERT(listen_fd >= 0); + + listen_port = sock_get_local_port(listen_fd, true); + + printf("Checking osmo_sock_init2_multiaddr(AF_UNSPEC) BIND + CONNECT on IPv4\n"); + fd = osmo_sock_init2_multiaddr(AF_UNSPEC, SOCK_STREAM, IPPROTO_SCTP, + addr_localhost, addr_size, 0, + addr_localhost, addr_size, listen_port, + OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT); + OSMO_ASSERT(fd >= 0); + close(fd); + + close(listen_fd); + return 0; +} +#endif /* ifdef HAVE_LIBSCTP */ const struct log_info_cat default_categories[] = { }; @@ -164,6 +335,11 @@ test_sockinit(); test_sockinit2(); +#ifdef HAVE_LIBSCTP + test_sockinit2_multiaddr_simple(); + test_sockinit2_multiaddr_several(); + test_sockinit2_multiaddr_mixed(); +#endif /* ifdef HAVE_LIBSCTP */ return EXIT_SUCCESS; } diff --git a/tests/socket/socket_test.err b/tests/socket/socket_test.err index 0f0f8da..a240196 100644 --- a/tests/socket/socket_test.err +++ b/tests/socket/socket_test.err @@ -2,3 +2,11 @@ invalid: you have to specify either BIND or CONNECT flags Unable to find a common protocol (IPv4 or IPv6) for local host: 127.0.0.1 and remote host: ::1. Unable to find a common protocol (IPv4 or IPv6) for local host: ::1 and remote host: 127.0.0.1. +invalid: you have to specify either BIND or CONNECT flags +invalid v4 vs v6 in local vs remote addresses +invalid v4 vs v6 in local vs remote addresses +invalid: you have to specify either BIND or CONNECT flags +invalid v4 vs v6 in local vs remote addresses +invalid v4 vs v6 in local vs remote addresses +getaddrinfo returned NULL: ::1:0: Transport endpoint is not connected +getaddrinfo returned NULL: 127.0.0.1:0: Transport endpoint is not connected diff --git a/tests/socket/socket_test.ok b/tests/socket/socket_test.ok index 4265be8..959fa84 100644 --- a/tests/socket/socket_test.ok +++ b/tests/socket/socket_test.ok @@ -9,3 +9,27 @@ Checking osmo_sock_init2(AF_UNSPEC) must fail on mixed IPv6 & IPv4 Checking osmo_sock_init2(AF_UNSPEC) BIND + CONNECT on IPv4 Checking osmo_sock_init2(AF_UNSPEC) BIND + CONNECT on IPv6 +Checking osmo_sock_init2_multiaddr() with bind to a random local SCTP IPv4 port +Checking osmo_sock_init2_multiaddr() with bind to a random local SCTP IPv6 port +Checking osmo_sock_init2_multiaddr() for OSMO_SOCK_F_NONBLOCK +Checking osmo_sock_init2_multiaddr() for invalid flags +Checking osmo_sock_init2_multiaddr() for combined BIND + CONNECT +Checking osmo_sock_init2_multiaddr(AF_UNSPEC) must fail on mixed IPv4 & IPv6 +Checking osmo_sock_init2_multiaddr(AF_UNSPEC) must fail on mixed IPv6 & IPv4 +Checking osmo_sock_init2_multiaddr(AF_UNSPEC) BIND + CONNECT on IPv4 +Checking osmo_sock_init2_multiaddr(AF_UNSPEC) BIND + CONNECT on IPv6 +Done +Checking osmo_sock_init2_multiaddr() with bind to a random local SCTP IPv4 port +Checking osmo_sock_init2_multiaddr() with bind to a random local SCTP IPv6 port +Checking osmo_sock_init2_multiaddr() for OSMO_SOCK_F_NONBLOCK +Checking osmo_sock_init2_multiaddr() for invalid flags +Checking osmo_sock_init2_multiaddr() for combined BIND + CONNECT +Checking osmo_sock_init2_multiaddr(AF_UNSPEC) must fail on mixed IPv4 & IPv6 +Checking osmo_sock_init2_multiaddr(AF_UNSPEC) must fail on mixed IPv6 & IPv4 +Checking osmo_sock_init2_multiaddr(AF_UNSPEC) BIND + CONNECT on IPv4 +Checking osmo_sock_init2_multiaddr(AF_UNSPEC) BIND + CONNECT on IPv6 +Done +Checking osmo_sock_init2_multiaddr(AF_UNSPEC) BIND on AF_INET IPv4+v6 fails +Checking osmo_sock_init2_multiaddr(AF_UNSPEC) BIND on AF_INET6 IPv4+v6 fails +Checking osmo_sock_init2_multiaddr(AF_UNSPEC) BIND on AF_UNSPEC IPv4+v6 succeeds +Checking osmo_sock_init2_multiaddr(AF_UNSPEC) BIND + CONNECT on IPv4 -- To view, visit https://gerrit.osmocom.org/c/libosmocore/+/19724 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Change-Id: I36d8ab85d92bba4d6adb83bc1875eb61094ed2ef Gerrit-Change-Number: 19724 Gerrit-PatchSet: 1 Gerrit-Owner: pespin <pespin at sysmocom.de> Gerrit-MessageType: newchange -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200819/d1ed2aca/attachment.htm>