Skip to content
This repository has been archived by the owner on Dec 11, 2019. It is now read-only.

Make polling for tor restart work. Call setupTor only once. #14585

Merged
merged 1 commit into from
Jun 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions app/filtering.js
Original file line number Diff line number Diff line change
Expand Up @@ -714,8 +714,6 @@ module.exports.relaunchTor = () => {
}
appActions.onTorInitError(null)
try {
// TODO (riastradh): why is calling setupTor again necessary?
setupTor()
ses.relaunchTor()
} catch (e) {
appActions.onTorInitError(`Could not restart Tor: ${e}`)
Expand Down
13 changes: 12 additions & 1 deletion app/tor.js
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ class TorDaemon extends EventEmitter {
const errorMethod = (err) => {
console.log(`tor: control socket connection error: ${err}`)
controlSocket.destroy(err)
return this._polled()
}
controlSocket.on('close', closeMethod)
controlSocket.on('error', errorMethod)
Expand All @@ -474,7 +475,7 @@ class TorDaemon extends EventEmitter {
console.log(`tor: close control socket failed: ${err}`)
}
})
return
return this._polled()
}

// Assert we are in a sane state: we have a process, but we have
Expand All @@ -492,6 +493,13 @@ class TorDaemon extends EventEmitter {
this._control = new TorControl(readable, writable)
this._control.on('error', (err) => this._controlError(err))
this._control.on('close', () => this._controlClosed())

// We have finished polling, _and_ we are scheduled to be
// notified either by (a) our file system activity watcher, or
// (b) failure on the control channel. That way we won't lose
// any notifications that tor has restarted.
this._polled()

const hexCookie = cookie.toString('hex')
this._control.cmd1(`AUTHENTICATE ${hexCookie}`, (err, status, reply) => {
if (!err) {
Expand Down Expand Up @@ -550,6 +558,9 @@ class TorDaemon extends EventEmitter {
this._control = null
// Assume this means the process exited.
this.emit('exit')
// Poll in case we received a watch event for file system activity
// before we actually closed the channel.
this._poll()
}

/**
Expand Down
29 changes: 29 additions & 0 deletions test/unit/app/torTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,5 +284,34 @@ describe('tor unit tests', function () {
})
})
})

it('notices tor restart', function (callback) {
torDaemon.setup(() => {
// Start watching.
torDaemon.start()
// Spawn a process.
torProcess = spawnTor(torDaemon)
// Wait for it to launch once.
const timeoutLaunch = setTimeout(() => {
assert.fail('tor daemon failed to start after 2sec')
}, 2000)
torDaemon.once('launch', (socksAddr) => {
clearTimeout(timeoutLaunch)
// Kill the _process_ once.
killTor(torDaemon, torProcess, () => {
// Spawn a new process.
torProcess = spawnTor(torDaemon)
// Wait for it to launch a second time.
const timeoutRelaunch = setTimeout(() => {
assert.fail('tor daemon failed to restart after 2sec')
}, 2000)
torDaemon.once('launch', (socksAddr) => {
clearTimeout(timeoutRelaunch)
killTor(torDaemon, torProcess, callback)
})
})
})
})
})
})
})