Hello, 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, 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. I was going to raise an issue about this, but wanted to see if anyone could spot something I'm doing wrong first. I remember TCP keep-alive not working being mentioned on this forum a few months ago, but I couldn't find an open issue about it. This is the code I am using to setup the TCP socket: ```c 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: ```c // 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; ``` Does anyone have any suggestions about how to resolve this? -- Matteo Golin
signature.asc
Description: PGP signature