From a4e79e4539770a6cc675cf822de36961c7191a41 Mon Sep 17 00:00:00 2001 From: jialiya Date: Thu, 29 Jan 2015 16:56:26 -0800 Subject: [PATCH 1/8] removing ability to throw errors on bsd timeout --- src/colony/modules/net.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/colony/modules/net.js b/src/colony/modules/net.js index ddc44ab2..9ba84b76 100644 --- a/src/colony/modules/net.js +++ b/src/colony/modules/net.js @@ -195,13 +195,16 @@ TCPSocket.prototype.connect = function (/*options | [port], [host], [cb]*/) { var closeRet = tm.tcp_close(self.socket); // returns -57 if socket is already closed if (closeRet < 0 && closeRet != -tm.ENOTCONN){ // couldn't close socket, throw an error - self.emit('error', new Error('ENOENT Cannot close socket ' + self.socket + ' Got: err'+closeRet)); + // failed to connect, stay silent + console.log("Failed to close socket", self.socket); + // self.emit('error', new Error('ENOENT Cannot close socket ' + self.socket + ' Got: err'+closeRet)); self.destroy(); - return self.__close(false); + return self.__close(); } if (retries > 3) { - self.emit('error', new Error('ENOENT Cannot connect to ' + ip + ' Got: err'+ret)); + console.log("Cannot connect to", ip); + // self.emit('error', new Error('ENOENT Cannot connect to ' + ip + ' Got: err'+ret)); // force the cleanup self.destroy(); return self.__close(); From ee4ec559643e39f7d94d4a0afe35dd0d492f336b Mon Sep 17 00:00:00 2001 From: jialiya Date: Mon, 2 Feb 2015 11:31:23 -0800 Subject: [PATCH 2/8] remove error on .close --- src/colony/modules/net.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/colony/modules/net.js b/src/colony/modules/net.js index 9ba84b76..c5a1e443 100644 --- a/src/colony/modules/net.js +++ b/src/colony/modules/net.js @@ -197,7 +197,7 @@ TCPSocket.prototype.connect = function (/*options | [port], [host], [cb]*/) { // couldn't close socket, throw an error // failed to connect, stay silent console.log("Failed to close socket", self.socket); - // self.emit('error', new Error('ENOENT Cannot close socket ' + self.socket + ' Got: err'+closeRet)); + self.emit('error', new Error('ENOENT Cannot close socket ' + self.socket + ' Got: err'+closeRet)); self.destroy(); return self.__close(); } @@ -470,7 +470,7 @@ TCPSocket.prototype.__close = function (tryToClose) { if (ret < 0 && ret != -tm.ENOTCONN) { // -57 is inactive, socket has already been closed if (retries > 3) { // tried 3 times and couldn't close, error out - self.emit('error', new Error('ENOENT Cannot close socket ' + self.socket + ' Got: err'+ret)); + // self.emit('error', new Error('ENOENT Cannot close socket ' + self.socket + ' Got: err'+ret)); self.emit('close'); } else { retries++; From cc9dbe4d06c7fda97b9c3ee4a22751b8e0ae4525 Mon Sep 17 00:00:00 2001 From: jialiya Date: Fri, 13 Feb 2015 12:06:11 -0800 Subject: [PATCH 3/8] adding more debug info --- src/colony/lua_tm.c | 17 +++++++++++++---- src/colony/modules/net.js | 14 +++++++++++--- src/tm_ssl.c | 1 + 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/colony/lua_tm.c b/src/colony/lua_tm.c index 02471db5..f9a9008f 100644 --- a/src/colony/lua_tm.c +++ b/src/colony/lua_tm.c @@ -261,9 +261,14 @@ static int l_tm_tcp_read (lua_State* L) uint8_t buf[512]; size_t buf_len = sizeof(buf); int err = tm_tcp_read(socket, buf, &buf_len); - (void) err; + + if (err < 0) { + lua_pushstring(L, "tcp read error"); + lua_error(L); + } else { + colony_pushbuffer(L, buf, buf_len); + } - colony_pushbuffer(L, buf, buf_len); return 1; } @@ -427,9 +432,13 @@ static int l_tm_ssl_read (lua_State* L) uint8_t buf[20000]; size_t buf_len = sizeof(buf); int err = tm_ssl_read(session, buf, &buf_len); - (void) err; + if (err < 0) { + lua_pushstring(L, "ssl read error"); + lua_error(L); + } else { + colony_pushbuffer(L, buf, buf_len); + } - colony_pushbuffer(L, buf, buf_len); return 1; } diff --git a/src/colony/modules/net.js b/src/colony/modules/net.js index c5a1e443..49ad524b 100644 --- a/src/colony/modules/net.js +++ b/src/colony/modules/net.js @@ -428,9 +428,17 @@ TCPSocket.prototype.__readSocket = function(restartTimeout) { var arr = [], flag = 0; while (self.socket != null && (flag = tm.tcp_readable(self.socket)) > 0) { if (self._ssl) { - var data = tm.ssl_read(self._ssl); + try { + var data = tm.ssl_read(self._ssl); + } catch(e){ + self.emit("error", e); + } } else { - var data = tm.tcp_read(self.socket); + try { + var data = tm.tcp_read(self.socket); + } catch(e){ + self.emit("error", e); + } } if (!data || data.length == 0) { break; @@ -466,10 +474,10 @@ TCPSocket.prototype.__close = function (tryToClose) { function closeSocket(){ if (self.socket === null) return; var ret = tm.tcp_close(self.socket); - if (ret < 0 && ret != -tm.ENOTCONN) { // -57 is inactive, socket has already been closed if (retries > 3) { // tried 3 times and couldn't close, error out + // removing this error for now, nothing for the user to do if this error occurs // self.emit('error', new Error('ENOENT Cannot close socket ' + self.socket + ' Got: err'+ret)); self.emit('close'); } else { diff --git a/src/tm_ssl.c b/src/tm_ssl.c index 990ab10c..fb52a03d 100644 --- a/src/tm_ssl.c +++ b/src/tm_ssl.c @@ -40,6 +40,7 @@ int tm_ssl_read (tm_ssl_session_t ssl, uint8_t *buf, size_t *buf_len) uint8_t *read_buf; int res = ssl_read(ssl, &read_buf); if (res < 0) { + TM_DEBUG("ssl read res %d", res); *buf_len = 0; return res; } else { From 92c6d3fefde4859f5c5dcc09fa8fec7785700963 Mon Sep 17 00:00:00 2001 From: jialiya Date: Fri, 13 Feb 2015 12:08:22 -0800 Subject: [PATCH 4/8] adding retry connection error back in --- src/colony/modules/net.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/colony/modules/net.js b/src/colony/modules/net.js index 49ad524b..f5e6b597 100644 --- a/src/colony/modules/net.js +++ b/src/colony/modules/net.js @@ -203,8 +203,7 @@ TCPSocket.prototype.connect = function (/*options | [port], [host], [cb]*/) { } if (retries > 3) { - console.log("Cannot connect to", ip); - // self.emit('error', new Error('ENOENT Cannot connect to ' + ip + ' Got: err'+ret)); + self.emit('error', new Error('ENOENT Cannot connect to ' + ip + ' Got: err'+ret)); // force the cleanup self.destroy(); return self.__close(); From c19b7fbe4ac3fc2ddaca8538e1e0d34f5491fa51 Mon Sep 17 00:00:00 2001 From: jialiya Date: Wed, 18 Feb 2015 14:21:09 -0800 Subject: [PATCH 5/8] !=0 is a tcp/ssl read error --- src/colony/lua_tm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/colony/lua_tm.c b/src/colony/lua_tm.c index f9a9008f..be5ffa5a 100644 --- a/src/colony/lua_tm.c +++ b/src/colony/lua_tm.c @@ -262,7 +262,7 @@ static int l_tm_tcp_read (lua_State* L) size_t buf_len = sizeof(buf); int err = tm_tcp_read(socket, buf, &buf_len); - if (err < 0) { + if (err != 0) { lua_pushstring(L, "tcp read error"); lua_error(L); } else { @@ -432,7 +432,7 @@ static int l_tm_ssl_read (lua_State* L) uint8_t buf[20000]; size_t buf_len = sizeof(buf); int err = tm_ssl_read(session, buf, &buf_len); - if (err < 0) { + if (err != 0) { lua_pushstring(L, "ssl read error"); lua_error(L); } else { From ea110d51a261327eee3eba87afe4e25616131d5f Mon Sep 17 00:00:00 2001 From: jialiya Date: Fri, 20 Feb 2015 15:46:10 -0800 Subject: [PATCH 6/8] emitting error #s --- src/colony/lua_tm.c | 17 +++++++++++++++-- src/colony/modules/net.js | 26 ++++++++++++-------------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/colony/lua_tm.c b/src/colony/lua_tm.c index be5ffa5a..d8c9426b 100644 --- a/src/colony/lua_tm.c +++ b/src/colony/lua_tm.c @@ -263,7 +263,13 @@ static int l_tm_tcp_read (lua_State* L) int err = tm_tcp_read(socket, buf, &buf_len); if (err != 0) { - lua_pushstring(L, "tcp read error"); + char strbuffer[100]; + ssize_t len = (ssize_t) snprintf(strbuffer, sizeof(strbuffer), "TCP read error: %d", err); + if (len > 0) { + lua_pushlstring(L, strbuffer, len); + } else { + lua_pushstring(L, "TCP read error: [unavailable]"); + } lua_error(L); } else { colony_pushbuffer(L, buf, buf_len); @@ -432,8 +438,15 @@ static int l_tm_ssl_read (lua_State* L) uint8_t buf[20000]; size_t buf_len = sizeof(buf); int err = tm_ssl_read(session, buf, &buf_len); + if (err != 0) { - lua_pushstring(L, "ssl read error"); + char strbuffer[100]; + ssize_t len = (ssize_t) snprintf(strbuffer, sizeof(strbuffer), "SSL read error: %d", err); + if (len > 0) { + lua_pushlstring(L, strbuffer, len); + } else { + lua_pushstring(L, "SSL read error: [unavailable]"); + } lua_error(L); } else { colony_pushbuffer(L, buf, buf_len); diff --git a/src/colony/modules/net.js b/src/colony/modules/net.js index f5e6b597..38403a12 100644 --- a/src/colony/modules/net.js +++ b/src/colony/modules/net.js @@ -188,7 +188,7 @@ TCPSocket.prototype.connect = function (/*options | [port], [host], [cb]*/) { self.emit('error', new Error("ENETUNREACH: Wifi is not connected")); // force the cleanup self.destroy(); - return self.__close(); // need to call close otherwise we keep listening for the tcp-close event + return self.__close(false); // need to call close otherwise we keep listening for the tcp-close event } if (ret < 0) { @@ -196,17 +196,16 @@ TCPSocket.prototype.connect = function (/*options | [port], [host], [cb]*/) { if (closeRet < 0 && closeRet != -tm.ENOTCONN){ // couldn't close socket, throw an error // failed to connect, stay silent - console.log("Failed to close socket", self.socket); self.emit('error', new Error('ENOENT Cannot close socket ' + self.socket + ' Got: err'+closeRet)); self.destroy(); - return self.__close(); + return self.__close(false); } if (retries > 3) { self.emit('error', new Error('ENOENT Cannot connect to ' + ip + ' Got: err'+ret)); // force the cleanup self.destroy(); - return self.__close(); + return self.__close(false); } else { retries++; setTimeout(function(){ @@ -223,7 +222,7 @@ TCPSocket.prototype.connect = function (/*options | [port], [host], [cb]*/) { // force the close self.destroy(); - return self.__close(); + return self.__close(false); } else { doConnect(); } @@ -256,13 +255,13 @@ TCPSocket.prototype.connect = function (/*options | [port], [host], [cb]*/) { tm.tcp_readable(self.socket); self.destroy(); - self.__close(); + self.__close(false); return; } else { // close socket self.emit('error', new Error('Could not validate SSL request (error ' + ret + ')')); self.destroy(); - self.__close(); + self.__close(false); return; } } @@ -374,7 +373,7 @@ TCPSocket.prototype.__send = function (cb) { if (this._queueEnd) { // close actual socket this._queueEnd = false; - this.__close(); + this.__close(false); } return cb ? cb() : false; } @@ -430,13 +429,13 @@ TCPSocket.prototype.__readSocket = function(restartTimeout) { try { var data = tm.ssl_read(self._ssl); } catch(e){ - self.emit("error", e); + self.emit("error", typeof e == 'string' ? new Error(e) : e); } } else { try { var data = tm.tcp_read(self.socket); } catch(e){ - self.emit("error", e); + self.emit("error", typeof e == 'string' ? new Error(e) : e); } } if (!data || data.length == 0) { @@ -475,9 +474,8 @@ TCPSocket.prototype.__close = function (tryToClose) { var ret = tm.tcp_close(self.socket); if (ret < 0 && ret != -tm.ENOTCONN) { // -57 is inactive, socket has already been closed if (retries > 3) { - // tried 3 times and couldn't close, error out - // removing this error for now, nothing for the user to do if this error occurs - // self.emit('error', new Error('ENOENT Cannot close socket ' + self.socket + ' Got: err'+ret)); + // tried 3 times and couldn't close + // nothing for the user to do if this occurs, close the socket and user should re-request connection self.emit('close'); } else { retries++; @@ -513,7 +511,7 @@ TCPSocket.prototype.destroy = TCPSocket.prototype.close = function () { if (self._outgoing.length || self._sending) { self._queueEnd = true; } else { - self.__close(); + self.__close(false); } } self.removeAllListeners(); From 64741be9d1eb3254d1d2f567187b843acf7c3076 Mon Sep 17 00:00:00 2001 From: jialiya Date: Fri, 20 Feb 2015 23:46:44 -0800 Subject: [PATCH 7/8] cache dns --- src/colony/lua_cares.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/colony/lua_cares.c b/src/colony/lua_cares.c index 0c765d58..50b34101 100644 --- a/src/colony/lua_cares.c +++ b/src/colony/lua_cares.c @@ -27,6 +27,7 @@ #define INET6_ADDRSTRLEN 46 uint8_t ipaddr[4] = { 0 }; +uint32_t ip_dns = 0; static void state_cb(void *data, int s, int read, int write) @@ -103,8 +104,12 @@ uint32_t tm__sync_gethostbyname (const char *domain) struct in_addr ns1; - // get the dns server - uint32_t ip_dns = tm_net_dnsserver(); + // check cache of old dns server + // if it isn't there, get the new dns server + if (ip_dns == 0) { + ip_dns = tm_net_dnsserver(); + } + if (ip_dns == 0) { // error not connected return 1; From 1de86adaecfd2e1cb49e3e56a887dbad3615efba Mon Sep 17 00:00:00 2001 From: jialiya Date: Fri, 20 Feb 2015 23:47:01 -0800 Subject: [PATCH 8/8] freeing ssl context --- src/colony/modules/net.js | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/colony/modules/net.js b/src/colony/modules/net.js index 38403a12..c407a1c8 100644 --- a/src/colony/modules/net.js +++ b/src/colony/modules/net.js @@ -188,7 +188,7 @@ TCPSocket.prototype.connect = function (/*options | [port], [host], [cb]*/) { self.emit('error', new Error("ENETUNREACH: Wifi is not connected")); // force the cleanup self.destroy(); - return self.__close(false); // need to call close otherwise we keep listening for the tcp-close event + return self.__close(true); // need to call close otherwise we keep listening for the tcp-close event } if (ret < 0) { @@ -198,14 +198,14 @@ TCPSocket.prototype.connect = function (/*options | [port], [host], [cb]*/) { // failed to connect, stay silent self.emit('error', new Error('ENOENT Cannot close socket ' + self.socket + ' Got: err'+closeRet)); self.destroy(); - return self.__close(false); + return self.__close(true); } if (retries > 3) { self.emit('error', new Error('ENOENT Cannot connect to ' + ip + ' Got: err'+ret)); // force the cleanup self.destroy(); - return self.__close(false); + return self.__close(true); } else { retries++; setTimeout(function(){ @@ -222,7 +222,7 @@ TCPSocket.prototype.connect = function (/*options | [port], [host], [cb]*/) { // force the close self.destroy(); - return self.__close(false); + return self.__close(true); } else { doConnect(); } @@ -255,13 +255,13 @@ TCPSocket.prototype.connect = function (/*options | [port], [host], [cb]*/) { tm.tcp_readable(self.socket); self.destroy(); - self.__close(false); + self.__close(true); return; } else { // close socket self.emit('error', new Error('Could not validate SSL request (error ' + ret + ')')); self.destroy(); - self.__close(false); + self.__close(true); return; } } @@ -373,7 +373,7 @@ TCPSocket.prototype.__send = function (cb) { if (this._queueEnd) { // close actual socket this._queueEnd = false; - this.__close(false); + this.__close(true); } return cb ? cb() : false; } @@ -498,6 +498,10 @@ TCPSocket.prototype.destroy = TCPSocket.prototype.close = function () { if (this._destroy) return; this._destroy = true; + if (this._secure) { + // free ssl context + tm.ssl_context_free(this._ssl_ctx); + } var self = this; setImmediate(function () { @@ -511,7 +515,7 @@ TCPSocket.prototype.destroy = TCPSocket.prototype.close = function () { if (self._outgoing.length || self._sending) { self._queueEnd = true; } else { - self.__close(false); + self.__close(true); } } self.removeAllListeners(); @@ -623,9 +627,15 @@ TCPServer.prototype.listen = function (port, host, backlog, cb) { clientsocket.remotePort = port; clientsocket.__listen(); self.emit('connection', clientsocket); - } - setTimeout(poll, 10); + // do not poll if we're not connected + // this also gives time for the 'disconnect' event to fire from the wifi-cc3000 lib + // user should listen for require('wifi-cc3000').on('disconnect') event and + // reissue the request + setTimeout(poll, 10); + } else { + self.emit('error', new Error("Cannot listen on a bad socket %d", client)); + } } return this; };