Search code examples
pythonnetworkingtorstem

Sending a signal to stem closes the socket


This code:

from stem import Signal
from stem.control import Controller

with Controller.from_port(port=9051) as controller:
    print('is alive BEFORE ? ')
    print(controller.is_alive())
    try:
        controller.signal(Signal.HEARTBEAT)
    except Exception as e:
        print(e)
    print('is alive AFTER ? ')
    print(controller.is_alive())

with Controller.from_port(port=9051) as controller:
    print('is alive 2 ? ')
    print(controller.is_alive())

produces this output:

is alive BEFORE ?
True
SIGNAL response contained unrecognized status code: 514
is alive AFTER ?
False
is alive 2 ?
True

and no heartbeat is logged. Also if I try to make a request to tor after sending the signal I get: [stem] INFO: Error while receiving a control message (SocketClosed): empty socket content

Tor configuration is: SocksPort 9050 ControlPort 9051


Solution

  • The 514 error means Authentication required.

    After connecting, the first thing you must do is authenticate:

    with Controller.from_port(port=9051) as controller:
        print('is alive BEFORE ? ')
        print(controller.is_alive())
        controller.authenticate()
        ...
    

    Also note, Tor closes the connection afer an authentication failure. See the control spec section 3.5 for more info.

    The first stem example goes into these basics in more detail: https://stem.torproject.org/tutorials/the_little_relay_that_could.html