The attached patch fixes a socket leak in the bsd_tcpip stack that happens when an incoming TCP connection is reset by the client immediately after the connection is established. When this occurs, the accept() call returns -1 with errno==353, and a socket structure is leaked.
For more details, see http://thread.gmane.org/gmane.os.ecos.general/27351/focus=27357 The attached Win32 C program can be used to trigger the leak in any eCos program that accepts incoming TCP connections. [I've only tested this program using Cygwin's gcc in "mingw" cross-compile mode to produce a native Win32 executable.] I was unable to get a Linux client to produce a TCP RST in a manner that would cause problems. -- Grant Edwards [email protected]
eCos-bsd_tcpip-socket-leak.patch
Description: application/patch
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
WSADATA wsaData;
BOOL dontlinger=0;
int sock;
int loops;
struct sockaddr_in servAddr;
char *host;
int port;
if (argc != 3)
{
fprintf(stderr,"usage: %s host port\n",argv[0]);
exit(1);
}
host = argv[1];
port = atoi(argv[2]);
if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) /* Load Winsock 2.0 DLL */
{
fprintf(stderr, "WSAStartup() failed");
exit(1);
}
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(host);
servAddr.sin_port = htons(port);
loops = 1;
printf("starting\n");
while (1)
{
if ( (sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
perror("socket() failed:");
exit(1);
}
setsockopt(sock,SOL_SOCKET,SO_DONTLINGER,(char *)&dontlinger,sizeof(BOOL));
if (connect(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
{
printf("connect() failed, sleeping...\n");
Sleep(1000);
}
else
{
printf("%4d\n",loops);
++loops;
}
closesocket(sock);
Sleep(250);
}
WSACleanup();
return 0;
}
