Example #1
0
def byplatform(request):
    """
    Return a graph representing the platforms of the active relays
    in the Tor network.

    @rtype: HttpResponse
    @return: A graph representing the platforms of the active relays
        in the Tor network as an HttpResponse object.
    """
    params = copy(DEFAULT_PARAMS)
    params['WIDTH'] = 480
    params['HEIGHT'] = 320
    params['X_FONT_SIZE'] = '9'
    params['TITLE'] = 'Number of Routers by Platform'

    last_va = Statusentry.objects.aggregate(
              last=Max('validafter'))['last']

    statusentries = Statusentry.objects.filter(
                    validafter=last_va)

    platform_map = {}
    keys = ['Linux', 'Windows', 'FreeBSD', 'Darwin', 'OpenBSD',
            'NetBSD', 'SunOS']
    for platform in keys:
        platform_map[platform] = 0

    platform_map['Unknown'] = 0

    # Inefficient for the same reason that the observed bandwidth
    # graph is inefficient; a custom SUM(CASE WHERE... should be
    # necessary here.
    for entry in statusentries:
        platform = entry.descriptorid.platform
        for key in keys:
            if key in platform:
                platform_map[key] += 1
                break
        # 'else' statement only runs if the for loop terminates
        # normally -- that is, without a break.
        else:
            platform_map['Unknown'] += 1

    keys.append('Unknown')

    num_params = len(keys)
    xs = range(num_params)
    ys = [platform_map[key] for key in keys]

    return draw_bar_graph(xs, ys, keys, params)
Example #2
0
def aggregatesummary(request):
    """
    Return a graph representing an aggregate summary of the routers on
    the network as an HttpResponse object.

    @rtype: HttpResponse
    @return: A graph representing an aggregate summary of the routers on
        the Tor network.
    """
    params = copy(DEFAULT_PARAMS)
    params['X_FONT_SIZE'] = '9'
    params['TITLE'] = 'Aggregate Summary -- Number of Routers Matching' \
                    + ' Specified Criteria'

    last_va = Statusentry.objects.aggregate(
              last=Max('validafter'))['last']

    statusentries = Statusentry.objects.filter(validafter=last_va)

    total = statusentries.count()
    counts = Statusentry.objects.filter(validafter=last_va).aggregate(
            isauthority=CountCase('isauthority', when=True),
            isbaddirectory=CountCase('isbaddirectory', when=True),
            isbadexit=CountCase('isbadexit', when=True),
            isexit=CountCase('isexit', when=True),
            isfast=CountCase('isfast', when=True),
            isguard=CountCase('isguard', when=True),
            isnamed=CountCase('isnamed', when=True),
            isstable=CountCase('isstable', when=True),
            isrunning=CountCase('isrunning', when=True),
            isvalid=CountCase('isvalid', when=True),
            isv2dir=CountCase('isv2dir', when=True))

    keys = ['isauthority', 'isbaddirectory', 'isbadexit', 'isexit',
            'isfast', 'isguard', 'isnamed', 'isstable', 'isrunning',
            'isvalid', 'isv2dir']
    labels = ['Total', 'Authority', 'BadDirectory', 'BadExit', 'Exit',
            'Fast', 'Guard', 'Named', 'Stable', 'Running', 'Valid',
            'V2Dir']
    num_params = len(labels)
    xs = range(num_params)

    ys = []
    ys.append(total)
    for count in keys:
        ys.append(counts[count])

    return draw_bar_graph(xs, ys, labels, params)
Example #3
0
def bytimerunning(request):
    """
    Return a graph representing the uptime of routers in the Tor
    network.

    @rtype: HttpResponse
    @return: A graph representing the uptime of routers in the
        Tor network as an HttpResponse object.
    """
    params = copy(DEFAULT_PARAMS)
    params['X_FONT_SIZE'] = '9'
    params['TITLE'] = 'Number of Routers by Time Running (weeks)'

    last_va = Statusentry.objects.aggregate(
              last=Max('validafter'))['last']

    statusentries = Statusentry.objects.filter(
                    validafter=last_va)

    uptime_map = {}

    # This step is very inefficient; a custom SUM(CASE WHERE...
    # should be written.
    for entry in statusentries:
        # The uptime in weeks is seconds / (seconds/min * min/hour
        # * hour/day * day/week), where / signifies floor division.
        weeks = entry.descriptorid.uptime / (60 * 60 * 24 * 7)
        if weeks in uptime_map:
            uptime_map[weeks] += 1
        else:
            uptime_map[weeks] = 1

    keys = sorted(uptime_map)
    num_params = len(keys)
    xs = range(num_params)
    ys = [uptime_map[key] for key in keys]

    return draw_bar_graph(xs, ys, keys, params)
