From accadc7759ca6e3690749417ef7d26d443bea5f7 Mon Sep 17 00:00:00 2001 From: Anthony Pesch Date: Wed, 7 Aug 2013 13:55:38 -0700 Subject: - select shouldn't return an error when the socket is valid, but disconnected - recv should return 0 once the socket has disconnected - send should set ENOTCONN once closed, and EAGAIN while connecting - updated tests to use O_NONBLOCK and better conform to coding standards --- tests/runner.py | 63 ++++---- tests/websockets.c | 118 +++++++------- tests/websockets_bi.c | 116 +++++++------- tests/websockets_bi_bigdata.c | 117 +++++++------- tests/websockets_bi_listener.c | 151 ------------------ tests/websockets_bi_side.c | 103 +++++++----- tests/websockets_bi_side_bigdata.c | 89 +++++++---- tests/websockets_gethostbyname.c | 114 ++++++------- tests/websockets_partial.c | 112 ++++++------- tests/websockets_select.c | 101 ++++++------ tests/websockets_select_server_closes_connection.c | 124 +++++++-------- ...websockets_select_server_closes_connection_rw.c | 176 ++++++++++----------- 12 files changed, 630 insertions(+), 754 deletions(-) delete mode 100644 tests/websockets_bi_listener.c (limited to 'tests') diff --git a/tests/runner.py b/tests/runner.py index b866cc08..2bd26eb7 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -12330,6 +12330,24 @@ elif 'browser' in str(sys.argv): 'browser.test_freealut' ] + if 'sockets' in sys.argv: + print + print 'Running the browser socket tests.' + print + i = sys.argv.index('sockets') + sys.argv = sys.argv[:i] + sys.argv[i+1:] + i = sys.argv.index('browser') + sys.argv = sys.argv[:i] + sys.argv[i+1:] + sys.argv += [ + 'browser.test_sockets_bi', + 'browser.test_sockets_gethostbyname', + 'browser.test_sockets_bi_bigdata', + 'browser.test_sockets_select_server_down', + 'browser.test_sockets_select_server_closes_connection', + 'browser.test_sockets_select_server_closes_connection_rw', + 'browser.test_enet' + ] + # Run a server and a web page. When a test runs, we tell the server about it, # which tells the web page, which then opens a window with the test. Doing # it this way then allows the page to close() itself when done. @@ -13930,14 +13948,14 @@ Press any key to continue.''' # always run these tests last # make sure to use different ports in each one because it takes a while for the processes to be cleaned up - def test_websockets(self): + def test_sockets(self): try: with self.WebsockHarness(8990): - self.btest('websockets.c', expected='571') + self.btest('websockets.c', expected='571', args=['-DSOCKK=8991']) finally: self.clean_pids() - def test_websockets_partial(self): + def test_sockets_partial(self): def partial(q): import socket @@ -13960,7 +13978,7 @@ Press any key to continue.''' try: with self.WebsockHarness(8990, partial): - self.btest('websockets_partial.c', expected='165') + self.btest('websockets_partial.c', expected='165', args=['-DSOCKK=8991']) finally: self.clean_pids() @@ -13972,35 +13990,26 @@ Press any key to continue.''' proc.communicate() return relay_server - def test_websockets_bi(self): + def test_sockets_bi(self): for datagram in [0,1]: for fileops in [0,1]: try: print >> sys.stderr, 'test_websocket_bi datagram %d, fileops %d' % (datagram, fileops) - with self.WebsockHarness(8992, self.make_relay_server(8992, 8994)): - with self.WebsockHarness(8994, no_server=True): - Popen([PYTHON, EMCC, path_from_root('tests', 'websockets_bi_side.c'), '-o', 'side.html', '-DSOCKK=8995', '-DTEST_DGRAM=%d' % datagram]).communicate() - self.btest('websockets_bi.c', expected='2499', args=['-DSOCKK=8993', '-DTEST_DGRAM=%d' % datagram, '-DTEST_FILE_OPS=%s' % fileops]) + with self.WebsockHarness(6992, self.make_relay_server(6992, 6994)): + with self.WebsockHarness(6994, no_server=True): + Popen([PYTHON, EMCC, path_from_root('tests', 'websockets_bi_side.c'), '-o', 'side.html', '-DSOCKK=6995', '-DTEST_DGRAM=%d' % datagram]).communicate() + self.btest('websockets_bi.c', expected='2499', args=['-DSOCKK=6993', '-DTEST_DGRAM=%d' % datagram, '-DTEST_FILE_OPS=%s' % fileops, '-DEMBED_SIDE']) finally: self.clean_pids() - def test_websockets_bi_listen(self): - try: - with self.WebsockHarness(6992, self.make_relay_server(6992, 6994)): - with self.WebsockHarness(6994, no_server=True): - Popen([PYTHON, EMCC, path_from_root('tests', 'websockets_bi_side.c'), '-o', 'side.html', '-DSOCKK=6995']).communicate() - self.btest('websockets_bi_listener.c', expected='2499', args=['-DSOCKK=6993']) - finally: - self.clean_pids() - - def test_websockets_gethostbyname(self): + def test_sockets_gethostbyname(self): try: with self.WebsockHarness(7000): - self.btest('websockets_gethostbyname.c', expected='571', args=['-O2']) + self.btest('websockets_gethostbyname.c', expected='571', args=['-O2', '-DSOCKK=7001']) finally: self.clean_pids() - def test_websockets_bi_bigdata(self): + def test_sockets_bi_bigdata(self): try: with self.WebsockHarness(3992, self.make_relay_server(3992, 3994)): with self.WebsockHarness(3994, no_server=True): @@ -14009,7 +14018,7 @@ Press any key to continue.''' finally: self.clean_pids() - def test_websockets_select_server_down(self): + def test_sockets_select_server_down(self): def closedServer(q): import socket @@ -14018,11 +14027,11 @@ Press any key to continue.''' ssock.bind(("127.0.0.1", 8994)) try: with self.WebsockHarness(8994, closedServer): - self.btest('websockets_select.c', expected='266') + self.btest('websockets_select.c', expected='266', args=['-DSOCKK=8995']) finally: self.clean_pids() - def test_websockets_select_server_closes_connection(self): + def test_sockets_select_server_closes_connection(self): def closingServer(q): import socket @@ -14038,11 +14047,11 @@ Press any key to continue.''' try: with self.WebsockHarness(8994, closingServer): - self.btest('websockets_select_server_closes_connection.c', expected='266') + self.btest('websockets_select_server_closes_connection.c', expected='266', args=['-DSOCKK=8995']) finally: self.clean_pids() - def test_websockets_select_server_closes_connection_rw(self): + def test_sockets_select_server_closes_connection_rw(self): def closingServer_rw(q): import socket @@ -14070,7 +14079,7 @@ Press any key to continue.''' try: with self.WebsockHarness(8998, closingServer_rw): - self.btest('websockets_select_server_closes_connection_rw.c', expected='266') + self.btest('websockets_select_server_closes_connection_rw.c', expected='266', args=['-DSOCKK=8999']) finally: self.clean_pids() diff --git a/tests/websockets.c b/tests/websockets.c index 8882f5ba..8845ef43 100644 --- a/tests/websockets.c +++ b/tests/websockets.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #if EMSCRIPTEN @@ -15,12 +16,18 @@ #define EXPECTED_BYTES 5 -int SocketFD; - +int sockfd; int not_always_data = 0; -unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) -{ +void finish(int result) { + close(sockfd); +#if EMSCRIPTEN + REPORT_RESULT(); +#endif + exit(result); +} + +unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) { // select check for IO fd_set sett; FD_ZERO(&sett); @@ -35,6 +42,7 @@ unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) int bytes; if (ioctl(sock, FIONREAD, &bytes) || bytes == 0) { not_always_data = 1; + printf("ioctl says 0, FD_ISSET says %ld\n", FD_ISSET(sock, &sett)); assert(FD_ISSET(sock, &sett) == 0); return 0; } @@ -47,28 +55,42 @@ unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) unsigned int offset = 0; while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) || errno == EINTR) { - if(n>0) - { - if (((unsigned int) n)+offset > maxsize) { fprintf(stderr, "too much data!"); exit(EXIT_FAILURE); } + if(n > 0) { + if (((unsigned int) n)+offset > maxsize) { + fprintf(stderr, "too much data!"); + finish(EXIT_FAILURE); + } memcpy(output+offset, buffer, n); offset += n; } } - if(n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { + if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { fprintf(stderr, "error in get_all_buf! %d", errno); - exit(EXIT_FAILURE); + finish(EXIT_FAILURE); } return offset; } -int done = 0; - void iter(void *arg) { - /* perform read write operations ... */ static char out[1024*2]; static int pos = 0; - int n = get_all_buf(SocketFD, out+pos, 1024-pos); + fd_set fdr; + int res; + + // make sure that sockfd is ready to read + FD_ZERO(&fdr); + FD_SET(sockfd, &fdr); + res = select(64, &fdr, NULL, NULL, NULL); + if (res == -1) { + perror("select failed"); + finish(EXIT_FAILURE); + } else if (!FD_ISSET(sockfd, &fdr)) { + return; + } + + // perform read write operations ... + int n = get_all_buf(sockfd, out+pos, 1024-pos); if (n) printf("read! %d\n", n); pos += n; if (pos >= EXPECTED_BYTES) { @@ -78,70 +100,44 @@ void iter(void *arg) { sum += out[i]; } - shutdown(SocketFD, SHUT_RDWR); - - close(SocketFD); + shutdown(sockfd, SHUT_RDWR); - done = 1; + close(sockfd); printf("sum: %d\n", sum); - -#if EMSCRIPTEN - //assert(not_always_data == 1); - - int result = sum; - REPORT_RESULT(); -#endif + finish(sum); } } -int main(void) -{ - struct sockaddr_in stSockAddr; - int Res; - SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); +void main() { + struct sockaddr_in addr; + int res; - if (-1 == SocketFD) - { + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == -1) { perror("cannot create socket"); - exit(EXIT_FAILURE); + finish(EXIT_FAILURE); } - - memset(&stSockAddr, 0, sizeof(stSockAddr)); - - stSockAddr.sin_family = AF_INET; - stSockAddr.sin_port = htons( -#if EMSCRIPTEN - 8991 -#else - 8990 -#endif - ); - Res = inet_pton(AF_INET, "127.0.0.1", &stSockAddr.sin_addr); - - if (0 > Res) { - perror("error: first parameter is not a valid address family"); - close(SocketFD); - exit(EXIT_FAILURE); - } else if (0 == Res) { - perror("char string (second parameter does not contain valid ipaddress)"); - close(SocketFD); - exit(EXIT_FAILURE); + fcntl(sockfd, F_SETFL, O_NONBLOCK); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); } - - if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) { + + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { perror("connect failed"); - close(SocketFD); - exit(EXIT_FAILURE); - + finish(EXIT_FAILURE); } #if EMSCRIPTEN emscripten_set_main_loop(iter, 0, 0); #else - while (!done) iter(NULL); + while (1) iter(NULL); #endif - - return EXIT_SUCCESS; } diff --git a/tests/websockets_bi.c b/tests/websockets_bi.c index fb60177b..e19f7fe8 100644 --- a/tests/websockets_bi.c +++ b/tests/websockets_bi.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #if EMSCRIPTEN #include @@ -14,14 +15,17 @@ #define EXPECTED_BYTES 28 -#ifndef SOCKK -#define SOCKK 8992 -#endif +int sockfd; -int SocketFD; +void finish(int result) { + close(sockfd); +#if EMSCRIPTEN + REPORT_RESULT(); +#endif + exit(result); +} -unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) -{ +unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) { int bytes; if (ioctl(sock, FIONREAD, &bytes)) return 0; if (bytes == 0) return 0; @@ -35,9 +39,11 @@ unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) || #endif errno == EINTR) { - if(n>0) - { - if (((unsigned int) n)+offset > maxsize) { fprintf(stderr, "too much data!"); exit(EXIT_FAILURE); } + if(n > 0) { + if (((unsigned int) n)+offset > maxsize) { + fprintf(stderr, "too much data!"); + finish(EXIT_FAILURE); + } memcpy(output+offset, buffer, n); offset += n; } @@ -45,18 +51,30 @@ unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) if(n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { fprintf(stderr, "error in get_all_buf!"); - exit(EXIT_FAILURE); + finish(EXIT_FAILURE); } return offset; } -int done = 0; - void iter(void *arg) { - /* perform read write operations ... */ static char out[1024*2]; static int pos = 0; - int n = get_all_buf(SocketFD, out+pos, 1024-pos); + fd_set fdr; + int res; + + // make sure that sockfd is ready to read + FD_ZERO(&fdr); + FD_SET(sockfd, &fdr); + res = select(64, &fdr, NULL, NULL, NULL); + if (res == -1) { + perror("select failed"); + finish(EXIT_FAILURE); + } else if (!FD_ISSET(sockfd, &fdr)) { + return; + } + + // perform read write operations ... + int n = get_all_buf(sockfd, out+pos, 1024-pos); if (n) printf("read! %d\n", n); pos += n; if (pos >= EXPECTED_BYTES) { @@ -66,75 +84,57 @@ void iter(void *arg) { sum += out[i]; } - shutdown(SocketFD, SHUT_RDWR); - - close(SocketFD); - - done = 1; + shutdown(sockfd, SHUT_RDWR); + close(sockfd); printf("sum: %d\n", sum); - - emscripten_cancel_main_loop(); - -#if EMSCRIPTEN - int result = sum; - REPORT_RESULT(); -#endif + finish(sum); } } -int main(void) -{ +int main() { + struct sockaddr_in addr; + int res; + printf("hello from main page\n"); - struct sockaddr_in stSockAddr; - int Res; #if !TEST_DGRAM - SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); #else - SocketFD = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); #endif - - if (-1 == SocketFD) - { + if (sockfd == -1) { perror("cannot create socket"); - exit(EXIT_FAILURE); + finish(EXIT_FAILURE); } - - memset(&stSockAddr, 0, sizeof(stSockAddr)); - - stSockAddr.sin_family = AF_INET; - stSockAddr.sin_port = htons(SOCKK); - Res = inet_pton(AF_INET, "127.0.0.1", &stSockAddr.sin_addr); - - if (0 > Res) { - perror("error: first parameter is not a valid address family"); - close(SocketFD); - exit(EXIT_FAILURE); - } else if (0 == Res) { - perror("char string (second parameter does not contain valid ipaddress)"); - close(SocketFD); - exit(EXIT_FAILURE); + fcntl(sockfd, F_SETFL, O_NONBLOCK); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); } - - if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) { + + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { perror("connect failed"); - close(SocketFD); - exit(EXIT_FAILURE); - + finish(EXIT_FAILURE); } #if EMSCRIPTEN +#if EMBED_SIDE emscripten_run_script("console.log('adding iframe');" "var iframe = document.createElement('iframe');" "iframe.src = 'side.html';" "document.body.appendChild(iframe);" "console.log('added.');"); +#endif emscripten_set_main_loop(iter, 0, 0); #else - while (!done) iter(NULL); + while (1) iter(NULL); #endif return EXIT_SUCCESS; } - diff --git a/tests/websockets_bi_bigdata.c b/tests/websockets_bi_bigdata.c index 2039f83c..e3509649 100644 --- a/tests/websockets_bi_bigdata.c +++ b/tests/websockets_bi_bigdata.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #if EMSCRIPTEN #include @@ -16,10 +17,17 @@ #define EXPECTED_BYTES DATA_SIZE -int SocketFD; +int sockfd; -unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) -{ +void finish(int result) { + close(sockfd); +#if EMSCRIPTEN + REPORT_RESULT(); +#endif + exit(result); +} + +unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) { int bytes; if (ioctl(sock, FIONREAD, &bytes)) return 0; if (bytes == 0) return 0; @@ -29,41 +37,51 @@ unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) unsigned int offset = 0; while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) || errno == EINTR) { - if(n>0) - { - if (((unsigned int) n)+offset > maxsize) { fprintf(stderr, "too much data!"); exit(EXIT_FAILURE); } + if (n > 0) { + if (((unsigned int) n)+offset > maxsize) { + fprintf(stderr, "too much data!"); + finish(EXIT_FAILURE); + } memcpy(output+offset, buffer, n); offset += n; } } - if(n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { + if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { fprintf(stderr, "error in get_all_buf!"); - exit(EXIT_FAILURE); + finish(EXIT_FAILURE); } return offset; } -int done = 0; - void iter(void *arg) { - /* perform read write operations ... */ static char out[EXPECTED_BYTES]; static int pos = 0; + fd_set fdr; + int res; + + // make sure that sockfd has finished connecting and is ready to read + FD_ZERO(&fdr); + FD_SET(sockfd, &fdr); + res = select(64, &fdr, NULL, NULL, NULL); + if (res == -1) { + perror("select failed"); + finish(EXIT_FAILURE); + return; + } else if (!FD_ISSET(sockfd, &fdr)) { + return; + } + + // perform read write operations ... printf("so far %d, expecting up to %d\n", pos, EXPECTED_BYTES-pos); - int n = get_all_buf(SocketFD, out+pos, EXPECTED_BYTES-pos); - if (n) printf("read! %d\n", n); - pos += n; + res = get_all_buf(sockfd, out+pos, EXPECTED_BYTES-pos); + if (res) printf("read! %d\n", res); + pos += res; if (pos >= EXPECTED_BYTES) { - shutdown(SocketFD, SHUT_RDWR); - - close(SocketFD); - - done = 1; + shutdown(sockfd, SHUT_RDWR); - emscripten_cancel_main_loop(); + close(sockfd); -#if EMSCRIPTEN char *comp = generateData(); int result = strcmp(comp, out); if (result != 0) { @@ -71,52 +89,35 @@ void iter(void *arg) { printf("%d:%d\n", comp[i], out[i]); } } - REPORT_RESULT(); -#endif + finish(result); } } -int main(void) -{ - printf("hello from main page\n"); +int main() { + struct sockaddr_in addr; + int res; - struct sockaddr_in stSockAddr; - int Res; - SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + printf("hello from main page\n"); - if (-1 == SocketFD) - { + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == -1) { perror("cannot create socket"); - exit(EXIT_FAILURE); + finish(EXIT_FAILURE); } - - memset(&stSockAddr, 0, sizeof(stSockAddr)); - - stSockAddr.sin_family = AF_INET; - stSockAddr.sin_port = htons( -#if EMSCRIPTEN - 3993 -#else - 3992 -#endif - ); - Res = inet_pton(AF_INET, "127.0.0.1", &stSockAddr.sin_addr); - - if (0 > Res) { - perror("error: first parameter is not a valid address family"); - close(SocketFD); - exit(EXIT_FAILURE); - } else if (0 == Res) { - perror("char string (second parameter does not contain valid ipaddress)"); - close(SocketFD); - exit(EXIT_FAILURE); + fcntl(sockfd, F_SETFL, O_NONBLOCK); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); } - if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) { + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { perror("connect failed"); - close(SocketFD); - exit(EXIT_FAILURE); - + finish(EXIT_FAILURE); } #if EMSCRIPTEN @@ -129,7 +130,7 @@ int main(void) "console.log('added.');"); emscripten_set_main_loop(iter, 3, 0); #else - while (!done) iter(NULL); + while (1) iter(NULL); #endif return EXIT_SUCCESS; diff --git a/tests/websockets_bi_listener.c b/tests/websockets_bi_listener.c deleted file mode 100644 index 6c3b17b1..00000000 --- a/tests/websockets_bi_listener.c +++ /dev/null @@ -1,151 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if EMSCRIPTEN -#include -#endif - -#define EXPECTED_BYTES 28 - -int ListenFD, SocketFD; - -unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) -{ - int bytes; - if (ioctl(sock, FIONREAD, &bytes)) return 0; - if (bytes == 0) return 0; - - char buffer[1024]; - int n; - unsigned int offset = 0; - while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) || - errno == EINTR) { - if(n>0) - { - if (((unsigned int) n)+offset > maxsize) { fprintf(stderr, "too much data!"); exit(EXIT_FAILURE); } - memcpy(output+offset, buffer, n); - offset += n; - } - } - - if(n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { - fprintf(stderr, "error in get_all_buf!"); - exit(EXIT_FAILURE); - } - return offset; -} - -int done = 0; - -void iter(void *arg) { - /* perform read write operations ... */ - static char out[1024*2]; - static int pos = 0; - int n = get_all_buf(SocketFD, out+pos, 1024-pos); - if (n) printf("read! %d\n", n); - pos += n; - if (pos >= EXPECTED_BYTES) { - int i, sum = 0; - for (i=0; i < pos; i++) { - printf("%x\n", out[i]); - sum += out[i]; - } - - shutdown(SocketFD, SHUT_RDWR); - - close(SocketFD); - - done = 1; - - printf("sum: %d\n", sum); - -#if EMSCRIPTEN - int result = sum; - REPORT_RESULT(); - emscripten_cancel_main_loop(); -#endif - } -} - -int main(void) -{ - struct sockaddr_in stSockAddr; - int Res; - ListenFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - - if (-1 == ListenFD) - { - perror("cannot create socket"); - exit(EXIT_FAILURE); - } - - memset(&stSockAddr, 0, sizeof(stSockAddr)); - - stSockAddr.sin_family = AF_INET; - stSockAddr.sin_port = htons( -#if EMSCRIPTEN - 6993 -#else - 6995 -#endif - ); - Res = inet_pton(AF_INET, "127.0.0.1", &stSockAddr.sin_addr); - - if (0 > Res) { - perror("error: first parameter is not a valid address family"); - close(ListenFD); - exit(EXIT_FAILURE); - } else if (0 == Res) { - perror("char string (second parameter does not contain valid ipaddress)"); - close(ListenFD); - exit(EXIT_FAILURE); - } - - printf("bind..\n"); - - if (-1 == bind(ListenFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) { - perror("bind failed"); - close(ListenFD); - exit(EXIT_FAILURE); - } - - printf("listen..\n"); - - if (-1 == listen(ListenFD, 50)) { - perror("listen failed"); - close(ListenFD); - exit(EXIT_FAILURE); - } - - printf("accept..\n"); - - struct sockaddr_in stSockAddr2; - socklen_t temp; - - if (-1 == (SocketFD = accept(ListenFD, (struct sockaddr *)&stSockAddr2, &temp))) { - perror("accept failed"); - close(ListenFD); - exit(EXIT_FAILURE); - } - -#if EMSCRIPTEN - emscripten_run_script("console.log('adding iframe');" - "var iframe = document.createElement('iframe');" - "iframe.src = 'side.html';" - "document.body.appendChild(iframe);" - "console.log('added.');"); - emscripten_set_main_loop(iter, 0, 0); -#else - while (!done) iter(NULL); -#endif - - return EXIT_SUCCESS; -} - diff --git a/tests/websockets_bi_side.c b/tests/websockets_bi_side.c index 1d557ed8..b8910632 100644 --- a/tests/websockets_bi_side.c +++ b/tests/websockets_bi_side.c @@ -3,10 +3,12 @@ #include #include #include +#include #include #include #include #include +#include #include #if EMSCRIPTEN #include @@ -14,62 +16,77 @@ #define EXPECTED_BYTES 5 -int main(void) -{ - struct sockaddr_in stSockAddr; - int Res; -#if !TEST_DGRAM - int SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); -#else - int SocketFD = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); -#endif +int sockfd = -1; - if (-1 == SocketFD) - { - perror("cannot create socket"); - exit(EXIT_FAILURE); - } - - memset(&stSockAddr, 0, sizeof(stSockAddr)); +void finish(int result) { + close(sockfd); + exit(result); +} - stSockAddr.sin_family = AF_INET; - stSockAddr.sin_port = htons(SOCKK); - Res = inet_pton(AF_INET, "127.0.0.1", &stSockAddr.sin_addr); +void loop() { + fd_set fdw; + int res; - if (0 > Res) { - perror("error: first parameter is not a valid address family"); - close(SocketFD); - exit(EXIT_FAILURE); - } else if (0 == Res) { - perror("char string (second parameter does not contain valid ipaddress)"); - close(SocketFD); - exit(EXIT_FAILURE); + // Make sure that sockfd has actually finished connecting + // and is ready to read. + FD_ZERO(&fdw); + FD_SET(sockfd, &fdw); + res = select(64, NULL, &fdw, NULL, NULL); + if (res == -1) { + perror("select failed"); + finish(EXIT_FAILURE); + } else if (!FD_ISSET(sockfd, &fdw)) { + return; } - printf("connect..\n"); + char data[] = "hello from the other siide\n"; - if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) { - perror("connect failed"); - close(SocketFD); - exit(EXIT_FAILURE); + printf("send..\n"); +#if TEST_FILE_OPS + res = write(sockfd, data, sizeof(data)); +#else + res = send(sockfd, data, sizeof(data), 0); +#endif + if (res == -1) { + if (errno != EAGAIN) { + perror("send error"); + finish(EXIT_FAILURE); + } + return; } -#if TEST_FILE_OPS - printf("write..\n"); + finish(EXIT_SUCCESS); +} - char data[] = "hello from the other siide (fileops)\n"; - write(SocketFD, data, sizeof(data)); +int main() { + struct sockaddr_in addr; + int res; +#if !TEST_DGRAM + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); #else - printf("send..\n"); - - char data[] = "hello from the other siide\n"; - send(SocketFD, data, sizeof(data), 0); + sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); #endif + if (sockfd == -1) { + perror("cannot create socket"); + finish(EXIT_FAILURE); + } + fcntl(sockfd, F_SETFL, O_NONBLOCK); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); + } - printf("stall..\n"); + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { + perror("connect failed"); + finish(EXIT_FAILURE); + } - //int bytes; - //while (1) ioctl(SocketFD, FIONREAD, &bytes); + emscripten_set_main_loop(loop, 0, 0); return EXIT_SUCCESS; } diff --git a/tests/websockets_bi_side_bigdata.c b/tests/websockets_bi_side_bigdata.c index 9b67fe4c..d131e6e0 100644 --- a/tests/websockets_bi_side_bigdata.c +++ b/tests/websockets_bi_side_bigdata.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #if EMSCRIPTEN #include @@ -16,54 +17,74 @@ #define EXPECTED_BYTES 5 -void stall(void *arg) { -} +int sockfd = -1; +char *data = NULL; -int main(void) -{ - struct sockaddr_in stSockAddr; - int Res; - int SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); +void finish(int result) { + close(sockfd); + exit(result); +} - if (-1 == SocketFD) - { - perror("cannot create socket"); - exit(EXIT_FAILURE); +void loop() { + fd_set fdw; + int res; + + // make sure that sockfd has finished connecting and is ready to write + FD_ZERO(&fdw); + FD_SET(sockfd, &fdw); + res = select(64, NULL, &fdw, NULL, NULL); + if (res == -1) { + perror("select failed"); + finish(EXIT_FAILURE); + return; + } else if (!FD_ISSET(sockfd, &fdw)) { + return; } - memset(&stSockAddr, 0, sizeof(stSockAddr)); + printf("send..\n"); - stSockAddr.sin_family = AF_INET; - stSockAddr.sin_port = htons(SOCKK); - Res = inet_pton(AF_INET, "127.0.0.1", &stSockAddr.sin_addr); + res = send(sockfd, data, DATA_SIZE, 0); + if (res == -1) { + if (errno != EAGAIN) { + perror("send error"); + finish(EXIT_FAILURE); + } + return; + } - if (0 > Res) { - perror("error: first parameter is not a valid address family"); - close(SocketFD); - exit(EXIT_FAILURE); - } else if (0 == Res) { - perror("char string (second parameter does not contain valid ipaddress)"); - close(SocketFD); + finish(EXIT_SUCCESS); +} + +int main() { + struct sockaddr_in addr; + int res; + + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == -1) { + perror("cannot create socket"); exit(EXIT_FAILURE); } + fcntl(sockfd, F_SETFL, O_NONBLOCK); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); + } printf("connect..\n"); - if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) { + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { perror("connect failed"); - close(SocketFD); - exit(EXIT_FAILURE); + finish(EXIT_FAILURE); } - printf("send..\n"); - - char *data = generateData(); - send(SocketFD, data, DATA_SIZE, 0); - - printf("stall..\n"); + data = generateData(); - emscripten_set_main_loop(stall, 1, 0); + emscripten_set_main_loop(loop, 1, 0); return EXIT_SUCCESS; -} - +} \ No newline at end of file diff --git a/tests/websockets_gethostbyname.c b/tests/websockets_gethostbyname.c index 1580d9a7..59c55ba1 100644 --- a/tests/websockets_gethostbyname.c +++ b/tests/websockets_gethostbyname.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #if EMSCRIPTEN #include @@ -14,10 +15,17 @@ #define EXPECTED_BYTES 5 -int SocketFD; +int sockfd; -unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) -{ +void finish(int result) { + close(sockfd); +#if EMSCRIPTEN + REPORT_RESULT(); +#endif + exit(result); +} + +unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) { int bytes; if (ioctl(sock, FIONREAD, &bytes)) return 0; if (bytes == 0) return 0; @@ -27,28 +35,42 @@ unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) unsigned int offset = 0; while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) || errno == EINTR) { - if(n>0) - { - if (((unsigned int) n)+offset > maxsize) { fprintf(stderr, "too much data!"); exit(EXIT_FAILURE); } + if (n > 0) { + if (((unsigned int) n)+offset > maxsize) { + fprintf(stderr, "too much data!"); + finish(EXIT_FAILURE); + } memcpy(output+offset, buffer, n); offset += n; } } - if(n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { - fprintf(stderr, "error in get_all_buf!"); - exit(EXIT_FAILURE); + if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { + perror("error in get_all_buf!"); + finish(EXIT_FAILURE); } return offset; } -int done = 0; - void iter() { - /* perform read write operations ... */ static char out[1024*2]; static int pos = 0; - int n = get_all_buf(SocketFD, out+pos, 1024-pos); + fd_set fdr; + int res; + + // make sure that sockfd has finished connecting and is ready to read + FD_ZERO(&fdr); + FD_SET(sockfd, &fdr); + res = select(64, &fdr, NULL, NULL, NULL); + if (res == -1) { + perror("select failed"); + finish(EXIT_FAILURE); + } else if (!FD_ISSET(sockfd, &fdr)) { + return; + } + + // perform read write operations ... + int n = get_all_buf(sockfd, out+pos, 1024-pos); if (n) printf("read! %d\n", n); pos += n; if (pos >= EXPECTED_BYTES) { @@ -58,73 +80,57 @@ void iter() { sum += out[i]; } - shutdown(SocketFD, SHUT_RDWR); + shutdown(sockfd, SHUT_RDWR); - close(SocketFD); - - done = 1; + close(sockfd); printf("sum: %d\n", sum); -#if EMSCRIPTEN - int result = sum; - REPORT_RESULT(); -#endif + finish(sum); } } -int main(void) -{ - struct sockaddr_in stSockAddr; - int Res; - SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); +int main() { + struct sockaddr_in addr; + int res; - if (-1 == SocketFD) - { + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == -1) { perror("cannot create socket"); - exit(EXIT_FAILURE); + finish(EXIT_FAILURE); } + fcntl(sockfd, F_SETFL, O_NONBLOCK); - memset(&stSockAddr, 0, sizeof(stSockAddr)); - - stSockAddr.sin_family = AF_INET; - stSockAddr.sin_port = htons(7001); - + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); struct hostent *host0 = gethostbyname("test.com"); // increment hostname counter to check for possible but at 0,0 not differentiating low/high struct hostent *host = gethostbyname("localhost"); - char **addr_list = host->h_addr_list; - int *addr = (int*)*addr_list; - printf("raw addr: %d\n", *addr); + char **raw_addr_list = host->h_addr_list; + int *raw_addr = (int*)*raw_addr_list; + printf("raw addr: %d\n", *raw_addr); char name[INET_ADDRSTRLEN]; - if (!inet_ntop(AF_INET, addr, name, sizeof(name))) { + if (!inet_ntop(AF_INET, raw_addr, name, sizeof(name))) { printf("could not figure out name\n"); - return 0; + finish(EXIT_FAILURE); } printf("localhost has 'ip' of %s\n", name); - Res = inet_pton(AF_INET, name, &stSockAddr.sin_addr); - - if (0 > Res) { - perror("error: first parameter is not a valid address family"); - close(SocketFD); - exit(EXIT_FAILURE); - } else if (0 == Res) { - perror("char string (second parameter does not contain valid ipaddress)"); - close(SocketFD); - exit(EXIT_FAILURE); + if (inet_pton(AF_INET, name, &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); } - if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) { + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { perror("connect failed"); - close(SocketFD); - exit(EXIT_FAILURE); - + finish(EXIT_FAILURE); } #if EMSCRIPTEN emscripten_set_main_loop(iter, 0, 0); #else - while (!done) iter(); + while (1) iter(); #endif return EXIT_SUCCESS; diff --git a/tests/websockets_partial.c b/tests/websockets_partial.c index f71160b7..5fe34721 100644 --- a/tests/websockets_partial.c +++ b/tests/websockets_partial.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -13,107 +14,98 @@ #include #endif -int SocketFD; -int done = 0; +int sockfd = -1; int sum = 0; +void finish(int result) { + close(sockfd); +#if EMSCRIPTEN + REPORT_RESULT(); +#endif + exit(result); +} + void iter(void *arg) { char buffer[1024]; char packetLength; - int n; + fd_set fdr; int i; - - if (done) { + int res; + + // make sure that sockfd is ready to read + FD_ZERO(&fdr); + FD_SET(sockfd, &fdr); + res = select(64, &fdr, NULL, NULL, NULL); + if (res == -1) { + perror("select failed"); + finish(EXIT_FAILURE); + } else if (!FD_ISSET(sockfd, &fdr)) { return; } - n = recv(SocketFD, buffer, 1, 0); - - if (n == -1) { + res = recv(sockfd, buffer, 1, 0); + if (res == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { return; //try again } - fprintf(stderr, "unexcepted end of data"); - exit(EXIT_FAILURE); + perror("unexcepted end of data"); + finish(EXIT_FAILURE); } - if (n != 1) { - fprintf(stderr, "should read 1 byte"); - exit(EXIT_FAILURE); + if (res != 1) { + perror("should read 1 byte"); + finish(EXIT_FAILURE); } packetLength = buffer[0]; - n = recv(SocketFD, buffer, packetLength, 0); + res = recv(sockfd, buffer, packetLength, 0); - printf("got %d,%d\n", n, packetLength); + printf("got %d,%d\n", res, packetLength); - if (n != packetLength) { - fprintf(stderr, "lost packet data, expected: %d readed: %d", packetLength, n); - exit(EXIT_FAILURE); + if (res != packetLength) { + fprintf(stderr, "lost packet data, expected: %d readed: %d", packetLength, res); + finish(EXIT_FAILURE); } for (i = 0; i < packetLength; ++i) { if (buffer[i] != i+1) { fprintf(stderr, "packet corrupted, expected: %d, actual: %d", i+1, buffer[i]); - exit(EXIT_FAILURE); + finish(EXIT_FAILURE); } sum += buffer[i]; } if (packetLength == buffer[0]) { // \x01\x01 - end marker - shutdown(SocketFD, SHUT_RDWR); - close(SocketFD); - done = 1; - - #if EMSCRIPTEN - printf("sum: %d\n", sum); - int result = sum; - REPORT_RESULT(); - #endif + printf("sum: %d\n", sum); + finish(sum); } } -int main(void) -{ - struct sockaddr_in stSockAddr; - int Res; - SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); +int main() { + struct sockaddr_in addr; + int res; - if (-1 == SocketFD) - { + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == -1) { perror("cannot create socket"); exit(EXIT_FAILURE); } - - memset(&stSockAddr, 0, sizeof(stSockAddr)); - - stSockAddr.sin_family = AF_INET; - stSockAddr.sin_port = htons( -#if EMSCRIPTEN - 8991 -#else - 8990 -#endif - ); - Res = inet_pton(AF_INET, "127.0.0.1", &stSockAddr.sin_addr); - - if (0 > Res) { - perror("error: first parameter is not a valid address family"); - close(SocketFD); - exit(EXIT_FAILURE); - } else if (0 == Res) { - perror("char string (second parameter does not contain valid ipaddress)"); - close(SocketFD); - exit(EXIT_FAILURE); + fcntl(sockfd, F_SETFL, O_NONBLOCK); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); } - if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) { + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { perror("connect failed"); - close(SocketFD); - exit(EXIT_FAILURE); - + finish(EXIT_FAILURE); } #if EMSCRIPTEN diff --git a/tests/websockets_select.c b/tests/websockets_select.c index b8ab9091..e05bd4c8 100644 --- a/tests/websockets_select.c +++ b/tests/websockets_select.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #if EMSCRIPTEN @@ -15,81 +16,83 @@ #define EXPECTED_BYTES 5 -int SocketFD; +int sockfd = -1; -int done = 0; +void finish(int result) { + close(sockfd); +#if EMSCRIPTEN + REPORT_RESULT(); +#endif + exit(result); +} + +void iter(void *arg) { + static int retries = 0; -void iter(void *arg) { fd_set sett; FD_ZERO(&sett); - FD_SET(SocketFD, &sett); + FD_SET(sockfd, &sett); - // The error should happen here - int select_says_yes = select(64, &sett, NULL, NULL, NULL); - if( select_says_yes == -1 ){ - printf( "Connection to websocket server failed as expected." ); - perror( "Error message" ); - int result = 266; - REPORT_RESULT(); - done = 1; + // currently, we've connected to a closed server port. + // the initial async connect "succeeded" and select + // should say that the socket is ready for a non-blocking + // read, however, the read should be 0 sized signalling + // that the remote end has closed. + int handles = select(64, &sett, NULL, NULL, NULL); + if (handles == -1) { + perror("select failed"); + finish(EXIT_FAILURE); } - assert(!select_says_yes); - done = 1; + if (FD_ISSET(sockfd, &sett)) { + char buffer[1024]; + int n = recv(sockfd, buffer, sizeof(buffer), 0); + if (n == -1 && retries++ > 10) { + perror("revv failed"); + finish(EXIT_FAILURE); + } else if (!n) { + perror("Connection to websocket server failed as expected."); + finish(266); + } + } } // This is for testing a websocket connection to a closed server port. // The connect call will succeed (due to the asynchronous websocket // behavior) but once the underlying websocket system realized that // the connection cannot be established, the next select call will fail. -int main(void) -{ - struct sockaddr_in stSockAddr; - int Res; - SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); +int main() { + struct sockaddr_in addr; + int res; - if (-1 == SocketFD) - { + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == -1) { perror("cannot create socket"); - exit(EXIT_FAILURE); + finish(EXIT_FAILURE); } + fcntl(sockfd, F_SETFL, O_NONBLOCK); - memset(&stSockAddr, 0, sizeof(stSockAddr)); - - stSockAddr.sin_family = AF_INET; - stSockAddr.sin_port = htons( -#if EMSCRIPTEN - 8995 -#else - 8994 -#endif - ); - Res = inet_pton(AF_INET, "127.0.0.1", &stSockAddr.sin_addr); - - if (0 > Res) { - perror("error: first parameter is not a valid address family"); - close(SocketFD); - exit(EXIT_FAILURE); - } else if (0 == Res) { - perror("char string (second parameter does not contain valid ipaddress)"); - close(SocketFD); - exit(EXIT_FAILURE); + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); } // This call should succeed (even if the server port is closed) - if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) { + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { perror("connect failed"); - close(SocketFD); - exit(EXIT_FAILURE); - + finish(EXIT_FAILURE); } #if EMSCRIPTEN emscripten_set_main_loop(iter, 0, 0); #else - while (!done) iter(NULL); + while (1) iter(NULL); #endif - - return EXIT_SUCCESS; + + return EXIT_FAILURE; } diff --git a/tests/websockets_select_server_closes_connection.c b/tests/websockets_select_server_closes_connection.c index 6ce6d311..4181b12b 100644 --- a/tests/websockets_select_server_closes_connection.c +++ b/tests/websockets_select_server_closes_connection.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #if EMSCRIPTEN @@ -15,9 +16,15 @@ #define EXPECTED_BYTES 5 -int SocketFD; +int sockfd = -1; -int done = 0; +void finish(int result) { + close(sockfd); +#if EMSCRIPTEN + REPORT_RESULT(); +#endif + exit(result); +} void iter(void *arg) { static char readbuf[1024]; @@ -25,44 +32,39 @@ void iter(void *arg) { fd_set sett; FD_ZERO(&sett); - FD_SET(SocketFD, &sett); + FD_SET(sockfd, &sett); + + int res = select(64, &sett, NULL, NULL, NULL); - if( readPos < 7 ){ - // still reading - int selectRes = select(64, &sett, NULL, NULL, NULL); + if (res == -1) { + perror("select failed"); + finish(EXIT_FAILURE); + } else if (res == 0) { + return; + } else if (res > 0) { + assert(FD_ISSET(sockfd, &sett)); - if( selectRes == 0 ) + int bytesRead = recv(sockfd, readbuf+readPos, 7-readPos, 0); + if (bytesRead == -1) { + if (errno != EAGAIN) { + perror("recv error"); + finish(EXIT_FAILURE); + } + // try again return; - - if( selectRes == -1 ){ - perror( "Connection to websocket server failed" ); - exit(EXIT_FAILURE); } - if( selectRes > 0 ){ - assert(FD_ISSET(SocketFD, &sett)); - - int bytesRead = recv( SocketFD, readbuf+readPos, 7-readPos, 0 ); + + if (readPos < 7) { readPos += bytesRead; + } else { + if (!bytesRead) { + perror("Connection to websocket server was closed as expected"); + finish(266); + } else { + perror("Connection to websocket server was not closed"); + finish(EXIT_FAILURE); + } } - } else { - // here the server should have closed the connection - int selectRes = select(64, &sett, NULL, NULL, NULL); - - if( selectRes == 0 ) - return; - - if( selectRes == -1 ){ - perror( "Connection to websocket server failed as expected" ); - int result = 266; - REPORT_RESULT(); - emscripten_cancel_main_loop(); - done = 1; - } - - if( selectRes > 0 ){ - printf( "Error: socket should not show up on select call anymore.\n" ); - exit(EXIT_FAILURE); - } } return; @@ -71,56 +73,40 @@ void iter(void *arg) { // Scenario: the server sends data and closes the connection after 7 bytes. // This test should provoke the situation in which the underlying // tcp connection has been torn down already but there is still data -// in the inQueue. The select call has to succeed as long the queue +// in the queue. The select call has to succeed as long the queue // still contains data and only then start to throw errors. -int main(void) -{ - struct sockaddr_in stSockAddr; - int Res; - SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); +int main() { + struct sockaddr_in addr; + int res; - if (-1 == SocketFD) - { + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == -1) { perror("cannot create socket"); - exit(EXIT_FAILURE); + finish(EXIT_FAILURE); } + fcntl(sockfd, F_SETFL, O_NONBLOCK); - memset(&stSockAddr, 0, sizeof(stSockAddr)); - - stSockAddr.sin_family = AF_INET; - stSockAddr.sin_port = htons( -#if EMSCRIPTEN - 8995 -#else - 8994 -#endif - ); - Res = inet_pton(AF_INET, "127.0.0.1", &stSockAddr.sin_addr); - - if (0 > Res) { - perror("error: first parameter is not a valid address family"); - close(SocketFD); - exit(EXIT_FAILURE); - } else if (0 == Res) { - perror("char string (second parameter does not contain valid ipaddress)"); - close(SocketFD); - exit(EXIT_FAILURE); + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); } // This call should succeed (even if the server port is closed) - if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) { + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { perror("connect failed"); - close(SocketFD); - exit(EXIT_FAILURE); - + finish(EXIT_FAILURE); } #if EMSCRIPTEN emscripten_set_main_loop(iter, 0, 0); #else - while (!done) iter(NULL); + while (1) iter(NULL); #endif - return EXIT_SUCCESS; + return EXIT_FAILURE; } diff --git a/tests/websockets_select_server_closes_connection_rw.c b/tests/websockets_select_server_closes_connection_rw.c index dd0913bf..f7e19aca 100644 --- a/tests/websockets_select_server_closes_connection_rw.c +++ b/tests/websockets_select_server_closes_connection_rw.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #if EMSCRIPTEN @@ -15,9 +16,15 @@ #define EXPECTED_BYTES 5 -int SocketFD; +int sockfd = -1; -int done = 0; +void finish(int result) { + close(sockfd); +#if EMSCRIPTEN + REPORT_RESULT(); +#endif + exit(result); +} void iter(void *arg) { static int state = 0; @@ -27,42 +34,40 @@ void iter(void *arg) { static int readPos = 0; int selectRes; ssize_t transferAmount; - fd_set sett; + fd_set sett; - - switch( state ){ + switch (state) { case 0: // writing 10 bytes to the server - // the socket in the read file descriptors has to result in a 0 return value - // because the connection exists, but there is no data yet - FD_ZERO( &sett ); - FD_SET(SocketFD, &sett); + // since the socket in the read file descriptors has no available data, + // select should tell us 0 handles are ready + FD_ZERO(&sett); + FD_SET(sockfd, &sett); selectRes = select(64, &sett, NULL, NULL, NULL); - if( selectRes != 0 ){ - printf( "case 0: read select != 0\n" ); - exit(EXIT_FAILURE); + if (selectRes != 0) { + printf("case 0: read select != 0 (%d)\n", selectRes); + finish(EXIT_FAILURE); } // the socket in the write file descriptors has to result in either a 0 or 1 // the connection either is setting up or is established and writing is possible - FD_ZERO( &sett ); - FD_SET(SocketFD, &sett); + FD_ZERO(&sett); + FD_SET(sockfd, &sett); selectRes = select(64, NULL, &sett, NULL, NULL); - if( selectRes == -1 ){ - printf( "case 0: write select == -1\n" ); - exit(EXIT_FAILURE); - } - if( selectRes == 0 ){ + if (selectRes == -1) { + printf("case 0: write select == -1\n"); + finish(EXIT_FAILURE); + } else if (selectRes == 0) { return; } // send a single byte - transferAmount = send( SocketFD, writebuf+writePos, 1, 0 ); + transferAmount = send(sockfd, writebuf+writePos, 1, 0); writePos += transferAmount; // after 10 bytes switch to next state - if( writePos >= 10 ){ + if (writePos >= 10) { state = 1; } break; @@ -70,79 +75,86 @@ void iter(void *arg) { case 1: // wait until we can read one byte to make sure the server // has sent the data and then closed the connection - FD_ZERO( &sett ); - FD_SET(SocketFD, &sett); + FD_ZERO(&sett); + FD_SET(sockfd, &sett); selectRes = select(64, &sett, NULL, NULL, NULL); - if( selectRes == -1 ){ - printf( "case 1: read selectRes == -1\n" ); - exit(EXIT_FAILURE); - } - if( selectRes == 0 ) + if (selectRes == -1) { + printf("case 1: read selectRes == -1\n"); + finish(EXIT_FAILURE); + } else if (selectRes == 0) { return; + } // read a single byte - transferAmount = recv( SocketFD, readbuf+readPos, 1, 0 ); + transferAmount = recv(sockfd, readbuf+readPos, 1, 0); readPos += transferAmount; // if successfully reading 1 byte, switch to next state - if( readPos >= 1 ){ + if (readPos >= 1) { state = 2; } break; case 2: - // calling select with the socket in the write file descriptors has - // to fail because the tcp network connection is already down - FD_ZERO( &sett ); - FD_SET(SocketFD, &sett); + // calling select with the socket in the write file descriptors should + // succeed, but the socket should not set in the set. + FD_ZERO(&sett); + FD_SET(sockfd, &sett); selectRes = select(64, NULL, &sett, NULL, NULL); - if( selectRes != -1 ){ - printf( "case 2: write selectRes != -1\n" ); - exit(EXIT_FAILURE); + if (selectRes != 0 || FD_ISSET(sockfd, &sett)) { + printf("case 2: write selectRes != 0 || FD_ISSET(sockfd, &sett)\n"); + finish(EXIT_FAILURE); } // calling select with the socket in the read file descriptors // has to succeed because there is still data in the inQueue - FD_ZERO( &sett ); - FD_SET(SocketFD, &sett); + FD_ZERO(&sett); + FD_SET(sockfd, &sett); selectRes = select(64, &sett, NULL, NULL, NULL); - if( selectRes != 1 ){ - printf( "case 2: read selectRes != 1\n" ); - exit(EXIT_FAILURE); - } - if( selectRes == 0 ) + if (selectRes != 1) { + printf("case 2: read selectRes != 1\n"); + finish(EXIT_FAILURE); + } else if (selectRes == 0) { return; + } // read a single byte - transferAmount = recv( SocketFD, readbuf+readPos, 1, 0 ); + transferAmount = recv(sockfd, readbuf+readPos, 1, 0); readPos += transferAmount; // with 10 bytes read the inQueue is empty => switch state - if( readPos >= 10 ){ + if (readPos >= 10) { state = 3; } break; case 3: // calling select with the socket in the read file descriptors - // now also has to fail as the inQueue is empty - FD_ZERO( &sett ); - FD_SET(SocketFD, &sett); + // should succeed + FD_ZERO(&sett); + FD_SET(sockfd, &sett); selectRes = select(64, &sett, NULL, NULL, NULL); - if( selectRes != -1 ){ - printf( "case 3: read selectRes != -1\n" ); - exit(EXIT_FAILURE); + if (selectRes != 1) { + printf("case 3: read selectRes != 1\n"); + finish(EXIT_FAILURE); + } + + // but recv should return 0 signaling the remote + // end has closed the connection. + transferAmount = recv(sockfd, readbuf, 1, 0); + if (transferAmount) { + printf("case 3: read != 0\n"); + finish(EXIT_FAILURE); } // report back success, the 266 is just an arbitrary value without // deeper meaning - int result = 266; - REPORT_RESULT(); + finish(266); break; default: - printf( "Impossible state!\n" ); - exit(EXIT_FAILURE); + printf("Impossible state!\n"); + finish(EXIT_FAILURE); break; } @@ -160,52 +172,36 @@ void iter(void *arg) { // as there are still 10 bytes to read from the inQueue. So, for the same socket the // select call behaves differently depending on whether the socket is listed in the // read or write file descriptors. -int main(void) -{ - struct sockaddr_in stSockAddr; - int Res; - SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); +int main() { + struct sockaddr_in addr; + int res; - if (-1 == SocketFD) - { + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == -1) { perror("cannot create socket"); - exit(EXIT_FAILURE); + finish(EXIT_FAILURE); } - - memset(&stSockAddr, 0, sizeof(stSockAddr)); - - stSockAddr.sin_family = AF_INET; - stSockAddr.sin_port = htons( -#if EMSCRIPTEN - 8999 -#else - 8998 -#endif - ); - Res = inet_pton(AF_INET, "127.0.0.1", &stSockAddr.sin_addr); - - if (0 > Res) { - perror("error: first parameter is not a valid address family"); - close(SocketFD); - exit(EXIT_FAILURE); - } else if (0 == Res) { - perror("char string (second parameter does not contain valid ipaddress)"); - close(SocketFD); - exit(EXIT_FAILURE); + fcntl(sockfd, F_SETFL, O_NONBLOCK); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); } // This call should succeed (even if the server port is closed) - if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) { + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { perror("connect failed"); - close(SocketFD); - exit(EXIT_FAILURE); - + finish(EXIT_FAILURE); } #if EMSCRIPTEN emscripten_set_main_loop(iter, 0, 0); #else - while (!done) iter(NULL); + while (1) iter(NULL); #endif return EXIT_SUCCESS; -- cgit v1.2.3-18-g5258 From 337817bf6c153f7cc2441c67dbc67ba510ed6b45 Mon Sep 17 00:00:00 2001 From: Anthony Pesch Date: Wed, 7 Aug 2013 14:07:43 -0700 Subject: renamed socket tests --- tests/runner.py | 20 +- tests/sockets/test_sockets.c | 143 ++++++++++++++ tests/sockets/test_sockets_bi.c | 140 ++++++++++++++ tests/sockets/test_sockets_bi_bigdata.c | 138 ++++++++++++++ tests/sockets/test_sockets_bi_side.c | 93 +++++++++ tests/sockets/test_sockets_bi_side_bigdata.c | 90 +++++++++ tests/sockets/test_sockets_bigdata.h | 20 ++ tests/sockets/test_sockets_gethostbyname.c | 138 ++++++++++++++ tests/sockets/test_sockets_partial.c | 119 ++++++++++++ tests/sockets/test_sockets_select.c | 98 ++++++++++ .../test_sockets_select_server_closes_connection.c | 112 +++++++++++ ...st_sockets_select_server_closes_connection_rw.c | 209 +++++++++++++++++++++ tests/websockets.c | 143 -------------- tests/websockets_bi.c | 140 -------------- tests/websockets_bi_bigdata.c | 138 -------------- tests/websockets_bi_side.c | 93 --------- tests/websockets_bi_side_bigdata.c | 90 --------- tests/websockets_bigdata.h | 20 -- tests/websockets_gethostbyname.c | 138 -------------- tests/websockets_partial.c | 119 ------------ tests/websockets_select.c | 98 ---------- tests/websockets_select_server_closes_connection.c | 112 ----------- ...websockets_select_server_closes_connection_rw.c | 209 --------------------- 23 files changed, 1310 insertions(+), 1310 deletions(-) create mode 100644 tests/sockets/test_sockets.c create mode 100644 tests/sockets/test_sockets_bi.c create mode 100644 tests/sockets/test_sockets_bi_bigdata.c create mode 100644 tests/sockets/test_sockets_bi_side.c create mode 100644 tests/sockets/test_sockets_bi_side_bigdata.c create mode 100644 tests/sockets/test_sockets_bigdata.h create mode 100644 tests/sockets/test_sockets_gethostbyname.c create mode 100644 tests/sockets/test_sockets_partial.c create mode 100644 tests/sockets/test_sockets_select.c create mode 100644 tests/sockets/test_sockets_select_server_closes_connection.c create mode 100644 tests/sockets/test_sockets_select_server_closes_connection_rw.c delete mode 100644 tests/websockets.c delete mode 100644 tests/websockets_bi.c delete mode 100644 tests/websockets_bi_bigdata.c delete mode 100644 tests/websockets_bi_side.c delete mode 100644 tests/websockets_bi_side_bigdata.c delete mode 100644 tests/websockets_bigdata.h delete mode 100644 tests/websockets_gethostbyname.c delete mode 100644 tests/websockets_partial.c delete mode 100644 tests/websockets_select.c delete mode 100644 tests/websockets_select_server_closes_connection.c delete mode 100644 tests/websockets_select_server_closes_connection_rw.c (limited to 'tests') diff --git a/tests/runner.py b/tests/runner.py index 2bd26eb7..dbf7cb4f 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -13951,7 +13951,7 @@ Press any key to continue.''' def test_sockets(self): try: with self.WebsockHarness(8990): - self.btest('websockets.c', expected='571', args=['-DSOCKK=8991']) + self.btest('sockets/test_sockets.c', expected='571', args=['-DSOCKK=8991']) finally: self.clean_pids() @@ -13978,7 +13978,7 @@ Press any key to continue.''' try: with self.WebsockHarness(8990, partial): - self.btest('websockets_partial.c', expected='165', args=['-DSOCKK=8991']) + self.btest('sockets/test_sockets_partial.c', expected='165', args=['-DSOCKK=8991']) finally: self.clean_pids() @@ -13997,15 +13997,15 @@ Press any key to continue.''' print >> sys.stderr, 'test_websocket_bi datagram %d, fileops %d' % (datagram, fileops) with self.WebsockHarness(6992, self.make_relay_server(6992, 6994)): with self.WebsockHarness(6994, no_server=True): - Popen([PYTHON, EMCC, path_from_root('tests', 'websockets_bi_side.c'), '-o', 'side.html', '-DSOCKK=6995', '-DTEST_DGRAM=%d' % datagram]).communicate() - self.btest('websockets_bi.c', expected='2499', args=['-DSOCKK=6993', '-DTEST_DGRAM=%d' % datagram, '-DTEST_FILE_OPS=%s' % fileops, '-DEMBED_SIDE']) + Popen([PYTHON, EMCC, path_from_root('tests', 'sockets/test_sockets_bi_side.c'), '-o', 'side.html', '-DSOCKK=6995', '-DTEST_DGRAM=%d' % datagram]).communicate() + self.btest('sockets/test_sockets_bi.c', expected='2499', args=['-DSOCKK=6993', '-DTEST_DGRAM=%d' % datagram, '-DTEST_FILE_OPS=%s' % fileops, '-DEMBED_SIDE']) finally: self.clean_pids() def test_sockets_gethostbyname(self): try: with self.WebsockHarness(7000): - self.btest('websockets_gethostbyname.c', expected='571', args=['-O2', '-DSOCKK=7001']) + self.btest('sockets/test_sockets_gethostbyname.c', expected='571', args=['-O2', '-DSOCKK=7001']) finally: self.clean_pids() @@ -14013,8 +14013,8 @@ Press any key to continue.''' try: with self.WebsockHarness(3992, self.make_relay_server(3992, 3994)): with self.WebsockHarness(3994, no_server=True): - Popen([PYTHON, EMCC, path_from_root('tests', 'websockets_bi_side_bigdata.c'), '-o', 'side.html', '-DSOCKK=3995', '-s', 'SOCKET_DEBUG=0', '-I' + path_from_root('tests')]).communicate() - self.btest('websockets_bi_bigdata.c', expected='0', args=['-DSOCKK=3993', '-s', 'SOCKET_DEBUG=0', '-I' + path_from_root('tests')]) + Popen([PYTHON, EMCC, path_from_root('tests', 'sockets/test_sockets_bi_side_bigdata.c'), '-o', 'side.html', '-DSOCKK=3995', '-s', 'SOCKET_DEBUG=0', '-I' + path_from_root('tests/sockets')]).communicate() + self.btest('sockets/test_sockets_bi_bigdata.c', expected='0', args=['-DSOCKK=3993', '-s', 'SOCKET_DEBUG=0', '-I' + path_from_root('tests/sockets')]) finally: self.clean_pids() @@ -14027,7 +14027,7 @@ Press any key to continue.''' ssock.bind(("127.0.0.1", 8994)) try: with self.WebsockHarness(8994, closedServer): - self.btest('websockets_select.c', expected='266', args=['-DSOCKK=8995']) + self.btest('sockets/test_sockets_select.c', expected='266', args=['-DSOCKK=8995']) finally: self.clean_pids() @@ -14047,7 +14047,7 @@ Press any key to continue.''' try: with self.WebsockHarness(8994, closingServer): - self.btest('websockets_select_server_closes_connection.c', expected='266', args=['-DSOCKK=8995']) + self.btest('sockets/test_sockets_select_server_closes_connection.c', expected='266', args=['-DSOCKK=8995']) finally: self.clean_pids() @@ -14079,7 +14079,7 @@ Press any key to continue.''' try: with self.WebsockHarness(8998, closingServer_rw): - self.btest('websockets_select_server_closes_connection_rw.c', expected='266', args=['-DSOCKK=8999']) + self.btest('sockets/test_sockets_select_server_closes_connection_rw.c', expected='266', args=['-DSOCKK=8999']) finally: self.clean_pids() diff --git a/tests/sockets/test_sockets.c b/tests/sockets/test_sockets.c new file mode 100644 index 00000000..8845ef43 --- /dev/null +++ b/tests/sockets/test_sockets.c @@ -0,0 +1,143 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if EMSCRIPTEN +#include +#endif + +#define EXPECTED_BYTES 5 + +int sockfd; +int not_always_data = 0; + +void finish(int result) { + close(sockfd); +#if EMSCRIPTEN + REPORT_RESULT(); +#endif + exit(result); +} + +unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) { + // select check for IO + fd_set sett; + FD_ZERO(&sett); + assert(select(64, &sett, NULL, NULL, NULL) == 0); // empty set + FD_SET(sock, &sett); + assert(select(0, &sett, NULL, NULL, NULL) == 0); // max FD to check is 0 + assert(FD_ISSET(sock, &sett) == 0); + FD_SET(sock, &sett); + int select_says_yes = select(64, &sett, NULL, NULL, NULL); + + // ioctl check for IO + int bytes; + if (ioctl(sock, FIONREAD, &bytes) || bytes == 0) { + not_always_data = 1; + printf("ioctl says 0, FD_ISSET says %ld\n", FD_ISSET(sock, &sett)); + assert(FD_ISSET(sock, &sett) == 0); + return 0; + } + + assert(FD_ISSET(sock, &sett)); + assert(select_says_yes); // ioctl must agree with select + + char buffer[1024]; + int n; + unsigned int offset = 0; + while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) || + errno == EINTR) { + if(n > 0) { + if (((unsigned int) n)+offset > maxsize) { + fprintf(stderr, "too much data!"); + finish(EXIT_FAILURE); + } + memcpy(output+offset, buffer, n); + offset += n; + } + } + + if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { + fprintf(stderr, "error in get_all_buf! %d", errno); + finish(EXIT_FAILURE); + } + return offset; +} + +void iter(void *arg) { + static char out[1024*2]; + static int pos = 0; + fd_set fdr; + int res; + + // make sure that sockfd is ready to read + FD_ZERO(&fdr); + FD_SET(sockfd, &fdr); + res = select(64, &fdr, NULL, NULL, NULL); + if (res == -1) { + perror("select failed"); + finish(EXIT_FAILURE); + } else if (!FD_ISSET(sockfd, &fdr)) { + return; + } + + // perform read write operations ... + int n = get_all_buf(sockfd, out+pos, 1024-pos); + if (n) printf("read! %d\n", n); + pos += n; + if (pos >= EXPECTED_BYTES) { + int i, sum = 0; + for (i=0; i < pos; i++) { + printf("%x\n", out[i]); + sum += out[i]; + } + + shutdown(sockfd, SHUT_RDWR); + + close(sockfd); + + printf("sum: %d\n", sum); + finish(sum); + } +} + +void main() { + struct sockaddr_in addr; + int res; + + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == -1) { + perror("cannot create socket"); + finish(EXIT_FAILURE); + } + fcntl(sockfd, F_SETFL, O_NONBLOCK); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); + } + + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { + perror("connect failed"); + finish(EXIT_FAILURE); + } + +#if EMSCRIPTEN + emscripten_set_main_loop(iter, 0, 0); +#else + while (1) iter(NULL); +#endif +} + diff --git a/tests/sockets/test_sockets_bi.c b/tests/sockets/test_sockets_bi.c new file mode 100644 index 00000000..e19f7fe8 --- /dev/null +++ b/tests/sockets/test_sockets_bi.c @@ -0,0 +1,140 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if EMSCRIPTEN +#include +#endif + +#define EXPECTED_BYTES 28 + +int sockfd; + +void finish(int result) { + close(sockfd); +#if EMSCRIPTEN + REPORT_RESULT(); +#endif + exit(result); +} + +unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) { + int bytes; + if (ioctl(sock, FIONREAD, &bytes)) return 0; + if (bytes == 0) return 0; + + char buffer[1024]; + int n; + unsigned int offset = 0; +#if TEST_FILE_OPS + while((errno = 0, (n = read(sock, buffer, sizeof(buffer)))>0) || +#else + while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) || +#endif + errno == EINTR) { + if(n > 0) { + if (((unsigned int) n)+offset > maxsize) { + fprintf(stderr, "too much data!"); + finish(EXIT_FAILURE); + } + memcpy(output+offset, buffer, n); + offset += n; + } + } + + if(n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { + fprintf(stderr, "error in get_all_buf!"); + finish(EXIT_FAILURE); + } + return offset; +} + +void iter(void *arg) { + static char out[1024*2]; + static int pos = 0; + fd_set fdr; + int res; + + // make sure that sockfd is ready to read + FD_ZERO(&fdr); + FD_SET(sockfd, &fdr); + res = select(64, &fdr, NULL, NULL, NULL); + if (res == -1) { + perror("select failed"); + finish(EXIT_FAILURE); + } else if (!FD_ISSET(sockfd, &fdr)) { + return; + } + + // perform read write operations ... + int n = get_all_buf(sockfd, out+pos, 1024-pos); + if (n) printf("read! %d\n", n); + pos += n; + if (pos >= EXPECTED_BYTES) { + int i, sum = 0; + for (i=0; i < pos; i++) { + printf("%x\n", out[i]); + sum += out[i]; + } + + shutdown(sockfd, SHUT_RDWR); + close(sockfd); + + printf("sum: %d\n", sum); + finish(sum); + } +} + +int main() { + struct sockaddr_in addr; + int res; + + printf("hello from main page\n"); + +#if !TEST_DGRAM + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); +#else + sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); +#endif + if (sockfd == -1) { + perror("cannot create socket"); + finish(EXIT_FAILURE); + } + fcntl(sockfd, F_SETFL, O_NONBLOCK); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); + } + + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { + perror("connect failed"); + finish(EXIT_FAILURE); + } + +#if EMSCRIPTEN +#if EMBED_SIDE + emscripten_run_script("console.log('adding iframe');" + "var iframe = document.createElement('iframe');" + "iframe.src = 'side.html';" + "document.body.appendChild(iframe);" + "console.log('added.');"); +#endif + emscripten_set_main_loop(iter, 0, 0); +#else + while (1) iter(NULL); +#endif + + return EXIT_SUCCESS; +} diff --git a/tests/sockets/test_sockets_bi_bigdata.c b/tests/sockets/test_sockets_bi_bigdata.c new file mode 100644 index 00000000..c1d8100e --- /dev/null +++ b/tests/sockets/test_sockets_bi_bigdata.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if EMSCRIPTEN +#include +#endif + +#include "test_sockets_bigdata.h" + +#define EXPECTED_BYTES DATA_SIZE + +int sockfd; + +void finish(int result) { + close(sockfd); +#if EMSCRIPTEN + REPORT_RESULT(); +#endif + exit(result); +} + +unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) { + int bytes; + if (ioctl(sock, FIONREAD, &bytes)) return 0; + if (bytes == 0) return 0; + + char buffer[EXPECTED_BYTES]; + int n; + unsigned int offset = 0; + while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) || + errno == EINTR) { + if (n > 0) { + if (((unsigned int) n)+offset > maxsize) { + fprintf(stderr, "too much data!"); + finish(EXIT_FAILURE); + } + memcpy(output+offset, buffer, n); + offset += n; + } + } + + if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { + fprintf(stderr, "error in get_all_buf!"); + finish(EXIT_FAILURE); + } + return offset; +} + +void iter(void *arg) { + static char out[EXPECTED_BYTES]; + static int pos = 0; + fd_set fdr; + int res; + + // make sure that sockfd has finished connecting and is ready to read + FD_ZERO(&fdr); + FD_SET(sockfd, &fdr); + res = select(64, &fdr, NULL, NULL, NULL); + if (res == -1) { + perror("select failed"); + finish(EXIT_FAILURE); + return; + } else if (!FD_ISSET(sockfd, &fdr)) { + return; + } + + // perform read write operations ... + printf("so far %d, expecting up to %d\n", pos, EXPECTED_BYTES-pos); + res = get_all_buf(sockfd, out+pos, EXPECTED_BYTES-pos); + if (res) printf("read! %d\n", res); + pos += res; + if (pos >= EXPECTED_BYTES) { + shutdown(sockfd, SHUT_RDWR); + + close(sockfd); + + char *comp = generateData(); + int result = strcmp(comp, out); + if (result != 0) { + for (int i = 0; i < DATA_SIZE; i++) { + printf("%d:%d\n", comp[i], out[i]); + } + } + finish(result); + } +} + +int main() { + struct sockaddr_in addr; + int res; + + printf("hello from main page\n"); + + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == -1) { + perror("cannot create socket"); + finish(EXIT_FAILURE); + } + fcntl(sockfd, F_SETFL, O_NONBLOCK); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); + } + + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { + perror("connect failed"); + finish(EXIT_FAILURE); + } + +#if EMSCRIPTEN + emscripten_run_script("console.log('adding iframe');" + "var iframe = document.createElement('iframe');" + "iframe.src = 'side.html';" + "iframe.width = '100%';" + "iframe.width = '40%';" + "document.body.appendChild(iframe);" + "console.log('added.');"); + emscripten_set_main_loop(iter, 3, 0); +#else + while (1) iter(NULL); +#endif + + return EXIT_SUCCESS; +} + diff --git a/tests/sockets/test_sockets_bi_side.c b/tests/sockets/test_sockets_bi_side.c new file mode 100644 index 00000000..b8910632 --- /dev/null +++ b/tests/sockets/test_sockets_bi_side.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if EMSCRIPTEN +#include +#endif + +#define EXPECTED_BYTES 5 + +int sockfd = -1; + +void finish(int result) { + close(sockfd); + exit(result); +} + +void loop() { + fd_set fdw; + int res; + + // Make sure that sockfd has actually finished connecting + // and is ready to read. + FD_ZERO(&fdw); + FD_SET(sockfd, &fdw); + res = select(64, NULL, &fdw, NULL, NULL); + if (res == -1) { + perror("select failed"); + finish(EXIT_FAILURE); + } else if (!FD_ISSET(sockfd, &fdw)) { + return; + } + + char data[] = "hello from the other siide\n"; + + printf("send..\n"); +#if TEST_FILE_OPS + res = write(sockfd, data, sizeof(data)); +#else + res = send(sockfd, data, sizeof(data), 0); +#endif + if (res == -1) { + if (errno != EAGAIN) { + perror("send error"); + finish(EXIT_FAILURE); + } + return; + } + + finish(EXIT_SUCCESS); +} + +int main() { + struct sockaddr_in addr; + int res; +#if !TEST_DGRAM + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); +#else + sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); +#endif + if (sockfd == -1) { + perror("cannot create socket"); + finish(EXIT_FAILURE); + } + fcntl(sockfd, F_SETFL, O_NONBLOCK); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); + } + + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { + perror("connect failed"); + finish(EXIT_FAILURE); + } + + emscripten_set_main_loop(loop, 0, 0); + + return EXIT_SUCCESS; +} + diff --git a/tests/sockets/test_sockets_bi_side_bigdata.c b/tests/sockets/test_sockets_bi_side_bigdata.c new file mode 100644 index 00000000..e31029b6 --- /dev/null +++ b/tests/sockets/test_sockets_bi_side_bigdata.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if EMSCRIPTEN +#include +#endif + +#include "test_sockets_bigdata.h" + +#define EXPECTED_BYTES 5 + +int sockfd = -1; +char *data = NULL; + +void finish(int result) { + close(sockfd); + exit(result); +} + +void loop() { + fd_set fdw; + int res; + + // make sure that sockfd has finished connecting and is ready to write + FD_ZERO(&fdw); + FD_SET(sockfd, &fdw); + res = select(64, NULL, &fdw, NULL, NULL); + if (res == -1) { + perror("select failed"); + finish(EXIT_FAILURE); + return; + } else if (!FD_ISSET(sockfd, &fdw)) { + return; + } + + printf("send..\n"); + + res = send(sockfd, data, DATA_SIZE, 0); + if (res == -1) { + if (errno != EAGAIN) { + perror("send error"); + finish(EXIT_FAILURE); + } + return; + } + + finish(EXIT_SUCCESS); +} + +int main() { + struct sockaddr_in addr; + int res; + + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == -1) { + perror("cannot create socket"); + exit(EXIT_FAILURE); + } + fcntl(sockfd, F_SETFL, O_NONBLOCK); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); + } + + printf("connect..\n"); + + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { + perror("connect failed"); + finish(EXIT_FAILURE); + } + + data = generateData(); + + emscripten_set_main_loop(loop, 1, 0); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/tests/sockets/test_sockets_bigdata.h b/tests/sockets/test_sockets_bigdata.h new file mode 100644 index 00000000..17149ad6 --- /dev/null +++ b/tests/sockets/test_sockets_bigdata.h @@ -0,0 +1,20 @@ + +#include + +#define DATA_SIZE (256*256*2) +// 1500 fails + +char *generateData() { + char *ret = malloc(256*256*2); + char *curr = ret; + for (int i = 0; i < 256; i++) { + for (int j = 0; j < 256; j++) { + *curr = i; + curr++; + *curr = j; + curr++; + } + } + return ret; +} + diff --git a/tests/sockets/test_sockets_gethostbyname.c b/tests/sockets/test_sockets_gethostbyname.c new file mode 100644 index 00000000..59c55ba1 --- /dev/null +++ b/tests/sockets/test_sockets_gethostbyname.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if EMSCRIPTEN +#include +#endif + +#define EXPECTED_BYTES 5 + +int sockfd; + +void finish(int result) { + close(sockfd); +#if EMSCRIPTEN + REPORT_RESULT(); +#endif + exit(result); +} + +unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) { + int bytes; + if (ioctl(sock, FIONREAD, &bytes)) return 0; + if (bytes == 0) return 0; + + char buffer[1024]; + int n; + unsigned int offset = 0; + while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) || + errno == EINTR) { + if (n > 0) { + if (((unsigned int) n)+offset > maxsize) { + fprintf(stderr, "too much data!"); + finish(EXIT_FAILURE); + } + memcpy(output+offset, buffer, n); + offset += n; + } + } + + if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { + perror("error in get_all_buf!"); + finish(EXIT_FAILURE); + } + return offset; +} + +void iter() { + static char out[1024*2]; + static int pos = 0; + fd_set fdr; + int res; + + // make sure that sockfd has finished connecting and is ready to read + FD_ZERO(&fdr); + FD_SET(sockfd, &fdr); + res = select(64, &fdr, NULL, NULL, NULL); + if (res == -1) { + perror("select failed"); + finish(EXIT_FAILURE); + } else if (!FD_ISSET(sockfd, &fdr)) { + return; + } + + // perform read write operations ... + int n = get_all_buf(sockfd, out+pos, 1024-pos); + if (n) printf("read! %d\n", n); + pos += n; + if (pos >= EXPECTED_BYTES) { + int i, sum = 0; + for (i=0; i < pos; i++) { + printf("%x\n", out[i]); + sum += out[i]; + } + + shutdown(sockfd, SHUT_RDWR); + + close(sockfd); + + printf("sum: %d\n", sum); + + finish(sum); + } +} + +int main() { + struct sockaddr_in addr; + int res; + + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == -1) { + perror("cannot create socket"); + finish(EXIT_FAILURE); + } + fcntl(sockfd, F_SETFL, O_NONBLOCK); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + struct hostent *host0 = gethostbyname("test.com"); // increment hostname counter to check for possible but at 0,0 not differentiating low/high + struct hostent *host = gethostbyname("localhost"); + char **raw_addr_list = host->h_addr_list; + int *raw_addr = (int*)*raw_addr_list; + printf("raw addr: %d\n", *raw_addr); + char name[INET_ADDRSTRLEN]; + if (!inet_ntop(AF_INET, raw_addr, name, sizeof(name))) { + printf("could not figure out name\n"); + finish(EXIT_FAILURE); + } + printf("localhost has 'ip' of %s\n", name); + + if (inet_pton(AF_INET, name, &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); + } + + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { + perror("connect failed"); + finish(EXIT_FAILURE); + } + +#if EMSCRIPTEN + emscripten_set_main_loop(iter, 0, 0); +#else + while (1) iter(); +#endif + + return EXIT_SUCCESS; +} + diff --git a/tests/sockets/test_sockets_partial.c b/tests/sockets/test_sockets_partial.c new file mode 100644 index 00000000..5fe34721 --- /dev/null +++ b/tests/sockets/test_sockets_partial.c @@ -0,0 +1,119 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if EMSCRIPTEN +#include +#endif + +int sockfd = -1; +int sum = 0; + +void finish(int result) { + close(sockfd); +#if EMSCRIPTEN + REPORT_RESULT(); +#endif + exit(result); +} + +void iter(void *arg) { + char buffer[1024]; + char packetLength; + fd_set fdr; + int i; + int res; + + // make sure that sockfd is ready to read + FD_ZERO(&fdr); + FD_SET(sockfd, &fdr); + res = select(64, &fdr, NULL, NULL, NULL); + if (res == -1) { + perror("select failed"); + finish(EXIT_FAILURE); + } else if (!FD_ISSET(sockfd, &fdr)) { + return; + } + + res = recv(sockfd, buffer, 1, 0); + if (res == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + return; //try again + } + + perror("unexcepted end of data"); + finish(EXIT_FAILURE); + } + + if (res != 1) { + perror("should read 1 byte"); + finish(EXIT_FAILURE); + } + + packetLength = buffer[0]; + res = recv(sockfd, buffer, packetLength, 0); + + printf("got %d,%d\n", res, packetLength); + + if (res != packetLength) { + fprintf(stderr, "lost packet data, expected: %d readed: %d", packetLength, res); + finish(EXIT_FAILURE); + } + + for (i = 0; i < packetLength; ++i) { + if (buffer[i] != i+1) { + fprintf(stderr, "packet corrupted, expected: %d, actual: %d", i+1, buffer[i]); + finish(EXIT_FAILURE); + } + + sum += buffer[i]; + } + + if (packetLength == buffer[0]) { // \x01\x01 - end marker + printf("sum: %d\n", sum); + finish(sum); + } +} + +int main() { + struct sockaddr_in addr; + int res; + + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == -1) { + perror("cannot create socket"); + exit(EXIT_FAILURE); + } + fcntl(sockfd, F_SETFL, O_NONBLOCK); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); + } + + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { + perror("connect failed"); + finish(EXIT_FAILURE); + } + +#if EMSCRIPTEN + emscripten_set_main_loop(iter, 0, 0); +#else + while (!done) iter(NULL); +#endif + + return EXIT_SUCCESS; +} + diff --git a/tests/sockets/test_sockets_select.c b/tests/sockets/test_sockets_select.c new file mode 100644 index 00000000..e05bd4c8 --- /dev/null +++ b/tests/sockets/test_sockets_select.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if EMSCRIPTEN +#include +#endif + +#define EXPECTED_BYTES 5 + +int sockfd = -1; + +void finish(int result) { + close(sockfd); +#if EMSCRIPTEN + REPORT_RESULT(); +#endif + exit(result); +} + +void iter(void *arg) { + static int retries = 0; + + fd_set sett; + FD_ZERO(&sett); + FD_SET(sockfd, &sett); + + // currently, we've connected to a closed server port. + // the initial async connect "succeeded" and select + // should say that the socket is ready for a non-blocking + // read, however, the read should be 0 sized signalling + // that the remote end has closed. + int handles = select(64, &sett, NULL, NULL, NULL); + if (handles == -1) { + perror("select failed"); + finish(EXIT_FAILURE); + } + + if (FD_ISSET(sockfd, &sett)) { + char buffer[1024]; + int n = recv(sockfd, buffer, sizeof(buffer), 0); + if (n == -1 && retries++ > 10) { + perror("revv failed"); + finish(EXIT_FAILURE); + } else if (!n) { + perror("Connection to websocket server failed as expected."); + finish(266); + } + } +} + +// This is for testing a websocket connection to a closed server port. +// The connect call will succeed (due to the asynchronous websocket +// behavior) but once the underlying websocket system realized that +// the connection cannot be established, the next select call will fail. +int main() { + struct sockaddr_in addr; + int res; + + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == -1) { + perror("cannot create socket"); + finish(EXIT_FAILURE); + } + fcntl(sockfd, F_SETFL, O_NONBLOCK); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); + } + + // This call should succeed (even if the server port is closed) + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { + perror("connect failed"); + finish(EXIT_FAILURE); + } + +#if EMSCRIPTEN + emscripten_set_main_loop(iter, 0, 0); +#else + while (1) iter(NULL); +#endif + + return EXIT_FAILURE; +} + diff --git a/tests/sockets/test_sockets_select_server_closes_connection.c b/tests/sockets/test_sockets_select_server_closes_connection.c new file mode 100644 index 00000000..4181b12b --- /dev/null +++ b/tests/sockets/test_sockets_select_server_closes_connection.c @@ -0,0 +1,112 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if EMSCRIPTEN +#include +#endif + +#define EXPECTED_BYTES 5 + +int sockfd = -1; + +void finish(int result) { + close(sockfd); +#if EMSCRIPTEN + REPORT_RESULT(); +#endif + exit(result); +} + +void iter(void *arg) { + static char readbuf[1024]; + static int readPos = 0; + + fd_set sett; + FD_ZERO(&sett); + FD_SET(sockfd, &sett); + + int res = select(64, &sett, NULL, NULL, NULL); + + if (res == -1) { + perror("select failed"); + finish(EXIT_FAILURE); + } else if (res == 0) { + return; + } else if (res > 0) { + assert(FD_ISSET(sockfd, &sett)); + + int bytesRead = recv(sockfd, readbuf+readPos, 7-readPos, 0); + if (bytesRead == -1) { + if (errno != EAGAIN) { + perror("recv error"); + finish(EXIT_FAILURE); + } + // try again + return; + } + + if (readPos < 7) { + readPos += bytesRead; + } else { + if (!bytesRead) { + perror("Connection to websocket server was closed as expected"); + finish(266); + } else { + perror("Connection to websocket server was not closed"); + finish(EXIT_FAILURE); + } + } + } + + return; +} + +// Scenario: the server sends data and closes the connection after 7 bytes. +// This test should provoke the situation in which the underlying +// tcp connection has been torn down already but there is still data +// in the queue. The select call has to succeed as long the queue +// still contains data and only then start to throw errors. +int main() { + struct sockaddr_in addr; + int res; + + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == -1) { + perror("cannot create socket"); + finish(EXIT_FAILURE); + } + fcntl(sockfd, F_SETFL, O_NONBLOCK); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); + } + + // This call should succeed (even if the server port is closed) + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { + perror("connect failed"); + finish(EXIT_FAILURE); + } + +#if EMSCRIPTEN + emscripten_set_main_loop(iter, 0, 0); +#else + while (1) iter(NULL); +#endif + + return EXIT_FAILURE; +} + diff --git a/tests/sockets/test_sockets_select_server_closes_connection_rw.c b/tests/sockets/test_sockets_select_server_closes_connection_rw.c new file mode 100644 index 00000000..f7e19aca --- /dev/null +++ b/tests/sockets/test_sockets_select_server_closes_connection_rw.c @@ -0,0 +1,209 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if EMSCRIPTEN +#include +#endif + +#define EXPECTED_BYTES 5 + +int sockfd = -1; + +void finish(int result) { + close(sockfd); +#if EMSCRIPTEN + REPORT_RESULT(); +#endif + exit(result); +} + +void iter(void *arg) { + static int state = 0; + static char writebuf[] = "01234567890123456789"; + static int writePos = 0; + static char readbuf[1024]; + static int readPos = 0; + int selectRes; + ssize_t transferAmount; + fd_set sett; + + switch (state) { + case 0: + // writing 10 bytes to the server + + // since the socket in the read file descriptors has no available data, + // select should tell us 0 handles are ready + FD_ZERO(&sett); + FD_SET(sockfd, &sett); + selectRes = select(64, &sett, NULL, NULL, NULL); + if (selectRes != 0) { + printf("case 0: read select != 0 (%d)\n", selectRes); + finish(EXIT_FAILURE); + } + + // the socket in the write file descriptors has to result in either a 0 or 1 + // the connection either is setting up or is established and writing is possible + FD_ZERO(&sett); + FD_SET(sockfd, &sett); + selectRes = select(64, NULL, &sett, NULL, NULL); + if (selectRes == -1) { + printf("case 0: write select == -1\n"); + finish(EXIT_FAILURE); + } else if (selectRes == 0) { + return; + } + + // send a single byte + transferAmount = send(sockfd, writebuf+writePos, 1, 0); + writePos += transferAmount; + + // after 10 bytes switch to next state + if (writePos >= 10) { + state = 1; + } + break; + + case 1: + // wait until we can read one byte to make sure the server + // has sent the data and then closed the connection + FD_ZERO(&sett); + FD_SET(sockfd, &sett); + selectRes = select(64, &sett, NULL, NULL, NULL); + if (selectRes == -1) { + printf("case 1: read selectRes == -1\n"); + finish(EXIT_FAILURE); + } else if (selectRes == 0) { + return; + } + + // read a single byte + transferAmount = recv(sockfd, readbuf+readPos, 1, 0); + readPos += transferAmount; + + // if successfully reading 1 byte, switch to next state + if (readPos >= 1) { + state = 2; + } + break; + + case 2: + // calling select with the socket in the write file descriptors should + // succeed, but the socket should not set in the set. + FD_ZERO(&sett); + FD_SET(sockfd, &sett); + selectRes = select(64, NULL, &sett, NULL, NULL); + if (selectRes != 0 || FD_ISSET(sockfd, &sett)) { + printf("case 2: write selectRes != 0 || FD_ISSET(sockfd, &sett)\n"); + finish(EXIT_FAILURE); + } + + // calling select with the socket in the read file descriptors + // has to succeed because there is still data in the inQueue + FD_ZERO(&sett); + FD_SET(sockfd, &sett); + selectRes = select(64, &sett, NULL, NULL, NULL); + if (selectRes != 1) { + printf("case 2: read selectRes != 1\n"); + finish(EXIT_FAILURE); + } else if (selectRes == 0) { + return; + } + + // read a single byte + transferAmount = recv(sockfd, readbuf+readPos, 1, 0); + readPos += transferAmount; + + // with 10 bytes read the inQueue is empty => switch state + if (readPos >= 10) { + state = 3; + } + break; + + case 3: + // calling select with the socket in the read file descriptors + // should succeed + FD_ZERO(&sett); + FD_SET(sockfd, &sett); + selectRes = select(64, &sett, NULL, NULL, NULL); + if (selectRes != 1) { + printf("case 3: read selectRes != 1\n"); + finish(EXIT_FAILURE); + } + + // but recv should return 0 signaling the remote + // end has closed the connection. + transferAmount = recv(sockfd, readbuf, 1, 0); + if (transferAmount) { + printf("case 3: read != 0\n"); + finish(EXIT_FAILURE); + } + + // report back success, the 266 is just an arbitrary value without + // deeper meaning + finish(266); + break; + + default: + printf("Impossible state!\n"); + finish(EXIT_FAILURE); + break; + } + + return; +} + +// This test checks for an intended asymmetry in the behavior of the select function. +// Scenario: the client sends data to the server. After 10 received bytes the +// server sends 10 bytes on its own and immediately afterwards closes the connection. +// This mimics a typical connect-request-response-disconnect situation. +// After the server closed the connection select calls with the socket in the write file +// descriptors have to fail as the tcp connection is already down and there is no way +// anymore to send data. +// Select calls with the socket in the read file descriptor list still have to succeed +// as there are still 10 bytes to read from the inQueue. So, for the same socket the +// select call behaves differently depending on whether the socket is listed in the +// read or write file descriptors. +int main() { + struct sockaddr_in addr; + int res; + + sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd == -1) { + perror("cannot create socket"); + finish(EXIT_FAILURE); + } + fcntl(sockfd, F_SETFL, O_NONBLOCK); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(SOCKK); + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { + perror("inet_pton failed"); + finish(EXIT_FAILURE); + } + + // This call should succeed (even if the server port is closed) + res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + if (res == -1 && errno != EINPROGRESS) { + perror("connect failed"); + finish(EXIT_FAILURE); + } + +#if EMSCRIPTEN + emscripten_set_main_loop(iter, 0, 0); +#else + while (1) iter(NULL); +#endif + + return EXIT_SUCCESS; +} + diff --git a/tests/websockets.c b/tests/websockets.c deleted file mode 100644 index 8845ef43..00000000 --- a/tests/websockets.c +++ /dev/null @@ -1,143 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if EMSCRIPTEN -#include -#endif - -#define EXPECTED_BYTES 5 - -int sockfd; -int not_always_data = 0; - -void finish(int result) { - close(sockfd); -#if EMSCRIPTEN - REPORT_RESULT(); -#endif - exit(result); -} - -unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) { - // select check for IO - fd_set sett; - FD_ZERO(&sett); - assert(select(64, &sett, NULL, NULL, NULL) == 0); // empty set - FD_SET(sock, &sett); - assert(select(0, &sett, NULL, NULL, NULL) == 0); // max FD to check is 0 - assert(FD_ISSET(sock, &sett) == 0); - FD_SET(sock, &sett); - int select_says_yes = select(64, &sett, NULL, NULL, NULL); - - // ioctl check for IO - int bytes; - if (ioctl(sock, FIONREAD, &bytes) || bytes == 0) { - not_always_data = 1; - printf("ioctl says 0, FD_ISSET says %ld\n", FD_ISSET(sock, &sett)); - assert(FD_ISSET(sock, &sett) == 0); - return 0; - } - - assert(FD_ISSET(sock, &sett)); - assert(select_says_yes); // ioctl must agree with select - - char buffer[1024]; - int n; - unsigned int offset = 0; - while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) || - errno == EINTR) { - if(n > 0) { - if (((unsigned int) n)+offset > maxsize) { - fprintf(stderr, "too much data!"); - finish(EXIT_FAILURE); - } - memcpy(output+offset, buffer, n); - offset += n; - } - } - - if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { - fprintf(stderr, "error in get_all_buf! %d", errno); - finish(EXIT_FAILURE); - } - return offset; -} - -void iter(void *arg) { - static char out[1024*2]; - static int pos = 0; - fd_set fdr; - int res; - - // make sure that sockfd is ready to read - FD_ZERO(&fdr); - FD_SET(sockfd, &fdr); - res = select(64, &fdr, NULL, NULL, NULL); - if (res == -1) { - perror("select failed"); - finish(EXIT_FAILURE); - } else if (!FD_ISSET(sockfd, &fdr)) { - return; - } - - // perform read write operations ... - int n = get_all_buf(sockfd, out+pos, 1024-pos); - if (n) printf("read! %d\n", n); - pos += n; - if (pos >= EXPECTED_BYTES) { - int i, sum = 0; - for (i=0; i < pos; i++) { - printf("%x\n", out[i]); - sum += out[i]; - } - - shutdown(sockfd, SHUT_RDWR); - - close(sockfd); - - printf("sum: %d\n", sum); - finish(sum); - } -} - -void main() { - struct sockaddr_in addr; - int res; - - sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (sockfd == -1) { - perror("cannot create socket"); - finish(EXIT_FAILURE); - } - fcntl(sockfd, F_SETFL, O_NONBLOCK); - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(SOCKK); - if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { - perror("inet_pton failed"); - finish(EXIT_FAILURE); - } - - res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); - if (res == -1 && errno != EINPROGRESS) { - perror("connect failed"); - finish(EXIT_FAILURE); - } - -#if EMSCRIPTEN - emscripten_set_main_loop(iter, 0, 0); -#else - while (1) iter(NULL); -#endif -} - diff --git a/tests/websockets_bi.c b/tests/websockets_bi.c deleted file mode 100644 index e19f7fe8..00000000 --- a/tests/websockets_bi.c +++ /dev/null @@ -1,140 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if EMSCRIPTEN -#include -#endif - -#define EXPECTED_BYTES 28 - -int sockfd; - -void finish(int result) { - close(sockfd); -#if EMSCRIPTEN - REPORT_RESULT(); -#endif - exit(result); -} - -unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) { - int bytes; - if (ioctl(sock, FIONREAD, &bytes)) return 0; - if (bytes == 0) return 0; - - char buffer[1024]; - int n; - unsigned int offset = 0; -#if TEST_FILE_OPS - while((errno = 0, (n = read(sock, buffer, sizeof(buffer)))>0) || -#else - while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) || -#endif - errno == EINTR) { - if(n > 0) { - if (((unsigned int) n)+offset > maxsize) { - fprintf(stderr, "too much data!"); - finish(EXIT_FAILURE); - } - memcpy(output+offset, buffer, n); - offset += n; - } - } - - if(n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { - fprintf(stderr, "error in get_all_buf!"); - finish(EXIT_FAILURE); - } - return offset; -} - -void iter(void *arg) { - static char out[1024*2]; - static int pos = 0; - fd_set fdr; - int res; - - // make sure that sockfd is ready to read - FD_ZERO(&fdr); - FD_SET(sockfd, &fdr); - res = select(64, &fdr, NULL, NULL, NULL); - if (res == -1) { - perror("select failed"); - finish(EXIT_FAILURE); - } else if (!FD_ISSET(sockfd, &fdr)) { - return; - } - - // perform read write operations ... - int n = get_all_buf(sockfd, out+pos, 1024-pos); - if (n) printf("read! %d\n", n); - pos += n; - if (pos >= EXPECTED_BYTES) { - int i, sum = 0; - for (i=0; i < pos; i++) { - printf("%x\n", out[i]); - sum += out[i]; - } - - shutdown(sockfd, SHUT_RDWR); - close(sockfd); - - printf("sum: %d\n", sum); - finish(sum); - } -} - -int main() { - struct sockaddr_in addr; - int res; - - printf("hello from main page\n"); - -#if !TEST_DGRAM - sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); -#else - sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); -#endif - if (sockfd == -1) { - perror("cannot create socket"); - finish(EXIT_FAILURE); - } - fcntl(sockfd, F_SETFL, O_NONBLOCK); - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(SOCKK); - if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { - perror("inet_pton failed"); - finish(EXIT_FAILURE); - } - - res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); - if (res == -1 && errno != EINPROGRESS) { - perror("connect failed"); - finish(EXIT_FAILURE); - } - -#if EMSCRIPTEN -#if EMBED_SIDE - emscripten_run_script("console.log('adding iframe');" - "var iframe = document.createElement('iframe');" - "iframe.src = 'side.html';" - "document.body.appendChild(iframe);" - "console.log('added.');"); -#endif - emscripten_set_main_loop(iter, 0, 0); -#else - while (1) iter(NULL); -#endif - - return EXIT_SUCCESS; -} diff --git a/tests/websockets_bi_bigdata.c b/tests/websockets_bi_bigdata.c deleted file mode 100644 index e3509649..00000000 --- a/tests/websockets_bi_bigdata.c +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if EMSCRIPTEN -#include -#endif - -#include "websockets_bigdata.h" - -#define EXPECTED_BYTES DATA_SIZE - -int sockfd; - -void finish(int result) { - close(sockfd); -#if EMSCRIPTEN - REPORT_RESULT(); -#endif - exit(result); -} - -unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) { - int bytes; - if (ioctl(sock, FIONREAD, &bytes)) return 0; - if (bytes == 0) return 0; - - char buffer[EXPECTED_BYTES]; - int n; - unsigned int offset = 0; - while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) || - errno == EINTR) { - if (n > 0) { - if (((unsigned int) n)+offset > maxsize) { - fprintf(stderr, "too much data!"); - finish(EXIT_FAILURE); - } - memcpy(output+offset, buffer, n); - offset += n; - } - } - - if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { - fprintf(stderr, "error in get_all_buf!"); - finish(EXIT_FAILURE); - } - return offset; -} - -void iter(void *arg) { - static char out[EXPECTED_BYTES]; - static int pos = 0; - fd_set fdr; - int res; - - // make sure that sockfd has finished connecting and is ready to read - FD_ZERO(&fdr); - FD_SET(sockfd, &fdr); - res = select(64, &fdr, NULL, NULL, NULL); - if (res == -1) { - perror("select failed"); - finish(EXIT_FAILURE); - return; - } else if (!FD_ISSET(sockfd, &fdr)) { - return; - } - - // perform read write operations ... - printf("so far %d, expecting up to %d\n", pos, EXPECTED_BYTES-pos); - res = get_all_buf(sockfd, out+pos, EXPECTED_BYTES-pos); - if (res) printf("read! %d\n", res); - pos += res; - if (pos >= EXPECTED_BYTES) { - shutdown(sockfd, SHUT_RDWR); - - close(sockfd); - - char *comp = generateData(); - int result = strcmp(comp, out); - if (result != 0) { - for (int i = 0; i < DATA_SIZE; i++) { - printf("%d:%d\n", comp[i], out[i]); - } - } - finish(result); - } -} - -int main() { - struct sockaddr_in addr; - int res; - - printf("hello from main page\n"); - - sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (sockfd == -1) { - perror("cannot create socket"); - finish(EXIT_FAILURE); - } - fcntl(sockfd, F_SETFL, O_NONBLOCK); - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(SOCKK); - if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { - perror("inet_pton failed"); - finish(EXIT_FAILURE); - } - - res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); - if (res == -1 && errno != EINPROGRESS) { - perror("connect failed"); - finish(EXIT_FAILURE); - } - -#if EMSCRIPTEN - emscripten_run_script("console.log('adding iframe');" - "var iframe = document.createElement('iframe');" - "iframe.src = 'side.html';" - "iframe.width = '100%';" - "iframe.width = '40%';" - "document.body.appendChild(iframe);" - "console.log('added.');"); - emscripten_set_main_loop(iter, 3, 0); -#else - while (1) iter(NULL); -#endif - - return EXIT_SUCCESS; -} - diff --git a/tests/websockets_bi_side.c b/tests/websockets_bi_side.c deleted file mode 100644 index b8910632..00000000 --- a/tests/websockets_bi_side.c +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if EMSCRIPTEN -#include -#endif - -#define EXPECTED_BYTES 5 - -int sockfd = -1; - -void finish(int result) { - close(sockfd); - exit(result); -} - -void loop() { - fd_set fdw; - int res; - - // Make sure that sockfd has actually finished connecting - // and is ready to read. - FD_ZERO(&fdw); - FD_SET(sockfd, &fdw); - res = select(64, NULL, &fdw, NULL, NULL); - if (res == -1) { - perror("select failed"); - finish(EXIT_FAILURE); - } else if (!FD_ISSET(sockfd, &fdw)) { - return; - } - - char data[] = "hello from the other siide\n"; - - printf("send..\n"); -#if TEST_FILE_OPS - res = write(sockfd, data, sizeof(data)); -#else - res = send(sockfd, data, sizeof(data), 0); -#endif - if (res == -1) { - if (errno != EAGAIN) { - perror("send error"); - finish(EXIT_FAILURE); - } - return; - } - - finish(EXIT_SUCCESS); -} - -int main() { - struct sockaddr_in addr; - int res; -#if !TEST_DGRAM - sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); -#else - sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); -#endif - if (sockfd == -1) { - perror("cannot create socket"); - finish(EXIT_FAILURE); - } - fcntl(sockfd, F_SETFL, O_NONBLOCK); - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(SOCKK); - if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { - perror("inet_pton failed"); - finish(EXIT_FAILURE); - } - - res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); - if (res == -1 && errno != EINPROGRESS) { - perror("connect failed"); - finish(EXIT_FAILURE); - } - - emscripten_set_main_loop(loop, 0, 0); - - return EXIT_SUCCESS; -} - diff --git a/tests/websockets_bi_side_bigdata.c b/tests/websockets_bi_side_bigdata.c deleted file mode 100644 index d131e6e0..00000000 --- a/tests/websockets_bi_side_bigdata.c +++ /dev/null @@ -1,90 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if EMSCRIPTEN -#include -#endif - -#include "websockets_bigdata.h" - -#define EXPECTED_BYTES 5 - -int sockfd = -1; -char *data = NULL; - -void finish(int result) { - close(sockfd); - exit(result); -} - -void loop() { - fd_set fdw; - int res; - - // make sure that sockfd has finished connecting and is ready to write - FD_ZERO(&fdw); - FD_SET(sockfd, &fdw); - res = select(64, NULL, &fdw, NULL, NULL); - if (res == -1) { - perror("select failed"); - finish(EXIT_FAILURE); - return; - } else if (!FD_ISSET(sockfd, &fdw)) { - return; - } - - printf("send..\n"); - - res = send(sockfd, data, DATA_SIZE, 0); - if (res == -1) { - if (errno != EAGAIN) { - perror("send error"); - finish(EXIT_FAILURE); - } - return; - } - - finish(EXIT_SUCCESS); -} - -int main() { - struct sockaddr_in addr; - int res; - - sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (sockfd == -1) { - perror("cannot create socket"); - exit(EXIT_FAILURE); - } - fcntl(sockfd, F_SETFL, O_NONBLOCK); - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(SOCKK); - if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { - perror("inet_pton failed"); - finish(EXIT_FAILURE); - } - - printf("connect..\n"); - - res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); - if (res == -1 && errno != EINPROGRESS) { - perror("connect failed"); - finish(EXIT_FAILURE); - } - - data = generateData(); - - emscripten_set_main_loop(loop, 1, 0); - - return EXIT_SUCCESS; -} \ No newline at end of file diff --git a/tests/websockets_bigdata.h b/tests/websockets_bigdata.h deleted file mode 100644 index 17149ad6..00000000 --- a/tests/websockets_bigdata.h +++ /dev/null @@ -1,20 +0,0 @@ - -#include - -#define DATA_SIZE (256*256*2) -// 1500 fails - -char *generateData() { - char *ret = malloc(256*256*2); - char *curr = ret; - for (int i = 0; i < 256; i++) { - for (int j = 0; j < 256; j++) { - *curr = i; - curr++; - *curr = j; - curr++; - } - } - return ret; -} - diff --git a/tests/websockets_gethostbyname.c b/tests/websockets_gethostbyname.c deleted file mode 100644 index 59c55ba1..00000000 --- a/tests/websockets_gethostbyname.c +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if EMSCRIPTEN -#include -#endif - -#define EXPECTED_BYTES 5 - -int sockfd; - -void finish(int result) { - close(sockfd); -#if EMSCRIPTEN - REPORT_RESULT(); -#endif - exit(result); -} - -unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) { - int bytes; - if (ioctl(sock, FIONREAD, &bytes)) return 0; - if (bytes == 0) return 0; - - char buffer[1024]; - int n; - unsigned int offset = 0; - while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) || - errno == EINTR) { - if (n > 0) { - if (((unsigned int) n)+offset > maxsize) { - fprintf(stderr, "too much data!"); - finish(EXIT_FAILURE); - } - memcpy(output+offset, buffer, n); - offset += n; - } - } - - if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { - perror("error in get_all_buf!"); - finish(EXIT_FAILURE); - } - return offset; -} - -void iter() { - static char out[1024*2]; - static int pos = 0; - fd_set fdr; - int res; - - // make sure that sockfd has finished connecting and is ready to read - FD_ZERO(&fdr); - FD_SET(sockfd, &fdr); - res = select(64, &fdr, NULL, NULL, NULL); - if (res == -1) { - perror("select failed"); - finish(EXIT_FAILURE); - } else if (!FD_ISSET(sockfd, &fdr)) { - return; - } - - // perform read write operations ... - int n = get_all_buf(sockfd, out+pos, 1024-pos); - if (n) printf("read! %d\n", n); - pos += n; - if (pos >= EXPECTED_BYTES) { - int i, sum = 0; - for (i=0; i < pos; i++) { - printf("%x\n", out[i]); - sum += out[i]; - } - - shutdown(sockfd, SHUT_RDWR); - - close(sockfd); - - printf("sum: %d\n", sum); - - finish(sum); - } -} - -int main() { - struct sockaddr_in addr; - int res; - - sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (sockfd == -1) { - perror("cannot create socket"); - finish(EXIT_FAILURE); - } - fcntl(sockfd, F_SETFL, O_NONBLOCK); - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(SOCKK); - struct hostent *host0 = gethostbyname("test.com"); // increment hostname counter to check for possible but at 0,0 not differentiating low/high - struct hostent *host = gethostbyname("localhost"); - char **raw_addr_list = host->h_addr_list; - int *raw_addr = (int*)*raw_addr_list; - printf("raw addr: %d\n", *raw_addr); - char name[INET_ADDRSTRLEN]; - if (!inet_ntop(AF_INET, raw_addr, name, sizeof(name))) { - printf("could not figure out name\n"); - finish(EXIT_FAILURE); - } - printf("localhost has 'ip' of %s\n", name); - - if (inet_pton(AF_INET, name, &addr.sin_addr) != 1) { - perror("inet_pton failed"); - finish(EXIT_FAILURE); - } - - res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); - if (res == -1 && errno != EINPROGRESS) { - perror("connect failed"); - finish(EXIT_FAILURE); - } - -#if EMSCRIPTEN - emscripten_set_main_loop(iter, 0, 0); -#else - while (1) iter(); -#endif - - return EXIT_SUCCESS; -} - diff --git a/tests/websockets_partial.c b/tests/websockets_partial.c deleted file mode 100644 index 5fe34721..00000000 --- a/tests/websockets_partial.c +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if EMSCRIPTEN -#include -#endif - -int sockfd = -1; -int sum = 0; - -void finish(int result) { - close(sockfd); -#if EMSCRIPTEN - REPORT_RESULT(); -#endif - exit(result); -} - -void iter(void *arg) { - char buffer[1024]; - char packetLength; - fd_set fdr; - int i; - int res; - - // make sure that sockfd is ready to read - FD_ZERO(&fdr); - FD_SET(sockfd, &fdr); - res = select(64, &fdr, NULL, NULL, NULL); - if (res == -1) { - perror("select failed"); - finish(EXIT_FAILURE); - } else if (!FD_ISSET(sockfd, &fdr)) { - return; - } - - res = recv(sockfd, buffer, 1, 0); - if (res == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - return; //try again - } - - perror("unexcepted end of data"); - finish(EXIT_FAILURE); - } - - if (res != 1) { - perror("should read 1 byte"); - finish(EXIT_FAILURE); - } - - packetLength = buffer[0]; - res = recv(sockfd, buffer, packetLength, 0); - - printf("got %d,%d\n", res, packetLength); - - if (res != packetLength) { - fprintf(stderr, "lost packet data, expected: %d readed: %d", packetLength, res); - finish(EXIT_FAILURE); - } - - for (i = 0; i < packetLength; ++i) { - if (buffer[i] != i+1) { - fprintf(stderr, "packet corrupted, expected: %d, actual: %d", i+1, buffer[i]); - finish(EXIT_FAILURE); - } - - sum += buffer[i]; - } - - if (packetLength == buffer[0]) { // \x01\x01 - end marker - printf("sum: %d\n", sum); - finish(sum); - } -} - -int main() { - struct sockaddr_in addr; - int res; - - sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (sockfd == -1) { - perror("cannot create socket"); - exit(EXIT_FAILURE); - } - fcntl(sockfd, F_SETFL, O_NONBLOCK); - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(SOCKK); - if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { - perror("inet_pton failed"); - finish(EXIT_FAILURE); - } - - res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); - if (res == -1 && errno != EINPROGRESS) { - perror("connect failed"); - finish(EXIT_FAILURE); - } - -#if EMSCRIPTEN - emscripten_set_main_loop(iter, 0, 0); -#else - while (!done) iter(NULL); -#endif - - return EXIT_SUCCESS; -} - diff --git a/tests/websockets_select.c b/tests/websockets_select.c deleted file mode 100644 index e05bd4c8..00000000 --- a/tests/websockets_select.c +++ /dev/null @@ -1,98 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if EMSCRIPTEN -#include -#endif - -#define EXPECTED_BYTES 5 - -int sockfd = -1; - -void finish(int result) { - close(sockfd); -#if EMSCRIPTEN - REPORT_RESULT(); -#endif - exit(result); -} - -void iter(void *arg) { - static int retries = 0; - - fd_set sett; - FD_ZERO(&sett); - FD_SET(sockfd, &sett); - - // currently, we've connected to a closed server port. - // the initial async connect "succeeded" and select - // should say that the socket is ready for a non-blocking - // read, however, the read should be 0 sized signalling - // that the remote end has closed. - int handles = select(64, &sett, NULL, NULL, NULL); - if (handles == -1) { - perror("select failed"); - finish(EXIT_FAILURE); - } - - if (FD_ISSET(sockfd, &sett)) { - char buffer[1024]; - int n = recv(sockfd, buffer, sizeof(buffer), 0); - if (n == -1 && retries++ > 10) { - perror("revv failed"); - finish(EXIT_FAILURE); - } else if (!n) { - perror("Connection to websocket server failed as expected."); - finish(266); - } - } -} - -// This is for testing a websocket connection to a closed server port. -// The connect call will succeed (due to the asynchronous websocket -// behavior) but once the underlying websocket system realized that -// the connection cannot be established, the next select call will fail. -int main() { - struct sockaddr_in addr; - int res; - - sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (sockfd == -1) { - perror("cannot create socket"); - finish(EXIT_FAILURE); - } - fcntl(sockfd, F_SETFL, O_NONBLOCK); - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(SOCKK); - if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { - perror("inet_pton failed"); - finish(EXIT_FAILURE); - } - - // This call should succeed (even if the server port is closed) - res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); - if (res == -1 && errno != EINPROGRESS) { - perror("connect failed"); - finish(EXIT_FAILURE); - } - -#if EMSCRIPTEN - emscripten_set_main_loop(iter, 0, 0); -#else - while (1) iter(NULL); -#endif - - return EXIT_FAILURE; -} - diff --git a/tests/websockets_select_server_closes_connection.c b/tests/websockets_select_server_closes_connection.c deleted file mode 100644 index 4181b12b..00000000 --- a/tests/websockets_select_server_closes_connection.c +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if EMSCRIPTEN -#include -#endif - -#define EXPECTED_BYTES 5 - -int sockfd = -1; - -void finish(int result) { - close(sockfd); -#if EMSCRIPTEN - REPORT_RESULT(); -#endif - exit(result); -} - -void iter(void *arg) { - static char readbuf[1024]; - static int readPos = 0; - - fd_set sett; - FD_ZERO(&sett); - FD_SET(sockfd, &sett); - - int res = select(64, &sett, NULL, NULL, NULL); - - if (res == -1) { - perror("select failed"); - finish(EXIT_FAILURE); - } else if (res == 0) { - return; - } else if (res > 0) { - assert(FD_ISSET(sockfd, &sett)); - - int bytesRead = recv(sockfd, readbuf+readPos, 7-readPos, 0); - if (bytesRead == -1) { - if (errno != EAGAIN) { - perror("recv error"); - finish(EXIT_FAILURE); - } - // try again - return; - } - - if (readPos < 7) { - readPos += bytesRead; - } else { - if (!bytesRead) { - perror("Connection to websocket server was closed as expected"); - finish(266); - } else { - perror("Connection to websocket server was not closed"); - finish(EXIT_FAILURE); - } - } - } - - return; -} - -// Scenario: the server sends data and closes the connection after 7 bytes. -// This test should provoke the situation in which the underlying -// tcp connection has been torn down already but there is still data -// in the queue. The select call has to succeed as long the queue -// still contains data and only then start to throw errors. -int main() { - struct sockaddr_in addr; - int res; - - sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (sockfd == -1) { - perror("cannot create socket"); - finish(EXIT_FAILURE); - } - fcntl(sockfd, F_SETFL, O_NONBLOCK); - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(SOCKK); - if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { - perror("inet_pton failed"); - finish(EXIT_FAILURE); - } - - // This call should succeed (even if the server port is closed) - res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); - if (res == -1 && errno != EINPROGRESS) { - perror("connect failed"); - finish(EXIT_FAILURE); - } - -#if EMSCRIPTEN - emscripten_set_main_loop(iter, 0, 0); -#else - while (1) iter(NULL); -#endif - - return EXIT_FAILURE; -} - diff --git a/tests/websockets_select_server_closes_connection_rw.c b/tests/websockets_select_server_closes_connection_rw.c deleted file mode 100644 index f7e19aca..00000000 --- a/tests/websockets_select_server_closes_connection_rw.c +++ /dev/null @@ -1,209 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if EMSCRIPTEN -#include -#endif - -#define EXPECTED_BYTES 5 - -int sockfd = -1; - -void finish(int result) { - close(sockfd); -#if EMSCRIPTEN - REPORT_RESULT(); -#endif - exit(result); -} - -void iter(void *arg) { - static int state = 0; - static char writebuf[] = "01234567890123456789"; - static int writePos = 0; - static char readbuf[1024]; - static int readPos = 0; - int selectRes; - ssize_t transferAmount; - fd_set sett; - - switch (state) { - case 0: - // writing 10 bytes to the server - - // since the socket in the read file descriptors has no available data, - // select should tell us 0 handles are ready - FD_ZERO(&sett); - FD_SET(sockfd, &sett); - selectRes = select(64, &sett, NULL, NULL, NULL); - if (selectRes != 0) { - printf("case 0: read select != 0 (%d)\n", selectRes); - finish(EXIT_FAILURE); - } - - // the socket in the write file descriptors has to result in either a 0 or 1 - // the connection either is setting up or is established and writing is possible - FD_ZERO(&sett); - FD_SET(sockfd, &sett); - selectRes = select(64, NULL, &sett, NULL, NULL); - if (selectRes == -1) { - printf("case 0: write select == -1\n"); - finish(EXIT_FAILURE); - } else if (selectRes == 0) { - return; - } - - // send a single byte - transferAmount = send(sockfd, writebuf+writePos, 1, 0); - writePos += transferAmount; - - // after 10 bytes switch to next state - if (writePos >= 10) { - state = 1; - } - break; - - case 1: - // wait until we can read one byte to make sure the server - // has sent the data and then closed the connection - FD_ZERO(&sett); - FD_SET(sockfd, &sett); - selectRes = select(64, &sett, NULL, NULL, NULL); - if (selectRes == -1) { - printf("case 1: read selectRes == -1\n"); - finish(EXIT_FAILURE); - } else if (selectRes == 0) { - return; - } - - // read a single byte - transferAmount = recv(sockfd, readbuf+readPos, 1, 0); - readPos += transferAmount; - - // if successfully reading 1 byte, switch to next state - if (readPos >= 1) { - state = 2; - } - break; - - case 2: - // calling select with the socket in the write file descriptors should - // succeed, but the socket should not set in the set. - FD_ZERO(&sett); - FD_SET(sockfd, &sett); - selectRes = select(64, NULL, &sett, NULL, NULL); - if (selectRes != 0 || FD_ISSET(sockfd, &sett)) { - printf("case 2: write selectRes != 0 || FD_ISSET(sockfd, &sett)\n"); - finish(EXIT_FAILURE); - } - - // calling select with the socket in the read file descriptors - // has to succeed because there is still data in the inQueue - FD_ZERO(&sett); - FD_SET(sockfd, &sett); - selectRes = select(64, &sett, NULL, NULL, NULL); - if (selectRes != 1) { - printf("case 2: read selectRes != 1\n"); - finish(EXIT_FAILURE); - } else if (selectRes == 0) { - return; - } - - // read a single byte - transferAmount = recv(sockfd, readbuf+readPos, 1, 0); - readPos += transferAmount; - - // with 10 bytes read the inQueue is empty => switch state - if (readPos >= 10) { - state = 3; - } - break; - - case 3: - // calling select with the socket in the read file descriptors - // should succeed - FD_ZERO(&sett); - FD_SET(sockfd, &sett); - selectRes = select(64, &sett, NULL, NULL, NULL); - if (selectRes != 1) { - printf("case 3: read selectRes != 1\n"); - finish(EXIT_FAILURE); - } - - // but recv should return 0 signaling the remote - // end has closed the connection. - transferAmount = recv(sockfd, readbuf, 1, 0); - if (transferAmount) { - printf("case 3: read != 0\n"); - finish(EXIT_FAILURE); - } - - // report back success, the 266 is just an arbitrary value without - // deeper meaning - finish(266); - break; - - default: - printf("Impossible state!\n"); - finish(EXIT_FAILURE); - break; - } - - return; -} - -// This test checks for an intended asymmetry in the behavior of the select function. -// Scenario: the client sends data to the server. After 10 received bytes the -// server sends 10 bytes on its own and immediately afterwards closes the connection. -// This mimics a typical connect-request-response-disconnect situation. -// After the server closed the connection select calls with the socket in the write file -// descriptors have to fail as the tcp connection is already down and there is no way -// anymore to send data. -// Select calls with the socket in the read file descriptor list still have to succeed -// as there are still 10 bytes to read from the inQueue. So, for the same socket the -// select call behaves differently depending on whether the socket is listed in the -// read or write file descriptors. -int main() { - struct sockaddr_in addr; - int res; - - sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (sockfd == -1) { - perror("cannot create socket"); - finish(EXIT_FAILURE); - } - fcntl(sockfd, F_SETFL, O_NONBLOCK); - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(SOCKK); - if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) { - perror("inet_pton failed"); - finish(EXIT_FAILURE); - } - - // This call should succeed (even if the server port is closed) - res = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); - if (res == -1 && errno != EINPROGRESS) { - perror("connect failed"); - finish(EXIT_FAILURE); - } - -#if EMSCRIPTEN - emscripten_set_main_loop(iter, 0, 0); -#else - while (1) iter(NULL); -#endif - - return EXIT_SUCCESS; -} - -- cgit v1.2.3-18-g5258 From 816e9c5698c3b285ffc3fe3bfd68fe290dca5034 Mon Sep 17 00:00:00 2001 From: Anthony Pesch Date: Wed, 7 Aug 2013 14:13:53 -0700 Subject: removed unused EMBED_SIDE define --- tests/runner.py | 2 +- tests/sockets/test_sockets_bi.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/runner.py b/tests/runner.py index dbf7cb4f..6734c7e6 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -13998,7 +13998,7 @@ Press any key to continue.''' with self.WebsockHarness(6992, self.make_relay_server(6992, 6994)): with self.WebsockHarness(6994, no_server=True): Popen([PYTHON, EMCC, path_from_root('tests', 'sockets/test_sockets_bi_side.c'), '-o', 'side.html', '-DSOCKK=6995', '-DTEST_DGRAM=%d' % datagram]).communicate() - self.btest('sockets/test_sockets_bi.c', expected='2499', args=['-DSOCKK=6993', '-DTEST_DGRAM=%d' % datagram, '-DTEST_FILE_OPS=%s' % fileops, '-DEMBED_SIDE']) + self.btest('sockets/test_sockets_bi.c', expected='2499', args=['-DSOCKK=6993', '-DTEST_DGRAM=%d' % datagram, '-DTEST_FILE_OPS=%s' % fileops]) finally: self.clean_pids() diff --git a/tests/sockets/test_sockets_bi.c b/tests/sockets/test_sockets_bi.c index e19f7fe8..4266d20c 100644 --- a/tests/sockets/test_sockets_bi.c +++ b/tests/sockets/test_sockets_bi.c @@ -124,13 +124,11 @@ int main() { } #if EMSCRIPTEN -#if EMBED_SIDE emscripten_run_script("console.log('adding iframe');" "var iframe = document.createElement('iframe');" "iframe.src = 'side.html';" "document.body.appendChild(iframe);" "console.log('added.');"); -#endif emscripten_set_main_loop(iter, 0, 0); #else while (1) iter(NULL); -- cgit v1.2.3-18-g5258