From 59b3d28a253fc352cff0e82bca268cdcd8ab8bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 21 Apr 2009 21:01:25 +0000 Subject: [PATCH] * Wrote a test application trying to reproduce bug #2197, ie. modelled after Mozilla's PR_NewTCPSocketPair() -- unfortunately, it doesn't seem to work. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30304 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tests/kits/net/Jamfile | 6 +- src/tests/kits/net/firefox_crash.cpp | 138 +++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 src/tests/kits/net/firefox_crash.cpp diff --git a/src/tests/kits/net/Jamfile b/src/tests/kits/net/Jamfile index d9c165edfd..cff0ab1a02 100644 --- a/src/tests/kits/net/Jamfile +++ b/src/tests/kits/net/Jamfile @@ -2,6 +2,8 @@ SubDir HAIKU_TOP src tests kits net ; SetSubDirSupportedPlatformsBeOSCompatible ; +SimpleTest firefox_crash : firefox_crash.cpp : $(TARGET_NETWORK_LIBS) ; + SimpleTest udp_client : udp_client.c : $(TARGET_NETWORK_LIBS) ; SimpleTest udp_echo : udp_echo.c : $(TARGET_NETWORK_LIBS) ; SimpleTest udp_server : udp_server.c : $(TARGET_NETWORK_LIBS) ; @@ -14,10 +16,10 @@ SimpleTest getpeername : getpeername.cpp : $(TARGET_NETWORK_LIBS) ; SimpleTest tcp_connection_test : tcp_connection_test.cpp : $(TARGET_NETWORK_LIBS) ; -SimpleTest NetAddressTest : NetAddressTest.cpp +SimpleTest NetAddressTest : NetAddressTest.cpp : $(TARGET_NETWORK_LIBS) $(HAIKU_NETAPI_LIB) ; -SimpleTest NetEndpointTest : NetEndpointTest.cpp +SimpleTest NetEndpointTest : NetEndpointTest.cpp : $(TARGET_NETWORK_LIBS) $(HAIKU_NETAPI_LIB) be ; SubInclude HAIKU_TOP src tests kits net DialUpPreflet ; diff --git a/src/tests/kits/net/firefox_crash.cpp b/src/tests/kits/net/firefox_crash.cpp new file mode 100644 index 0000000000..936bfba754 --- /dev/null +++ b/src/tests/kits/net/firefox_crash.cpp @@ -0,0 +1,138 @@ +/* + * Copyright 2009, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ + +//! A test app trying to reproduce bug #2197. + +#include +#include +#include +#include +#include +#include +#include +#include + + +static int +open_tcp_socket() +{ + int fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) + return -1; + + // make it non-blocking + fcntl(fd, F_SETFL, O_NONBLOCK); + + return fd; +} + + +static void +init_sockaddr(struct sockaddr_in& address, unsigned ipAddress, unsigned port) +{ + memset(&address, 0, sizeof(sockaddr_in)); + address.sin_family = AF_INET; + address.sin_port = htons(port); + address.sin_addr.s_addr = htonl(ipAddress); +} + + +static int +tcp_pair(int pair[]) +{ + pair[0] = pair[1] = -1; + + int listenSocket = open_tcp_socket(); + if (listenSocket < 0) + return -1; + + sockaddr_in listenAddress; + sockaddr_in peerAddress; + sockaddr_in address; + socklen_t length; + init_sockaddr(listenAddress, INADDR_LOOPBACK, 0); + + if (bind(listenSocket, (sockaddr*)&listenAddress, sizeof(sockaddr_in)) != 0) + goto error; + + length = sizeof(sockaddr_in); + if (getsockname(listenSocket, (sockaddr*)&listenAddress, &length) != 0) + goto error; + + if (listen(listenSocket, 5) != 0) + goto error; + + pair[0] = open_tcp_socket(); + if (pair[0] < 0) + goto error; + + init_sockaddr(address, INADDR_LOOPBACK, ntohs(listenAddress.sin_port)); + + if (connect(pair[0], (sockaddr*)&address, sizeof(sockaddr_in)) != 0 + && errno != EINPROGRESS) + goto error; + + if (errno == EINPROGRESS) { + struct timeval tv; + tv.tv_sec = 100000; + tv.tv_usec = 0; + fd_set set; + FD_ZERO(&set); + FD_SET(pair[0], &set); + if (select(pair[0] + 1, NULL, &set, NULL, &tv) < 0) + fprintf(stderr, "write select() failed: %s\n", strerror(errno)); + } + + length = sizeof(sockaddr_in); + if (getsockname(pair[0], (sockaddr*)&address, &length) != 0) + goto error; + + while (true) { + pair[1] = accept(listenSocket, (sockaddr*)&peerAddress, &length); + if (pair[1] >= 0) + break; + + if (errno != EAGAIN && errno != EWOULDBLOCK && errno != ETIMEDOUT) + goto error; + + struct timeval tv; + tv.tv_sec = 100000; + tv.tv_usec = 0; + fd_set set; + FD_ZERO(&set); + FD_SET(listenSocket, &set); + if (select(listenSocket + 1, &set, NULL, NULL, &tv) < 0) + fprintf(stderr, "read select() failed: %s\n", strerror(errno)); + } + + if (peerAddress.sin_port != address.sin_port) + goto error; + + close(listenSocket); + return 0; + +error: + close(listenSocket); + for (int i = 0; i < 2; i++) { + if (pair[i] >= 0) + close(pair[i]); + } + + return -1; +} + + +int +main(int argc, char** argv) +{ + int pair[2]; + if (tcp_pair(pair) == 0) { + close(pair[0]); + close(pair[1]); + } else + fprintf(stderr, "pair failed: %s\n", strerror(errno)); + return 0; +} +