diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f2b5920 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.pyz +torparse/* diff --git a/src/tor_relay_scanner/scanner.py b/src/tor_relay_scanner/scanner.py index 76a5a50..334e9ed 100644 --- a/src/tor_relay_scanner/scanner.py +++ b/src/tor_relay_scanner/scanner.py @@ -4,14 +4,13 @@ import asyncio import random import sys import urllib.parse - +import argparse import requests -TIMEOUT = 10.0 - +DESCRIPTION = "Downloads all Tor Relay IP addresses from onionoo.torproject.org and checks whether random Relays are available." class TCPSocketConnectChecker: - def __init__(self, host, port, timeout=TIMEOUT): + def __init__(self, host, port, timeout=10.0): self.host = host self.port = port self.timeout = timeout @@ -26,7 +25,7 @@ class TCPSocketConnectChecker: try: # Open connection reader, writer = await asyncio.wait_for( - asyncio.open_connection(self.host, self.port), TIMEOUT) + asyncio.open_connection(self.host, self.port), self.timeout) # And close it writer.close() await writer.wait_closed() @@ -36,10 +35,12 @@ class TCPSocketConnectChecker: self.connection_status = False return (False, e) - class TorRelayGrabber: + def __init__(self, timeout=10.0): + self.timeout = timeout + def _grab(self, url): - with requests.get(url, timeout=int(TIMEOUT)) as r: + with requests.get(url, timeout=int(self.timeout)) as r: return r.json() def grab(self): @@ -105,14 +106,15 @@ class TorRelay: return bool(self.reachable) -async def main_async(): - NUM_RELAYS = 30 - WORKING_RELAY_NUM_GOAL = 5 +async def main_async(args): + NUM_RELAYS = args.num_relays + WORKING_RELAY_NUM_GOAL = args.working_relay_num_goal + TIMEOUT = args.timeout print(f"Tor Relay Scanner. Will scan up to {WORKING_RELAY_NUM_GOAL}" + " working relays (or till the end)", file=sys.stderr) print("Downloading Tor Relay information from onionoo.torproject.org…", file=sys.stderr) - relays = TorRelayGrabber().grab_parse() + relays = TorRelayGrabber(timeout=TIMEOUT).grab_parse() print("Done!", file=sys.stderr) random.shuffle(relays) @@ -164,4 +166,9 @@ async def main_async(): def main(): - asyncio.run(main_async()) + parser = argparse.ArgumentParser(description=DESCRIPTION) + parser.add_argument('-n', type=int, dest='num_relays', nargs='?', default=30, help='The number of concurrent relays tested.') + parser.add_argument('-g', '--goal', type=int, dest='working_relay_num_goal', nargs='?', default=5, help='Test until at least this number of working relays are found') + parser.add_argument('--timeout', type=float, nargs='?', default=10.0, help='socket connection timeout') + args = parser.parse_args() + asyncio.run(main_async(args))