summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEmīls Piņķis <emils@mullvad.net>2018-09-10 11:41:00 +0100
committerEmīls Piņķis <emils@mullvad.net>2018-09-10 11:41:00 +0100
commitbf3a84467d8972315dbdafa5b49d43780fafe8f7 (patch)
tree4ee45f37ada2bf1cdef15dc6d55c868666a6ff44
parent215e0f69ee09aa35517a82ba1b697d50a4eaf1c2 (diff)
parent4e3ceb972375ad0037dd02daeb0f78ed5fc869be (diff)
downloadmullvadvpn-bf3a84467d8972315dbdafa5b49d43780fafe8f7.tar.xz
mullvadvpn-bf3a84467d8972315dbdafa5b49d43780fafe8f7.zip
Merge branch 'fix-ipc-reconnect'
-rw-r--r--gui/packages/desktop/src/renderer/app.js30
-rw-r--r--gui/packages/desktop/src/renderer/lib/daemon-rpc.js5
-rw-r--r--gui/packages/desktop/src/renderer/lib/jsonrpc-client.js38
3 files changed, 38 insertions, 35 deletions
diff --git a/gui/packages/desktop/src/renderer/app.js b/gui/packages/desktop/src/renderer/app.js
index ebc32b9f81..54275ec76a 100644
--- a/gui/packages/desktop/src/renderer/app.js
+++ b/gui/packages/desktop/src/renderer/app.js
@@ -47,6 +47,7 @@ export default class AppRenderer {
_reduxStore: ReduxStore;
_reduxActions: *;
_accountDataState = new AccountDataState();
+ _connectedToDaemon = false;
constructor() {
const store = configureStore(null, this._memoryHistory);
@@ -439,6 +440,8 @@ export default class AppRenderer {
}
async _onOpenConnection() {
+ this._connectedToDaemon = true;
+
// reset the reconnect backoff when connection established.
this._reconnectBackoff.reset();
@@ -477,7 +480,6 @@ export default class AppRenderer {
async _onCloseConnection(error: ?Error) {
const actions = this._reduxActions;
- const history = this._memoryHistory;
// recover connection on error
if (error) {
@@ -495,19 +497,15 @@ export default class AppRenderer {
recover();
});
- // take user back to the launch screen `/` except when user is in settings.
- if (history.location.pathname.startsWith('/settings')) {
- // TODO: Reinvent the navigation back in history to make sure that user does not end up on
- // the restricted screen due to changes in daemon's state.
- for (const entry of history.entries) {
- if (!entry.pathname.startsWith('/settings')) {
- entry.pathname = '/';
- }
- }
- } else {
+ // only send to the connecting to daemon view if the daemon was
+ // connnected previously
+ if (this._connectedToDaemon) {
actions.history.replace('/');
}
+ } else {
+ log.info(`Disconnected from the daemon`);
}
+ this._connectedToDaemon = false;
}
async _subscribeStateListener() {
@@ -620,16 +618,6 @@ export default class AppRenderer {
return;
}
}
-
- async _authenticate(sharedSecret: string) {
- try {
- await this._daemonRpc.authenticate(sharedSecret);
- log.info('Authenticated with backend');
- } catch (e) {
- log.error(`Failed to authenticate with backend: ${e.message}`);
- throw e;
- }
- }
}
// Helper class to keep track of account data updates
diff --git a/gui/packages/desktop/src/renderer/lib/daemon-rpc.js b/gui/packages/desktop/src/renderer/lib/daemon-rpc.js
index 7b5eb86f3a..b13da5f2ab 100644
--- a/gui/packages/desktop/src/renderer/lib/daemon-rpc.js
+++ b/gui/packages/desktop/src/renderer/lib/daemon-rpc.js
@@ -305,7 +305,6 @@ export interface DaemonRpcProtocol {
subscribeStateListener((state: ?TunnelState, error: ?Error) => void): Promise<void>;
addOpenConnectionObserver(() => void): ConnectionObserver;
addCloseConnectionObserver((error: ?Error) => void): ConnectionObserver;
- authenticate(sharedSecret: string): Promise<void>;
getAccountHistory(): Promise<Array<AccountToken>>;
removeAccountFromHistory(accountToken: AccountToken): Promise<void>;
getCurrentVersion(): Promise<string>;
@@ -335,10 +334,6 @@ const NETWORK_CALL_TIMEOUT = 10000;
export class DaemonRpc implements DaemonRpcProtocol {
_transport = new JsonRpcClient(new SocketTransport());
- async authenticate(sharedSecret: string): Promise<void> {
- await this._transport.send('auth', sharedSecret);
- }
-
connect(connectionParams: { path: string }) {
this._transport.connect(connectionParams);
}
diff --git a/gui/packages/desktop/src/renderer/lib/jsonrpc-client.js b/gui/packages/desktop/src/renderer/lib/jsonrpc-client.js
index cf779c83be..9cafade681 100644
--- a/gui/packages/desktop/src/renderer/lib/jsonrpc-client.js
+++ b/gui/packages/desktop/src/renderer/lib/jsonrpc-client.js
@@ -120,11 +120,7 @@ export class WebSocketError extends Error {
}
}
-export class TransportError extends Error {
- constructor(reason: string) {
- super(reason);
- }
-}
+export class TransportError extends Error {}
const DEFAULT_TIMEOUT_MILLIS = 5000;
@@ -389,19 +385,33 @@ export class SocketTransport implements Transport<{ path: string }> {
onMessage: (message: Object) => void;
onClose: (error: ?Error) => void;
onOpen: (event: Event) => void;
+ socketClosed: boolean;
+ shouldClose: boolean;
constructor() {
this.connection = null;
this.onMessage = () => {};
this.onClose = () => {};
this.onOpen = () => {};
+ this.socketClosed = false;
+ this.shouldClose = false;
}
_connect(options: { path: string }) {
const connection = new net.Socket();
+
connection.on('error', (err) => {
- this.onClose(err);
- this.close();
+ this._fail(err);
+ });
+
+ connection.on('close', (hadErr) => {
+ // if there's no error but nobody expected the socket to be closed an
+ // error should still be propagated
+ let err = null;
+ if (!this.shouldClose || hadErr) {
+ err = new TransportError('socket closed unexpectedly');
+ }
+ this._fail(err);
});
connection.on('connect', (event) => {
@@ -416,14 +426,24 @@ export class SocketTransport implements Transport<{ path: string }> {
jsonStream.on('data', this.onMessage);
jsonStream.on('error', (err) => {
- this.onClose(err);
- this.close();
+ this._fail(err);
});
+ this.socketClosed = false;
+ this.shouldClose = false;
connection.connect(options);
}
+ _fail(err: ?Error) {
+ if (!this.socketClosed) {
+ this.socketClosed = true;
+ this.onClose(err);
+ this.close();
+ }
+ }
+
close() {
+ this.shouldClose = true;
try {
if (this.connection) {
this.connection.end();