From 9e9938a62a2e52859e4d2dd9b07e1aa9a6a88e9d Mon Sep 17 00:00:00 2001 From: Min RK Date: Mon, 26 Aug 2024 13:03:17 +0200 Subject: [PATCH 1/2] ipc connect can fail, even after bind --- src/ip.cpp | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/ip.cpp b/src/ip.cpp index 1aaf6ad6b1..db10b136f5 100644 --- a/src/ip.cpp +++ b/src/ip.cpp @@ -23,6 +23,10 @@ #include "tcp.hpp" #ifdef ZMQ_HAVE_IPC #include "ipc_address.hpp" +// Don't try ipc if it fails once +namespace zmq { + static bool try_ipc_first = true; +} #endif #include @@ -555,9 +559,14 @@ int zmq::make_fdpair (fd_t *r_, fd_t *w_) // It appears that a lack of runtime AF_UNIX support // can fail in more than one way. - // At least: open_socket can fail or later in bind + // At least: open_socket can fail or later in bind or even in connect after bind bool ipc_fallback_on_tcpip = true; + if (!zmq::try_ipc_first) { + // a past ipc attempt failed, skip straight to try_tcpip in the future; + goto try_tcpip; + } + // Create a listening socket. const SOCKET listener = open_socket (AF_UNIX, SOCK_STREAM, 0); if (listener == retired_fd) { @@ -585,8 +594,7 @@ int zmq::make_fdpair (fd_t *r_, fd_t *w_) goto error_closelistener; } // if we got here, ipc should be working, - // so raise any remaining errors - ipc_fallback_on_tcpip = false; + // but there are at least some cases where connect can still fail // Listen for incoming connections. rc = listen (listener, 1); @@ -597,11 +605,11 @@ int zmq::make_fdpair (fd_t *r_, fd_t *w_) rc = getsockname (listener, reinterpret_cast (&lcladdr), &lcladdr_len); - wsa_assert (rc != -1); + wsa_assert (rc == 0); // Create the client socket. *w_ = open_socket (AF_UNIX, SOCK_STREAM, 0); - if (*w_ == -1) { + if (*w_ == retired_fd) { errno = wsa_error_to_errno (WSAGetLastError ()); goto error_closelistener; } @@ -609,12 +617,16 @@ int zmq::make_fdpair (fd_t *r_, fd_t *w_) // Connect to the remote peer. rc = ::connect (*w_, reinterpret_cast (&lcladdr), lcladdr_len); - if (rc == -1) { + if (rc != 0) { + errno = wsa_error_to_errno (WSAGetLastError ()); goto error_closeclient; } + // if we got here, ipc should be working, + // so raise any remaining errors + ipc_fallback_on_tcpip = false; *r_ = accept (listener, NULL, NULL); - errno_assert (*r_ != -1); + wsa_assert (*r_ != retired_fd); // Close the listener socket, we don't need it anymore. rc = closesocket (listener); @@ -636,6 +648,7 @@ int zmq::make_fdpair (fd_t *r_, fd_t *w_) saved_errno = errno; rc = closesocket (*w_); wsa_assert (rc == 0); + *w_ = retired_fd; errno = saved_errno; error_closelistener: @@ -663,9 +676,13 @@ int zmq::make_fdpair (fd_t *r_, fd_t *w_) try_tcpip: // try to fallback to TCP/IP - // TODO: maybe remember this decision permanently? -#endif - + rc = make_fdpair_tcpip (r_, w_); + if (rc == 0 && zmq::try_ipc_first) { + // ipc didn't work but tcp/ip did; skip ipc in the future + zmq::try_ipc_first = false; + } + return rc; +#endif // ZMQ_HAVE_IPC return make_fdpair_tcpip (r_, w_); #elif defined ZMQ_HAVE_OPENVMS From 27696d7eaaed945fcf84aae4dfc999e81ca28266 Mon Sep 17 00:00:00 2001 From: Min RK Date: Mon, 26 Aug 2024 14:00:43 +0200 Subject: [PATCH 2/2] clang-format --- src/ip.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ip.cpp b/src/ip.cpp index db10b136f5..30d70eb022 100644 --- a/src/ip.cpp +++ b/src/ip.cpp @@ -24,8 +24,9 @@ #ifdef ZMQ_HAVE_IPC #include "ipc_address.hpp" // Don't try ipc if it fails once -namespace zmq { - static bool try_ipc_first = true; +namespace zmq +{ +static bool try_ipc_first = true; } #endif