Description
Description / Steps to reproduce the issue
I am having some issues with TCP keep-alive on the W5500-EVB pico. Namely, all the keep-alive socket options can be set nominally (no error from setsockopt
), but the connection does not reset after the keep-alive time. I am testing this by setting up a connection successfully between two W5500-EVB Picos, and then turning off the client EVB Pico and waiting for the timeout to occur. The timeout never happens (blocking recv
should return ECONNRESET as it does on Linux, or at least some error code).
For testing, I am using 2 probes with an interval of 5 seconds.
This is the code I am using to setup the TCP socket:
static int controller_init(controller_t *controller, uint16_t port) {
int err;
/* Initialize the socket connection. */
controller->sock = socket(AF_INET, SOCK_STREAM, 0);
if (controller->sock < 0) return errno;
int opt = 1;
err = setsockopt(controller->sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
if (err < 0) {
herr("Failed to set option SO_REUSEADDR: %d\n", errno);
return errno;
}
/* Create address */
controller->addr.sin_family = AF_INET;
controller->addr.sin_addr.s_addr = INADDR_ANY;
controller->addr.sin_port = htons(port);
/* Make sure client socket fd is marked as invalid until it gets a connection */
controller->client = -1;
if (bind(controller->sock, (struct sockaddr *)&controller->addr, sizeof(controller->addr)) < 0) {
herr("Failed to bind\n");
return errno;
}
/* Set up keep-alive options */
int keepalive = 1;
err = setsockopt(controller->sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive, sizeof(keepalive));
if (err < 0) {
herr("Failed to set socket as keep-alive: %d.\n", errno);
return errno;
}
/* Each interval between ACK probes is `int_secs` long */
int int_secs = KEEPALIVE_INTERVAL_SECS;
err = setsockopt(controller->sock, IPPROTO_TCP, TCP_KEEPINTVL, &int_secs, sizeof(int));
if (err < 0) {
herr("Failed to set keep-alive interval to %d: %d.\n", int_secs, errno);
return errno;
}
hinfo("Set keep-alive interval %d s\n", int_secs);
int count = KEEPALIVE_N_PROBES; /* Gives 10 probes (10 * `int_secs` seconds) to regain connection */
err = setsockopt(controller->sock, IPPROTO_TCP, TCP_KEEPCNT, &count, sizeof(int));
if (err < 0) {
herr("Failed to set keep-alive probe count to %d: %d.\n", count, errno);
return errno;
}
hinfo("Set number of keep-alive probes: %d\n", count);
return 0;
}
And here is the code where I expect to see the timeout:
// controller->client is the `accept`-ed client connection fd
bread = recv(controller->client, (char *)&hdr + total_read, sizeof(hdr) - total_read, 0);
if (bread == -1) {
herr("Error reading message header: %s\n", strerror(errno));
if (errno == ECONNRESET) {
// TODO: this should trigger an abort because it happens when TCP keep-alive is done
herr("Lost connection! ABORT!\n");
}
break;
} else if (bread == 0) {
herr("Control box disconnected.\n");
break;
}
total_read += bread;
I have also used Wireshark to listen to the network traffic being sent and I am unable to see any of the probes being sent at all.
On which OS does this issue occur?
[OS: Linux]
What is the version of your OS?
Linux 6.14.7-arch2-1 SMP PREEMPT_DYNAMIC Thu, 22 May 2025 05:37:49 +0000 x86_64 GNU/Linux
NuttX Version
master
Issue Architecture
[Arch: arm]
Issue Area
[Area: Networking]
Host information
No response
Verification
- I have verified before submitting the report.