flashflow.cmd package


flashflow.cmd.ctrl module


Add the cmd line options for this FlashFlow command

Return type


flashflow.cmd.ctrl.main(args, conf)
Return type


flashflow.cmd.measurer module

class flashflow.cmd.measurer.CoordConnRes

Bases: enum.Enum

Part of the return value of try_connect_to_coord().


We were not successful, and trying again in the future is extremely unlikely to be successful. We should give up.


We were not successful, but whatever happened may be temporary and it’s logical to try connecting again in the future.


We successfully connected to the coord, shook our TLS hands, and all is well.

class flashflow.cmd.measurer.CoordProtocol

Bases: asyncio.protocols.Protocol


Called when the connection is lost or closed.

The argument is an exception object or None (the latter meaning a regular EOF is received or the connection was aborted or closed).


Called when a connection is made.

The argument is the transport representing the pipe connection. To receive data, wait for data_received() calls. When the connection is closed, connection_lost() is called.


Receive data from the coordinator. Parse it into a FFMsg and tell other code about the message.

It’s possible that this is called before the entire message is received. In that case, we’ll need to edit this function to buffer bytes until the entire message has arrived.

transport = None
class flashflow.cmd.measurer.Measurement(connect_msg)

Bases: object

State related to a single measurement.

property alloc_bw

The amount of bandwidth, in bytes/second, the client should allocate for this measurement

Return type


bad_circs: Set[int] = None

Our circuit ids that we’ve been told have CLOSED or FAILED at any point

circs: Set[int] = None

Our circuit ids with the relay. Filled in once we know what they are (they’re launched) but not yet bullt

connect_msg: msg.ConnectToRelay = None

keep a copy of flashflow.msg.ConnectToRelay command so we can send it back to the coord when we’re ready to go (or have failed)

property meas_duration

The duration, in seconds, that active measurement should last.

Return type


property meas_id

The measurement ID

Return type


ready_circs: Set[int] = None

Our built circuit ids with the relay. Filled in as we learn of launched circuits becoming built.

property relay_fp

The fingerprint of the relay to measure

Return type


property waiting_circs

Circs that we have LAUNCHED but have not yet added to ready_circs because we haven’t seen BUILT yet.

Note that as far as this function is concerned, there’s no such thing as a circuit becoming un-BUILT. This functiion doesn’t know anything about circuits closing. Other code needs to manipulate circs and ready_circs as it deems fit.

Return type


class flashflow.cmd.measurer.State

Bases: object

Global state for the measurer process

coord_proto: CoordProtocol = None

how we communicate with the coord

coord_trans: asyncio.WriteTransport = None

how we communicate with the coord

measurements: Dict[int, Measurement] = None

state specific to each measurement, obviously

tor_client: Controller = None

Our Tor client, set in main


Cleanup all of the State object while being very careful to not allow any exceptions to bubble up. Use this when in an error state and you want to cleanup before starting over or just dying.


End execution of the program.

async flashflow.cmd.measurer.ensure_conn_w_coord(conf, delay)

Repeatedly try connecting to the coordinator until we are successful or have a fatal error warranting completely giving up on life.

This function uses asynchronous python: the connection is represented by a transport and protocol, and we try connecting asynchronously and use a callback to find out the result. That said, the work done here should probably be the only thing going on.

Return type

Tuple[bool, Union[Tuple[BaseTransport, BaseProtocol], str]]


Create a Tor client, connect to its control socket, authenticate, and return the Controller. On success, return True and the controller. Otherwise return False and an operator-meaningful error message.


Add the cmd line options for this FlashFlow command

Return type


flashflow.cmd.measurer.main(args, conf)
Return type



Called from stem to tell us about circuit events.

We are currently in a different thread. We tell the main thread’s loop (in a threadsafe manner) to handle this event.


Called from stem to tell us about FF_MEAS events.

We are currently in a different thread. We tell the main thread’s loop (in a threadsafe manner) to handle this event.

async flashflow.cmd.measurer.try_connect_to_coord(addr_port, our_key, coord_cert)

Try to connect to the coordinator at the given (host, port) tuple. Perform the TLS handshake using our client TLS key in the file our_key and only trusting the coord server cert in the file coord_cert.

Returns a tuple in all cases. The first item indicates success with CoordConnRes. If it is an *_ERROR, then the second item is a string with more details. If it is SUCCESS, then the second item is the transport and protocol with the coordinator.

This function is a coroutine and all exceptions should be handled within this function’s body. If they aren’t, that’s a programming error.

Return type

Tuple[CoordConnRes, Union[str, Tuple[BaseTransport, BaseProtocol]]]

Module contents