aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Barksdale <amatus@amatus.name>2016-11-02 22:20:43 -0500
committerDavid Barksdale <amatus@amatus.name>2016-11-02 22:20:43 -0500
commit15c260010354c1d3881cc0716e7426bb3e4542ff (patch)
tree2e033793d71434776c148589395093e8686fc389
parent9f446be952d53009ba585ac64992a9db260d3e4f (diff)
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.
-rw-r--r--gnunet-build/packages/gnunet/gnunet/files/network.js35
-rw-r--r--gnunet-build/packages/gnunet/gnunet/files/scheduler.js10
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);