From: Stefan Metzmacher Date: Thu, 22 May 2025 08:06:53 +0000 (+0200) Subject: async_sock: move samba_socket_{poll,sock,poll_or_sock}_error() from util_net.c to... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=69eb53d4cbffc76b9c089ef11840c1008dc96ff3;p=thirdparty%2Fsamba.git async_sock: move samba_socket_{poll,sock,poll_or_sock}_error() from util_net.c to async_sock.c The change to LGPL is also intended. It will be used in the the next commit that adds wait_for_error_send/recv. Signed-off-by: Stefan Metzmacher Reviewed-by: Volker Lendecke --- diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 06ffb942967..fadcb4f3daa 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -24,6 +24,7 @@ #include "replace.h" #include "system/network.h" #include "system/filesys.h" +#include "system/select.h" #include #include #include "lib/async_req/async_sock.h" @@ -33,6 +34,104 @@ /* Note: lib/util/ is currently GPL */ #include "lib/util/tevent_unix.h" #include "lib/util/samba_util.h" +#include "lib/util/select.h" + +int samba_socket_poll_error(int fd) +{ + struct pollfd pfd = { + .fd = fd, +#ifdef POLLRDHUP + .events = POLLRDHUP, /* POLLERR and POLLHUP are not needed */ +#endif + }; + int ret; + + errno = 0; + ret = sys_poll_intr(&pfd, 1, 0); + if (ret == 0) { + return 0; + } + if (ret != 1) { + return POLLNVAL; + } + + if (pfd.revents & POLLERR) { + return POLLERR; + } + if (pfd.revents & POLLHUP) { + return POLLHUP; + } +#ifdef POLLRDHUP + if (pfd.revents & POLLRDHUP) { + return POLLRDHUP; + } +#endif + + /* should never be reached! */ + return POLLNVAL; +} + +int samba_socket_sock_error(int fd) +{ + int ret, error = 0; + socklen_t len = sizeof(error); + + /* + * if no data is available check if the socket is in error state. For + * dgram sockets it's the way to return ICMP error messages of + * connected sockets to the caller. + */ + ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len); + if (ret == -1) { + return ret; + } + if (error != 0) { + errno = error; + return -1; + } + return 0; +} + +int samba_socket_poll_or_sock_error(int fd) +{ + int ret; + int poll_error = 0; + + poll_error = samba_socket_poll_error(fd); + if (poll_error == 0) { + return 0; + } + +#ifdef POLLRDHUP + if (poll_error == POLLRDHUP) { + errno = ECONNRESET; + return -1; + } +#endif + + if (poll_error == POLLHUP) { + errno = EPIPE; + return -1; + } + + /* + * POLLERR and POLLNVAL fallback to + * getsockopt(fd, SOL_SOCKET, SO_ERROR) + * and force EPIPE as fallback. + */ + + errno = 0; + ret = samba_socket_sock_error(fd); + if (ret == 0) { + errno = EPIPE; + } + + if (errno == 0) { + errno = EPIPE; + } + + return -1; +} struct async_connect_state { int fd; diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 780195e3725..2f84b7b8ec0 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -28,6 +28,20 @@ #include #include "system/network.h" +/* + * check for POLLERR or POLL*HUP + */ +int samba_socket_poll_error(int fd); +/* + * getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) + */ +int samba_socket_sock_error(int fd); +/* + * check for POLL*HUP and fallback to + * getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) + */ +int samba_socket_poll_or_sock_error(int fd); + struct tevent_req *async_connect_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const struct sockaddr *address, socklen_t address_len, diff --git a/lib/async_req/wscript_build b/lib/async_req/wscript_build index 4486a5b2f06..fbf712d57f2 100644 --- a/lib/async_req/wscript_build +++ b/lib/async_req/wscript_build @@ -4,7 +4,7 @@ bld.SAMBA_SUBSYSTEM('LIBASYNC_REQ', source='async_sock.c', public_deps='talloc tevent iov_buf', - deps='tevent-util socket-blocking' + deps='tevent-util samba-util socket-blocking' ) bld.SAMBA_BINARY('async_connect_send_test', diff --git a/lib/tsocket/tsocket_bsd.c b/lib/tsocket/tsocket_bsd.c index 83f2efcfc84..aab30f12cb5 100644 --- a/lib/tsocket/tsocket_bsd.c +++ b/lib/tsocket/tsocket_bsd.c @@ -30,6 +30,7 @@ #include "lib/util/blocking.h" #include "lib/util/util_net.h" #include "lib/util/samba_util.h" +#include "lib/async_req/async_sock.h" static int tsocket_bsd_error_from_errno(int ret, int sys_errno, diff --git a/lib/tsocket/wscript b/lib/tsocket/wscript index fa284a78f25..f50d9c54483 100644 --- a/lib/tsocket/wscript +++ b/lib/tsocket/wscript @@ -13,7 +13,7 @@ def build(bld): bld.SAMBA_SUBSYSTEM( 'LIBTSOCKET', source='tsocket.c tsocket_helpers.c tsocket_bsd.c', - public_deps='talloc tevent iov_buf socket-blocking', + public_deps='talloc tevent iov_buf socket-blocking LIBASYNC_REQ', public_headers='tsocket.h tsocket_internal.h' ) diff --git a/lib/util/util_net.c b/lib/util/util_net.c index 48c9552558b..5c19cc90003 100644 --- a/lib/util/util_net.c +++ b/lib/util/util_net.c @@ -27,8 +27,6 @@ #include "system/network.h" #include "system/locale.h" #include "system/filesys.h" -#include "system/select.h" -#include "lib/util/select.h" #include "lib/util/util_net.h" #undef strcasecmp @@ -1141,100 +1139,3 @@ bool samba_sockaddr_get_port(const struct samba_sockaddr *sa, uint16_t *port) #endif return false; } - -int samba_socket_poll_error(int fd) -{ - struct pollfd pfd = { - .fd = fd, -#ifdef POLLRDHUP - .events = POLLRDHUP, /* POLLERR and POLLHUP are not needed */ -#endif - }; - int ret; - - errno = 0; - ret = sys_poll_intr(&pfd, 1, 0); - if (ret == 0) { - return 0; - } - if (ret != 1) { - return POLLNVAL; - } - - if (pfd.revents & POLLERR) { - return POLLERR; - } - if (pfd.revents & POLLHUP) { - return POLLHUP; - } -#ifdef POLLRDHUP - if (pfd.revents & POLLRDHUP) { - return POLLRDHUP; - } -#endif - - /* should never be reached! */ - return POLLNVAL; -} - -int samba_socket_sock_error(int fd) -{ - int ret, error = 0; - socklen_t len = sizeof(error); - - /* - * if no data is available check if the socket is in error state. For - * dgram sockets it's the way to return ICMP error messages of - * connected sockets to the caller. - */ - ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len); - if (ret == -1) { - return ret; - } - if (error != 0) { - errno = error; - return -1; - } - return 0; -} - -int samba_socket_poll_or_sock_error(int fd) -{ - int ret; - int poll_error = 0; - - poll_error = samba_socket_poll_error(fd); - if (poll_error == 0) { - return 0; - } - -#ifdef POLLRDHUP - if (poll_error == POLLRDHUP) { - errno = ECONNRESET; - return -1; - } -#endif - - if (poll_error == POLLHUP) { - errno = EPIPE; - return -1; - } - - /* - * POLLERR and POLLNVAL fallback to - * getsockopt(fd, SOL_SOCKET, SO_ERROR) - * and force EPIPE as fallback. - */ - - errno = 0; - ret = samba_socket_sock_error(fd); - if (ret == 0) { - errno = EPIPE; - } - - if (errno == 0) { - errno = EPIPE; - } - - return -1; -} diff --git a/lib/util/util_net.h b/lib/util/util_net.h index 30399d81105..adfe749d4b7 100644 --- a/lib/util/util_net.h +++ b/lib/util/util_net.h @@ -128,18 +128,4 @@ bool sockaddr_storage_to_samba_sockaddr( bool samba_sockaddr_set_port(struct samba_sockaddr *sa, uint16_t port); bool samba_sockaddr_get_port(const struct samba_sockaddr *sa, uint16_t *port); -/* - * check for POLLERR or POLL*HUP - */ -int samba_socket_poll_error(int fd); -/* - * getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) - */ -int samba_socket_sock_error(int fd); -/* - * check for POLL*HUP and fallback to - * getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) - */ -int samba_socket_poll_or_sock_error(int fd); - #endif /* _SAMBA_UTIL_NET_H_ */ diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 3b692fdca87..ff0e708e938 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -33,6 +33,7 @@ #include "../lib/util/bitmap.h" #include "../librpc/gen_ndr/krb5pac.h" #include "lib/util/iov_buf.h" +#include "lib/async_req/async_sock.h" #include "auth.h" #include "libcli/smb/smbXcli_base.h" #include "source3/lib/substitute.h"