AS Reachability Visualization

December 4th, 2024 by Bradley Huffaker

The AS Reach Visualization provides a geographic breakdown of the number of ASes reachable through an AS’s customer, peers, providers, or an unknown neighbor. The interactive interface to the visualization can be found at https://www.caida.org/catalog/media/visualizations/as-reach/

Independent networks (Autonomous Systems, or ASes) engage in typically voluntary bilateral interconnection (“peering”) agreements to provide reachability to each other for some subset of the Internet. The implementation of these agreements introduces a non-trivial set of constraints regarding paths over which Internet traffic can flow, with implications for network operations, research, and evolution. Realistic models of Internet topology, routing, workload, and performance
must account for the underlying economic dynamics.

Although these business agreements between ISPs can be complicated, the original model introduced by Gao (On inferring autonomous system relationships in the Internet), abstracts business relationships into the following three most common types:

  • customer-to provider: in which a customer network gets access to the internet from a provider network
  • provider-to-customer: the reverse of the customer-to-provider, the provider provides access to it’s customer
  • peer-to-peer: where both ASes exchange traffic between their customers

An AS’s Reach is defined as the set of ASes the target AS can reach through its customers, peers, providers, or unknown. The Customer Reach is the set of ASes reachable through the AS’s customers. The Peer Reach is the set of ASes that are not in the Customer Reach, but reachable through the AS’s peers. The Provider Reach is the set of ASes not in the Customer or Peer Reach, but reachable through the AS’s provider. The Unknown Reach is the set of ASes not in the Customer, Peer, or Provider Reach. More details at https://www.caida.org/catalog/media/visualizations/as-reach/

CAIDA’s 2023 Annual Report

October 23rd, 2024 by kc

The CAIDA annual report (quite a bit later than usual this year due to an unprecedented level of activity in 2024 which we will report on earlier next year!) summarizes CAIDA’s activities for 2023 in the areas of research, infrastructure, data collection and analysis. The executive summary is excerpted below:
Read the rest of this entry »

Streamlining Access to BGP Routing Data

October 7th, 2024 by Elena Yulaeva

