diff options
Diffstat (limited to 'cli/onionshare_cli/onion.py')
-rw-r--r-- | cli/onionshare_cli/onion.py | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/cli/onionshare_cli/onion.py b/cli/onionshare_cli/onion.py index aa057b12..7c9d0a67 100644 --- a/cli/onionshare_cli/onion.py +++ b/cli/onionshare_cli/onion.py @@ -169,6 +169,9 @@ class Onion(object): # Assigned later if we are using stealth mode self.auth_string = None + # Keep track of onions where it's important to gracefully close to prevent truncated downloads + self.graceful_close_onions = [] + def connect( self, custom_settings=None, @@ -600,7 +603,7 @@ class Onion(object): else: return False - def start_onion_service(self, mode_settings, port, await_publication): + def start_onion_service(self, mode, mode_settings, port, await_publication): """ Start a onion service on port 80, pointing to the given port, and return the onion hostname. @@ -678,6 +681,10 @@ class Onion(object): onion_host = res.service_id + ".onion" + # Gracefully close share mode rendezvous circuits + if mode == "share": + self.graceful_close_onions.append(res.service_id) + # Save the service_id mode_settings.set("general", "service_id", res.service_id) @@ -709,7 +716,7 @@ class Onion(object): "Onion", "stop_onion_service", f"failed to remove {onion_host}" ) - def cleanup(self, stop_tor=True): + def cleanup(self, stop_tor=True, wait=True): """ Stop onion services that were created earlier. If there's a tor subprocess running, kill it. """ @@ -736,6 +743,46 @@ class Onion(object): if stop_tor: # Stop tor process if self.tor_proc: + if wait: + # Wait for Tor rendezvous circuits to close + # Catch exceptions to prevent crash on Ctrl-C + try: + rendevouz_circuit_ids = [] + for c in self.c.get_circuits(): + if ( + c.purpose == "HS_SERVICE_REND" + and c.rend_query in self.graceful_close_onions + ): + rendevouz_circuit_ids.append(c.id) + + symbols = [c for c in "\\|/-"] + symbols_i = 0 + + while True: + num_rend_circuits = 0 + for c in self.c.get_circuits(): + if c.id in rendevouz_circuit_ids: + num_rend_circuits += 1 + + if num_rend_circuits == 0: + print( + "\rTor rendezvous circuits have closed" + " " * 20 + ) + break + + if num_rend_circuits == 1: + circuits = "circuit" + else: + circuits = "circuits" + print( + f"\rWaiting for {num_rend_circuits} Tor rendezvous {circuits} to close {symbols[symbols_i]} ", + end="", + ) + symbols_i = (symbols_i + 1) % len(symbols) + time.sleep(1) + except: + pass + self.tor_proc.terminate() time.sleep(0.2) if self.tor_proc.poll() is None: |