The branch, master has been updated via 0b33070 Bump version to 1.5.1 via d991f24 socket_wrapper: add SOCKET_WRAPPER_ALLOW_DGRAM_SEQPACKET_FALLBACK support from 028b916 Bump version to 1.5.0
https://git.samba.org/?p=socket_wrapper.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 0b3307005470b9bb4d561a3d4be6c46f70ef4e36 Author: Stefan Metzmacher <me...@samba.org> Date: Mon May 26 13:47:08 2025 +0200 Bump version to 1.5.1 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit d991f2478a6904977091b854702b21c191006cc4 Author: Stefan Metzmacher <me...@samba.org> Date: Mon May 19 20:37:20 2025 +0200 socket_wrapper: add SOCKET_WRAPPER_ALLOW_DGRAM_SEQPACKET_FALLBACK support If the server of a IPPROTO_QUIC socket used SOCK_SEQPACKET it is desired that a client using IPPROTO_UDP in connected mode is able to talk to the server. So we need to catch EPROTOTYPE from libc_connect() and reopen the socket using SOCK_SEQPACKET and retry libc_connect(). Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> ----------------------------------------------------------------------- Summary of changes: CHANGELOG | 3 ++ CMakeLists.txt | 4 +-- src/socket_wrapper.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 101 insertions(+), 3 deletions(-) Changeset truncated at 500 lines: diff --git a/CHANGELOG b/CHANGELOG index 367d9a3..eb572e0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ CHANGELOG ========= +version 1.5.1 (released 2025-05-26) + * Added support for SOCKET_WRAPPER_ALLOW_DGRAM_SEQPACKET_FALLBACK + version 1.5.0 (released 2025-05-06) * Added support for quic_ko_wrapper * Fixed pcap frames generation for recv(m)msg and recvfrom diff --git a/CMakeLists.txt b/CMakeLists.txt index f5a480e..1fdb660 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules") include(DefineCMakeDefaults) include(DefineCompilerFlags) -project(socket_wrapper VERSION 1.5.0 LANGUAGES C) +project(socket_wrapper VERSION 1.5.1 LANGUAGES C) # global needed variables set(APPLICATION_NAME ${PROJECT_NAME}) @@ -25,7 +25,7 @@ set(APPLICATION_NAME ${PROJECT_NAME}) # Increment PATCH. set(LIBRARY_VERSION_MAJOR 0) set(LIBRARY_VERSION_MINOR 5) -set(LIBRARY_VERSION_PATCH 0) +set(LIBRARY_VERSION_PATCH 1) set(LIBRARY_VERSION "${LIBRARY_VERSION_MAJOR}.${LIBRARY_VERSION_MINOR}.${LIBRARY_VERSION_PATCH}") set(LIBRARY_SOVERSION ${LIBRARY_VERSION_MAJOR}) diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c index c4df8ed..bc4000c 100644 --- a/src/socket_wrapper.c +++ b/src/socket_wrapper.c @@ -324,6 +324,7 @@ struct socket_info */ int family; + int type_flags; /* SOCK_CLOEXEC or SOCK_NONBLOCK */ int type; int protocol; int opt_type; @@ -3804,6 +3805,7 @@ static int swrap_socket(int family, int type, int protocol, int allow_quic) /* however, the rest of the socket_wrapper code expects just * the type, not the flags */ si->type = real_type; + si->type_flags = type & ~real_type; si->protocol = protocol; si->opt_type = opt_type; si->opt_protocol = opt_protocol; @@ -4074,6 +4076,7 @@ static int swrap_accept(int s, child_si = &new_si; child_si->family = parent_si->family; + child_si->type_flags = parent_si->type_flags; child_si->type = parent_si->type; child_si->protocol = parent_si->protocol; child_si->opt_type = parent_si->opt_type; @@ -5628,7 +5631,7 @@ static int swrap_sendmsg_filter_cmsg_sol_socket(const struct cmsghdr *cmsg, return rc; } -static const uint64_t swrap_unix_scm_right_magic = 0x8e0e13f27c42fc37; +static const uint64_t swrap_unix_scm_right_magic = 0x8e0e13f27c42fc38; /* * We only allow up to 6 fds at a time @@ -6504,6 +6507,90 @@ static ssize_t swrap_recvmsg_after_unix(struct msghdr *msg_tmp, #endif /* ! HAVE_STRUCT_MSGHDR_MSG_CONTROL */ } +static int swrap_protocol_fallback(int fd, struct socket_info *si) +{ + const char *env_var = "SOCKET_WRAPPER_ALLOW_DGRAM_SEQPACKET_FALLBACK"; + const char *env_allow_dgram_seqpacket_fallback = NULL; + bool allow_dgram_seqpacket_fallback = false; + struct swrap_address un_addr = { + .sa_socklen = sizeof(struct sockaddr_un), + .sa = { + .un = si->un_addr, + }, + }; + int new_type; + int tfd = -1; + int rc; + + if (si->is_server) { + errno = EHOSTUNREACH; + return -1; + } + + if (!si->connected) { + errno = EHOSTUNREACH; + return -1; + } + + if (si->opt_type != SOCK_DGRAM) { + errno = EHOSTUNREACH; + return -1; + } + + if (si->opt_protocol != IPPROTO_UDP) { + errno = EHOSTUNREACH; + return -1; + } + + env_allow_dgram_seqpacket_fallback = getenv(env_var); + if (env_allow_dgram_seqpacket_fallback != NULL && + strlen(env_allow_dgram_seqpacket_fallback) >= 1 && + strcmp(env_allow_dgram_seqpacket_fallback, "0") != 0) + { + allow_dgram_seqpacket_fallback = true; + } + + if (!allow_dgram_seqpacket_fallback) { + errno = EHOSTUNREACH; + return -1; + } + + /* + * Change the low level socket to + * SOCK_SEQPACKET as the other end + * may used IPPROTO_QUIC with SOCK_SEQPACKET. + */ + new_type = SOCK_SEQPACKET | si->type_flags; + tfd = libc_socket(AF_UNIX, new_type, 0); + if (tfd == -1) { + errno = EHOSTUNREACH; + return -1; + } + + /* + * Now rebind the local end + */ + unlink(un_addr.sa.un.sun_path); + rc = libc_bind(tfd, &un_addr.sa.s, un_addr.sa_socklen); + if (rc == -1) { + close(tfd); + errno = EHOSTUNREACH; + return -1; + } + + /* + * Now replace the callers known fd. + */ + rc = libc_dup2(tfd, fd); + if (rc == -1) { + close(tfd); + errno = EHOSTUNREACH; + return -1; + } + + return 0; +} + static ssize_t swrap_sendmsg_before(int fd, struct socket_info *si, struct msghdr *msg, @@ -6643,6 +6730,14 @@ static ssize_t swrap_sendmsg_before(int fd, ret = libc_connect(fd, (struct sockaddr *)(void *)tmp_un, sizeof(*tmp_un)); + if (ret == -1 && errno == EPROTOTYPE) { + ret = swrap_protocol_fallback(fd, si); + if (ret == 0) { + ret = libc_connect(fd, + (struct sockaddr *)(void *)tmp_un, + sizeof(*tmp_un)); + } + } /* to give better errors */ if (ret == -1 && errno == ENOENT) { -- Socket Wrapper Repository