| 28 | | DNS lookup on its host's IP address and then obtains the SRV resource |
| 29 | | record associated with the host's domain name. For example, a host with |
| 30 | | IPv4 address w.x.y.z obtains the PTR record at |
| 31 | | |
| 32 | | :: |
| 33 | | z.y.x.w.in-addr.arpa |
| 34 | | |
| 35 | | Assume the returned PTR record contains example.com. The client then |
| 36 | | looks up the SRV record at |
| 37 | | |
| 38 | | :: |
| 39 | | _bittorrent._tcp.example.com |
| 40 | | |
| 41 | | The target field in the SRV resource record contains the domain name |
| 42 | | of the cache and the port specifies the location on that cache where |
| 43 | | the BitTorrent implementation listens. |
| 44 | | |
| 45 | | The SRV resource record type is described in RFC 2782 [#RFC-2782]_. Reverse DNS |
| 46 | | lookups are described in RFC 1034 [#RFC-1034]_. |
| | 37 | DNS lookup on its external IP address and then obtains the BitTorrent |
| | 38 | SRV resource record associated with the host's domain name. For |
| | 39 | example, a host with address 69.107.0.14 obtains the PTR record at |
| | 40 | |
| | 41 | :: |
| | 42 | |
| | 43 | 14.0.107.69.in-addr.arpa |
| | 44 | |
| | 45 | The client's host IP address may not match the host's IP address as |
| | 46 | seen outside the client's private network. We address this in Section |
| | 47 | `Network Address Translators`_. |
| | 48 | |
| | 49 | The PTR resource record returned for this example contains domain name |
| | 50 | |
| | 51 | :: |
| | 52 | |
| | 53 | adsl-69-107-0-14.dsl.pltn13.pacbell.net |
| | 54 | |
| | 55 | The client then looks up the SRV records at |
| | 56 | |
| | 57 | :: |
| | 58 | |
| | 59 | _bittorrent-tracker._tcp.adsl-69-107-0-14.dsl.pltn13.pacbell.net |
| | 60 | |
| | 61 | If no SRV record is found, one or more subsequent queries take place as |
| | 62 | described in `Iterative Queries`_. |
| | 63 | |
| | 64 | The target field in each returned SRV resource record contains the |
| | 65 | domain name of a tracker and the port on which the tracker runs. This |
| | 66 | tracker is called a *cache tracker*, but the protocol to talk to this |
| | 67 | tracker is no different from the standard BitTorrent tracker protocol |
| | 68 | described in [#BEP-3]_. |
| | 69 | |
| | 70 | When the BitTorrent client joins a swarm it announces to one or more |
| | 71 | of the trackers referenced in the .torrent file and announces to the |
| | 72 | cache tracker. The cache tracker returns peers which may be caches or |
| | 73 | other peers that announced the same file to the cache tracker. |
| | 74 | |
| | 75 | A cache is a BitTorrent peer. A client MAY treat it preferentially. |
| | 76 | |
| | 77 | Reverse DNS lookups are described in RFC 1034 [#RFC-1034]_. |
| | 78 | The SRV resource record type is described in RFC 2782 [#RFC-2782]_. |
| | 79 | |
| | 80 | |
| | 81 | Iterative Queries |
| | 82 | ================= |
| | 83 | |
| | 84 | The domain name returned from the reverse DNS lookup is specific to |
| | 85 | the querying host. In the naive implementation in DNS, there would be |
| | 86 | one SRV resource record for every querying host. The most obvious |
| | 87 | solution is to use a wildcard of the form:: |
| | 88 | |
| | 89 | *.pacbell.net |
| | 90 | |
| | 91 | However, if wildcards are implemented according to the algorithm in |
| | 92 | section 4.3.2 in [#RFC-1034]_ then all subdomains of pacbell.net that |
| | 93 | do not have an exact label match will match the wildcard. Thus, |
| | 94 | |
| | 95 | :: |
| | 96 | |
| | 97 | _jabber._tcp.pacbell.net |
| | 98 | |
| | 99 | and |
| | 100 | |
| | 101 | :: |
| | 102 | |
| | 103 | _bittorrent-tracker._tcp.pacbell.net |
| | 104 | |
| | 105 | both match \*.pacbell.net and all SRV resource records with owner |
| | 106 | \*.pacbell.net would be returned with the name set to the name in the |
| | 107 | query. Thus it would be impossible to disambiguate Jabber from |
| | 108 | BitTorrent SRV records without further information. This behavior is |
| | 109 | implemented with BIND 9.4.1. |
| | 110 | |
| | 111 | The natural solution would be to specify domain names of the type |
| | 112 | |
| | 113 | :: |
| | 114 | |
| | 115 | _bittorrent-tracker._tcp.*.pacbell.net |
| | 116 | |
| | 117 | However, section 4.3.3 in [#RFC-1034]_ specifies that wildcards only |
| | 118 | appear as the first label in a domain name. This restriction was |
| | 119 | lifted in [#RFC-4592]_, but not with semantics applicable to our use |
| | 120 | case. An asterisk not at the beginning of a domain name is not |
| | 121 | treated like a wildcard. Only a lookup for the exact domain name |
| | 122 | |
| | 123 | :: |
| | 124 | |
| | 125 | _bittorrent-tracker._tcp.*.pacbell.net |
| | 126 | |
| | 127 | matches. |
| | 128 | |
| | 129 | We propose an alternative that avoids wildcards and has the advantage |
| | 130 | that it allows suborganizations to override the SRV records provided |
| | 131 | by parent organizations: the peer starts by querying using its |
| | 132 | fully-qualified domain name returned from the reverse DNS lookup, and |
| | 133 | if this fails then it queries again after removing the most specific |
| | 134 | (leftmost) label in the domain name. For example, if no SRV records |
| | 135 | are returned when querying for |
| | 136 | |
| | 137 | :: |
| | 138 | |
| | 139 | _bittorrent-tracker._tcp.adsl-69-107-0-14.dsl.pltn13.pacbell.net |
| | 140 | |
| | 141 | then the client queries for |
| | 142 | |
| | 143 | :: |
| | 144 | |
| | 145 | _bittorrent-tracker.dsl.pltn13.pacbell.net |
| | 146 | |
| | 147 | and then |
| | 148 | |
| | 149 | :: |
| | 150 | |
| | 151 | _bittorrent-tracker.pltn13.pacbell.net |
| | 152 | |
| | 153 | The search removes one domain at a time terminating when one or more |
| | 154 | resource records are found or before querying the root domain or |
| | 155 | top-level domains that are not ccTLDs, e.g., .com, .org, .net. We |
| | 156 | avoid querying the root or global top-level domains given the low |
| | 157 | likelihood that caches would be defined globally, and thus clients |
| | 158 | would unnecessarily burden the root domain name servers with queries |
| | 159 | generating negative results. We considered stopping before querying |
| | 160 | country-level domains, but a country providing public infrastructure |
| | 161 | might choose to provide caches. |
| 54 | | an IP address allocated from one of the three private IP address |
| 55 | | ranges defined by IANA, i.e., 10.*.*.*, 172.*.*.*, or 192.*.*.*. When |
| 56 | | communicating with hosts outside the private network, the NAT |
| 57 | | translates the private IP to an IP address that is globally routable. |
| 58 | | This globally routable address is the host's *public IP address*. |
| 59 | | |
| 60 | | When finding a cache, the BitTorrent client must use its host's public |
| 61 | | IP address. A BitTorrent client can obtain its host's public IP by |
| 62 | | either querying the tracker and looking at the value to the returned |
| 63 | | *external ip* key [#BEP-24]_ or from other peers using the *yourip* |
| | 169 | an IP address allocated from one of the private IP address ranges |
| | 170 | defined by IANA, e.g., ranges with prefixes 10/8, 172.16/12, and |
| | 171 | 192.168/16. When communicating with hosts outside the private |
| | 172 | network, the NAT translates the private IP to a globally-routable IP |
| | 173 | address. This globally-routable address is the host's *external IP |
| | 174 | address*. |
| | 175 | |
| | 176 | When finding a cache, the BitTorrent client must use its host's |
| | 177 | external IP address. A BitTorrent client can obtain its host's |
| | 178 | external IP either from the *external ip* key returned from a tracker |
| | 179 | implementing BEP 24 [#BEP-24]_ or from peers using the *yourip* |
| | 182 | |
| | 183 | Example |
| | 184 | ======= |
| | 185 | |
| | 186 | In our example, we used AT&T's PacBell network. AT&T could implement |
| | 187 | cache discovery by adding the following lines to the zone file for |
| | 188 | pacbell.net, |
| | 189 | |
| | 190 | :: |
| | 191 | |
| | 192 | ; name ttl cls rr pri weight port target |
| | 193 | _bittorrent-tracker._tcp.pacbell.net. 600 IN SRV 5 0 6969 tracker |
| | 194 | |
| | 195 | Now when a client performs cache discovery, it performs three DNS |
| | 196 | queries removing labels before reaching the domain name pacbell.net, |
| | 197 | at which point the SRV record would be returned and the client would |
| | 198 | then query tracker.pacbell.net to obtain caches. |
| | 199 | |
| | 200 | In Python, the cache tracker's port and domain can be obtained using |
| | 201 | PyDNS using the following code:: |
| | 202 | |
| | 203 | import DNS |
| | 204 | |
| | 205 | tlds = ["com", "net", "org"] # add more TLDs here. |
| | 206 | |
| | 207 | name = DNS.revlookup( "69.107.0.14" ) |
| | 208 | names = name.split('.') |
| | 209 | while names and names[0] not in tlds: |
| | 210 | name = "_bittorrent._tcp." + ".".join(names) |
| | 211 | req = DNS.Request( name=name, qtype="SRV", protocol="udp") |
| | 212 | response = req.req() |
| | 213 | if response.answers: |
| | 214 | break |
| | 215 | del names[0] |
| | 216 | |
| | 217 | print "response=", response.show() |
| | 218 | |
| | 219 | which might generate output like |
| | 220 | |
| | 221 | :: |
| | 222 | |
| | 223 | response= ; <<>> PDG.py 1.0 <<>> _bittorrent._tcp.pacbell.net SRV |
| | 224 | ;; options: recurs |
| | 225 | ;; got answer: |
| | 226 | ;; ->>HEADER<<- opcode 0, status NOERROR, id 0 |
| | 227 | ;; flags: qr aa rd ra; Ques: 1, Ans: 1, Auth: 2, Addit: 3 |
| | 228 | ;; QUESTIONS: |
| | 229 | ;; _bittorrent._tcp.pacbell.net, type = SRV, class = IN |
| | 230 | |
| | 231 | ;; ANSWERS: |
| | 232 | _bittorrent._tcp.pacbell.net 600 SRV (5, 0, 6969, 'cache.pacbell.net') |
| | 233 | |
| | 234 | ;; AUTHORITY RECORDS: |
| | 235 | pacbell.net 86400 NS ns1.pbi.net |
| | 236 | pacbell.net 86400 NS ns2.pbi.net |
| | 237 | |
| | 238 | ;; ADDITIONAL RECORDS: |
| | 239 | cache.pacbell.net 86400 A 69.107.0.1 |
| | 240 | ns1.pacbell.net 86400 A 206.13.28.11 |
| | 241 | ns2.pacbell.net 86400 A 206.13.29.11 |
| | 242 | |
| | 243 | ;; Total query time: 0 msec |
| | 244 | ;; To SERVER: localhost |
| | 245 | ;; WHEN: Mon May 19 16:00:12 2008 |
| | 246 | |
| | 247 | The answer above is fictional since AT&T does not at this time |
| | 248 | implement SRV records for BitTorrent trackers. |
| | 249 | |
| | 250 | In Microsoft Windows, the port and domain name of the server can be |
| | 251 | obtained using WinDNS (Dnsapi.lib) using DnsQuery(). In Unix, the |
| | 252 | relevant call is res_query() from libresolv. |