diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-10-02 12:41:22 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-10-02 12:41:22 -0700 |
commit | d62af69d5347f670c678efae81d3dbf69bb88fd4 (patch) | |
tree | ecd74993712237c6635f674ccf4a894475584895 | |
parent | 0035201655ece68da0e1f201e2028562869328d5 (diff) |
support for connecting to sockets with fake ips from gethostbyname
-rw-r--r-- | src/library.js | 10 | ||||
-rwxr-xr-x | tests/runner.py | 7 | ||||
-rw-r--r-- | tests/websockets_gethostbyname.c | 132 |
3 files changed, 148 insertions, 1 deletions
diff --git a/src/library.js b/src/library.js index 5d97b41f..57a107ea 100644 --- a/src/library.js +++ b/src/library.js @@ -6412,7 +6412,7 @@ LibraryManager.library = { return fd; }, - connect__deps: ['$Sockets', '_inet_ntop_raw', 'ntohs'], + connect__deps: ['$Sockets', '_inet_ntop_raw', 'ntohs', 'gethostbyname'], connect: function(fd, addr, addrlen) { var info = Sockets.fds[fd]; if (!info) return -1; @@ -6420,6 +6420,14 @@ LibraryManager.library = { info.addr = getValue(addr + Sockets.sockaddr_in_layout.sin_addr, 'i32'); info.port = _ntohs(getValue(addr + Sockets.sockaddr_in_layout.sin_port, 'i16')); info.host = __inet_ntop_raw(info.addr); + // Support 'fake' ips from gethostbyname + var parts = info.host.split('.'); + if (parts[0] == '172' && parts[1] == '29') { + var low = Number(parts[2]); + var high = Number(parts[3]); + info.host = _gethostbyname.table[low + 0xff*high]; + assert(info.host, 'problem translating fake ip ' + parts); + } info.socket = new WebSocket('ws://' + info.host + ':' + info.port, ['arraybuffer']); info.socket.binaryType = 'arraybuffer'; info.buffer = new Uint8Array(Sockets.BUFFER_SIZE); diff --git a/tests/runner.py b/tests/runner.py index 2fe41a84..07c5e990 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -8791,6 +8791,13 @@ elif 'browser' in str(sys.argv): finally: self.clean_pids() + def test_zz_websockets_gethostbyname(self): + try: + with self.WebsockHarness(7000): + self.btest('websockets_gethostbyname.c', expected='571') + finally: + self.clean_pids() + def zzztest_zz_enet(self): #try: # with self.WebsockHarness(8992, self.relay_server): diff --git a/tests/websockets_gethostbyname.c b/tests/websockets_gethostbyname.c new file mode 100644 index 00000000..847187c7 --- /dev/null +++ b/tests/websockets_gethostbyname.c @@ -0,0 +1,132 @@ +#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 5 + +int 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(); +#endif + } +} + +int main(void) +{ + struct sockaddr_in stSockAddr; + int Res; + SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + + if (-1 == SocketFD) + { + perror("cannot create socket"); + exit(EXIT_FAILURE); + } + + memset(&stSockAddr, 0, sizeof(stSockAddr)); + + stSockAddr.sin_family = AF_INET; + stSockAddr.sin_port = htons(7001); + + 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 name[INET_ADDRSTRLEN]; + if (!inet_ntop(AF_INET, addr, name, sizeof(name))) { + printf("could not figure out name\n"); + return 0; + } + 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 (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) { + perror("connect failed"); + close(SocketFD); + exit(EXIT_FAILURE); + + } + +#if EMSCRIPTEN + emscripten_set_main_loop(iter, 0); +#else + while (!done) iter(NULL); +#endif + + return EXIT_SUCCESS; +} + |