# Tracking and Changing Live Tor State

## TorState

class txtorcon.TorState(protocol, bootstrap=True)

  This tracks the current state of Tor using a TorControlProtocol.

  On setup it first queries the initial state of streams and circuits. It then asks for updates via the listeners. It requires an ITorControlProtocol instance. The control protocol doesn’t need to be bootstrapped yet. The Deferred .post_boostrap is driggered when the TorState instance is fully ready to go. The easiest way is to use the helper method `txtorcon.build_tor_connection()`. For details, see the implementation of that.

  You may add an `txtorcon.interface.IStreamAttacher` to provide a custom mapping for Strams to Circuits (by default Tor picks by itself).

  This is also a good example of the various listeners, and acts as an `txtorcon.interface.ICircuitContainer` and `txtorcon.interface.IRouterContainer`.

  Variables:

    DO_NOT_ATTACH – Constant to return from an IAttacher indicating you don’t want to attach this stream at all.

## Circuit

class txtorcon.Circuit(routercontainer)

  Used by `txtorcon.TorState` to represent one of Tor’s circuits.

  This is kept up-to-date by the :class`txtorcon.TorState` that owns it, and individual circuits can be listened to for updates (or listen to every one using `txtorcon.TorState.add_circuit_listener()`)

  Variables:

    - path – contains a list of `txtorcon.Router` objects representing the path this Circuit takes. Mostly this will be 3 or 4 routers long. Note that internally Tor uses single-hop paths for some things. See also the purpose instance-variable.

    - streams – contains a list of Stream objects representing all streams currently attached to this circuit.

    - state –

      contains a string from Tor describing the current state of the stream. From control-spec.txt section 4.1.1, these are:

      > - LAUNCHED: circuit ID assigned to new circuit

      > - BUILT: all hops finished, can now accept streams

      > - EXTENDED: one more hop has been completed

      > - FAILED: circuit closed (was not built)

      > - CLOSED: circuit closed (was built)

    - purpose –

      The reason this circuit was built. For most purposes, you’ll want to look at GENERAL circuits only. Values can currently be one of (but see control-spec.txt 4.1.1):

      > - GENERAL

      > - HS_CLIENT_INTRO

      > - HS_CLIENT_REND

      > - HS_SERVICE_INTRO

      > - HS_SERVICE_REND

      > - TESTING

      > - CONTROLLER

    - id – The ID of this circuit, a number (or None if unset).

  Parameters:

    routercontainer – should implement `txtorcon.interface.IRouterContainer`.

## Stream

class txtorcon.Stream(circuitcontainer, addrmap=None)

  Represents an active stream in Tor’s state (`txtorcon.TorState`).

  Variables:

    - circuit – Streams will generally be attached to circuits pretty quickly. If they are attached, circuit will be a `txtorcon.Circuit` instance or None if this stream isn’t yet attached to a circuit.

    - state –

      Tor’s idea of the stream’s state, one of:

        - NEW: New request to connect

        - NEWRESOLVE: New request to resolve an address

        - REMAP: Address re-mapped to another

        - SENTCONNECT: Sent a connect cell along a circuit

        - SENTRESOLVE: Sent a resolve cell along a circuit

        - SUCCEEDED: Received a reply; stream established

        - FAILED: Stream failed and not retriable

        - CLOSED: Stream closed

        - DETACHED: Detached from circuit; still retriable

    - target_host – Something like www.example.com – the host the stream is destined for.

    - target_port – The port the stream will exit to.

    - target_addr – Target address, looked up (usually) by Tor (e.g. 127.0.0.1).

    - id – The ID of this stream, a number (or None if unset).

  Parameters:

    circuitcontainer – an object which implements `interface.ICircuitContainer`

## Router

class txtorcon.Router(controller)

  Represents a Tor Router, including location.

  The controller you pass in is really only used to do get_info calls for ip-to-country/IP in case the `txtorcon.util.NetLocation` stuff fails to find a country.

  After an .update() call, the id_hex attribute contains a hex-encoded long hash (suitable, for example, to use in a `GETINFO ns/id/*` call).

  After setting the policy property you may call accepts_port() to find out if the router will accept a given port. This works with the reject or accept based policies.