Commit cad26f4c authored by Pier Angelo Vendrame's avatar Pier Angelo Vendrame 🎃 Committed by Dan Ballard
Browse files

fixup! TB 40933: Add tor-launcher functionality

TB 44619: Add more tor logs to the UI.

Usually, we show in the UI only the logs we received from the tor
daemon.
However, for troubleshooting, it makes sense to display more errors,
e.g., about failure to start a tor process, or to connect to the
control port.

We already had those in the browser console, however it is not trivial
to get them, especially on Android.

TB 43403&43560: Add "UTC" to the log timestamp.
parent 9815068b
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ const lazy = {};

ChromeUtils.defineESModuleGetters(lazy, {
  FileUtils: "resource://gre/modules/FileUtils.sys.mjs",
  TorProviderTopics: "resource://gre/modules/TorProviderBuilder.sys.mjs",
});

const kPropBundleURI = "chrome://torbutton/locale/torlauncher.properties";
@@ -699,4 +700,27 @@ export const TorLauncherUtil = {
      console.warn("Could not remove the IPC directory", e);
    }
  },

  /**
   * Broadcast a tor log message. This message will be visible to the user.
   *
   * NOTE: Users are likely to copy and paste their tor log to forums, etc.
   * Therefore, the messages should avoid containing any information that might
   * identify information about the user.
   *
   * @param {string} type The log type (ERR, WARN, etc...)
   * @param {string} msg The log message
   */
  log(type, msg) {
    const timestamp =
      new Date().toISOString().replace("T", " ").replace("Z", "") + " UTC";
    Services.obs.notifyObservers(
      { type, msg, timestamp },
      lazy.TorProviderTopics.TorLog
    );
    if (type === "WARN" || type === "ERR") {
      // Notify so that Copy Log can be enabled.
      Services.obs.notifyObservers(null, lazy.TorProviderTopics.HasWarnOrErr);
    }
  },
};
+17 −1
Original line number Diff line number Diff line
@@ -141,9 +141,18 @@ export class TorProcess {
      this.#status = TorProcessStatus.Exited;
      this.#subprocess = null;
      logger.error("startTor error:", e);
      lazy.TorLauncherUtil.log(
        "PARENT-ERR",
        "Failed to start a tor process (more information in the browser console)."
      );
      throw e;
    }

    lazy.TorLauncherUtil.log(
      "PARENT-INFO",
      `New tor process started with pid ${this.#subprocess.pid}.`
    );

    // Do not await the following functions, as they will return only when the
    // process exits.
    this.#dumpStdout();
@@ -189,8 +198,15 @@ export class TorProcess {
      const { exitCode } = await watched.wait();
      processExitCode = exitCode;

      lazy.TorLauncherUtil.log(
        exitCode !== 0 ? "PARENT-WARN" : "PARENT-INFO",
        `The tor process with pid ${this.#subprocess.pid} exited with code ${exitCode}.`
      );

      if (watched !== this.#subprocess) {
        logger.debug(`A Tor process exited with code ${exitCode}.`);
        logger.debug(
          `The tor process ${watched.pid} exited with code ${exitCode}.`
        );
      } else if (exitCode) {
        logger.warn(`The watched Tor process exited with code ${exitCode}.`);
      } else {
+22 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ const lazy = {};

ChromeUtils.defineESModuleGetters(lazy, {
  EventDispatcher: "resource://gre/modules/Messaging.sys.mjs",
  TorLauncherUtil: "resource://gre/modules/TorLauncherUtil.sys.mjs",
});

const logger = console.createInstance({
@@ -107,6 +108,27 @@ export class TorProcessAndroid {
  }

  onEvent(event, data, _callback) {
    switch (event) {
      case TorIncomingEvents.started:
        lazy.TorLauncherUtil.log(
          "PARENT-INFO",
          `New tor process with handle ${data.handle} started.`
        );
        break;
      case TorIncomingEvents.startFailed:
        lazy.TorLauncherUtil.log(
          "PARENT-ERR",
          `Failed to start a tor process: ${data.error}`
        );
        break;
      case TorIncomingEvents.exited:
        lazy.TorLauncherUtil.log(
          data.status !== 0 ? "PARENT-WARN" : "PARENT-INFO",
          `The tor process with handle ${data.handle} exited with status ${data.status}.`
        );
        break;
    }

    if (data?.handle !== this.#processHandle) {
      logger.debug(`Ignoring event ${event} with another handle`, data);
      return;
+8 −15
Original line number Diff line number Diff line
@@ -207,8 +207,15 @@ export class TorProvider {
      await this.#firstConnection();
    } catch (e) {
      logger.error("Cannot connect to the control port", e);
      // Log this also to the UI, as getting console logs from Android
      // makes troubleshooting more difficult and involved.
      TorLauncherUtil.log(
        "PARENT-ERR",
        `Connection to the control port failed: ${e.message}.`
      );
      throw e;
    }
    TorLauncherUtil.log("PARENT-INFO", "Connected to the control port.", false);

    if (this.ownsTorDaemon) {
      try {
@@ -1021,21 +1028,7 @@ export class TorProvider {
   * @param {string} msg The message
   */
  onLogMessage(type, msg) {
    if (type === "WARN" || type === "ERR") {
      // Notify so that Copy Log can be enabled.
      Services.obs.notifyObservers(null, TorProviderTopics.HasWarnOrErr);
    }

    const timestamp = new Date()
      .toISOString()
      .replace("T", " ")
      .replace("Z", "");

    Services.obs.notifyObservers(
      { type, msg, timestamp },
      TorProviderTopics.TorLog
    );

    TorLauncherUtil.log(type, msg);
    switch (type) {
      case "ERR":
        logger.error(`[Tor error] ${msg}`);