Networking: don't enable TFO if server doesn't support it

This commit is contained in:
Carter Li
2025-03-18 10:20:23 +08:00
committed by 李通洲
parent 3489cc8fe8
commit 8851821484
4 changed files with 54 additions and 25 deletions
+1
View File
@@ -26,6 +26,7 @@ typedef struct FFNetworkingState {
uint32_t timeout;
bool ipv6;
bool compression; // if true, HTTP content compression will be enabled if supported
bool tfo; // if true, TCP Fast Open will be attempted first, and fallback to traditional connection if it fails
} FFNetworkingState;
const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers);
+38 -19
View File
@@ -19,7 +19,17 @@
// Try to use TCP Fast Open to send data
static const char* tryTcpFastOpen(FFNetworkingState* state)
{
#if !defined(TCP_FASTOPEN) || (defined(__linux__) && !defined(MSG_FASTOPEN))
if (!state->tfo)
{
#ifndef __APPLE__
FF_DEBUG("TCP Fast Open disabled, skipping");
return "TCP Fast Open disabled";
#else
FF_DEBUG("TCP Fast Open disabled, using connectx() to send data");
#endif
}
#if (!defined(__APPLE__) && !defined(TCP_FASTOPEN)) || (defined(__linux__) && !defined(MSG_FASTOPEN))
FF_DEBUG("TCP Fast Open not supported on this system");
FF_UNUSED(state);
return "TCP Fast Open not supported";
@@ -81,7 +91,7 @@ static const char* tryTcpFastOpen(FFNetworkingState* state)
.sae_dstaddr = state->addr->ai_addr,
.sae_dstaddrlen = state->addr->ai_addrlen,
},
SAE_ASSOCID_ANY, CONNECT_DATA_IDEMPOTENT,
SAE_ASSOCID_ANY, state->tfo ? CONNECT_DATA_IDEMPOTENT : 0,
&(struct iovec) {
.iov_base = state->command.chars,
.iov_len = state->command.length,
@@ -91,31 +101,40 @@ static const char* tryTcpFastOpen(FFNetworkingState* state)
return "fcntl(F_SETFL) failed";
}
#endif
if (sent >= 0 || (errno == EAGAIN || errno == EWOULDBLOCK))
if (sent > 0 || (errno == EAGAIN || errno == EWOULDBLOCK
#ifdef __APPLE__
// On macOS EINPROGRESS means the connection cannot be completed immediately
// On Linux, it means the TFO cookie is not available locally
|| errno == EINPROGRESS
#endif
))
{
FF_DEBUG("TCP Fast Open %s (sent=%zd, errno=%d: %s)", errno == 0 ? "succeeded" : "was in progress",
sent, errno, strerror(errno));
FF_DEBUG(
#ifdef __APPLE__
"connectx()"
#else
"sendto()"
#endif
" %s (sent=%zd, errno=%d: %s)", errno == 0 ? "succeeded" : "was in progress",
sent, errno, strerror(errno));
freeaddrinfo(state->addr);
state->addr = NULL;
ffStrbufDestroy(&state->command);
return NULL;
}
if (errno == EINPROGRESS)
{
FF_DEBUG("TCP Fast Open cookie is not available locally");
return "sendto() reports EINPROGRESS";
}
else
{
// Fast Open failed
FF_DEBUG("TCP Fast Open failed: %s (errno=%d)", strerror(errno), errno);
FF_DEBUG(
#ifdef __APPLE__
return "connectx() failed";
"connectx()"
#else
return "sendto() failed";
"sendto()"
#endif
}
" failed: %s (errno=%d)", strerror(errno), errno);
#ifdef __APPLE__
return "connectx() failed";
#else
return "sendto() failed";
#endif
#endif
}
@@ -316,10 +335,10 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
const char* tfoResult = tryTcpFastOpen(state);
if (tfoResult == NULL) {
FF_DEBUG("TCP Fast Open succeeded or in progress");
FF_DEBUG("TryTcpFastOpen succeeded or in progress");
return NULL;
}
FF_DEBUG("TCP Fast Open unavailable or failed: %s, trying traditional connection", tfoResult);
FF_DEBUG("TryTcpFastOpen failed: %s, trying traditional connection", tfoResult);
#ifdef FF_HAVE_THREADS
if (instance.config.general.multithreading)
+14 -6
View File
@@ -166,12 +166,19 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
ffStrbufAppendS(&command, "\r\n");
#ifdef TCP_FASTOPEN
// Set TCP Fast Open
flag = 1;
if (setsockopt(state->sockfd, IPPROTO_TCP, TCP_FASTOPEN, (char*)&flag, sizeof(flag)) != 0) {
FF_DEBUG("Failed to set TCP_FASTOPEN option: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
} else {
FF_DEBUG("Successfully set TCP_FASTOPEN option");
if (state->tfo)
{
// Set TCP Fast Open
flag = 1;
if (setsockopt(state->sockfd, IPPROTO_TCP, TCP_FASTOPEN, (char*)&flag, sizeof(flag)) != 0) {
FF_DEBUG("Failed to set TCP_FASTOPEN option: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
} else {
FF_DEBUG("Successfully set TCP_FASTOPEN option");
}
}
else
{
FF_DEBUG("TCP Fast Open disabled");
}
#endif
@@ -181,6 +188,7 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
command.chars, command.length, &sent, &state->overlapped);
freeaddrinfo(addr);
addr = NULL;
if(!result)
{
+1
View File
@@ -21,6 +21,7 @@ void ffPreparePublicIp(FFPublicIpOptions* options)
if (options->url.length == 0)
{
state->compression = true;
state->tfo = true;
*status = ffNetworkingSendHttpRequest(state, options->ipv6 ? "v6.ipinfo.io" : "ipinfo.io", "/json", NULL);
}
else