summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2019-02-11 15:15:37 +0100
committerAndrej Mihajlov <and@mullvad.net>2019-02-11 15:15:37 +0100
commit26866ed828176a51e12cc56c5abf13eed91dc874 (patch)
tree18307ee784d236d2ae45a3cc2c3284773f2e9c89
parent9f70827cbd1e5df4e6ee7cbba13d3cc7cea654a1 (diff)
downloadmullvadvpn-26866ed828176a51e12cc56c5abf13eed91dc874.tar.xz
mullvadvpn-26866ed828176a51e12cc56c5abf13eed91dc874.zip
Fix the potential reconnect loop in GUI, triggered by the timeout when receiving the initial state of the daemon
-rw-r--r--CHANGELOG.md5
-rw-r--r--gui/packages/desktop/src/main/jsonrpc-client.ts47
2 files changed, 33 insertions, 19 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3f58601507..5672999394 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,11 @@ Line wrap the file at 100 chars. Th
## [Unreleased]
+### Fixed
+
+- Fix the potential reconnect loop in GUI, triggered by the timeout when receiving
+ the initial state of the daemon.
+
## [2019.1] - 2019-01-29
This release is identical to 2019.1-beta1
diff --git a/gui/packages/desktop/src/main/jsonrpc-client.ts b/gui/packages/desktop/src/main/jsonrpc-client.ts
index 2faf473c3e..f85560b610 100644
--- a/gui/packages/desktop/src/main/jsonrpc-client.ts
+++ b/gui/packages/desktop/src/main/jsonrpc-client.ts
@@ -370,8 +370,8 @@ export class WebsocketTransport implements ITransport<string> {
// domain sockets, and also TCP/UDP sockets
export class SocketTransport implements ITransport<{ path: string }> {
private connection?: net.Socket;
+ private jsonStream?: NodeJS.ReadWriteStream;
private socketReady = false;
- private shouldClose = false;
private lastError?: Error;
public onMessage = (_message: object) => {
// no-op
@@ -388,16 +388,16 @@ export class SocketTransport implements ITransport<{ path: string }> {
const jsonStream = JSONStream.parse(null)
.on('data', this.onJsonStreamData)
- .on('error', this.onJsonStreamError);
+ .once('error', this.onJsonStreamError);
const connection = new net.Socket()
- .on('ready', this.onSocketReady)
- .on('error', this.onSocketError)
- .on('close', this.onSocketClose);
+ .once('ready', this.onSocketReady)
+ .once('error', this.onSocketError)
+ .once('close', this.onSocketClose);
this.connection = connection;
+ this.jsonStream = jsonStream;
this.socketReady = false;
- this.shouldClose = false;
this.lastError = undefined;
log.debug('Connect socket');
@@ -407,17 +407,30 @@ export class SocketTransport implements ITransport<{ path: string }> {
}
public close() {
- this.shouldClose = true;
+ if (this.connection) {
+ log.debug('Close socket');
- try {
- if (this.connection) {
+ // closing socket is not synchronous, so remove all of the event handlers first
+ this.connection
+ .removeListener('ready', this.onSocketReady)
+ .removeListener('error', this.onSocketError)
+ .removeListener('close', this.onSocketClose);
+
+ this.jsonStream!.removeListener('data', this.onJsonStreamData).removeListener(
+ 'error',
+ this.onJsonStreamError,
+ );
+
+ try {
this.connection.end();
+ } catch (error) {
+ log.error('Failed to close the socket: ', error);
}
- } catch (error) {
- log.error('Failed to close the socket: ', error);
- }
- this.connection = undefined;
+ this.connection = undefined;
+ this.jsonStream = undefined;
+ this.onClose();
+ }
}
public send(msg: string) {
@@ -443,12 +456,8 @@ export class SocketTransport implements ITransport<{ path: string }> {
};
private onSocketClose = (hadError: boolean) => {
- if (this.shouldClose) {
- log.debug(`Socket was closed deliberately`);
-
- this.onClose();
- } else if (hadError) {
- log.debug(`Socket was closed due to an error`);
+ if (hadError) {
+ log.debug(`Socket was closed due to an error: `, this.lastError);
this.onClose(this.lastError);
} else {