From 15c260010354c1d3881cc0716e7426bb3e4542ff Mon Sep 17 00:00:00 2001 From: David Barksdale Date: Wed, 2 Nov 2016 22:20:43 -0500 Subject: Improve socket emulation Since MessagePort.close() doesn't close the other end, send a "close" message. Return proper errno codes. Handle race conditions in scheduling callbacks. --- .../packages/gnunet/gnunet/files/network.js | 35 ++++++++++++++++++---- .../packages/gnunet/gnunet/files/scheduler.js | 10 ++++++- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/gnunet-build/packages/gnunet/gnunet/files/network.js b/gnunet-build/packages/gnunet/gnunet/files/network.js index 80ad2e5..84a9d16 100644 --- a/gnunet-build/packages/gnunet/gnunet/files/network.js +++ b/gnunet-build/packages/gnunet/gnunet/files/network.js @@ -20,7 +20,13 @@ mergeInto(LibraryManager.library, { GNUNET_NETWORK_socket_create__deps: ['$SOCKETS', '$NEXT_SOCKET'], GNUNET_NETWORK_socket_create: function(domain, type, protocol) { console.debug("socket_create(", domain, type, protocol, ")"); - if (domain != 1 || type != 1 || protocol != 0) { + if (domain != 1) { + ___setErrNo(ERRNO_CODES.EAFNOSUPPORT); + return 0; + + } + if (type != 1 || protocol != 0) { + ___setErrNo(ERRNO_CODES.EPROTONOSUPPORT); return 0; } return NEXT_SOCKET++; @@ -30,9 +36,12 @@ mergeInto(LibraryManager.library, { console.debug("socket_connect(", desc, address, address_len, ")"); if (desc in SOCKETS) { console.error("socket already connected?"); + ___setErrNo(ERRNO_CODES.EISCONN); return -1; } - if (110 != address_len) { + var af = {{{ makeGetValue('address', '0', 'i16') }}}; + if (1 != af) { + ___setErrNo(ERRNO_CODES.EAFNOSUPPORT); return -1; } var path = Pointer_stringify(address + 2); @@ -42,6 +51,7 @@ mergeInto(LibraryManager.library, { channel = new MessageChannel(); } catch (e) { console.error("No MessageChannel in this browser", e); + ___setErrNo(ERRNO_CODES.ENETUNREACH); return -1; } var socket = SOCKETS[desc] = { @@ -66,6 +76,7 @@ mergeInto(LibraryManager.library, { gnunet_web.service.client_connect(path, 'client.js', channel.port2); } catch(e) { console.error('Failed to connect to', path, e); + ___setErrNo(ERRNO_CODES.ENETUNREACH); return -1; } } @@ -76,6 +87,7 @@ mergeInto(LibraryManager.library, { console.debug("socket_send(", desc, buffer, length, ")"); if (!(desc in SOCKETS)) { console.error("socket not connected?"); + ___setErrNo(ERRNO_CODES.ENOTCONN); return -1; } var view = {{{ makeHEAPView('U8', 'buffer', 'buffer+length') }}}; @@ -83,6 +95,7 @@ mergeInto(LibraryManager.library, { SOCKETS[desc].port.postMessage(new Uint8Array(view)); } catch (e) { console.error("Failed to send"); + ___setErrNo(ERRNO_CODES.ECONNRESET); return -1; } return length; @@ -91,13 +104,15 @@ mergeInto(LibraryManager.library, { GNUNET_NETWORK_socket_close: function(desc) { console.debug("socket_close(", desc, ")"); if (!(desc in SOCKETS)) { - return 1; + ___setErrNo(ERRNO_CODES.EBADF); + return -1; } var socket = SOCKETS[desc]; - delete SOCKETS[desc]; if ("port" in socket) { + socket.port.postMessage("close"); socket.port.close(); } + delete SOCKETS[desc]; return 1; }, GNUNET_NETWORK_socket_bind__deps: ['$SOCKETS'], @@ -105,9 +120,11 @@ mergeInto(LibraryManager.library, { console.debug("socket_bind(", desc, address, address_len, ")"); if (desc in SOCKETS) { console.error("socket already bound?"); + ___setErrNo(ERRNO_CODES.EINVAL); return -1; } if (110 != address_len) { + ___setErrNo(ERRNO_CODES.EINVAL); return -1; } var path = Pointer_stringify(address + 2); @@ -130,10 +147,12 @@ mergeInto(LibraryManager.library, { console.debug("socket_accept(", desc, address, address_len, ")"); if (desc != SOCKETS.listening) { console.error("socket is not listening"); + ___setErrNo(ERRNO_CODES.EINVAL); return 0; } if (0 == SOCKETS.incoming.length) { console.debug("no incoming connections"); + ___setErrNo(ERRNO_CODES.EWOULDBLOCK); return 0; } var data = SOCKETS.incoming.shift(); @@ -162,14 +181,20 @@ mergeInto(LibraryManager.library, { console.debug("socket_recv(", desc, buffer, length, ")"); if (!(desc in SOCKETS)) { console.error("socket not connected?"); + ___setErrNo(ERRNO_CODES.ENOTCONN); return -1; } var socket = SOCKETS[desc]; if (0 == socket.queue.length) { console.debug("nothing to read"); - return 0; + ___setErrNo(ERRNO_CODES.EWOULDBLOCK); + return -1; } var data = socket.queue[0]; + if ("close" == data) { + console.debug("socket closed"); + return 0; + } var sub = data.subarray(0, length); HEAP8.set(sub, buffer); if (sub.length == data.length) { diff --git a/gnunet-build/packages/gnunet/gnunet/files/scheduler.js b/gnunet-build/packages/gnunet/gnunet/files/scheduler.js index 5f07bbb..6331e09 100644 --- a/gnunet-build/packages/gnunet/gnunet/files/scheduler.js +++ b/gnunet-build/packages/gnunet/gnunet/files/scheduler.js @@ -39,7 +39,9 @@ mergeInto(LibraryManager.library, { var t = SCHEDULER_TASKS[task]; delete SCHEDULER_TASKS[task]; if ("socket" in t) { - delete SOCKETS[t.socket]["task"]; + if (t.socket in SOCKETS) { + delete SOCKETS[t.socket]["task"]; + } } return t.cls; } @@ -64,6 +66,9 @@ mergeInto(LibraryManager.library, { } else if (0 == socket.queue.length) { return; } + if (!(id in SCHEDULER_TASKS)) { + return; + } delete SCHEDULER_TASKS[id]; delete socket["task"]; Runtime.dynCall('vi', task, [task_cls]); @@ -94,6 +99,9 @@ mergeInto(LibraryManager.library, { } // always writable var id = setTimeout(function() { + if (!(id in SCHEDULER_TASKS)) { + return; + } delete SCHEDULER_TASKS[id]; Runtime.dynCall('vi', task, [task_cls]); }, 0); -- cgit v1.2.3-18-g5258