Loading tests/server/sockfilt.c +59 −47 Original line number Diff line number Diff line Loading @@ -143,7 +143,7 @@ static void sigpipe_handler(int sig) } #endif char use_ipv6=FALSE; bool use_ipv6=FALSE; unsigned short port = DEFAULT_PORT; unsigned short connectport = 0; /* if non-zero, we activate this mode */ Loading Loading @@ -427,25 +427,43 @@ static curl_socket_t sockdaemon(curl_socket_t sock, #endif /* ENABLE_IPV6 */ int flag = 1; int rc; int maxretr = 12; int delay= 10; int totdelay = 0; int maxretr = 10; int delay= 20; int attempt = 0; int error = 0; do { attempt++; rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&flag, sizeof(flag)); while ((rc < 0) && maxretr) { maxretr--; go_sleep(delay); if(rc) { error = SOCKERRNO; if(maxretr) { rc = wait_ms(delay); if(rc) { /* should not happen */ error = SOCKERRNO; logmsg("wait_ms() failed: (%d) %s", error, strerror(error)); sclose(sock); return CURL_SOCKET_BAD; } totdelay += delay; delay *= 2; /* double the sleep for next attempt */ rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&flag, sizeof(flag)); } if (rc < 0) { perror("setsockopt(SO_REUSEADDR)"); } } while(rc && maxretr--); if(rc) { logmsg("setsockopt(SO_REUSEADDR) failed %d times in %d ms. Error: (%d) %s", attempt, totdelay, error, strerror(error)); logmsg("Continuing anyway..."); } #ifdef ENABLE_IPV6 if(!use_ipv6) { #endif memset(&me, 0, sizeof(me)); me.sin_family = AF_INET; me.sin_addr.s_addr = INADDR_ANY; me.sin_port = htons(*listenport); Loading @@ -453,16 +471,17 @@ static curl_socket_t sockdaemon(curl_socket_t sock, #ifdef ENABLE_IPV6 } else { memset(&me6, 0, sizeof(struct sockaddr_in6)); memset(&me6, 0, sizeof(me6)); me6.sin6_family = AF_INET6; me6.sin6_addr = in6addr_any; me6.sin6_port = htons(*listenport); rc = bind(sock, (struct sockaddr *) &me6, sizeof(me6)); } #endif /* ENABLE_IPV6 */ if(rc < 0) { perror("binding stream socket"); logmsg("Error binding socket"); if(rc) { error = SOCKERRNO; logmsg("Error binding socket: (%d) %s", error, strerror(error)); sclose(sock); return CURL_SOCKET_BAD; } Loading @@ -475,16 +494,21 @@ static curl_socket_t sockdaemon(curl_socket_t sock, if(getsockname(sock, (struct sockaddr *) &add, &socksize)<0) { logmsg("getsockname() failed with error: %d", SOCKERRNO); error = SOCKERRNO; logmsg("getsockname() failed with error: (%d) %s", error, strerror(error)); sclose(sock); return CURL_SOCKET_BAD; } *listenport = ntohs(add.sin_port); } /* start accepting connections */ rc = listen(sock, 4); rc = listen(sock, 5); if(0 != rc) { logmsg("listen() failed with error: %d", SOCKERRNO); error = SOCKERRNO; logmsg("listen() failed with error: (%d) %s", error, strerror(error)); sclose(sock); return CURL_SOCKET_BAD; } Loading @@ -492,28 +516,6 @@ static curl_socket_t sockdaemon(curl_socket_t sock, return sock; } static curl_socket_t mksock(bool ipv6) { curl_socket_t sock; #ifdef ENABLE_IPV6 if(!ipv6) #else (void)ipv6; #endif sock = socket(AF_INET, SOCK_STREAM, 0); #ifdef ENABLE_IPV6 else sock = socket(AF_INET6, SOCK_STREAM, 0); #endif if (CURL_SOCKET_BAD == sock) { perror("opening stream socket"); logmsg("Error opening socket"); } return sock; } int main(int argc, char *argv[]) { Loading Loading @@ -616,10 +618,19 @@ int main(int argc, char *argv[]) #endif #endif #ifdef ENABLE_IPV6 if(!use_ipv6) #endif sock = socket(AF_INET, SOCK_STREAM, 0); #ifdef ENABLE_IPV6 else sock = socket(AF_INET6, SOCK_STREAM, 0); #endif sock = mksock(use_ipv6); if(CURL_SOCKET_BAD == sock) { logmsg("Error opening socket: %d", SOCKERRNO); error = SOCKERRNO; logmsg("Error creating socket: (%d) %s", error, strerror(error)); return 1; } Loading Loading @@ -652,8 +663,9 @@ int main(int argc, char *argv[]) } #endif /* ENABLE_IPV6 */ if(rc) { perror("connecting stream socket"); logmsg("Error connecting to port %d", port); error = SOCKERRNO; logmsg("Error connecting to port %d: (%d) %s", port, error, strerror(error)); sclose(sock); return 1; } Loading tests/server/util.c +52 −23 Original line number Diff line number Diff line Loading @@ -165,31 +165,60 @@ char *test2file(long testno) return filename; } void go_sleep(long ms) /* * Portable function used for waiting a specific amount of ms. * Waiting indefinitely with this function is not allowed, a * zero or negative timeout value will return immediately. * * Return values: * -1 = system call error, or invalid timeout value * 0 = specified timeout has elapsed */ int wait_ms(int timeout_ms) { #ifdef HAVE_POLL_FINE /* portable subsecond "sleep" */ poll((void *)0, 0, (int)ms); #else /* systems without poll() need other solutions */ #ifdef WIN32 /* Windows offers a millisecond sleep */ Sleep(ms); #elif defined(MSDOS) delay(ms); #else /* Other systems must use select() for this */ struct timeval timeout; timeout.tv_sec = ms/1000; ms = ms%1000; timeout.tv_usec = ms * 1000; select(0, NULL, NULL, NULL, &timeout); #if !defined(MSDOS) && !defined(USE_WINSOCK) #ifndef HAVE_POLL_FINE struct timeval pending_tv; #endif struct timeval initial_tv; int pending_ms; int error; #endif } int r = 0; if(!timeout_ms) return 0; if(timeout_ms < 0) { SET_SOCKERRNO(EINVAL); return -1; } #if defined(MSDOS) delay(timeout_ms); #elif defined(USE_WINSOCK) Sleep(timeout_ms); #else pending_ms = timeout_ms; initial_tv = curlx_tvnow(); do { #if defined(HAVE_POLL_FINE) r = poll(NULL, 0, pending_ms); #else pending_tv.tv_sec = pending_ms / 1000; pending_tv.tv_usec = (pending_ms % 1000) * 1000; r = select(0, NULL, NULL, NULL, &pending_tv); #endif /* HAVE_POLL_FINE */ if(r != -1) break; error = SOCKERRNO; if(error == EINVAL) break; pending_ms = timeout_ms - (int)curlx_tvdiff(curlx_tvnow(), initial_tv); if(pending_ms <= 0) break; } while(r == -1); #endif /* USE_WINSOCK */ if(r) r = -1; return r; } tests/server/util.h +2 −2 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms Loading Loading @@ -49,6 +49,6 @@ void win32_cleanup(void); /* returns the path name to the test case file */ char *test2file(long testno); void go_sleep(long ms); int wait_ms(int timeout_ms); #endif /* __SERVER_UTIL_H */ Loading
tests/server/sockfilt.c +59 −47 Original line number Diff line number Diff line Loading @@ -143,7 +143,7 @@ static void sigpipe_handler(int sig) } #endif char use_ipv6=FALSE; bool use_ipv6=FALSE; unsigned short port = DEFAULT_PORT; unsigned short connectport = 0; /* if non-zero, we activate this mode */ Loading Loading @@ -427,25 +427,43 @@ static curl_socket_t sockdaemon(curl_socket_t sock, #endif /* ENABLE_IPV6 */ int flag = 1; int rc; int maxretr = 12; int delay= 10; int totdelay = 0; int maxretr = 10; int delay= 20; int attempt = 0; int error = 0; do { attempt++; rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&flag, sizeof(flag)); while ((rc < 0) && maxretr) { maxretr--; go_sleep(delay); if(rc) { error = SOCKERRNO; if(maxretr) { rc = wait_ms(delay); if(rc) { /* should not happen */ error = SOCKERRNO; logmsg("wait_ms() failed: (%d) %s", error, strerror(error)); sclose(sock); return CURL_SOCKET_BAD; } totdelay += delay; delay *= 2; /* double the sleep for next attempt */ rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&flag, sizeof(flag)); } if (rc < 0) { perror("setsockopt(SO_REUSEADDR)"); } } while(rc && maxretr--); if(rc) { logmsg("setsockopt(SO_REUSEADDR) failed %d times in %d ms. Error: (%d) %s", attempt, totdelay, error, strerror(error)); logmsg("Continuing anyway..."); } #ifdef ENABLE_IPV6 if(!use_ipv6) { #endif memset(&me, 0, sizeof(me)); me.sin_family = AF_INET; me.sin_addr.s_addr = INADDR_ANY; me.sin_port = htons(*listenport); Loading @@ -453,16 +471,17 @@ static curl_socket_t sockdaemon(curl_socket_t sock, #ifdef ENABLE_IPV6 } else { memset(&me6, 0, sizeof(struct sockaddr_in6)); memset(&me6, 0, sizeof(me6)); me6.sin6_family = AF_INET6; me6.sin6_addr = in6addr_any; me6.sin6_port = htons(*listenport); rc = bind(sock, (struct sockaddr *) &me6, sizeof(me6)); } #endif /* ENABLE_IPV6 */ if(rc < 0) { perror("binding stream socket"); logmsg("Error binding socket"); if(rc) { error = SOCKERRNO; logmsg("Error binding socket: (%d) %s", error, strerror(error)); sclose(sock); return CURL_SOCKET_BAD; } Loading @@ -475,16 +494,21 @@ static curl_socket_t sockdaemon(curl_socket_t sock, if(getsockname(sock, (struct sockaddr *) &add, &socksize)<0) { logmsg("getsockname() failed with error: %d", SOCKERRNO); error = SOCKERRNO; logmsg("getsockname() failed with error: (%d) %s", error, strerror(error)); sclose(sock); return CURL_SOCKET_BAD; } *listenport = ntohs(add.sin_port); } /* start accepting connections */ rc = listen(sock, 4); rc = listen(sock, 5); if(0 != rc) { logmsg("listen() failed with error: %d", SOCKERRNO); error = SOCKERRNO; logmsg("listen() failed with error: (%d) %s", error, strerror(error)); sclose(sock); return CURL_SOCKET_BAD; } Loading @@ -492,28 +516,6 @@ static curl_socket_t sockdaemon(curl_socket_t sock, return sock; } static curl_socket_t mksock(bool ipv6) { curl_socket_t sock; #ifdef ENABLE_IPV6 if(!ipv6) #else (void)ipv6; #endif sock = socket(AF_INET, SOCK_STREAM, 0); #ifdef ENABLE_IPV6 else sock = socket(AF_INET6, SOCK_STREAM, 0); #endif if (CURL_SOCKET_BAD == sock) { perror("opening stream socket"); logmsg("Error opening socket"); } return sock; } int main(int argc, char *argv[]) { Loading Loading @@ -616,10 +618,19 @@ int main(int argc, char *argv[]) #endif #endif #ifdef ENABLE_IPV6 if(!use_ipv6) #endif sock = socket(AF_INET, SOCK_STREAM, 0); #ifdef ENABLE_IPV6 else sock = socket(AF_INET6, SOCK_STREAM, 0); #endif sock = mksock(use_ipv6); if(CURL_SOCKET_BAD == sock) { logmsg("Error opening socket: %d", SOCKERRNO); error = SOCKERRNO; logmsg("Error creating socket: (%d) %s", error, strerror(error)); return 1; } Loading Loading @@ -652,8 +663,9 @@ int main(int argc, char *argv[]) } #endif /* ENABLE_IPV6 */ if(rc) { perror("connecting stream socket"); logmsg("Error connecting to port %d", port); error = SOCKERRNO; logmsg("Error connecting to port %d: (%d) %s", port, error, strerror(error)); sclose(sock); return 1; } Loading
tests/server/util.c +52 −23 Original line number Diff line number Diff line Loading @@ -165,31 +165,60 @@ char *test2file(long testno) return filename; } void go_sleep(long ms) /* * Portable function used for waiting a specific amount of ms. * Waiting indefinitely with this function is not allowed, a * zero or negative timeout value will return immediately. * * Return values: * -1 = system call error, or invalid timeout value * 0 = specified timeout has elapsed */ int wait_ms(int timeout_ms) { #ifdef HAVE_POLL_FINE /* portable subsecond "sleep" */ poll((void *)0, 0, (int)ms); #else /* systems without poll() need other solutions */ #ifdef WIN32 /* Windows offers a millisecond sleep */ Sleep(ms); #elif defined(MSDOS) delay(ms); #else /* Other systems must use select() for this */ struct timeval timeout; timeout.tv_sec = ms/1000; ms = ms%1000; timeout.tv_usec = ms * 1000; select(0, NULL, NULL, NULL, &timeout); #if !defined(MSDOS) && !defined(USE_WINSOCK) #ifndef HAVE_POLL_FINE struct timeval pending_tv; #endif struct timeval initial_tv; int pending_ms; int error; #endif } int r = 0; if(!timeout_ms) return 0; if(timeout_ms < 0) { SET_SOCKERRNO(EINVAL); return -1; } #if defined(MSDOS) delay(timeout_ms); #elif defined(USE_WINSOCK) Sleep(timeout_ms); #else pending_ms = timeout_ms; initial_tv = curlx_tvnow(); do { #if defined(HAVE_POLL_FINE) r = poll(NULL, 0, pending_ms); #else pending_tv.tv_sec = pending_ms / 1000; pending_tv.tv_usec = (pending_ms % 1000) * 1000; r = select(0, NULL, NULL, NULL, &pending_tv); #endif /* HAVE_POLL_FINE */ if(r != -1) break; error = SOCKERRNO; if(error == EINVAL) break; pending_ms = timeout_ms - (int)curlx_tvdiff(curlx_tvnow(), initial_tv); if(pending_ms <= 0) break; } while(r == -1); #endif /* USE_WINSOCK */ if(r) r = -1; return r; }
tests/server/util.h +2 −2 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms Loading Loading @@ -49,6 +49,6 @@ void win32_cleanup(void); /* returns the path name to the test case file */ char *test2file(long testno); void go_sleep(long ms); int wait_ms(int timeout_ms); #endif /* __SERVER_UTIL_H */