aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-10-03 17:38:19 -0700
committerAlon Zakai <alonzakai@gmail.com>2012-10-03 17:38:19 -0700
commit4f2f867026315a33a30344a9cedc500568e9cb04 (patch)
tree2ce5753fd55eb8f7d310d3f4c9692accaa3004b7
parent363ce16a8980f08b9c81fea4d51d3356cbad21a9 (diff)
socket listen faking
-rw-r--r--src/library.js28
-rwxr-xr-xtests/runner.py11
-rw-r--r--tests/websockets_bi_listener.c151
-rw-r--r--tests/websockets_bi_side.c17
4 files changed, 200 insertions, 7 deletions
diff --git a/src/library.js b/src/library.js
index 72fb07e7..6c0a67a0 100644
--- a/src/library.js
+++ b/src/library.js
@@ -1209,7 +1209,7 @@ LibraryManager.library = {
return 0;
case {{{ cDefine('F_SETOWN') }}}:
case {{{ cDefine('F_GETOWN') }}}:
- // These are for sockets. We don't have them implemented (yet?).
+ // These are for sockets. We don't have them fully implemented yet.
___setErrNo(ERRNO_CODES.EINVAL);
return -1;
default:
@@ -6398,7 +6398,8 @@ LibraryManager.library = {
},
// ==========================================================================
- // sockets
+ // sockets. Note that the implementation assumes all sockets are always
+ // nonblocking
// ==========================================================================
$Sockets__deps: ['__setErrNo', '$ERRNO_CODES'],
@@ -6575,6 +6576,29 @@ LibraryManager.library = {
return 0;
},
+ bind__deps: ['connect'],
+ bind: function(fd, addr, addrlen) {
+ return _connect(fd, addr, addrlen);
+ },
+
+ listen: function(fd, backlog) {
+ return 0;
+ },
+
+ accept: function(fd, addr, addrlen) {
+ // TODO: webrtc queued incoming connections, etc.
+ // For now, the model is that bind does a connect, and we "accept" that one connection,
+ // which has host:port the same as ours. We also return the same socket fd.
+ var info = Sockets.fds[fd];
+ if (!info) return -1;
+ if (addr) {
+ setValue(addr + Sockets.sockaddr_in_layout.sin_addr, info.addr, 'i32');
+ setValue(addr + Sockets.sockaddr_in_layout.sin_port, info.port, 'i32');
+ setValue(addrlen, Sockets.sockaddr_in_layout.__size__, 'i32');
+ }
+ return fd;
+ },
+
// ==========================================================================
// emscripten.h
// ==========================================================================
diff --git a/tests/runner.py b/tests/runner.py
index 02e0428e..9608f24d 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -8798,11 +8798,20 @@ elif 'browser' in str(sys.argv):
try:
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']).communicate()
+ Popen(['python', EMCC, path_from_root('tests', 'websockets_bi_side.c'), '-o', 'side.html', '-DSOCKK=8995']).communicate()
self.btest('websockets_bi.c', expected='2499')
finally:
self.clean_pids()
+ def test_zz_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')
+ finally:
+ self.clean_pids()
+
def test_zz_websockets_gethostbyname(self):
try:
with self.WebsockHarness(7000):
diff --git a/tests/websockets_bi_listener.c b/tests/websockets_bi_listener.c
new file mode 100644
index 00000000..21005cc5
--- /dev/null
+++ b/tests/websockets_bi_listener.c
@@ -0,0 +1,151 @@
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#if EMSCRIPTEN
+#include <emscripten.h>
+#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) {
+ 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);
+#else
+ while (!done) iter(NULL);
+#endif
+
+ return EXIT_SUCCESS;
+}
+
diff --git a/tests/websockets_bi_side.c b/tests/websockets_bi_side.c
index ab9fa86a..c9c50618 100644
--- a/tests/websockets_bi_side.c
+++ b/tests/websockets_bi_side.c
@@ -7,15 +7,15 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <sys/ioctl.h>
+#if EMSCRIPTEN
#include <emscripten.h>
+#endif
#define EXPECTED_BYTES 5
int main(void)
{
-emscripten_run_script("console.log('hallo from siide')");
- printf("hello from side page\n");
-
struct sockaddr_in stSockAddr;
int Res;
int SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
@@ -29,7 +29,7 @@ emscripten_run_script("console.log('hallo from siide')");
memset(&stSockAddr, 0, sizeof(stSockAddr));
stSockAddr.sin_family = AF_INET;
- stSockAddr.sin_port = htons(8995);
+ stSockAddr.sin_port = htons(SOCKK);
Res = inet_pton(AF_INET, "127.0.0.1", &stSockAddr.sin_addr);
if (0 > Res) {
@@ -42,15 +42,24 @@ emscripten_run_script("console.log('hallo from siide')");
exit(EXIT_FAILURE);
}
+ printf("connect..\n");
+
if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) {
perror("connect failed");
close(SocketFD);
exit(EXIT_FAILURE);
}
+ printf("send..\n");
+
char data[] = "hello from the other siide\n";
send(SocketFD, data, sizeof(data), 0);
+ printf("stall..\n");
+
+ //int bytes;
+ //while (1) ioctl(SocketFD, FIONREAD, &bytes);
+
return EXIT_SUCCESS;
}