Skip to content
Permalink
Browse files
Bug 14937: Show meek bridge in tor circuit display
  • Loading branch information
arthuredelstein committed Mar 17, 2015
1 parent bf2ee7e commit 7653f8e44e7800915563b622c4a5ef6931db4d23
Showing with 59 additions and 19 deletions.
  1. +36 −17 src/chrome/content/tor-circuit-display.js
  2. +23 −2 src/modules/tor-control-port.js
@@ -53,12 +53,29 @@ let trimQuotes = s => s ? s.match(/^\"(.*)\"$/)[1] : undefined;
// Gets the bridge parameters for a given node ID. If the node
// is not currently used as a bridge, returns null.
let getBridge = function* (controller, id) {
let bridges = yield controller.getConf("bridge");
let bridges = yield controller.getConf("bridge"),
descriptorAnnotations;
try {
descriptorAnnotations = yield controller.getInfo("desc-annotations/id/" + id);
// We may get an error if there are no annotations for this node; ignore.
} catch (e) { }
if (bridges) {
for (let bridge of bridges) {
if (bridge.ID && bridge.ID.toUpperCase() === id.toUpperCase()) {
return bridge;
}
// In the case of meek, we don't have an ID (fingerprint) in the
// bridge line in the configuration, but we can match the dummy
// IP address meek supplies to its "@source" in the descriptor
// annotation. May work for other bridges too.
if (!bridge.ID &&
descriptorAnnotations &&
bridge.address &&
bridge.address.split(":")[0] === descriptorAnnotations.source &&
descriptorAnnotations.purpose === "bridge") {
bridge.ID = id;
return bridge;
}
}
}
return null;
@@ -89,7 +106,8 @@ let nodeDataForID = function* (controller, id) {
if (result.ip) {
// Get the country code for the node's IP address.
try {
result.countryCode = yield controller.getInfo("ip-to-country/" + result.ip);
let countryCode = yield controller.getInfo("ip-to-country/" + result.ip);
result.countryCode = countryCode === "??" ? null : countryCode;
} catch (e) { }
}
return result;
@@ -190,22 +208,23 @@ let showCircuitDisplay = function (show) {
let nodeLines = function (nodeData) {
let result = [];
for (let {ip, countryCode, type, bridgeType} of nodeData) {
let bridge = type === "bridge";
let bridge = type === "bridge",
country = countryCode ? localizedCountryNameFromCode(countryCode) : null;
result.push(
// For each relay, show its apparent host country.
(countryCode ? localizedCountryNameFromCode(countryCode)
: uiString("unknown_country")) +
(bridge ?
// As we have a bridge, don't show the IP address
// but show the bridge type.
" (" + uiString("tor_bridge") +
((bridgeType !== "vanilla") ? (": " + bridgeType) : "") + ")"
:
// As we don't have a bridge, show the IP address
// of the node. Use unicode escapes to ensure that
// parentheses behave properly in both left-to-right
// and right-to-left languages.
" ‭ (" + (ip || uiString("ip_unknown")) + ")‬"));
bridge ?
// As we have a bridge, don't show the IP address
// but show the bridge type.
(uiString("tor_bridge") +
((bridgeType !== "vanilla") ? (": " + bridgeType) : "") +
(country ? " (" + country + ")" : ""))
:
// For each non-bridge relay, show its host country and IP.
(country || uiString("unknown_country")) +
// As we don't have a bridge, show the IP address
// of the node. Use unicode escapes to ensure that
// parentheses behave properly in both left-to-right
// and right-to-left languages.
" ‭ (" + (ip || uiString("ip_unknown")) + ")‬" );
}
return result;
};
@@ -480,12 +480,32 @@ info.bridgeParser = function(bridgeLine) {
.indexOf(result.type) >= 0) {
[result.address, result.ID] = tokens.slice(1);
} else if (result.type === "meek") {
// do nothing for now
result.address = tokens[1];
}
}
return result.type ? result : null;
};

// __info.descriptorAnnotationsParser(annotationsText)__
// Parses the results from a "desc-annotations/id/*" query.
// Takes multiple lines of annotations, that look something like
// @downloaded-at 2015-03-17 04:16:27
// @source "0.0.2.0"
// @purpose bridge
// And returns a map, like { "downloaded-at", "2015-03-17 04:16:27" ...}.
info.descriptorAnnotationsParser = function (annotationsText) {
let result = {};
utils.splitLines(annotationsText).map(function(line) {
let [name, value] = utils.splitAtFirst(line, /\s/);
if (name && name.startsWith("@")) {
// Remove surrounding whitespace and quotation marks, if present.
let valueTrimmed = value.trim().match(/^\"?(.*?)\"?$|(.*)/)[1];
result[name.substring(1)] = valueTrimmed;
}
});
return result;
};

// __info.parsers__.
// A map of GETINFO and GETCONF keys to parsing function, which convert
// result strings to JavaScript data.
@@ -499,7 +519,8 @@ info.parsers = {
"ip-to-country/" : utils.identity,
"circuit-status" : info.applyPerLine(info.circuitStatusParser),
"stream-status" : info.applyPerLine(info.streamStatusParser),
"bridge" : info.bridgeParser
"bridge" : info.bridgeParser,
"desc-annotations/id/" : info.descriptorAnnotationsParser,
};

// __info.getParser(key)__.

0 comments on commit 7653f8e

Please sign in to comment.