diff --git a/src/get-exit-nodes.js b/src/get-exit-nodes.js index 8278caa..16c31ed 100644 --- a/src/get-exit-nodes.js +++ b/src/get-exit-nodes.js @@ -39,9 +39,19 @@ class Logger { } } +function ip4ToInt(ipAddress) { + const parts = ipAddress.split('.'); + if (parts.length !== 4) { + throw new Error('Invalid IP address'); + } + const intIp = (+parts[0] << 24) + (+parts[1] << 16) + (+parts[2] << 8) + (+parts[3]); + return intIp >>> 0; // Ensure unsigned 32-bit integer +} + (async function main(args) { try { - const ip_only = args[0] === '--ip-only'; + const ip4_only = args[0] === '--ip4-only'; + const ip6_only = args[0] === '--ip6-only'; const logger = new Logger(); const home = process.env.HOME || process.env.USERPROFILE; const app_cache_path = path.join(home, '.cache', 'mini-tor-js'); @@ -55,10 +65,27 @@ class Logger { const routers = consensus.get_onion_routers_by_criteria({ flags: OR.valid | OR.exit }); + const ips_v4 = new Set(); + const ips_v6 = new Set(); for (const router of routers) { - if (ip_only) console.log(router.ip); + if (ip4_only) ips_v4.add(router.ip) + else if (ip6_only) { + router.ip_v6 && ips_v6.add(router.ip_v6); + } else console.log(router.name, router.ip, router.dir_port, router.or_port); } + if (ip4_only) { + const ips = [...ips_v4].sort((a, b) => ip4ToInt(a) - ip4ToInt(b)); + for (const ip of ips) { + console.log(ip); + } + } + if (ip6_only) { + const ips = [...ips_v6].sort((a, b) => a < b ? -1 : 1); + for (const ip of ips) { + console.log(ip); + } + } } catch (error) { console.error(error); } diff --git a/src/tor/Consensus.js b/src/tor/Consensus.js index d777c0b..857e2a1 100644 --- a/src/tor/Consensus.js +++ b/src/tor/Consensus.js @@ -257,6 +257,11 @@ class Consensus { } current_router.flags = flags; break; + case 'a': + const r = /\[([^\[]+)]:(\d+)$/; + const m = r.exec(parts[1]); + current_router.ip_v6 = m[1]; + break; case 'directory-footer': return; } diff --git a/src/tor/OnionRouter.js b/src/tor/OnionRouter.js index 6d9d734..a3a91f8 100644 --- a/src/tor/OnionRouter.js +++ b/src/tor/OnionRouter.js @@ -18,6 +18,7 @@ class OnionRouter { _consensus = null; _nickname = ''; _ip = ''; + _ip_v6 = ''; _or_port = 0; _dir_port = 0; /** @type Buffer */ @@ -42,6 +43,8 @@ class OnionRouter { get consensus() { return this._consensus; } get name() { return this._nickname; } get ip() { return this._ip; } + get ip_v6() { return this._ip_v6; } + set ip_v6(value) { this._ip_v6 = value; } get flags() { return this._flags; } get or_port() { return this._or_port; } get dir_port() { return this._dir_port; }