|
@@ -86,8 +86,11 @@ class ExperimentController:
|
|
self.connection = stem.control.Controller.from_port(address=self.control_address[0], port=self.control_address[1])
|
|
self.connection = stem.control.Controller.from_port(address=self.control_address[0], port=self.control_address[1])
|
|
self.connection.authenticate()
|
|
self.connection.authenticate()
|
|
#
|
|
#
|
|
- self.connection.add_event_listener(self._attach_stream, stem.control.EventType.STREAM)
|
|
|
|
|
|
+ self.connection.add_event_listener(self.stream_event, stem.control.EventType.STREAM)
|
|
|
|
+ self.connection.add_event_listener(self.circuit_event, stem.control.EventType.CIRC)
|
|
self.connection.set_conf('__LeaveStreamsUnattached', '1')
|
|
self.connection.set_conf('__LeaveStreamsUnattached', '1')
|
|
|
|
+ #self.connection.set_conf('__DisablePredictedCircuits', '1')
|
|
|
|
+ # we still need to generate circuits for things like directory fetches
|
|
#
|
|
#
|
|
def disconnect(self):
|
|
def disconnect(self):
|
|
#if len(self.unused_circuit_ids) > 0:
|
|
#if len(self.unused_circuit_ids) > 0:
|
|
@@ -104,53 +107,80 @@ class ExperimentController:
|
|
self.assigned_streams[from_address] = circuit_id
|
|
self.assigned_streams[from_address] = circuit_id
|
|
return circuit_id
|
|
return circuit_id
|
|
#
|
|
#
|
|
- def _attach_stream(self, stream):
|
|
|
|
|
|
+ def stream_event(self, stream):
|
|
try:
|
|
try:
|
|
if stream.status == 'NEW':
|
|
if stream.status == 'NEW':
|
|
# by default, let tor handle new streams
|
|
# by default, let tor handle new streams
|
|
circuit_id = 0
|
|
circuit_id = 0
|
|
#
|
|
#
|
|
if stream.purpose == 'USER':
|
|
if stream.purpose == 'USER':
|
|
|
|
+ # NOTE: we used to try to attach all streams (including non-user streams,
|
|
|
|
+ # which we attached to circuit 0, but Stem was found to hang sometimes
|
|
|
|
+ # when attaching DIR_FETCH streams, so now we only attach user streams
|
|
|
|
+ # and let tor take care of other streams
|
|
|
|
+ #
|
|
# this is probably one of our streams (although not guaranteed)
|
|
# this is probably one of our streams (although not guaranteed)
|
|
circuit_id = self.assigned_streams[(stream.source_address, stream.source_port)]
|
|
circuit_id = self.assigned_streams[(stream.source_address, stream.source_port)]
|
|
- #
|
|
|
|
- try:
|
|
|
|
- self.connection.attach_stream(stream.id, circuit_id)
|
|
|
|
- #logging.debug('Attaching to circuit {}'.format(circuit_id))
|
|
|
|
- except stem.InvalidRequest:
|
|
|
|
- if stream.purpose != 'USER':
|
|
|
|
- # could not attach a non-user stream, ignoring
|
|
|
|
- pass
|
|
|
|
- else:
|
|
|
|
- raise
|
|
|
|
#
|
|
#
|
|
- except stem.UnsatisfiableRequest:
|
|
|
|
- if stream.purpose != 'USER':
|
|
|
|
- # could not attach a non-user stream, so probably raised:
|
|
|
|
- # stem.UnsatisfiableRequest: Connection is not managed by controller.
|
|
|
|
- # therefore we should ignore this exception
|
|
|
|
- pass
|
|
|
|
- else:
|
|
|
|
- raise
|
|
|
|
|
|
+ try:
|
|
|
|
+ logging.debug('Attaching to circuit {}'.format(circuit_id))
|
|
|
|
+ self.connection.attach_stream(stream.id, circuit_id)
|
|
|
|
+ logging.debug('Attached to circuit {}'.format(circuit_id))
|
|
|
|
+ except stem.InvalidRequest:
|
|
|
|
+ if stream.purpose != 'USER':
|
|
|
|
+ # could not attach a non-user stream, ignoring
|
|
|
|
+ pass
|
|
|
|
+ else:
|
|
|
|
+ raise
|
|
|
|
+ #
|
|
|
|
+ except stem.UnsatisfiableRequest:
|
|
|
|
+ if stream.purpose != 'USER':
|
|
|
|
+ # could not attach a non-user stream, so probably raised:
|
|
|
|
+ # stem.UnsatisfiableRequest: Connection is not managed by controller.
|
|
|
|
+ # therefore we should ignore this exception
|
|
|
|
+ pass
|
|
|
|
+ else:
|
|
|
|
+ raise
|
|
|
|
+ #
|
|
|
|
+ except stem.SocketClosed:
|
|
|
|
+ logging.debug('Stream {} ({}, controller={}) {}: socket closed while attaching'.format(stream.id,
|
|
|
|
+ stream.purpose, self.control_address, stream.status))
|
|
|
|
+ raise
|
|
#
|
|
#
|
|
#
|
|
#
|
|
#
|
|
#
|
|
|
|
+ if stream.status == 'DETACHED' or stream.status == 'FAILED':
|
|
|
|
+ logging.debug('Stream {} ({}, controller={}) {}: {}; {}'.format(stream.id, stream.purpose, self.control_address,
|
|
|
|
+ stream.status, stream.reason, stream.remote_reason))
|
|
|
|
+ #
|
|
except:
|
|
except:
|
|
logging.exception('Error while attaching the stream.')
|
|
logging.exception('Error while attaching the stream.')
|
|
raise
|
|
raise
|
|
#
|
|
#
|
|
#
|
|
#
|
|
|
|
+ def circuit_event(self, circuit):
|
|
|
|
+ if circuit.purpose == 'CONTROLLER' and (circuit.status == 'FAILED' or circuit.status == 'CLOSED'):
|
|
|
|
+ logging.debug('Circuit {} ({}, controller={}) {}: {}; {}'.format(circuit.id, circuit.purpose, self.control_address,
|
|
|
|
+ circuit.status, circuit.reason, circuit.remote_reason))
|
|
|
|
+ #
|
|
|
|
+ #
|
|
def build_circuit(self, circuit_generator, gen_id):
|
|
def build_circuit(self, circuit_generator, gen_id):
|
|
circuit_id = None
|
|
circuit_id = None
|
|
|
|
+ tries_remaining = 5
|
|
#
|
|
#
|
|
- while circuit_id is None:
|
|
|
|
|
|
+ while circuit_id is None and tries_remaining > 0:
|
|
try:
|
|
try:
|
|
circuit = circuit_generator(gen_id)
|
|
circuit = circuit_generator(gen_id)
|
|
- circuit_id = self.connection.new_circuit(circuit, await_build=True)
|
|
|
|
- logging.debug('New circuit (id={}, controller={}): {}'.format(circuit_id, self.control_address, circuit))
|
|
|
|
|
|
+ tries_remaining -= 1
|
|
|
|
+ circuit_id = self.connection.new_circuit(circuit, await_build=True, purpose='controller', timeout=10)
|
|
|
|
+ logging.debug('New circuit (circ_id={}, controller={}): {}'.format(circuit_id, self.control_address, circuit))
|
|
except stem.CircuitExtensionFailed as e:
|
|
except stem.CircuitExtensionFailed as e:
|
|
wait_seconds = 1
|
|
wait_seconds = 1
|
|
logging.debug('Failed circuit: {}'.format(circuit))
|
|
logging.debug('Failed circuit: {}'.format(circuit))
|
|
|
|
+ if tries_remaining == 0:
|
|
|
|
+ logging.warning('Tried too many times')
|
|
|
|
+ raise
|
|
|
|
+ #
|
|
logging.warning('Circuit creation failed (CircuitExtensionFailed: {}). Retrying in {} second{}...'.format(str(e),
|
|
logging.warning('Circuit creation failed (CircuitExtensionFailed: {}). Retrying in {} second{}...'.format(str(e),
|
|
wait_seconds,
|
|
wait_seconds,
|
|
's' if wait_seconds != 1 else ''))
|
|
's' if wait_seconds != 1 else ''))
|
|
@@ -158,10 +188,25 @@ class ExperimentController:
|
|
except stem.InvalidRequest as e:
|
|
except stem.InvalidRequest as e:
|
|
wait_seconds = 15
|
|
wait_seconds = 15
|
|
logging.debug('Failed circuit: {}'.format(circuit))
|
|
logging.debug('Failed circuit: {}'.format(circuit))
|
|
|
|
+ if tries_remaining == 0:
|
|
|
|
+ logging.warning('Tried too many times')
|
|
|
|
+ raise
|
|
|
|
+ #
|
|
logging.warning('Circuit creation failed (InvalidRequest: {}). Retrying in {} second{}...'.format(str(e),
|
|
logging.warning('Circuit creation failed (InvalidRequest: {}). Retrying in {} second{}...'.format(str(e),
|
|
wait_seconds,
|
|
wait_seconds,
|
|
's' if wait_seconds != 1 else ''))
|
|
's' if wait_seconds != 1 else ''))
|
|
time.sleep(wait_seconds)
|
|
time.sleep(wait_seconds)
|
|
|
|
+ except stem.Timeout as e:
|
|
|
|
+ wait_seconds = 5
|
|
|
|
+ logging.debug('Failed circuit: {}'.format(circuit))
|
|
|
|
+ if tries_remaining == 0:
|
|
|
|
+ logging.warning('Tried too many times')
|
|
|
|
+ raise
|
|
|
|
+ #
|
|
|
|
+ logging.warning('Circuit creation timed out (Timeout: {}). Retrying in {} second{}...'.format(str(e),
|
|
|
|
+ wait_seconds,
|
|
|
|
+ 's' if wait_seconds != 1 else ''))
|
|
|
|
+ time.sleep(wait_seconds)
|
|
#
|
|
#
|
|
#
|
|
#
|
|
self.unassigned_circuit_ids.append(circuit_id)
|
|
self.unassigned_circuit_ids.append(circuit_id)
|
|
@@ -169,10 +214,13 @@ class ExperimentController:
|
|
#
|
|
#
|
|
#
|
|
#
|
|
class ExperimentProtocol(basic_protocols.ChainedProtocol):
|
|
class ExperimentProtocol(basic_protocols.ChainedProtocol):
|
|
- def __init__(self, socket, endpoint, num_bytes, custom_data=None, send_buffer_len=None, push_start_cb=None):
|
|
|
|
|
|
+ def __init__(self, socket, endpoint, num_bytes, circuit_info, custom_data=None, send_buffer_len=None, push_start_cb=None):
|
|
proxy_username = bytes([z for z in os.urandom(12) if z != 0])
|
|
proxy_username = bytes([z for z in os.urandom(12) if z != 0])
|
|
proxy_protocol = basic_protocols.Socks4Protocol(socket, endpoint, username=proxy_username)
|
|
proxy_protocol = basic_protocols.Socks4Protocol(socket, endpoint, username=proxy_username)
|
|
#
|
|
#
|
|
|
|
+ self.proxy_info = socket.getpeername()
|
|
|
|
+ self.circuit_info = circuit_info
|
|
|
|
+ #
|
|
throughput_protocol = throughput_protocols.ClientProtocol(socket, num_bytes,
|
|
throughput_protocol = throughput_protocols.ClientProtocol(socket, num_bytes,
|
|
custom_data=custom_data,
|
|
custom_data=custom_data,
|
|
send_buffer_len=send_buffer_len,
|
|
send_buffer_len=send_buffer_len,
|
|
@@ -181,6 +229,13 @@ class ExperimentProtocol(basic_protocols.ChainedProtocol):
|
|
#
|
|
#
|
|
super().__init__([proxy_protocol, throughput_protocol])
|
|
super().__init__([proxy_protocol, throughput_protocol])
|
|
#
|
|
#
|
|
|
|
+ def get_desc(self):
|
|
|
|
+ super_desc = super().get_desc()
|
|
|
|
+ if super_desc is not None:
|
|
|
|
+ return '{} -> {} - {}'.format(self.proxy_info, self.circuit_info, super_desc)
|
|
|
|
+ else:
|
|
|
|
+ return '{} -> {}'.format(self.proxy_info, self.circuit_info)
|
|
|
|
+ #
|
|
#
|
|
#
|
|
class ExperimentProtocolManager():
|
|
class ExperimentProtocolManager():
|
|
def __init__(self):
|
|
def __init__(self):
|
|
@@ -188,6 +243,7 @@ class ExperimentProtocolManager():
|
|
self.process_counter = 0
|
|
self.process_counter = 0
|
|
self.used_ids = []
|
|
self.used_ids = []
|
|
self.running_processes = {}
|
|
self.running_processes = {}
|
|
|
|
+ self.checked_in = multiprocessing.Manager().dict()
|
|
self.global_finished_process_queue = multiprocessing.Queue()
|
|
self.global_finished_process_queue = multiprocessing.Queue()
|
|
self.local_finished_process_queue = queue.Queue()
|
|
self.local_finished_process_queue = queue.Queue()
|
|
self.queue_getter = useful.QueueGetter(self.global_finished_process_queue,
|
|
self.queue_getter = useful.QueueGetter(self.global_finished_process_queue,
|
|
@@ -196,7 +252,8 @@ class ExperimentProtocolManager():
|
|
def _run_client(self, protocol, protocol_id):
|
|
def _run_client(self, protocol, protocol_id):
|
|
had_error = False
|
|
had_error = False
|
|
try:
|
|
try:
|
|
- logging.debug('Starting client protocol (id: {})'.format(protocol_id))
|
|
|
|
|
|
+ logging.debug('Starting client protocol (id: {}, desc: {})'.format(protocol_id, protocol.get_desc()))
|
|
|
|
+ self.checked_in[protocol_id] = True
|
|
protocol.run()
|
|
protocol.run()
|
|
logging.debug('Done client protocol (id: {})'.format(protocol_id))
|
|
logging.debug('Done client protocol (id: {})'.format(protocol_id))
|
|
except KeyboardInterrupt:
|
|
except KeyboardInterrupt:
|
|
@@ -220,8 +277,11 @@ class ExperimentProtocolManager():
|
|
assert not self.stopped
|
|
assert not self.stopped
|
|
assert protocol_id not in self.used_ids, 'Protocol ID already used'
|
|
assert protocol_id not in self.used_ids, 'Protocol ID already used'
|
|
#
|
|
#
|
|
|
|
+ #logging.debug('Launching client protocol (id: {})'.format(protocol_id))
|
|
p = multiprocessing.Process(target=self._run_client, args=(protocol, protocol_id))
|
|
p = multiprocessing.Process(target=self._run_client, args=(protocol, protocol_id))
|
|
self.running_processes[protocol_id] = p
|
|
self.running_processes[protocol_id] = p
|
|
|
|
+ self.checked_in[protocol_id] = False
|
|
|
|
+ # because of Python multiprocessing bugs, the process may deadlock when it starts
|
|
self.used_ids.append(protocol_id)
|
|
self.used_ids.append(protocol_id)
|
|
#
|
|
#
|
|
p.start()
|
|
p.start()
|
|
@@ -229,46 +289,110 @@ class ExperimentProtocolManager():
|
|
#
|
|
#
|
|
#protocol.socket.close()
|
|
#protocol.socket.close()
|
|
#
|
|
#
|
|
- def wait(self, finished_protocol_cb=None, kill_timeout=None):
|
|
|
|
- timed_out = False
|
|
|
|
|
|
+ def _get_not_checked_in(self):
|
|
|
|
+ temp = self.checked_in.copy()
|
|
|
|
+ return [x for x in temp if not temp[x]]
|
|
|
|
+ #
|
|
|
|
+ #def _count_checked_in(self):
|
|
|
|
+ # temp = self.checked_in.copy()
|
|
|
|
+ # only_checked_in = [True for x in temp if temp is True]
|
|
|
|
+ # return (len(only_checked_in), len(self.checked_in))
|
|
|
|
+ #
|
|
|
|
+ def _get_dead_processes(self):
|
|
|
|
+ dead_processes = []
|
|
|
|
+ for (protocol_id, p) in self.running_processes.items():
|
|
|
|
+ if not p.is_alive():
|
|
|
|
+ dead_processes.append((protocol_id, p))
|
|
|
|
+ #
|
|
|
|
+ #
|
|
|
|
+ return dead_processes
|
|
|
|
+ #
|
|
|
|
+ def _cleanup_process(self, p, protocol_id, had_error, finished_protocol_cb):
|
|
|
|
+ p.join()
|
|
|
|
+ self.running_processes.pop(protocol_id)
|
|
|
|
+ if finished_protocol_cb is not None:
|
|
|
|
+ finished_protocol_cb(protocol_id, had_error)
|
|
|
|
+ #
|
|
|
|
+ #
|
|
|
|
+ def _wait(self, timeout=None, finished_protocol_cb=None):
|
|
|
|
+ return_on_timeout = True if timeout is not None else False
|
|
|
|
+ timeout = timeout if timeout is not None else 10
|
|
|
|
+ last_waiting_message = None
|
|
#
|
|
#
|
|
while len(self.running_processes) > 0:
|
|
while len(self.running_processes) > 0:
|
|
- logging.debug('Waiting for processes ({} left)'.format(len(self.running_processes)))
|
|
|
|
|
|
+ dead_processes = self._get_dead_processes()
|
|
#
|
|
#
|
|
- if not timed_out:
|
|
|
|
|
|
+ while len(self.running_processes) > 0:
|
|
|
|
+ #checked_in_count = self._count_checked_in()
|
|
|
|
+ #not_checked_in = checked_in_count[1]-checked_in_count[0]
|
|
|
|
+ not_checked_in = self._get_not_checked_in()
|
|
|
|
+ #
|
|
|
|
+ if last_waiting_message is None or last_waiting_message != len(self.running_processes):
|
|
|
|
+ logging.debug('Waiting for processes ({} left, {} not checked in)'.format(len(self.running_processes),
|
|
|
|
+ len(not_checked_in)))
|
|
|
|
+ last_waiting_message = len(self.running_processes)
|
|
|
|
+ #
|
|
|
|
+ if len(self.running_processes) <= len(not_checked_in):
|
|
|
|
+ running_not_checked_in = [protocol_id for protocol_id in self.running_processes if protocol_id in not_checked_in]
|
|
|
|
+ if len(self.running_processes) == len(running_not_checked_in):
|
|
|
|
+ logging.debug('The remaining processes have not checked in, so stopping the wait')
|
|
|
|
+ return
|
|
|
|
+ #
|
|
|
|
+ #
|
|
try:
|
|
try:
|
|
- (protocol_id, had_error) = self.local_finished_process_queue.get(timeout=kill_timeout)
|
|
|
|
|
|
+ (protocol_id, had_error) = self.local_finished_process_queue.get(timeout=timeout)
|
|
p = self.running_processes[protocol_id]
|
|
p = self.running_processes[protocol_id]
|
|
|
|
+ self._cleanup_process(p, protocol_id, had_error, finished_protocol_cb)
|
|
|
|
+ if (protocol_id, p) in dead_processes:
|
|
|
|
+ dead_processes.remove((protocol_id, p))
|
|
|
|
+ #
|
|
|
|
+ logging.debug('Completed protocol (id: {}, checked_in={})'.format(protocol_id,
|
|
|
|
+ self.checked_in[protocol_id]))
|
|
except queue.Empty:
|
|
except queue.Empty:
|
|
- if kill_timeout is None:
|
|
|
|
- raise
|
|
|
|
|
|
+ if return_on_timeout:
|
|
|
|
+ return
|
|
|
|
+ else:
|
|
|
|
+ break
|
|
|
|
+ #
|
|
|
|
+ #if kill_timeout is not None:
|
|
|
|
+ # logging.warning('Timed out waiting for processes to finish, will terminate remaining processes')
|
|
|
|
+ # kill_remaining = True
|
|
#
|
|
#
|
|
- logging.warning('Timed out waiting for processes to finish, will terminate remaining processes')
|
|
|
|
- timed_out = True
|
|
|
|
#
|
|
#
|
|
#
|
|
#
|
|
- if timed_out:
|
|
|
|
- (protocol_id, p) = next(iter(self.running_processes.items()))
|
|
|
|
- # just get any process and kill it
|
|
|
|
- had_error = True
|
|
|
|
- p.terminate()
|
|
|
|
- logging.debug('Terminated protocol {}'.format(protocol_id))
|
|
|
|
|
|
+ for (protocol_id, p) in dead_processes:
|
|
|
|
+ # these processes were dead but didn't add themselves to the finished queue
|
|
|
|
+ logging.debug('Found a dead process (id: {})'.format(protocol_id))
|
|
|
|
+ self._cleanup_process(p, protocol_id, True, finished_protocol_cb)
|
|
#
|
|
#
|
|
- p.join()
|
|
|
|
- self.running_processes.pop(protocol_id)
|
|
|
|
- if finished_protocol_cb is not None:
|
|
|
|
- finished_protocol_cb(protocol_id, had_error)
|
|
|
|
|
|
+ #
|
|
|
|
+ #
|
|
|
|
+ def wait(self, finished_protocol_cb=None, kill_timeout=None):
|
|
|
|
+ self._wait(kill_timeout, finished_protocol_cb)
|
|
|
|
+ #
|
|
|
|
+ if len(self.running_processes) > 0:
|
|
|
|
+ logging.warning('Timed out ({} seconds) waiting for processes to finish, will terminate remaining processes'.format(kill_timeout))
|
|
|
|
+ #
|
|
|
|
+ while len(self.running_processes) > 0:
|
|
|
|
+ (protocol_id, p) = next(iter(self.running_processes.items()))
|
|
|
|
+ # just get any process and kill it
|
|
|
|
+ was_alive = p.is_alive()
|
|
|
|
+ p.terminate()
|
|
|
|
+ logging.debug('Terminated protocol (id: {}, was_dead={}, checked_in={})'.format(protocol_id,
|
|
|
|
+ (not was_alive),
|
|
|
|
+ self.checked_in[protocol_id]))
|
|
#
|
|
#
|
|
|
|
+ self._cleanup_process(p, protocol_id, True, finished_protocol_cb)
|
|
#
|
|
#
|
|
#
|
|
#
|
|
def stop(self):
|
|
def stop(self):
|
|
self.wait(kill_timeout=1.5)
|
|
self.wait(kill_timeout=1.5)
|
|
self.queue_getter.stop()
|
|
self.queue_getter.stop()
|
|
- self.queue_getter.join()
|
|
|
|
|
|
+ self.queue_getter.join(timeout=10)
|
|
self.stopped = True
|
|
self.stopped = True
|
|
#
|
|
#
|
|
#
|
|
#
|
|
-def build_client_protocol(endpoint, socks_address, control_address, controller, start_event, wait_duration=0, measureme_id=None, num_bytes=None, buffer_len=None):
|
|
|
|
|
|
+def build_client_protocol(endpoint, socks_address, control_address, controller, start_event, send_measureme, wait_duration=0, measureme_id=None, num_bytes=None, buffer_len=None):
|
|
client_socket = socket.socket()
|
|
client_socket = socket.socket()
|
|
#
|
|
#
|
|
logging.debug('Socket %d connecting to proxy %r...', client_socket.fileno(), socks_address)
|
|
logging.debug('Socket %d connecting to proxy %r...', client_socket.fileno(), socks_address)
|
|
@@ -282,7 +406,9 @@ def build_client_protocol(endpoint, socks_address, control_address, controller,
|
|
#
|
|
#
|
|
if measureme_id is not None:
|
|
if measureme_id is not None:
|
|
custom_data['measureme_id'] = measureme_id
|
|
custom_data['measureme_id'] = measureme_id
|
|
- #
|
|
|
|
|
|
+ #
|
|
|
|
+ if send_measureme:
|
|
|
|
+ assert measureme_id != None
|
|
hops = list(range(len(controller.circuits[circuit_id])+1))[::-1]
|
|
hops = list(range(len(controller.circuits[circuit_id])+1))[::-1]
|
|
# send the measureme cells to the last relay first
|
|
# send the measureme cells to the last relay first
|
|
start_cb = lambda control_address=control_address, circuit_id=circuit_id, measureme_id=measureme_id, \
|
|
start_cb = lambda control_address=control_address, circuit_id=circuit_id, measureme_id=measureme_id, \
|
|
@@ -293,6 +419,7 @@ def build_client_protocol(endpoint, socks_address, control_address, controller,
|
|
#
|
|
#
|
|
custom_data = json.dumps(custom_data).encode('utf-8')
|
|
custom_data = json.dumps(custom_data).encode('utf-8')
|
|
protocol = ExperimentProtocol(client_socket, endpoint, num_bytes,
|
|
protocol = ExperimentProtocol(client_socket, endpoint, num_bytes,
|
|
|
|
+ '{}: {}'.format(circuit_id, controller.circuits[circuit_id]),
|
|
custom_data=custom_data,
|
|
custom_data=custom_data,
|
|
send_buffer_len=buffer_len,
|
|
send_buffer_len=buffer_len,
|
|
push_start_cb=start_cb)
|
|
push_start_cb=start_cb)
|
|
@@ -369,7 +496,8 @@ if __name__ == '__main__':
|
|
measureme_id = None
|
|
measureme_id = None
|
|
#
|
|
#
|
|
wait_duration = random.randint(0, args.wait_range)
|
|
wait_duration = random.randint(0, args.wait_range)
|
|
- protocol = build_client_protocol(endpoint, proxy_address['socks'], proxy_address['control'], controller, start_event,
|
|
|
|
|
|
+ protocol = build_client_protocol(endpoint, proxy_address['socks'], proxy_address['control'],
|
|
|
|
+ controller, start_event, args.measureme,
|
|
wait_duration=wait_duration, measureme_id=measureme_id,
|
|
wait_duration=wait_duration, measureme_id=measureme_id,
|
|
num_bytes=args.num_bytes, buffer_len=args.buffer_len)
|
|
num_bytes=args.num_bytes, buffer_len=args.buffer_len)
|
|
protocol_manager.start_experiment_protocol(protocol, protocol_id=None)
|
|
protocol_manager.start_experiment_protocol(protocol, protocol_id=None)
|