cf-socket: don't bypass fclosesocket callback if cancelled before connect

After upgrading to 8.1.2 from 7.84.0, I found that sockets were being
closed without calling the fclosesocket callback if a request was
cancelled after the associated socket was created, but before the socket
was connected. This lead to an imbalance of fopensocket & fclosesocket
callbacks, causing problems with a custom event loop integration using
the multi-API.

This was caused by cf_socket_close() calling sclose() directly instead
of calling socket_close() if the socket was not active. For regular TCP
client connections, the socket is activated by cf_socket_active(), which
is only called when the socket completes the connect.

As far as I can tell, this issue has existed since 7.88.0. That is,
since the code in question was introduced by:
    commit 71b7e01610
    Author: Stefan Eissing <stefan@eissing.org>
    Date:   Fri Dec 30 09:14:55 2022 +0100

        lib: connect/h2/h3 refactor

Closes #11439
This commit is contained in:
Chris Paulson-Ellis 2023-07-14 13:15:56 +01:00 committed by Daniel Stenberg
parent e53df4cf08
commit a70d97c46c
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2

View File

@ -871,7 +871,7 @@ static void cf_socket_close(struct Curl_cfilter *cf, struct Curl_easy *data)
/* this is our local socket, we did never publish it */
DEBUGF(LOG_CF(data, cf, "cf_socket_close(%" CURL_FORMAT_SOCKET_T
", not active)", ctx->sock));
sclose(ctx->sock);
socket_close(data, cf->conn, !ctx->accepted, ctx->sock);
ctx->sock = CURL_SOCKET_BAD;
}
Curl_bufq_reset(&ctx->recvbuf);