mirror of
https://github.com/curl/curl.git
synced 2026-08-25 16:53:33 +03:00
cf-socket: disable TCP SYN retransmissions for localhost on Windows
Suggested-by: Marcel Jamin URL: https://curl.se/mail/lib-2026-08/0002.html URL: https://daniel.haxx.se/blog/2024/08/14/slow-tcp-connect-on-windows/ Closes #22494
This commit is contained in:
parent
9ea48811fe
commit
abcb5349e3
2 changed files with 58 additions and 5 deletions
|
|
@ -81,7 +81,9 @@
|
|||
#include "curlx/version_win32.h"
|
||||
#include "curlx/strerr.h"
|
||||
#include "curlx/strparse.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <mstcpip.h> /* for TCP_INITIAL_RTO_PARAMETERS */
|
||||
#endif
|
||||
|
||||
/* retrieves ip address and port from a sockaddr structure. note it calls
|
||||
* curlx_inet_ntop which sets errno on fail, not SOCKERRNO.
|
||||
|
|
@ -1141,6 +1143,51 @@ static int cf_socktype(int x)
|
|||
return x;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* Offered by mingw-w64 v10+, MS SDK 8.0/~VS2012+ */
|
||||
#ifndef SIO_TCP_INITIAL_RTO
|
||||
#define SIO_TCP_INITIAL_RTO _WSAIOW(IOC_VENDOR, 17)
|
||||
#define TCP_INITIAL_RTO_DEFAULT_RTT 0
|
||||
|
||||
/* !checksrc! disable TYPEDEFSTRUCT 1 */
|
||||
typedef struct _TCP_INITIAL_RTO_PARAMETERS {
|
||||
USHORT Rtt;
|
||||
UCHAR MaxSynRetransmissions;
|
||||
} TCP_INITIAL_RTO_PARAMETERS;
|
||||
#endif
|
||||
|
||||
#ifndef TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS
|
||||
#define TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS 0xFE /* -2 */
|
||||
#endif
|
||||
|
||||
static bool targets_localhost(struct cf_socket_ctx *ctx)
|
||||
{
|
||||
return (((ctx->addr.family == AF_INET) &&
|
||||
!strcmp(ctx->ip.remote_ip, "127.0.0.1")) ||
|
||||
((ctx->addr.family == AF_INET6) &&
|
||||
!strcmp(ctx->ip.remote_ip, "::1")));
|
||||
}
|
||||
|
||||
/* disable TCP SYN retransmissions for localhost connection on Windows to
|
||||
detect problems faster */
|
||||
static void tcplocalhost(struct Curl_cfilter *cf,
|
||||
curl_socket_t sockfd)
|
||||
{
|
||||
if(targets_localhost(cf->ctx)) {
|
||||
TCP_INITIAL_RTO_PARAMETERS rto;
|
||||
DWORD bytes = 0;
|
||||
memset(&rto, 0, sizeof(rto));
|
||||
rto.Rtt = TCP_INITIAL_RTO_DEFAULT_RTT;
|
||||
rto.MaxSynRetransmissions = TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS;
|
||||
(void)WSAIoctl(sockfd, SIO_TCP_INITIAL_RTO, &rto, sizeof(rto),
|
||||
NULL, 0, &bytes, NULL, NULL);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define tcplocalhost(x, y)
|
||||
#endif
|
||||
|
||||
static CURLcode cf_socket_open(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
|
|
@ -1214,11 +1261,15 @@ static CURLcode cf_socket_open(struct Curl_cfilter *cf,
|
|||
is_tcp = (ctx->addr.family == AF_INET) &&
|
||||
cf_socktype(ctx->addr.socktype) == SOCK_STREAM;
|
||||
#endif
|
||||
if(is_tcp && data->set.tcp_nodelay)
|
||||
tcpnodelay(cf, data, ctx->sock);
|
||||
if(is_tcp) {
|
||||
if(data->set.tcp_nodelay)
|
||||
tcpnodelay(cf, data, ctx->sock);
|
||||
|
||||
if(is_tcp && data->set.tcp_keepalive)
|
||||
tcpkeepalive(cf, data, ctx->sock);
|
||||
if(data->set.tcp_keepalive)
|
||||
tcpkeepalive(cf, data, ctx->sock);
|
||||
|
||||
tcplocalhost(cf, ctx->sock);
|
||||
}
|
||||
|
||||
if(data->set.fsockopt) {
|
||||
/* activate callback for setting socket options */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue