lib/tsocket: add tstream_bsd_fail_readv_first_error() This gives the caller the option to fail immediately if TEVENT_FD_ERROR appear even with pending bytes in the recv queue. Servers typically want to activate this in order to avoid pointless work, while clients typically want to read pending responses from the recv queue. Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/tsocket: make use of TEVENT_FD_ERROR in tstream_bsd_fde_handler() This makes the logic introduced to fix bug #15202 simpler. While developing this I noticed that a lot of callers rely on the fact that they can read the pending bytes out of the recv queue before EOF is reported. So I changed the code handle TEVENT_FD_ERROR together with TEVENT_FD_READ in a way that keep the existing callers happy. In the next step we'll add a way to let callers opt-in in order to fail immediately if TEVENT_FD_ERROR appears (even if there are pending bytes remaining in the recv queue). BUG: https://bugzilla.samba.org/show_bug.cgi?id=15202 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/tsocket: let tstream_bsd_connect_send() use TEVENT_FD_ERROR instead of TEVENT_FD_READ This mostly cosmetic, but now that we have TEVENT_FD_ERROR we should use it. Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/tsocket: make use of samba_socket_sock_error() This is nicer than calling getsockopt(state->fd, SOL_SOCKET, SO_ERROR) directly. Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
tsocket: Increase tcp_user_timeout max_loops Often, on rackspace GitLab CI runners, we get: UNEXPECTED(failure): samba.unittests.tsocket_tstream.test_tstream_more_tcp_user_timeout_spin(none) REASON: Exception: Exception: 0xf == 0xf ../../lib/tsocket/tests/test_tstream.c:405: error: Failure! This allows us more spins before we fail the test. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15328 Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
lib/tsocket: avoid endless cpu-spinning in tstream_bsd_fde_handler() There were some reports that strace output an LDAP server socket is in CLOSE_WAIT state, returning EAGAIN for writev over and over (after a call to epoll() each time). In the tstream_bsd code the problem happens when we have a pending writev_send, while there's no readv_send pending. In that case we still ask for TEVENT_FD_READ in order to notice connection errors early, so we try to call writev even if the socket doesn't report TEVENT_FD_WRITE. And there are situations where we do that over and over again. It happens like this with a Linux kernel: tcp_fin() has this: struct tcp_sock *tp = tcp_sk(sk); inet_csk_schedule_ack(sk); sk->sk_shutdown |= RCV_SHUTDOWN; sock_set_flag(sk, SOCK_DONE); switch (sk->sk_state) { case TCP_SYN_RECV: case TCP_ESTABLISHED: /* Move to CLOSE_WAIT */ tcp_set_state(sk, TCP_CLOSE_WAIT); inet_csk_enter_pingpong_mode(sk); break; It means RCV_SHUTDOWN gets set as well as TCP_CLOSE_WAIT, but sk->sk_err is not changed to indicate an error. tcp_sendmsg_locked has this: ... err = -EPIPE; if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) goto do_error; while (msg_data_left(msg)) { int copy = 0; skb = tcp_write_queue_tail(sk); if (skb) copy = size_goal - skb->len; if (copy <= 0 || !tcp_skb_can_collapse_to(skb)) { bool first_skb; new_segment: if (!sk_stream_memory_free(sk)) goto wait_for_space; ... wait_for_space: set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); if (copied) tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH, size_goal); err = sk_stream_wait_memory(sk, &timeo); if (err != 0) goto do_error; It means if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) doesn't hit as we only have RCV_SHUTDOWN and sk_stream_wait_memory returns -EAGAIN. tcp_poll has this: if (sk->sk_shutdown & RCV_SHUTDOWN) mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP; So we'll get EPOLLIN | EPOLLRDNORM | EPOLLRDHUP triggering TEVENT_FD_READ and writev/sendmsg keeps getting EAGAIN. So we need to always clear TEVENT_FD_READ if we don't have readable handler in order to avoid burning cpu. But we turn it on again after a timeout of 1 second in order to monitor the error state of the connection. And now that our tsocket_bsd_error() helper checks for POLLRDHUP, we can check if the socket is in an error state before calling the writable handler when TEVENT_FD_READ was reported. Only on error we'll call the writable handler, which will pick the error without calling writev(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=15202 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
lib/tsocket: remember the first error as tstream_bsd->error If we found that the connection is broken, there's no point in trying to use it anymore, so just return the first error we detected. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15202 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
lib/tsocket: check for errors indicated by poll() before getsockopt(fd, SOL_SOCKET, SO_ERROR) This also returns an error if we got TCP_FIN from the peer, which is only reported by an explicit POLLRDHUP check. Also on FreeBSD getsockopt(fd, SOL_SOCKET, SO_ERROR) fetches and resets the error, so a 2nd call no longer returns an error. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15202 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
lib/tsocket: Add tests for loop on EAGAIN BUG: https://bugzilla.samba.org/show_bug.cgi?id=15202 Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> Signed-off-by: Andrew Bartlett <abartlet@samba.org> Signed-off-by: Stefan Metzmacher <metze@samba.org>
selftest: test tsocket_address_inet_from_hostport_strings Signed-off-by: Uri Simchoni <uri@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org> Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> Autobuild-Date(master): Tue Sep 28 10:34:12 UTC 2021 on sn-devel-184
lib/tsocket: new function to parse host port strs. tsocket_address_inet_from_hostport_strings() on top of tsocket_address_inet_from_strings(), implementing the ability to parse a port number appended to an IPv6 or IPv4 address. IPv6 addresses can also optionally have square brackets around them, but these are needed to specify the port number as colon is used to delimit port from the IP address in the string. Note that this code just recognises and parses the strings with port given, or just IPv6 with square brackets. The rest of the parsing is passed on to tsocket_address_inet_from strings(), and errors from there passed back up the stack. Signed-off-by: Matthew Grant <grantma@mattgrant.net.nz> Reviewed-by: Uri Simchoni <uri@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/tsocket: Fix build on Freebsd This fixes the following build error on freebsd. [1567/3959] Compiling lib/tsocket/tsocket_bsd.c ../../lib/tsocket/tsocket_bsd.c:415:8: error: use of undeclared identifier 'EAI_ADDRFAMILY' case EAI_ADDRFAMILY: ^ On FreeBSD EAI_ADDRFAMILY is obsoleted. Here's the relevant excerpt from netdb.h on FreeBSD 13. ----------------------------------------------------------------- /* * Error return codes from gai_strerror(3), see RFC 3493. */ #if 0 /* Obsoleted on RFC 2553bis-02 */ #define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ #endif ----------------------------------------------------------------- Signed-off-by: Amitay Isaacs <amitay@gmail.com> Reviewed-by: Uri Simchoni <uri@samba.org> Autobuild-User(master): Jeremy Allison <jra@samba.org> Autobuild-Date(master): Thu Sep 16 19:42:19 UTC 2021 on sn-devel-184
tsocket: set errno on some failures of tsocket_address_inet_from_strings Fix setting errno on all failure modes of tsocket_address_inet_from_strings. Signed-off-by: Uri Simchoni <uri@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org> Autobuild-User(master): Jeremy Allison <jra@samba.org> Autobuild-Date(master): Mon Sep 13 22:27:59 UTC 2021 on sn-devel-184