Well, I thought to hack away and see what happens. Maybe there is a better way of doing it as I am still learning...
After 1 runtime exception when I thought a "free (serverState->clientFd);" might do the trick, I came to with this code, which works but I am ending up with "localFd" that increments after each client reboot (that can actually be a good thing as gives you a failure indicator or reboot counter).
EDIT: Sorted (I think). Adding in a close(serverState->clientFd); solves the socket increment problem (localFd).
static void HandleListenEvent(EventData *eventData)
{
EchoServer_ServerState *serverState =
EventDataToServerState(eventData, offsetof(EchoServer_ServerState, listenEvent));
int localFd = -1;
do {
// Create a new accepted socket to connect to the client.
// The newly-accepted sockets should be opened in non-blocking mode, and use
// EPOLLIN and EPOLLOUT to transfer data.
struct sockaddr in_addr;
socklen_t sockLen = sizeof(in_addr);
// If there is already a client, then we close that first
// - this works as only one client IP address is handled via DHCP.
if (serverState->clientFd >= 0) {
UnregisterEventHandlerFromEpoll(serverState->epollFd, serverState->clientFd);
serverState->epollInEnabled = false;
close(serverState->clientFd);
serverState->clientFd = -1;
Log_Debug(
"INFO: TCP server: Closing old client connection as only one client supported "
"at a time. A new connection will be issued.\n");
}
localFd = accept4(serverState->listenFd, &in_addr, &sockLen, SOCK_NONBLOCK | SOCK_CLOEXEC);
if (localFd == -1) {
ReportError("accept");
break;
}
Log_Debug("INFO: TCP server: Accepted client connection (fd %d).\n", localFd);
// Socket opened successfully, so transfer ownership to EchoServer_ServerState object.
serverState->clientFd = localFd;
localFd = -1;
LaunchRead(serverState);
} while (0);
close(localFd);
}