Repository navigation
Conversation
curl >= 8.x gates lib/select.c on HAVE_POLL; HAVE_POLL_FINE is the pre-8.x name. Without HAVE_POLL libcurl falls back to select(), and VERIFY_SOCK rejects any fd >= FD_SETSIZE (1024): the connect succeeds, SO_ERROR is 0, and cf_socket_connect still returns CURLE_COULDNT_CONNECT and closes the socket. Observed in production with ~130+ concurrent proxied clients.
|
Heads-up for reviewers and for anyone consuming this through Short version: with The isahc fix is to treat |
Fixes #684
What
Defines
HAVE_POLLincurl-sys/build.rsfor non-Apple Unix targets, next to the existingHAVE_POLL_FINE.Why
curl commit
c72cefea0(first released in curl 8.11.0) changedlib/select.cto gate thepoll()implementation onHAVE_POLL;HAVE_POLL_FINEis the pre-8.11 name and is no longer referenced anywhere undercurl/lib/. Sincebuild.rsonly defines the old name, every vendored (static-curl) build on Linux and other non-Apple Unix targets has been compiling libcurl with theselect()fallback.In that fallback
Curl_poll()runsVERIFY_SOCK(), which rejects any descriptor>= FD_SETSIZE(1024). The effect is that once a process has more than ~1024 open file descriptors, new connections landing on a high fd number fail right after a successful TCP handshake withCURLE_COULDNT_CONNECT("Could not connect to server"), with no further detail becauseverifyconnect()overwrites the errno with the (zero)SO_ERROR. Details, strace output and the fd-number split are in #684.HAVE_POLL_FINEis kept so that pinning an older curl checkout keeps working. Apple targets are intentionally unchanged.Verification
Built a binary against the patched crate (curl 8.15.0 vendored) and traced it:
poll()now appears beforegetsockopt(SOL_SOCKET, SO_ERROR)for every new socket, and sockets with fd >= 1024 connect and send normally. Without the patch the same binary showsgetsockoptimmediately followed byclose()and the transfer fails with error 7.The change is identical on
main(curl 8.22); the branch is based on the0.4.83+curl-8.15.0release commit (8b34786) so it can also be consumed as a[patch.crates-io]override for that pinned release.