Example #4
0
def exitbycountrycode(request):
    """
    Return a graph representing the number of exit routers
    by country code.

    @rtype: HttpResponse
    @return: A graph representing the number of exit routers by country
        code as an HttpResponse object.
    """
    params = copy(DEFAULT_PARAMS)
    params['LABEL_ROT'] = 'vertical'
    params['TITLE'] = 'Number of Exit Routers by Country Code'

    last_va = Statusentry.objects.aggregate(
              last=Max('validafter'))['last']

    statusentries = Statusentry.objects.filter(
                    validafter=last_va, isexit=1).extra(
                            select={'geoip': 'geoip_lookup(address)'})

    country_map = {}

    for entry in statusentries:
        # 'geoip' is a string, where the second and third characters
        # make the country code.
        country = entry.geoip[1:3]
        if country in country_map:
            country_map[country] += 1
        else:
            country_map[country] = 1

    keys = sorted(country_map)
    num_params = len(keys)
    xs = range(num_params)
    ys = [country_map[key] for key in keys]

    return draw_bar_graph(xs, ys, keys, params)
Example #5
0
def byobservedbandwidth(request):
    """
    Return a graph representing the observed bandwidth of the
    routers in the Tor network.

    @rtype: HttpResponse
    @return: A graph representing the observed bandwidth of the
        routers in the Tor network.
    """
    params = copy(DEFAULT_PARAMS)
    # Width and height of the graph in pixels
    params['WIDTH'] = 480
    params['HEIGHT'] = 320
    # Space in pixels given around plot
    params['TOP_MARGIN'] = 25
    params['BOTTOM_MARGIN'] = 64
    params['LEFT_MARGIN'] = 38
    params['RIGHT_MARGIN'] = 5
    params['LABEL_ROT'] = 'vertical'
    params['TITLE'] = 'Number of Routers by Observed Bandwidth (KB/sec)'

    # Define the ranges for the graph, a list of 2-tuples of ints.
    RANGES = [(0, 10), (11, 20), (21, 50), (51, 100), (101, 500),
              (501, 1000), (1001, 2000), (2001, 3000), (3001, 5000)]

    last_va = Statusentry.objects.aggregate(
              last=Max('validafter'))['last']

    statusentries = Statusentry.objects.filter(
                    validafter=last_va)

    bw_map = {}
    excess = RANGES[-1][1] + 1

    for rng in RANGES:
        bw_map[rng] = 0
    bw_map[excess] = 0

    for entry in statusentries:
        kbps = entry.descriptorid.bandwidthobserved / 1024

        # Binary search
        # Is there a way to clean up this bit? It could be its own
        # function...
        rngs = RANGES
        while (rngs and (not rngs[len(rngs) / 2][0] <= kbps <= \
                             rngs[len(rngs) / 2][1])):
            if rngs[len(rngs) / 2][0] > kbps:
                rngs = rngs[:(len(rngs) / 2)]
            else:
                rngs = rngs[(len(rngs) / 2 + 1):]
        if rngs:
            bw_map[rngs[len(rngs) / 2][0], rngs[len(rngs) / 2][1]] += 1
        else:
            bw_map[excess] += 1


    num_params = len(bw_map)
    xs = range(num_params)
    ys = [bw_map[lower, upper] for lower, upper in RANGES]
    ys.append(bw_map[excess])

    labels = ['%s-%s' % (lower, upper) for lower, upper in RANGES]
    labels.append('%s+' % excess)

    return draw_bar_graph(xs, ys, labels, params)