We made two different types of measurement:
The measurement methods and result analysis are discussed in our paper (PDF).
Here you can download the raw measurement data. The file format is SQLite3 compressed with bzip2. The database files do not contain indexes.
This file is no longer available for download.
SQLite database schema:
-- dependencies: -- answerip -> response -> run -- ^ -- | -- query CREATE TABLE answerip(response INTEGER, ttl INTEGER, hosttype TEXT, host TEXT, FOREIGN KEY (response) REFERENCES response(id)); CREATE TABLE query(run INTEGER, ip TEXT, domain TEXT, tid INTEGER, ts REAL, FOREIGN KEY (run) REFERENCES run(id)); CREATE TABLE response(id INTEGER PRIMARY KEY AUTOINCREMENT, run INTEGER, ip TEXT, port INTEGER, tid INTEGER, ts REAL, domain TEXT, rcode TEXT, flags TEXT, FOREIGN KEY (run) REFERENCES run(id)); CREATE TABLE run(id INTEGER PRIMARY KEY AUTOINCREMENT, startstamp REAL, startday TEXT DEFAULT CURRENT_DATE, starttime TEXT DEFAULT CURRENT_TIME, endstamp REAL, eagain INTEGER);
This is a stateless measurement (send query, record responses, don't care about timeouts or errors). Brief explanation of tables:
tid
is the transaction id, ts is timestampdomain
is the query name copied from QUESTION section or NULL if none foundrcode
and flags
standard DNS header fields in text format. rcode
MALFORMED means the message could not be parsed by dnspythonhosttype
is the RR type (A, CNAME)host
is the IPv4 address or CNAME targetThis file is no longer available for download.
SQLite database schema:
-- dependencies: -- answerip -> response -> run -- ^ -- | -- query CREATE TABLE answerip(response INTEGER, ttl INTEGER, hosttype TEXT, host TEXT, FOREIGN KEY (response) REFERENCES response(id)); CREATE TABLE query(run INTEGER, ip TEXT, experiment INTEGER, ts REAL, FOREIGN KEY (run) REFERENCES run(id)); CREATE TABLE response(id INTEGER PRIMARY KEY AUTOINCREMENT, run INTEGER, ip TEXT, port INTEGER, experiment INTEGER, ts REAL, domain TEXT, rcode INTEGER, flags INTEGER, FOREIGN KEY (run) REFERENCES run(id)); CREATE TABLE run(id INTEGER PRIMARY KEY AUTOINCREMENT, startstamp REAL, startday TEXT DEFAULT CURRENT_DATE, starttime TEXT DEFAULT CURRENT_TIME, endstamp REAL, eagain INTEGER);
This is a stateful measurement. Each open resolver is sent 1165 different queries (experiments) with some idle time between each query. In case of timeout, the query is sent again. After 5 timeouts, we abort sending further queries to the open resolver. Around 30,000 resolvers have incomplete data because the measurement was stopped prematurely due to complaints.
The experiments no. 0 to 9 are various supplemental queries, e.g. to find out whether the open resolver is returning correct responses. Experiments no. 10 to 1164 are the main measurement with 1155 public root and top-level domain name servers. The list of experiments shows which experiment tests which name server and for which domain this server is authoritative for (e.g. experiment no. 745 is testing "a.nic.de." which is authoritative for "de."). The domain name and other query contents can be generated with experiments.py.
IP addresses of open resolvers are anonymized in the form of DE-AS680-00001, where DE is the country code, AS680 the AS number, and 00001 a unique identifier within that AS (AS and geolocation information created with GeoLite data from MaxMind).
Database format is similar to the above probing measurement, except for the following changes:
domain
and tid
with experiment
tid
with experiment
domain
contains a short mnemonic instead of the full domain name, e.g. "$E3" instead of "sigfail.verteiltesysteme.net.", except when the domain name differs from the expected name or would be ambigous for other reasonsrcode
and flags
are integers instead of textrcode
-1 means malformed message, -2 is a timeout with flags
indicating the attempt 1 to 5