3

I'm currently experimenting with Tor via the Stem python lib and using process.launch_tor_with_config() with a pool of processes, each using a different Control Port.

However as I increase pool size from 3 and above I'm seeing multiple OSError: Process terminated: No, it's still there. Exiting stack traces. Each process in the pool connects, sends out a HTTP request and terminates the connection, going on to the next request.

Is there a max number of concurrent connections or is the terminate killing more than a single tor connection?

  • Can you post the code you're using? Is there a particular reason you need more than one tor process? Wouldn't passing all the traffic through the same instance work as well? – Peter Gerber Apr 1 '17 at 22:53
0

The issue appears to be that the DataDirectory is ~/.tor by default. It contains a lock file, which is why stem believes that Tor is already running.

You can change the DataDirectory like this:

process.launch_tor_with_config({…, 'DataDirectory': '~/.tor/custom1'})

I recommend that you run only one Tor instance, reducing complexity and resource use. The only reason I can think of why that you would want multiple instances is if you wanted to be sure that a different circuit is used for every connection. If you want that, you can simply set a different proxy password for every connection. As far as I know, Tor Browser still uses this technique to get a different circuit for every first party domain.

Here is a short example:

import itertools
from stem import process
import requests

with process.launch_tor_with_config({'ControlPort': '3421', 'SocksPort': '3420'}) as tor:
    session = requests.session()

    def receive(password):
        proxies = {
            'http': 'socks5://user:{}@localhost:3420'.format(password),
            'https': 'socks5://user:{}@localhost:3420'.format(password)
        }
        return session.get('https://ipinfo.io', proxies=proxies)

    print('== use 10 different circuits ==')
    for response in map(receive, range(10)):
        print(response.json()['ip'])
    print()

    print('== use 10 times same circuit (same password, same circuit) ==')
    for response in map(receive, itertools.repeat('secret', 10)):
        print(response.json()['ip'])

    tor.terminate()

How many local concurrent Tor connections can I run?

I'm not sure if there is a limit for clients. There probably is a limit per guard node. This usually shouldn't be an issue though since a guard won't know anything about the connections you have made to the other guards. So, if a guard is randomly picked, you shouldn't be able hit the limit easily.

If you're running a relay, the limit is 2 per IP.

  • While I'm here @P. Gerber, what is the difference between process terminate & kill? – user1561108 Apr 2 '17 at 10:42
  • 1
    Terminate sends signal SIGTERM to the process in which case Tor, according to its manpage, does this: "Tor will catch this, clean up and sync to disk if necessary, and exit." If it gets killed, the process seizes to exist without Tor having a change to do any clean-up work. You probably want to make sure caches are written to disk, so they can be reused on the next start. If so, use terminate. – Peter Gerber Apr 2 '17 at 11:05
  • Mentioned code doesn't work. Tested with requests, the get is never completed, hangs forever; and also Selenium/Chrome, displays a "Page cannot be reached" error. – Veehmot Aug 29 '17 at 11:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.