commit bf12640cca3e758a565cb3f9f5a2ad8a5f22bb92 Author: Illia Volochii illia.volochii@gmail.com Date: Mon Nov 1 20:20:40 2021 +0200
Bug 14939: Support IPv6 addresses in Tor Circuit Display
Fix the visualization of bridge addresses when using IPv6, and display both IPv4 and IPv6 addresses on normal relays. --- chrome/content/tor-circuit-display.js | 39 ++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 14 deletions(-)
diff --git a/chrome/content/tor-circuit-display.js b/chrome/content/tor-circuit-display.js index d6034384..440e9de9 100644 --- a/chrome/content/tor-circuit-display.js +++ b/chrome/content/tor-circuit-display.js @@ -70,38 +70,49 @@ let getBridge = async function (controller, id) { };
// nodeDataForID(controller, id)__. -// Returns the type, IP and country code of a node with given ID. +// Returns the type, IP addresses and country code of a node with given ID. // Example: `nodeDataForID(controller, "20BC91DC525C3DC9974B29FBEAB51230DE024C44")` -// => `{ type : "default", ip : "12.23.34.45", countryCode : "fr" }` +// => `{ type: "default", ipAddrs: ["12.23.34.45", "2001:db8::"], countryCode: "fr" }` let nodeDataForID = async function (controller, id) { - let result = {}, - bridge = await getBridge(controller, id); // type, ip, countryCode; + let result = {ipAddrs: []}; + const bridge = await getBridge(controller, id); // type, ip, countryCode; + const addrRe = /^[?([^]]+)]?:\d+$/ if (bridge) { result.type = "bridge"; result.bridgeType = bridge.type; // Attempt to get an IP address from bridge address string. try { - result.ip = bridge.address.split(":")[0]; - } catch (e) { } + const ip = bridge.address.match(addrRe)[1]; + if (!ip.startsWith("0.")) { + result.ipAddrs = [ip]; + } + } catch (e) { + } } else { // either dealing with a relay, or a bridge whose fingerprint is not saved in torrc try { - let statusMap = await controller.getInfo("ns/id/" + id); + const statusMap = await controller.getInfo("ns/id/" + id); result.type = "default"; - result.ip = statusMap.IP; + if (!statusMap.IP.startsWith("0.")) { + result.ipAddrs.push(statusMap.IP); + } + try { + result.ipAddrs.push(statusMap.IPv6.match(addrRe)[1]); + } catch (e) { + } } catch (e) { // getInfo will throw if the given id is not a relay // this probably means we are dealing with a user-provided bridge with no fingerprint result.type = "bridge"; - // we don't know the ip or type, so leave blank - result.ip = ""; + // we don't know the ip/ipv6 or type, so leave blank + result.ipAddrs = []; result.bridgeType = ""; } } - if (result.ip) { + if (result.ipAddrs.length) { // Get the country code for the node's IP address. try { - let countryCode = await controller.getInfo("ip-to-country/" + result.ip); + const countryCode = await controller.getInfo("ip-to-country/" + result.ipAddrs[0]); result.countryCode = countryCode === "??" ? null : countryCode; } catch (e) { } } @@ -305,8 +316,8 @@ let updateCircuitDisplay = function () { } else if (nodeData[i].type == "default") { relayText = localizedCountryNameFromCode(nodeData[i].countryCode); } - let ip = nodeData[i].ip.startsWith("0.") ? "" : nodeData[i].ip; - li(relayText, " ", ["span", { class: "circuit-ip-address" }, ip], " ", + const ipAddrs = nodeData[i].ipAddrs.join(", "); + li(relayText, " ", ["span", { class: "circuit-ip-address" }, ipAddrs], " ", (i === 0 && nodeData[0].type !== "bridge") ? ["span", { class: "circuit-guard-info" }, uiString("guard")] : null); }