[tor-commits] [tor-browser] 15/33: fixup! fixup! Bug 40597: Implement TorSettings module
gitolite role
git at cupani.torproject.org
Tue May 3 22:40:23 UTC 2022
This is an automated email from the git hooks/post-receive script.
richard pushed a commit to branch tor-browser-91.9.0esr-11.5-1
in repository tor-browser.
commit ccd86dbf59ee124ee72f743d6da2731742e4681c
Author: Pier Angelo Vendrame <pierov at torproject.org>
AuthorDate: Mon Apr 11 12:52:05 2022 +0200
fixup! fixup! Bug 40597: Implement TorSettings module
The Internet status is now checked as a part of the manual/quick
bootstrap state. If the bootstrap fails *and* Moat cannot be reached,
the type of error that is transitioned to has the offline message.
---
browser/modules/TorConnect.jsm | 140 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 137 insertions(+), 3 deletions(-)
diff --git a/browser/modules/TorConnect.jsm b/browser/modules/TorConnect.jsm
index 5a7172c51244f..a9d4c01086dc9 100644
--- a/browser/modules/TorConnect.jsm
+++ b/browser/modules/TorConnect.jsm
@@ -1,12 +1,12 @@
"use strict";
-var EXPORTED_SYMBOLS = ["TorConnect", "TorConnectTopics", "TorConnectState", "TorCensorshipLevel"];
+var EXPORTED_SYMBOLS = ["InternetStatus", "TorConnect", "TorConnectTopics", "TorConnectState", "TorCensorshipLevel"];
const { Services } = ChromeUtils.import(
"resource://gre/modules/Services.jsm"
);
-const { setTimeout } = ChromeUtils.import(
+const { setTimeout, clearTimeout } = ChromeUtils.import(
"resource://gre/modules/Timer.jsm"
);
@@ -225,6 +225,94 @@ const debug_sleep = async (ms) => {
});
}
+const InternetStatus = Object.freeze({
+ Unknown: -1,
+ Offline: 0,
+ Online: 1,
+});
+
+class InternetTest {
+ static get TIMEOUT() {
+ return 30000;
+ }
+
+ constructor() {
+ this._status = InternetStatus.Unknown;
+ this._error = null;
+ this._pending = false;
+ this._timeout = setTimeout(() => {
+ this._timeout = null;
+ this.test();
+ }, InternetTest.TIMEOUT + this.timeoutRand());
+ this.onResult = (online, date) => {}
+ this.onError = (err) => {};
+ }
+
+ test() {
+ if (this._pending) {
+ return;
+ }
+ this.cancel();
+ this._pending = true;
+
+ this._testAsync()
+ .then((status) => {
+ this._pending = false;
+ this._status = status.successful ? InternetStatus.Online : InternetStatus.Offline;
+ this.onResult(this.status, status.date);
+ })
+ .catch(error => {
+ this._error = error;
+ this._pending = false;
+ this.onError(error);
+ });
+ }
+
+ cancel() {
+ if (this._timeout !== null) {
+ clearTimeout(this._timeout);
+ this._timeout = null;
+ }
+ }
+
+ async _testAsync() {
+ // Callbacks for the Internet test are desirable, because we will be
+ // waiting both for the bootstrap, and for the Internet test.
+ // However, managing Moat with async/await is much easier as it avoids a
+ // callback hell, and it makes extra esplicit that we are uniniting it.
+ const mrpc = new MoatRPC();
+ let status = null;
+ let error = null;
+ try {
+ await mrpc.init();
+ status = await mrpc.testInternetConnection();
+ } catch (err) {
+ console.error("Error while checking the Internet connection", err);
+ error = err;
+ } finally {
+ mrpc.uninit();
+ }
+ if (error !== null) {
+ throw error;
+ }
+ return status;
+ }
+
+ get status() {
+ return this._status;
+ }
+
+ get error() {
+ return this._error;
+ }
+
+ // We randomize the Internet test timeout to make fingerprinting it harder, at least a little bit...
+ timeoutRand() {
+ const window = 5000;
+ return window * (Math.random() * 2 - 1);
+ }
+}
+
const TorConnect = (() => {
let retval = {
@@ -232,6 +320,7 @@ const TorConnect = (() => {
_bootstrapProgress: 0,
_bootstrapStatus: null,
_detectedCensorshipLevel: TorCensorshipLevel.None,
+ _internetStatus: InternetStatus.Unknown,
// list of country codes Moat has settings for
_countryCodes: [],
_countryNames: Object.freeze((() => {
@@ -311,9 +400,36 @@ const TorConnect = (() => {
}
const tbr = new TorBootstrapRequest();
+ const internetTest = new InternetTest();
+
+ let bootstrapError = "";
+ let bootstrapErrorDetails = "";
+ const maybeTransitionToError = () => {
+ console.log("TorConnect: maybe transition!", internetTest.status, internetTest.error, bootstrapError);
+ if (internetTest.status === InternetStatus.Unknown && internetTest.error === null) {
+ // We have been called by a failed bootstrap, but the internet test has not run yet - force
+ // it to run immediately!
+ internetTest.test();
+ // Return from this call, because the Internet test's callback will call us again
+ return;
+ }
+ // Do not transition to the offline error until we are sure that also the bootstrap failed, in
+ // case Moat is down but the bootstrap can proceed anyway.
+ if (bootstrapError === "") {
+ return;
+ }
+ if (internetTest.status === InternetStatus.Offline) {
+ TorConnect._changeState(TorConnectState.Error, TorStrings.torConnect.offline, "", true);
+ } else {
+ // Give priority to the bootstrap error, in case the Internet test fails
+ TorConnect._changeState(TorConnectState.Error, bootstrapError, bootstrapErrorDetails, true);
+ }
+ }
+
this.on_transition = async (nextState) => {
if (nextState === TorConnectState.Configuring) {
// stop bootstrap process if user cancelled
+ internetTest.cancel();
await tbr.cancel();
}
resolve();
@@ -323,12 +439,26 @@ const TorConnect = (() => {
TorConnect._updateBootstrapStatus(progress, status);
};
tbr.onbootstrapcomplete = () => {
+ internetTest.cancel();
TorConnect._changeState(TorConnectState.Bootstrapped);
};
tbr.onbootstraperror = (message, details) => {
- TorConnect._changeState(TorConnectState.Error, message, details, true);
+ // We have to wait for the Internet test to finish before sending the bootstrap error
+ bootstrapError = message;
+ bootstrapErrorDetails = details;
+ maybeTransitionToError();
};
+ internetTest.onResult = (status, date) => {
+ // TODO: Use the date to save the clock skew?
+ console.log("TorConnect: Internet test", status, date);
+ TorConnect._internetStatus = status;
+ maybeTransitionToError();
+ };
+ internetTest.onError = () => {
+ maybeTransitionToError();
+ }
+
tbr.bootstrap();
});
})],
@@ -619,6 +749,10 @@ const TorConnect = (() => {
return this._detectedCensorshipLevel;
},
+ get internetStatus() {
+ return this._internetStatus;
+ },
+
get errorMessage() {
return this._errorMessage;
},
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the tor-commits
mailing list