Users can now request access to the CAIDA BGP2GO (https://bgp2go.caida.org) platform. BGP2GO lets users find the MRT files that contain a specific resource and thus avoid the download and processing of unrelated data. Users can compile a customize list of relevant MRT files, share that exact list with others, or stream the matching MRT files (e.g., using BGPStream). 

Finding the needle in the haystack 

Public BGP route collectors receive update messages from over 1,000 BGP routers worldwide. These updates are archived and made available for download and analysis. However, the data is organized in a way that often requires downloading vast amounts of unrelated information making it increasingly difficult to focus on the needles in the haystack. 

Imagine you’re a network operator announcing a new prefix and you want to analyze its propagation. You may not know exactly which collector or MRT file contains the relevant data, forcing you to download and sift through unnecessary information. 

BGP2GO solves this problem by allowing users to easily select only the files they need, saving significant time and effort. 

We have developed a comprehensive index of all prefixes, ASNs, and communities across RouteViews update files (https://archive.routeviews.org), along with BGP2GO, a user interface that allows you to easily select the specific files you need (https://bgp2go.caida.org) 

Use Case: Analyzing Prefix Propagation with PEERING Testbed, BGP2GO, and BGPStream 

Let’s walk through a real-world example. Suppose you’re a network operator advertising a prefix and want to examine how it propagates across RouteViews collectors. Using the PEERING testbed (https://peering.ee.columbia.edu/), we performed a controlled advertisement of the prefix 184.164.246.0/24 during August 2024. 

Step 1: Looking up the prefix and setting filters 

In this case, we search for the prefix 184.164.246.0/24 in BGP2GO, filtering for data from August 2024. The platform identifies 33,251 announcements and withdrawals, spread across 746 files (2.32GB) from 26 collectors. This curated selection lets us focus only on the data we need, saving time and resources. 

https://bgp2go.caida.org/details?pre=184.164.246.0/24&years=2024&months=8

Step 2: Stream selected files in the terminal 

Once the relevant MRT files are selected, you can stream them for further processing using BGPStream. Clicking the BGPSTREAM button in the top right corner, right above the “collectors” chart gives instructions on how to stream the files in your terminal. 

 

For this example, we use the following command (see step 4a above) in the terminal to process the relevant files: 

bgpreader -k 184.164.246.0/24 -d csvfile -o csv-file="bgp2go.csv" 

This command leverages bgpreader to read the files and output the lines that pertain to the resource (prefix 184.164.246.0/24) . The following screenshot shows an excerpt of routes related to the prefix 184.164.246.0/24 extracted from all files that contain this prefix in August 2024. 

 

To learn more about the bgpreader command and its options, visit the BGPStream website  (https://bgpstream.caida.org/) . 

Getting Access to BGP2GO 

To request access to the BGP2GO platform, a user should first create an account with the CAIDA Services Single Sign On (SSO) system ( https://auth.caida.org/realms/CAIDA/account ) by providing basic information and undergoing authentication via Keycloak. After authentication, a user can request access to the BGP2Go platform (which requires a CAIDA-authorized account with bgp2go-api:read role) by going to https://bgp2go.caida.org/ and filling out the request form.  If you have any questions or problems, please contact us at data-info@caida.org 

Seeking Beta Users for 100 GB link Anonymized Passive Traces

August 11th, 2024 by Elena Yulaeva

We are seeking beta users for our new Anonymized Two-Way Passive Trace dataset, captured on a 100 GB link between Los Angeles and San Jose. Beginning in April 2024, we have been capturing a one-hour trace each month. To protect privacy, we strip all packet payloads after the layer 4 headers, and anonymize IP (v4 and v6) addresses with CryptoPan. The monthly data is provided in two separate files, one for each direction of traffic.

This dataset includes the following metadata fields:

  • Monitor Name
  • Year and month (including a link to a graphical display of breakup by protocol, application, and country)
  • Start time of trace (UTC)
  • Stop time of trace (UTC)
  • Number of IPv4 packets
  • Number of IPv6 packets
  • Unknown packets (as a fraction of the total number of packets)
  • Transmission rate in packets per second
  • Transmission rate in bits per second
  • Link load (as a fraction of the nominal maximum load for a 100 GB link)
  • Average packet size (bytes) (including a link to a graph of the packet size distribution).

The data is stored in our Swift OpenStack object storage. Each one-directional anonymized pcap file captured monthly is approximately 1TB in size, so users will need more than 2TB of space to download the entire one-hour capture. For those without access to such storage and/or processing capacity, contact us and we will discuss other alternatives. We are also releasing statistical information for each hourly trace.

Academic researchers can request access to the data by filling out and submitting the request form.

We will prioritize users who:

  • Have significant experience with network traffic analysis
  • Demonstrate a clear plan for how they will use the dataset
  • Can commit to regular feedback and participation throughout the beta testing period

Help CAIDA Refine and Enhance the FANTAIL Traceroute Analytics platform.

August 9th, 2024 by Elena Yulaeva

We are excited to announce the beta testing phase of the Facilitating Advances in Network Topology Analysis (FANTAIL) platform (https://www.caida.org/projects/fantail/), a cutting-edge topology query system designed to search vast archives of raw Internet end-to-end path (traceroute) measurement data. FANTAIL is poised to support and advance various research domains within the Computer and Information Science and Engineering (CISE) field that heavily rely on the emerging sub-discipline of Internet cartography. Key areas of focus include:

  • Understanding the intricate ownership and interconnection structures and dynamics of Internet infrastructure.
  • Exploring methods for device identification and characterization within the digital landscape.
  • Enhancing the ability to detect and respond to network outages and route hijacking incidents.
  • Investigating network congestion patterns and their impact on data flow and quality of service.
  • Identifying and mitigating vulnerabilities within network topologies.

FANTAIL consists of four components:

  1. Interactive Web Interface: FANTAIL Web Interface
  2. Application Programming Interface (API): Built on web standards (FANTAIL API Documentation)
  3. Full-Text Search System
  4. Big Data Processing System

The system’s central data type is the traceroute path, representing the inferred IP-level Internet path that network traffic would take between two hosts, from the measurement vantage point to the destination, as determined with the traceroute technique by scamper (https://catalog.caida.org/software/scamper). FANTAIL leverages annotated and indexed data generated through the utilization of Spark, SQLite, and Elasticsearch, originating from CAIDA Internet traceroute probing data dating back to 2015.

Academic researchers interested in accessing the platform can request access by emailing fantail-info@caida.org.

We will prioritize users who can commit to regular feedback and participation throughout the beta testing period. 

Understanding the deployment of public recursive resolvers

May 6th, 2024 by Matthew Luckie

This is the third in a series of essays (two earlier blog posts [1, 2]) about CAIDA’s new effort to reduce the barrier to performing a variety of Internet measurements.

We were recently asked about running Trufflehunter, which infers the usage properties of rare domain names on the Internet by cache snooping public recursive resolvers, on Ark. The basic idea of Trufflehunter is to provide a lower bound of the use of a domain name by sampling caches of large recursive resolvers.  One component of Trufflehunter is to identify the anycast instances that would answer a given vantage point’s DNS queries.   Trufflehunter uses a series of TXT queries to obtain the anycast instance of a given public recursive resolver, and considers four large public recursive resolvers: Cloudflare (1.1.1.1), Google (8.8.8.8), Quad9 (9.9.9.9), and OpenDNS (208.67.220.220).  The original paper describes the queries in section 4.1, which we summarize below, highlighting the interesting parts of each response with blue color.

Cloudflare returns an airport code representing the anycast deployment location used by the VP:
$ host -c ch -t txt id.server 1.1.1.1
id.server descriptive text "AKL"

Google returns an IP address representing the anycast deployment used by the VP, which can be mapped to an anycast deployment location with a second query:
$ host -t txt o-o.myaddr.l.google.com 8.8.8.8
o-o.myaddr.l.google.com descriptive text "172.253.218.133"
o-o.myaddr.l.google.com descriptive text "edns0-client-subnet <redacted>/24"

$ host -t txt locations.publicdns.goog
locations.publicdns.goog descriptive text "34.64.0.0/24 icn " ... "172.253.218.128/26 syd " "172.253.218.192/26 cbf " ...

Quad9 returns the hostname representing the resolver that provides the answer:
$ host -c ch -t txt id.server 9.9.9.9
id.server descriptive text "res100.akl.rrdns.pch.net"

and finally, OpenDNS returns a bunch of information in a debugging query, which includes the server that handles the query:
$ host -t txt debug.opendns.com 208.67.220.220
debug.opendns.com descriptive text "server r2004.syd"
debug.opendns.com descriptive text "flags 20040020 0 70 400180000000000000000007950800000000000000"
debug.opendns.com descriptive text "originid 0"
debug.opendns.com descriptive text "orgflags 2000000"
debug.opendns.com descriptive text "actype 0"
debug.opendns.com descriptive text "source <redacted>:42845"

Each of these queries requires a slightly different approach to extract the location of the anycast instance.  Our suggestion is for experimenters to use our newly created python library, which provides programmatic access to measurement capabilities of Ark VPs (described in two earlier blog posts [1, 2]).  The code for querying the recursive resolvers from all VPs is straight forward, and is shown below.  First, on lines 15-27, we get the Google mapping, so that we can translate the address returned to an anycast location.  This query requires TCP to complete, as the entry is larger than can fit in a UDP payload (the response is 9332 bytes at the time of writing this blog).  This query is synchronous (we wait for the answer before continuing, because the google queries that follow depend on the mapping) and is issued using a randomly selected Ark VP.  Then, on lines 29-38, we issue the four queries to each of the anycasted recursive resolvers from each VP.  These queries are asynchronous; we receive the answers as each Ark VP obtains a response.  On lines 40-82, we process the responses, storing the results in a multi-dimensional python dictionary, which associates each Ark VPs with their anycast recursive resolver location, as well as the RTT between asking the query and obtaining the response.  Finally, on lines 84-96, we dump the results out in a nicely formatted table that allows us to spot interesting patterns.

01 import argparse
02 import datetime
03 import ipaddress
04 import random
05 import re
06 from scamper import ScamperCtrl
07
08 def _main():
09   parser = argparse.ArgumentParser(description='get public recursive locs')
10   parser.add_argument('sockets')
11   args = parser.parse_args()
12
13   ctrl = ScamperCtrl(remote_dir=args.sockets)
14
15   # pick an ark VP at random to issue the query that gets the mapping
16   # of google recursive IP to location
17   goog_nets = {}
18   obj = ctrl.do_dns('locations.publicdns.goog',
19     inst=random.choice(ctrl.instances()),
20     qtype='txt', tcp=True, sync=True)
21   if obj is None or len(obj.ans_txts()) == 0:
22     print("could not get google mapping")
23     return
24   for rr in obj.ans_txts():
25     for txt in rr.txt:
26       net, loc = txt.split()
27       goog_nets[ipaddress.ip_network(net)] = loc
28
29   # issue the magic queries to get the instance that answers the query
30   for inst in ctrl.instances():
31     ctrl.do_dns('o-o.myaddr.l.google.com', server='8.8.8.8', qtype='txt',
32       attempts=2, wait_timeout=2, inst=inst)
33     ctrl.do_dns('id.server', server='1.1.1.1', qclass='ch', qtype='txt',
34       attempts=2, wait_timeout=2, inst=inst)
35     ctrl.do_dns('id.server', server='9.9.9.9', qclass='ch', qtype='txt',
36       attempts=2, wait_timeout=2, inst=inst)
37     ctrl.do_dns('debug.opendns.com', server='208.67.220.220', qtype='txt',
38       attempts=2, wait_timeout=2, inst=inst)
39
40   # collect the data
41   data = {}
42   for obj in ctrl.responses(timeout=datetime.timedelta(seconds=10)):
43     vp = obj.inst.name
44     if vp not in data:
45       data[vp] = {}
46     dst = str(obj.dst)
47     if dst in data[vp]:
48       continue
49     data[vp][dst] = {}
50     data[vp][dst]['rtt'] = obj.rtt
51
52     for rr in obj.ans_txts():
53       for txt in rr.txt:
54         if dst == '8.8.8.8':
55           # google reports an IPv4 address that represents
56           # the site that answers the query. we then map
57           # that address to a location using the mapping
58           # returned by the locations TCP query.
59           try:
60             addr = ipaddress.ip_address(txt)
61           except ValueError:
62             continue
63           for net, loc in goog_nets.items():
64             if addr in net:
65               data[vp][dst]['loc'] = loc
66               break
67         elif dst == '1.1.1.1':
68           # Cloudflare replies with a single TXT record
69           # containing an airport code
70           data[vp][dst]['loc'] = txt
71         elif dst == '9.9.9.9':
72           # Quad9 reports a hostname with an embedded
73           # airport code.
74           match = re.search("\\.(.+?)\\.rrdns\\.pch\\.net", txt)
75           if match:
76             data[vp][dst]['loc'] = match.group(1)
77         elif dst == '208.67.220.220':
78           # opendns reports multiple TXT records; we want the one
79           # that looks like "server r2005.syd"
80           match = re.search("^server .+\\.(.+?)$", txt)
81           if match:
82             data[vp][dst]['loc'] = match.group(1)
83
84   # format the output
85   print("{:15} {:>13} {:>13} {:>13} {:>13}".format(
86     "# vp", "google", "couldflare", "quad9", "opendns"))
87   for vp, recs in sorted(data.items()):
88     line = f"{vp:15}"
89     for rec in ('8.8.8.8', '1.1.1.1', '9.9.9.9', '208.67.220.220'):
90       cell = ""
91       if 'loc' in recs[rec]:
92         rtt = recs[rec]['rtt']
93         loc = recs[rec]['loc']
94         cell = f"{loc} {rtt.total_seconds()*1000:5.1f}"
95       line += f" {cell:>13}"
96     print(line)
97
98 if __name__ == "__main__":
99    _main()

The code runs quickly — no longer than 10 seconds (if one of the VPs is slow to report back), illustrating the capabilities of the Ark platform.

The output of running this program is shown below.  We have highlighted cells where the RTT was at least 50ms larger than the minimum RTT to any of the large recursive resolvers for the given VP.  These cells identify low-hanging fruit for operators, who could examine BGP routing policies with the goal of selecting better alternative paths.

# vp             google   couldflare         quad9      opendns
abz-uk.ark    lhr  24.4    LHR  16.5     lhr  16.9    lon  16.4
abz2-uk.ark   lhr  23.4    MAN   8.7     man   8.4   man1   8.5
acc-gh.ark    jnb 246.7    JNB 167.3     acc   0.5   cpt1 236.6
adl-au.ark    mel  28.1    ADL   5.5     syd  22.6   mel1  14.0
aep-ar.ark    scl  29.4    EZE   8.0   qaep2   4.6   sao1  34.0
aep2-ar.ark   scl  38.2    EZE   6.6   qaep2   5.7   sao1  42.5
akl-nz.ark    syd  26.9    AKL   2.6    akl2   4.0    syd  26.1
akl2-nz.ark   syd  29.2    AKL   4.9    akl2   4.0    syd  26.9
ams-gc.ark    grq   5.0    FRA   6.3     ams   0.8    ams   1.1
ams3-nl.ark   grq   6.0    AMS   2.1     ams   1.3    ams   1.9
ams5-nl.ark   grq   5.1    AMS   1.2     ams   1.9    ams   1.7
ams7-nl.ark   grq   6.0    AMS   2.4     ams   1.8    ams   2.3
ams8-nl.ark   grq  14.8    AMS  11.5     fra  17.7    ams  11.8
arn-se.ark    lpp   9.7    ARN   2.0     arn   0.8   cph1  10.5
asu-py.ark    scl  55.4    EZE  22.6     asu   0.8   sao1  57.0
atl2-us.ark   atl   9.8    DFW  23.6   qiad3  20.5   atl1   4.6
atl3-us.ark   atl  22.7    ATL  13.1     atl  17.0   atl1  19.7
aus-us.ark    dfw  80.7    DFW  56.6     dfw  46.6    dfw  17.6
avv-au.ark    mel 142.3    MEL   9.4     syd  22.6   mel1   8.5
bcn-es.ark    mad  38.0    BCN  13.3     bcn   0.5   mad1   9.8
bdl-us.ark    iad  13.3    EWR   5.0     lga   4.9    ash  10.6
bed-us.ark    iad  30.6    BOS  15.2     bos  13.5   bos1  19.8
beg-rs.ark    mil  62.5    BEG   1.2     beg   0.7   otp1  12.9
bfi-us.ark    dls  11.7    SEA   3.8   xsjc1  96.9    sea  10.5
bjl-gm.ark    bru  87.5    CDG  71.1     bjl   6.7   cdg1  73.4
bna-us.ark    atl  11.4    BNA   9.0     atl   9.5   atl1   9.3
bna2-us.ark   cbf  25.5    ORD  19.7     ord  12.8    chi  12.8
bos6-us.ark   iad  17.6    BOS   5.6   qiad3  15.5   bos1   5.7
bre-de.ark    grq  21.4    TXL  23.1     ber  17.2    ams  23.7
btr-us.ark    dfw  20.3    ORD  29.5     dfw  13.2    dfw  11.4
bwi2-us.ark   iad  12.7    IAD   4.4   qiad3   3.6   rst1   3.1
cdg-fr.ark    mil  24.9    MRS   1.5     mrs   1.0   mrs1  11.6
cdg3-fr.ark   bru   8.5    CDG   3.9     ams  13.7   cdg1   5.5
cgs-us.ark    iad   4.5    EWR   7.9     iad   2.2    ash   2.1
cjj-kr.ark    hkg  63.4                qhnd2  70.7    hkg  47.3
cld4-us.ark   lax  22.7    LAX  15.7     bur 104.1    lax  14.3
cld5-us.ark   lax  52.6    LAX  20.7     bur 103.1    lax  21.9
cld6-us.ark   lax  14.5    LAX   5.2   qlax1   7.0    lax   6.0
cos-us.ark    cbf  22.9    DEN   7.3     ord  36.0   den1  12.6
dar-tz.ark    jnb 224.6    NBO  14.0     dar   1.0    jnb  51.1
dar2-tz.ark   jnb 223.0    DAR   0.9     dar   0.9    jnb  48.0
dmk-th.ark    sin  32.2    SIN  28.0     bkk   2.4   nrt2  95.0
dtw2-us.ark   cbf  18.1    DTW   4.6     dtw   4.2    chi  10.7
dub-ie.ark    lhr  18.9    DUB   1.2     dub   0.7   dub1   0.7
dub2-ie.ark   lhr  18.7    DUB   1.8     dub   1.1   dub1   1.2
dub3-ie.ark   lhr  35.5    ZRH  45.6     dub  16.9   dub1  11.6
ens-nl.ark    grq   9.3    AMS   5.2     ams   4.0    ams   4.9
eug-us.ark    dls  15.7    SJC  18.3     sea   6.5    sea   6.5
fra-gc.ark    fra   9.1    FRA   1.1     fra   1.1    fra   1.1
gig-br.ark    gru 125.2    GIG   2.2   qrio1   1.4   rio1   1.1
gva-ch.ark                 ZRH   5.3     gva   1.0    fra  10.8
gye-ec.ark    chs 128.7    MIA  66.8   quio2  10.7    mia  77.1
ham-de.ark    grq  19.7    HAM   8.5     ber  11.0    fra  17.7
her2-gr.ark   mil  64.9                  ath   7.5   mil1  32.6
hkg4-cn.ark   tpe  13.6    HKG   1.0   qhkg3   4.9    hkg   9.5
hkg5-cn.ark   hkg  16.3    HKG   2.6   qhkg3   3.9    hkg   3.6
hlz2-nz.ark   syd  40.9    AKL  16.9     akl  13.8    syd  38.2
hnd-jp.ark    nrt   6.5    NRT   3.4   qhnd2  80.3    nrt   3.6
hnl-us.ark    dls  82.3    HNL   1.1     sea  75.2    sea  75.3
iev-ua.ark    waw  45.5    FRA  29.8   qwaw2  14.3   wrw1  14.9
igx2-us.ark   iad  16.1    EWR  16.9   qiad3  11.5   atl1  11.8
ind-us.ark    atl  25.1    IND   1.1     ord   8.5   atl1  11.0
ixc-in.ark    del  78.8    DEL   0.8   qsin1   0.7   mum2   0.7
jfk-us.ark    iad   9.6    EWR   1.5     lga   0.6    nyc   1.0
kgl-rw.ark    jnb 231.6    NBO  15.0     kgl   3.3    jnb  73.6
ktm-np.ark    del  98.6    DEL  30.4     ktm   7.6   mum1  94.4
las-us.ark    lax  15.5    LAX   8.4     pao  15.9    lax   8.2
lax3-us.ark   lax  10.5    LAX   3.0     bur   2.0    lax   2.0
lcy2-uk.ark   lhr  11.5    MAN   7.4     lhr  11.2    lon   2.2
lej-de.ark    fra  21.2    FRA   9.7     fra  12.5    fra   9.6
lex-us.ark    iad  17.9    IAD  15.7     iad  17.3   atl1  25.9
lgw-uk.ark    lhr  31.3    LHR  24.2     lhr  24.6    lon  23.6
lhe2-pk.ark   dia 195.0    KHI  35.0   qsin4 113.1    sin 130.6
lis-pt.ark    mad  33.0    LIS   4.5     lis   3.9   mad1  18.0
lke2-us.ark   dls  21.7    SEA  21.4     sea  15.1    sea  11.7
lun-zm.ark    jnb 189.9    JNB  32.2     jnb  23.3    jnb  23.3
lwc-us.ark    tul  18.0    MCI   1.4   xsjc1 106.3    dfw  10.4
lwc2-us.ark   dfw  24.4    DFW  15.7   qlax1  46.9    dfw  16.5
mdw-us.ark    cbf  25.7    ORD   7.0     ord   3.4    chi   4.4
med2-co.ark   mrn  96.4    MIA  50.7   qbog1  22.7    mia  48.9
mhg-de.ark    fra  30.7    FRA  19.1     fra  21.4    fra  18.4
mia-gc.ark    mrn  19.7    MIA   1.1     mia   1.0    mia   0.6
mnl-ph.ark    hkg  87.9    MNL   1.8   qsin1  50.8    hkg  75.8
mnz-us.ark    iad  13.4    IAD   5.8   qiad3   5.2   rst1   4.0
mru-mu.ark    jnb 206.1    JNB  43.1     mru   1.0    jnb  43.3
msy-us.ark    dfw  34.4    DFW  21.9   qlax1  55.2    dfw  23.0
mty-mx.ark    tul  44.1    MFE   4.5   qiad3  39.6    dfw  16.7
muc-de.ark    fra  30.3    FRA   9.1     fra   8.8    fra   8.9
muc3-de.ark   zrh  25.9    MUC   6.1     fra  11.0    fra  12.2
nap2-it.ark   mil  37.8    MXP  19.8     fra  38.0   mil1  15.2
nbo-ke.ark    jnb 220.5    NBO   2.4     nbo   2.2    jnb  60.7
nic-cy.ark    mil  61.3    LCA   1.0     mrs  35.2   mrs1  35.4
nrn-nl.ark    grq   8.6    AMS   5.5     ams   2.9    ams   3.1
nrt-jp.ark    nrt   4.8    NRT   1.2     hkg 101.9   nrt2   1.0
nrt3-jp.ark   nrt   6.5    NRT   3.5     pao 101.7   nrt2   3.5
oak5-us.ark   lax  19.3    SJC   5.9    sjc0   4.4    pao   4.4
okc-us.ark    dfw   9.6    MCI   9.6     dal   8.2    dfw   7.3
ord-us.ark    cbf  13.0    ORD   2.9     iad  19.0    chi   1.6
ory4-fr.ark   bru   6.5    CDG   2.0     cdg   1.4   cdg1   1.7
ory6-fr.ark   bru   6.4    LHR   8.8     lhr   8.4    lon   8.6
ory7-fr.ark   bru   7.7    CDG   4.0     cdg   5.0   cdg1   4.0
ory8-fr.ark   bru   6.3    CDG   2.0     lhr  25.7    lon   9.4
osl-no.ark    lpp  46.5    OSL   0.9     osl  25.8   sto1   9.0
pbh2-bt.ark   bom 105.2    MAA  92.0     pbh   1.8    sin  91.7
per-au.ark    syd  48.9    PER   2.0     per   1.2    syd  45.3
per2-au.ark   syd 140.0    PER   2.5     per   1.5    syd  44.9
phl-us.ark    iad  15.9                  iad  14.0   rst1  15.9
pna-es.ark    mad  33.9    BCN  13.5     bcn  13.3   mad1  19.3
prg-cz.ark    fra  16.9    PRG   1.1   qbts1   5.9   prg1   0.6
prg2-cz.ark   fra  29.8    PRG   1.7   qfra3  14.0   prg1   1.5
pry-za.ark    jnb 167.3    JNB   1.2     jnb   0.6   cpt1  18.4
puw-ru.ark    lpp  18.2    DME   1.5     beg  67.1    fra  34.3
pvu-us.ark    lax  25.2    SLC   3.8     slc   2.7    sea  18.4
rdu-us.ark    iad   9.5    IAD   8.1     iad   7.7    ash   8.6
rdu2-us.ark   iad  11.3    IAD   8.1     iad   8.5    ash   8.6
rdu3-us.ark   iad  27.5    IAD  18.6     iad  18.4   atl1  23.8
rkv-is.ark    lhr  49.0    KEF   2.0     kef   0.8   dub1  23.0
san-us.ark    lax  10.4    LAX   4.7     bur  87.2    lax   3.1
san2-us.ark   lax  39.0    LAX   6.5   qlax1   7.5    lax   5.6
san4-us.ark   lax  26.6    LAX  20.2     bur 106.8    lax  17.3
sao-br.ark    gru 117.3    GRU   2.5   qgru1   1.3   rio1   9.6
scq-es.ark    mad  31.7    MAD  11.0     mad  10.8   mad1  11.3
sea3-us.ark   dls  10.1    SEA   3.9     pao  24.6    sea   3.0
sin-gc.ark    sin   4.0    SIN   1.5   qsin1  93.5    sin   1.1
sin-sg.ark    sin   3.2    SIN   2.3   qsin1  12.2    sin   0.7
sjc2-us.ark   lax  15.2    SJC   1.4    sjc0   0.5    pao   2.1
sjj-ba.ark    waw  71.1    BUD  57.5     vie 213.3   mil1  89.4
sjo-cr.ark    chs  63.0    SJO   2.2     mia  51.8    mia  78.6
snn-ie.ark    lhr  20.4    DUB   4.4     dub   3.9   dub1   3.9
sql-us.ark    lax  19.6    SJC   2.2     pao   1.2    pao   0.9
stx-vi.ark    chs  38.3    MIA  26.4     mia  25.5    mia  25.1
svo2-ru.ark   lpp  22.4    DME   5.8     fra  41.1    fra  38.2
swu-kr.ark    hkg  77.6    ICN   6.5   qsin1  76.9   nrt2  38.5
syd3-au.ark   syd   4.8    SYD   0.9     syd   1.0    syd   0.5
tij-mx.ark    lax  15.8    LAX   6.6   qlax1   6.6    lax   5.6
tlv-il.ark    mil  80.2    MRS  43.6     tlv   2.0   mil1  50.5
tlv3-il.ark   mil  64.2    TLV   2.1     tlv   2.1   tlv1   3.0
tnr-mg.ark                 JNB 215.7                  jnb 199.1
tpe-tw.ark    tpe  10.3    TPE   5.2     tpe   3.1    sin  74.4
vdp-dk.ark    lpp  21.9    CPH   5.6     arn  13.4   cph1   5.4
vie-at.ark    fra  22.5    FRA  13.8     vie   2.1   prg1   6.5
waw-pl.ark    waw  20.1    HAM  31.3   qwaw2   1.3   wrw1   0.9
wbu-us.ark    cbf  13.4    DEN   2.7     den   1.8   den1   1.5
wlg2-nz.ark   syd  35.3    AKL  17.0    akl2  16.5    syd  32.4
ygk-ca.ark    yyz  29.5    YYZ  16.7     iad  35.5    yyz  16.1
yyc-ca.ark    dls  26.5    YYC   4.6     sea  21.8    yvr  16.7
zrh-ch.ark    zrh  14.5    ZRH   1.1    zrh2   0.6   mil1   8.1
zrh2-ch.ark   zrh  16.2    ZRH   1.1    zrh2   1.0    fra   6.8
zrh4-ch.ark   zrh  15.8    ZRH   1.5    zrh2   0.8   mil1   9.0

 

ITDK 2024-02

April 23rd, 2024 by Matthew Luckie

CAIDA has released the 2024-02 Internet Topology Data Kit (ITDK), the 24th ITDK in a series published over the past 14 years. In the year since the 2023-03 release, CAIDA has expanded its Ark platform with both hardware and software vantage points (VPs), and re-architected the ITDK probing software. We have been busy modernizing the software to enable us to collect ITDK snapshots more regularly, as well as annotate the router-level Internet topology graph with more features.

For IPv4, the ITDK probing software is based primarily around two reliable alias resolution techniques. The first, MIDAR, probes for IPID behavior that suggests that responses from different IP addresses had IPID values derived from a single counter, and thus the addresses are assigned to the same router. This inference is challenging because of the sheer number of router addresses observed in macroscopic Internet topologies, and the IPID value is held in a 16-bit field, requiring sophisticated probing techniques to identify distinct counters.  The second, iffinder, probes for common source IP addresses in responses to probes sent to different target IP addresses.

In the past few months, we have replaced the MIDAR and iffinder probing component on the Ark VPs to use alias resolution primitives present in scamper (specifically, the midarest, midardisc, and radargun primitives). We used the recently released scamper python module, and 902 lines of python, which executes on a single machine at CAIDA to coordinate the probing from many VPs.

The following table provides statistics illustrating the growth of the ITDK over the past year, driven by the expansion of Ark VPs. Overall, we increased the number of Ark VPs providing topology data from 93 to 142, the number of addresses probed from 2.6 to 3.6M, doubled the number of VPs that we use for alias resolution probing, and found aliases for 50% more addresses than a year ago.  Note that we use the term “node” to distinguish between our router inferences, and the actual routers themselves.  By definition all routers have at least two IP addresses; our “nodes with at least two IPs” are the subset of routers we were able to observe with that property.

 

2023-03 2024-02
Input:
Number of addresses probed: 2.64M 3.58M
Number of ark VPs: 93 142
Number of countries: 37 52
Alias resolution:
Number of ark VPs for MIDAR: 55 101
Number of ark VPs for iffinder: 46 101
MIDAR + iffinder Output:
Nodes with at least two IPs: 75,660 107,976
Addresses in nodes with at least two IPs:  284,479 425,964
MIDAR, iffinder, SNMP Output:
Nodes with at least two IPs: 124,857
Addresses in nodes with at least two IPs:  – 515,524

For 2024-02, we also evaluated the gains provided by SNMPv3 probing, following a paper published in IMC 2021 that showed many routers return a unique SNMP Engine ID in response to a SNMPv3 request; the basic idea is that different IP addresses returning the same SNMPv3 Engine ID are likely aliases.  Of the 3.58M addresses we probed, 672K returned an SNMPv3 response.  We inferred that IP addresses belonged to the same router when they return the same SNMP Engine ID, the size of the engine ID was at least 4 bytes, the number of engine boots was the same, and the router uptime was the same; we did not use the other filters in section 4.4 of the IMC paper.  This inferred 47,770 nodes with at least two IPs, many of which were shared with existing nodes found with MIDAR + iffinder. In total, when we combined MIDAR, iffinder, and SNMP probing, we obtained a graph with 124,857 nodes with at least two IPs, covering 515,524 addresses. We are including both the MIDAR + iffinder and MIDAR + iffinder + SNMP graphs in ITDK 2024-02.

Our ITDK also includes an IPv6 graph derived from speedtrap, which infers that IPv6 addresses belong to the same router if the IPID values in fragmented IPv6 responses appear to be derived from a single counter, and a graph derived from speedtrap and SNMP. For IPv6, the gains provided by SNMP are more significant, as the effectiveness of the IPv6 IPID as an alias inference vector wanes.  Of the 929K IPv6 addresses we probed, 68K returned an SNMPv3 response.

2023-03 2024-02
Input:
Number of addresses probed: 592K 929K
Number of ark VPs: 36 54
Number of countries: 18 25
Speedtrap output:
Nodes with at least two IPs: 4,945 4,129
Addresses in nodes with at least two IPs: 12,638 10,886
Speedtrap + SNMP output:
Nodes with at least two IPs: 8,935
Addresses in nodes with at least two IPs:  – 35,164

Beyond the alias resolution, the nodes are also annotated with their bdrmapIT-inferred operator (expressed as an ASN) as well as an inferred geolocation. We look up the PTR records of all router IP addresses with zdns, following CNAMEs where they exist, and provide these names as part of the ITDK.  For router geolocation, we used a combination of DNS-based heuristics, IXP geolocation (routers connected to an IXP are likely located at that IXP), and Maxmind GeoLite2.

We inferred DNS-based geolocation heuristics using RTT measurements from 148 Ark VPs in 52 countries to constrain Hoiho, which automatically infers naming conventions in PTR records as regular expressions, and covered 819 different suffixes (e.g.,  ^.+\.([a-z]+)\d+\.level3\.net$ and ^.+\.([a-z]{3})\d+\.[a-z\d]+\.cogentco\.com$ extract geolocation hints in hostnames for Level3 and Cogent in the above figure). There is no dominant source of geohint observed in these naming conventions; 443 (54.1%) embedded IATA airport codes (e.g. IAD, WAS for the Washington D.C. area), 310 (37.9%) embedded place names (e.g. Ashburn for Ashburn, VA, US), 87 (10.6%) embedded the first six characters of a CLLI code (e.g. ASBNVA for Ashburn), and 12 (1.4%) embedded locodes (e.g. USQAS for Ashburn, VA, US). Interestingly, the operators that used CLLI and locodes had conventions that were more congruent with observed RTT values than operators that used IATA codes or place names.  For the nodes in the ITDK, hoiho provided a geolocation inference for 127K, IXP provided a geolocation inference for 14K, and maxmind covered the remainder.  The rules we inferred are usable via CAIDA’s Hoiho API.

ITDKs older than one year are publicly available, and ITDK 2024-02 is available to researchers and CAIDA members, after completing a simple form for access.

Acknowledgment: We are grateful to all of the Ark hosting sites, MaxMind’s freely available geolocation database, and academic research access to Iconectiv’s CLLI database to support this work.

A First Look at Suspicious IRR Records

February 15th, 2024 by Ben Du

The Internet Routing Registry (IRR) is a set of distributed databases used by networks to register routing policy information and to validate messages received in the Border Gateway Protocol (BGP). 

 

First deployed in the 1990s, the IRR remains the most widely used database for routing security purposes, despite the existence of more recent and more secure alternatives such as the Resource Public Key Infrastructure (RPKI). Yet, the IRR lacks a strict validation standard and the limited coordination across different database providers can lead to inaccuracies. Moreover, it has been reported that attackers have begun to register false records in the IRR to bypass operators’ defenses when launching attacks on the Internet routing system, such as BGP hijacks. 

 

In our paper, IRRegularities in the Internet Routing Registry, we at CAIDA/UC San Diego, in collaboration with Georgia Tech and Stanford, proposed a workflow to identify suspicious IRR records. In this post, we succinctly describe how we quantified the inconsistencies across all IRR databases, identified likely suspicious IRR records, and validated our results against relevant studies.

 

Reported false IRR records

 

Each IRR database is managed independently under different policies and registration processes. The five RIRs (RIPE, ARIN, APNIC, AFRINIC, and LACNIC) manage authoritative IRR databases. Routing information registered in those IRR databases undergoes a validation process against the address ownership information to ensure correctness. IRR databases operated by other institutions are non-authoritative IRR databases and are not strictly validated.

 

To increase the likelihood of launching a successful BGP hijack attack, malicious actors may inject false records into non-authoritative IRR databases. There have been reported cases of successful BGP hijacking attempts that also abused the IRR.

 

In one prominent case, an attacker successfully hijacked Amazon’s address space that was used to host Celer Network’s cryptocurrency exchange website. The attacker, AS209243 (QuickHost.uk), pretended to be an upstream provider of AS16509 (Amazon) by registering false objects in ALTDB. In a different case, AS207427 (GoHosted.eu) registered false IRR objects for 3 UCSD-announced prefixes and hijacked those prefixes in BGP for more than a month.

 

Workflow to identify suspicious IRR records

 

Following the diagram in Figure 1, we consider an IRR record in a non-authoritative database suspicious if it satisfies the following conditions:

  1. The IRR record conflicted with corresponding records (containing the same prefix but different origin) in the authoritative IRR database.
  2. The prefix in the IRR record from step 1 was originated in BGP by multiple ASes, one of which is the AS in the IRR record.

 

We validate our inferred suspicious IRR records with the Resource Public Key Infrastructure (RPKI), a more recent and secure alternative of the IRR. We also check if the origin ASes in the suspicious IRR records were classified as serial hijacker ASes by Testart et al. published at IMC 2019.

Figure 1. Workflow to identify suspicious IRR records (solid arrows) and methods to validate our results (dotted arrows).

 

Baseline: Inconsistency across IRR databases

 

We discuss the results of the first step in the workflow above. To understand the baseline characteristics of the IRR databases, we analyze the consistency between all pairs of IRR databases.

 

Figure 2 shows the percentage of records with the same prefix but different origin ASes between pairs of IRRs. We found that most IRR databases have mismatching records with one another, consistent with persistent neglect by IRR users and thus an increasing number of outdated entries. We also noticed instances where a company registered records in multiple IRR databases, but only updated the records in one IRR database, causing inter-IRR inconsistency. 

 

Most surprising were the mismatching records between pairs of authoritative IRR databases, since each RIR only allows registration of records containing address blocks managed by that RIR, which do not overlap with each other. We speculate that those mismatching records correspond to address space that was transferred across RIRs, and the address owner from the previous RIR did not remove the outdated object. As of January 2024, two months since our paper was published, the RIRs have removed all inconsistent IRR records in their authoritative databases. We provide the updated results on github https://github.com/CAIDA/IRR-IRRegularities-Analysis

Figure 2. Fraction of inconsistent records in the IRR on the Y-axis with respect to the IRR on the X-axis. The denominators shown in Figure 1b in the paper.

 

Suspicious records in RADB

 

Out of 1.5 million RADB records (1.2 million unique prefixes), we identified 34,199 potentially suspicious records. We further checked the RPKI consistency of those records. Out of those 34,199 records, 4,082 records had a mismatching ASN, 144 had prefixes that were too specific, and 9,450 had no matching ROA in RPKI. To further narrow down the list of suspicious IRR records, we removed the ones whose AS appear in other RPKI-consistent records (assuming those ASes were unlikely to be malicious), leaving 6,373 suspicious records. Network operators who use IRR-based filtering should carefully consider those suspicious records.

 

We also compared our list of 34,199 suspicious records with the list of serial hijackers from Testart et al.  and found 5,581 records registered by 168 serial hijacker ASes. We found one of those ASes to be a small US-based ISP with 10 customers according to CAIDA’s AS Rank. Another serial hijacker AS was a European hosting provider with more than 100 customers, which was also known to be exploited by attackers to abuse the DNS system. However, networks may have registered both suspicious and benign records, which can complicate the inference of suspicious IRR records.

 

Summary

We provided a first look at inconsistencies across IRR databases and proposed an approach to infer suspicious activities in the IRR without external sources of ground truth. We found IRR databases prone to staleness and errors, confirming the importance of operators transitioning to RPKI-based filtering. We hope this work inspires new directions in automating the detection of abuse of IRRs, ideally in time to prevent or thwart an attacker’s ultimate objective. We publicly provide our analysis code on Github https://github.com/CAIDA/IRR-IRRegularities-Analysis with more recent sample data and results.

Developing active Internet measurement software locally to run on Ark

January 24th, 2024 by Matthew Luckie

In the first part of our blog series, we introduced our brand-new python module for scamper, the packet-prober underpinning much of Ark’s ongoing measurements. One aspect that we highlighted was the ability for potential users of Ark to develop their code locally, before running it on the Ark platform. When I develop measurement applications, I use a couple of local Raspberry Pis and my own workstation to get the code correct, and then copy the code to the CAIDA system to run the experiment using available Ark vantage points. The goal of this blog article is to describe different ways to locally develop your measurement experiment code.

Example #1: Starting small with one scamper process.

The easiest way to begin is with one scamper process running on the same system where you develop your python code. With scamper installed (we recommend that you use a package listed on the scamper website), start a scamper process, and make it available for measurement commands on a Unix domain socket. For example, you might run scamper as follows:

$ scamper -U /tmp/scamper -p 100

This will create a Unix domain socket to drive scamper at /tmp/scamper, and tell scamper that it can probe at up to 100 packets/second. You can adjust these parameters to what is appropriate locally.

You can then develop and debug your measurement code in Python. To use this scamper process, your Python code might begin as follows:

01 from scamper import ScamperCtrl
02
03 # use the scamper process available at /tmp/scamper
04 ctrl = ScamperCtrl(unix="/tmp/scamper")
05
06 # do a simple ping to 8.8.8.8 and print the outcome
07 o = ctrl.do_ping("8.8.8.8")
08 if o.min_rtt is not None:
09   print(f"{o.min_rtt.total_seconds()*1000):.1f} ms")
10 else:
11   print("no reply")

Example #2: Coordinating measurements among VPs.

Once you are comfortable using the python module with a single local scamper instance, you might want to test your code with multiple scamper instances, each representing a distinct vantage point. The scamper software includes the sc_remoted interface to support that. sc_remoted has features for authenticating endpoints with TLS, but you might choose to initially operate endpoints without the complexity of TLS.

sc_remoted listens on a port for inbound scamper connections, and makes Unix domain sockets — one for each VP — available in a nominated directory. The best idea is to create an empty directory for these sockets. You might run sc_remoted as follows:

$ mkdir -p /path/to/remote-sockets
$ sc_remoted -U /path/to/remote-sockets -P 50265

The first command creates the directory, because sc_remoted will not create that directory for you. The second command starts sc_remoted listening on port 50265 for incoming scamper connections, and will place Unix domain sockets in /path/to/remote-sockets as they arrive.  Note, we use /path/to as a placeholder to the actual path in your local file system that is appropriate for your environment; you might put these sockets in a directory somewhere in your home directory, for example.

Then, on the systems that you want to act as vantage points, the following command:

$ scamper -p 100 -R 192.0.2.28:50265 -M foo.bar

will (1) start a scamper process, (2) tell it that it can probe at up to 100 packets-per-second, (3) connect it to the specified IP address and port to receive measurement commands from, and (4) tell it to identify itself as “foo.bar” to the remote controller. If you go into /path/to/remote-sockets, you might see the following:

$ cd /path/to/remote-sockets
$ ls -l
total 0
srwx------ 1 mjl mjl 0 Jan 22 16:57 foo.bar-192.0.2.120:12369

This socket represents the scamper process you just started. The filename begins with foo.bar, the parameter that you gave to scamper to identify itself. After the dash is the IP address and port number that the remote controller observed the remote system coming from. You can connect as many additional scamper instances as you like, and you will see them listed in the directory individually. You should name each differently with something meaningful to you (foo.bar, bar.baz, etc) so that you can identify them on the system on which you’re writing your python code.

The python code we wrote in Example #1 above might be modified as follows:

01 import sys
02 from scamper import ScamperCtrl
03
04 if len(sys.argv) != 2:
05   print("specify path to unix domain socket")
06   sys.exit(-1)
07
08 # use the remote scamper process available at the specified location
09 ctrl = ScamperCtrl(remote=sys.argv[1])
10
11 # do a simple ping to 8.8.8.8 and print the outcome
12 o = ctrl.do_ping("8.8.8.8")
13 if o.min_rtt is not None:
14   print(f"{o.min_rtt.total_seconds()*1000):.1f} ms")
15 else:
16   print("no reply")

And run as:

$ python ping.py /path/to/remote-sockets/foo.bar-192.0.2.120\:12369

If you have multiple remote-sockets in the directory, you can add them individually, or use all sockets in the directory. For example:

01 import sys
02 from datetime import timedelta
03 from scamper import ScamperCtrl
04
05 if len(sys.argv) != 3:
06   print("usage: single-radius.py $dir $ip")
07   sys.exit(-1)
08
09 ctrl = ScamperCtrl(remote_dir=sys.argv[1])
10 for i in ctrl.instances():
11   ctrl.do_ping(sys.argv[2], inst=i)
12
13 min_rtt = None
14 min_vp = None
15 for o in ctrl.responses(timeout=timedelta(seconds=10)):
16   if o.min_rtt is not None and (min_rtt is None or min_rtt > o.min_rtt):
17     min_rtt = o.min_rtt
18     min_vp = o.inst
19
20 if min_rtt is not None:
21   print(f"{min_vp.name} {(min_rtt.total_seconds()*1000):.1f} ms")
22 else:
23   print(f"no responses for {sys.argv[2]}")

and run this command:

$ python single-radius.py /path/to/remote-sockets 8.8.8.8

We encourage you to reach out via email if you have questions about using the module. In the first instance, you can email ark-info at caida.org.

Towards a Domain Specific Language for Internet Active Measurement

January 16th, 2024 by Matthew Luckie

This is the first in a series of essays about CAIDA’s new effort to reduce the barrier to performing a variety of Internet measurements.

Network operators and researchers often require the ability to conduct active measurements of networks from a specific location in order to understand some property of the network. However, obtaining access to a vantage point at a given location is challenging, as there can be significant trust barriers that prevent access: a platform operator has to provide vantage point hosts with guarantees about the activity that their vantage points will exhibit, and a platform operator has to trust that users will stay within those guarantees. Current access control to active measurement infrastructure has two extremes: access that allows for trusted users to run arbitrary code, and API access that allows arbitrary users to schedule a (limited) set of measurements, and obtain their results. Prior research thrusts in active measurement design have focused on interfaces that allow a user to request a host to send arbitrary packets, leaving the implementation of the measurement to the user. However, this design pattern limits the guarantees that a platform operator can provide a vantage point host regarding what their vantage point will actually do. A domain-specific language for conducting active measurements can alleviate these concerns because it (1) allows a platform operator to specify the measurements that a user can run, and communicate to the host what their vantage point will do, (2) provides users reference implementations of measurement applications that act as building blocks to more complex measurements.

Over the past six months, in consultation with members of the active measurement community, CAIDA has been working towards a next-generation measurement infrastructure, built on the existing Archipelago (Ark) platform. One aspect of this platform is the notion of a researcher development environment that allows for complex, distributed, and reactive measurements built on a well-defined set of measurement primitives. In an effort to make the Ark platform easier to use for measurement researchers, while also providing important access control, CAIDA has developed the scamper python module that provides an interface to the measurement primitives available on each of the Ark nodes. Today, we are releasing the source code of that module, so that researchers can develop and test complex measurements locally, before running vetted experiments on Ark.

Scamper architecture chart

The architecture of scamper. Measurement tasks are supplied from one or more input sources, including from an input file, from the command line, or from a control socket.

The module provides user-friendly interfaces to existing scamper functionality. We illustrate the module with some examples.

Example #1: Implementation of RTT-based geolocation measurement

The following is an implementation of the well-known single-radius measurement, which conducts delay measurements to an IP address from a distributed set of vantage points, and reports the shortest of all the RTTs obtained with the name of the monitor, which on Ark, is derived from its location (e.g., lax-us, hlz2-nz, ams-nl, and so on). Researchers and operators might use this technique to understand approximately where a system is located, using the RTT constraint of the vantage point that reports the shortest delay.

01 import sys
02 from datetime import timedelta
03 from scamper import ScamperCtrl
04
05 if len(sys.argv) != 3:
06   print("usage: single-radius.py $dir $ip")
07   sys.exit(-1)
08
09 ctrl = ScamperCtrl(remote_dir=sys.argv[1])
10 for i in ctrl.instances():
11   ctrl.do_ping(sys.argv[2], inst=i)
12
13 min_rtt = None
14 min_vp = None
15 for o in ctrl.responses(timeout=timedelta(seconds=10)):
16   if o.min_rtt is not None and (min_rtt is None or min_rtt > o.min_rtt):
17     min_rtt = o.min_rtt
18     min_vp = o.inst
19
20 if min_rtt is not None:
21   print(f"{min_vp.name} {(min_rtt.total_seconds()*1000):.1f} ms")
22 else:
23   print(f"no responses for {sys.argv[2]}")

This implementation takes two parameters (lines 5-7) — a directory that contains a set of unix domain sockets, each of which represents an interface to a single vantage point, and an IP address to probe. On line 9, we open an interface (represented by a ScamperCtrl object) that contains all of the vantage points in that directory. We then send a ping measurement to each of the vantage point instances (lines 10-11). These ping measurements operate in parallel — the ping measurements on each of the nodes operate asynchronously. We then collect the results of the measurements (lines 13-18), noting the minimum observed RTT, and the vantage point where it came from. We pass a 10-second timeout on line 15, so that a vantage point that experiences an outage after we send the measurements does not hold up the whole experiment. Finally, on lines 20-23, we print the result of the measurement.

Example #2: RTTs to authoritative name servers of a specific domain

The next example shows a more complex measurement. Let’s say we want to know the RTTs to the authoritative name servers for a zone from a single vantage point.

01 import sys
02 from datetime import timedelta
03 from scamper import ScamperCtrl
04
05 if len(sys.argv) != 3:
06   print("usage: authns-delay.py $vp $zone")
07   sys.exit(-1)
08
09 ctrl = ScamperCtrl(remote=sys.argv[1])
10
11 # get the list of NS for the zone
12 o = ctrl.do_dns(sys.argv[2], qtype='NS', wait_timeout=1, sync=True)
13
14 # issue queries for the IP addresses of the authoritative servers
15 ns = {}
16 for rr in o.ans():
17   if rr.ns is not None and rr.ns not in ns:
18     ns[rr.ns] = 1
19     ctrl.do_dns(rr.ns, qtype='A', wait_timeout=1)
20     ctrl.do_dns(rr.ns, qtype='AAAA', wait_timeout=1)
21
22 # collect the unique addresses out of the address lookups
23 addr = {}
24 for o in ctrl.responses(timeout=timedelta(seconds=3)):
25   for a in o.ans_addrs():
26     addr[a] = o.qname
27
28 # collect RTTs for the unique IP addresses
29 for a in addr:
30   ctrl.do_ping(a)
31 for o in ctrl.responses(timeout=timedelta(seconds=10)):
32   print(f"{addr[o.dst]} {o.dst} " +
33         (f"{(o.min_rtt.total_seconds() * 1000):.1f}"
34          if o.min_rtt is not None else "???"))

This implementation takes two parameters (lines 5-7) — a single vantage point, and a zone name to study. As before, we open an interface to that VP on line 9, and then issue a DNS query for the authoritative name servers for the zone (line 12).

There are a couple of interesting things to note about line 12. First, we do not pass a handle representing the VP instance to the do_dns method, as the ScamperCtrl interface only has a single instance associated with it — it is smart enough to use that single instance for the measurement. Second, we pass sync=True to make the measurement synchronous — the method does not return until it has the results of that single measurement. This is shorter (in lines of code) and more readable than issuing an asynchronous measurement and then collecting the single result. Then, we issue asynchronous queries for the IPv4 and IPv6 addresses for the name servers returned (lines 14-20) and send ping measurements for each of the addresses (lines 29-30). Finally, we print the names of the nameservers, their IP addresses, and the minimum RTT observed to each.

The scamper python module supports most of the measurement primitives currently available in scamper: ping, traceroute, DNS query, alias resolution, HTTP, and simple UDP probes. We’ve used the module internally to: (1) reproduce the data collection methodology of a recent router fingerprinting method; (2) study the deployment of Netflix fast.com speed test endpoints, (3) implement MIDAR; (4) study anycast open resolvers, and (5) monitor serial number changes of zones amongst a set of nameservers authoritative for a zone. One important feature of our module is that it provides a python interface, which means that you can use our measurement module alongside existing python modules that parse JSON, etc. The documentation for the module is publicly available and we will write additional blog entries in the coming days that show more of its features, in a digestible form.

In the short term, measurement researchers can request access to the infrastructure to run vetted experiments by emailing ark-info at caida.org. Note: the access does not provide a login on any of the Ark nodes. Rather, it provides access to a system that can access the measurement primitives of the vantage points, as illustrated above. Again, we are releasing the python module to allow researchers to develop and debug experiments locally, before running them on Ark. We hope that this approach provides a convenient development lifecycle for researchers, as the CAIDA system you will have access to when running the experiments will not necessarily have the local development environment that you are accustomed to.

The module itself is written in cython, providing a wrapper around two C libraries in scamper that do much of the heavy lifting. You build and install the module using the instructions on the scamper website, install the module using the Ubuntu PPA (preferred if you are using Ubuntu), or install the module using one of the packages available on other operating systems as these become available.