Commit 1fe199cd authored by Matt Traudt's avatar Matt Traudt
Browse files

Make multiple bandwidth measurements

parent 0567cce8
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -24,19 +24,21 @@ class V3BWLine:
        self.bw = bw
        self.nick = nick
        # convert to ms
        self.rtts = [int(round(r * 1000)) for r in rtts]
        rtts = [round(r * 1000) for r in rtts]
        self.rtt = round(median(rtts))

    def __str__(self):
        frmt = 'node_id={fp} bw={sp} nick={n} min_rtt={rtt}'
        frmt = 'node_id={fp} bw={sp} nick={n} rtt={rtt}'
        return frmt.format(fp=self.fp, sp=round(self.bw), n=self.nick,
                           rtt=min(self.rtts))
                           rtt=self.rtt)


def result_data_to_v3bw_line(data, fingerprint):
    assert fingerprint in data
    results = data[fingerprint]
    nick = results[0]['nickname']
    speeds = [r['amount'] / r['duration'] for r in results]
    speeds = [dl['amount'] / dl['duration']
              for r in results for dl in r['downloads']]
    speed = median(speeds)
    rtts = [rtt for r in results for rtt in r['rtts']]
    return V3BWLine(fingerprint, speed, nick, rtts)
+7 −16
Original line number Diff line number Diff line
@@ -11,12 +11,11 @@ from datetime import date
class Result:
    ''' A simple struct to pack a measurement result into so that other code
    can be confident it is handling a well-formed result. '''
    def __init__(self, relay, circ, server_host, rtts, duration, amount):
    def __init__(self, relay, circ, server_host, rtts, download_results):
        self._relay = relay
        self._circ = circ
        self._duration = duration
        self._amount = amount
        self._server_host = server_host
        self._downloads = download_results
        self._rtts = rtts
        self._time = time.time()

@@ -45,12 +44,8 @@ class Result:
        return self._time

    @property
    def duration(self):
        return self._duration

    @property
    def amount(self):
        return self._amount
    def downloads(self):
        return self._downloads

    @property
    def server_host(self):
@@ -61,8 +56,7 @@ class Result:
            'fingerprint': self.fingerprint,
            'nickname': self.nickname,
            'time': self.time,
            'duration': self.duration,
            'amount': self.amount,
            'downloads': self.downloads,
            'address': self.address,
            'circ': self.circ,
            'rtts': self.rtts,
@@ -107,8 +101,5 @@ class ResultDump:
            fp = result.fingerprint
            nick = result.nickname
            self.write_result(result)
            amount = result.amount
            duration = result.duration
            rate = amount / duration
            rate = rate * 8 / 1024 / 1024
            print(fp, nick, rate, duration)
            dls = result.downloads
            print(fp, nick, dls)
+15 −15
Original line number Diff line number Diff line
@@ -19,9 +19,8 @@ stream_building_lock = RLock()

# maximum we want to read per read() call
MAX_RECV_PER_READ = 1*1024*1024
# minimum amount of time a transfer needs to take in order for us to consider
# it a measurement
MIN_TIME_REQUIRED = 5
DOWNLOAD_TIMES = {'toofast': 1, 'min': 5, 'target': 6, 'max': 10}
DESIRED_RESULTS = 5


def fail_hard(*s):
@@ -148,9 +147,9 @@ def measure_relay(args, cb, rl, relay):
        return
    # SECOND: measure throughput on this sircuit. Start with what should be a
    # small amount
    result_time = None
    results = []
    expected_amount = 16*1024
    while result_time is None or result_time < MIN_TIME_REQUIRED:
    while len(results) < DESIRED_RESULTS:
        # Tell the server to send us the current expected_amount.
        if not tell_server_amount(s, expected_amount):
            close_socket(s)
@@ -163,20 +162,21 @@ def measure_relay(args, cb, rl, relay):
            close_socket(s)
            cb.close_circuit(circ_id)
            return
        # If it took long enough, make an educated guess about how many bytes
        # it should take to have MIN_TIME_REQUIRED seconds to elapse while
        # doing so
        if result_time > 1:
        if result_time < DOWNLOAD_TIMES['toofast']:
            expected_amount = int(expected_amount * 10)
        elif result_time < DOWNLOAD_TIMES['min']:
            expected_amount = int(
                expected_amount * MIN_TIME_REQUIRED / result_time * 1.1)
        # If it didn't take very long at all, then greatly increase the amount
        # to send
                expected_amount * DOWNLOAD_TIMES['target'] / result_time)
        elif result_time < DOWNLOAD_TIMES['target']:
            results.append({'duration': result_time, 'amount': expected_amount})
        elif result_time < DOWNLOAD_TIMES['max']:
            results.append({'duration': result_time, 'amount': expected_amount})
        else:
            expected_amount = int(expected_amount * 10)
            expected_amount = int(
                expected_amount * DOWNLOAD_TIMES['target'] / result_time)
    circ = cb.get_circuit_path(circ_id)
    cb.close_circuit(circ_id)
    return Result(relay, circ, args.server_host, rtts, result_time,
                  expected_amount)
    return Result(relay, circ, args.server_host, rtts, results)


def result_putter(result_dump):