| 1 | BEP: 22 |
|---|
| 2 | Title: BitTorrent Local Tracker Discovery Protocol |
|---|
| 3 | Version: $Revision$ |
|---|
| 4 | Last-Modified: $Date$ |
|---|
| 5 | Author: David Harrison <dave@bittorrent.com>, Stanislav Shalunov <shalunov@bittorrent.com>, Greg Hazel <greg@bittorrent.com> |
|---|
| 6 | Status: Draft |
|---|
| 7 | Type: Standards track |
|---|
| 8 | Content-Type: text/x-rst |
|---|
| 9 | Created: 12-May-2008 |
|---|
| 10 | Post-History: |
|---|
| 11 | |
|---|
| 12 | Motivation |
|---|
| 13 | ========== |
|---|
| 14 | |
|---|
| 15 | Some Internet Service Providers (ISPs) may wish to localize traffic |
|---|
| 16 | to reduce transit costs, reduce internal traffic, and improve user |
|---|
| 17 | experience by speeding up downloads. |
|---|
| 18 | |
|---|
| 19 | With this extension, BitTorrent clients are able to discover a tracker |
|---|
| 20 | nearby on the network, and via this tracker discover nearby caches or |
|---|
| 21 | peers. A cache may simply be a fast peer in the middle of the network. It |
|---|
| 22 | might also have substantial disk space. The client communicates with a |
|---|
| 23 | cache using the normal BitTorrent protocol. |
|---|
| 24 | |
|---|
| 25 | When a cache is present, the user benefits from having a high capacity |
|---|
| 26 | peer from which the user's client downloads and to which it can |
|---|
| 27 | delegate seeding. When a cache inside the user's ISP network seeds on |
|---|
| 28 | behalf of the client, it frees upstream capacity in the user's access |
|---|
| 29 | network benefiting the user and those that share the access network. |
|---|
| 30 | When subsequent peers transfer from their ISP's cache, the ISP |
|---|
| 31 | experiences less transit traffic. |
|---|
| 32 | |
|---|
| 33 | The scope of this BEP is limited to the local tracker discovery |
|---|
| 34 | process. Extensions to the BitTorrent protocol suite to delegate |
|---|
| 35 | seeding or improve cache performance are beyond the scope of this BEP. |
|---|
| 36 | |
|---|
| 37 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL |
|---|
| 38 | NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and |
|---|
| 39 | "OPTIONAL" in this document are to be interpreted as described in |
|---|
| 40 | IETF RFC 2119 [#RFC-2119]_. |
|---|
| 41 | |
|---|
| 42 | Client implementation of local tracker discovery is OPTIONAL. Clients |
|---|
| 43 | MUST NOT announce private torrents to a local tracker. It is |
|---|
| 44 | RECOMMENDED that clients provide a user option for turning off local |
|---|
| 45 | tracker discovery. Local tracker discovery MAY be off by default. |
|---|
| 46 | Clients MAY automatically turn off caching if the performance benefit |
|---|
| 47 | is not obvious. Determining obviousness is beyond the scope of this |
|---|
| 48 | BEP. |
|---|
| 49 | |
|---|
| 50 | The Discovery Mechanism |
|---|
| 51 | ======================= |
|---|
| 52 | |
|---|
| 53 | To find the tracker for its ISP, a BitTorrent client performs a reverse |
|---|
| 54 | DNS lookup on its external IP address and then obtains the BitTorrent |
|---|
| 55 | SRV resource record associated with the host's domain name. For |
|---|
| 56 | example, a host with address 69.107.0.14 obtains the PTR record at |
|---|
| 57 | |
|---|
| 58 | :: |
|---|
| 59 | |
|---|
| 60 | 14.0.107.69.in-addr.arpa |
|---|
| 61 | |
|---|
| 62 | The client's host IP address may not match the host's IP address as |
|---|
| 63 | seen outside the client's private network. We address this in Section |
|---|
| 64 | `Network Address Translators`_. |
|---|
| 65 | |
|---|
| 66 | The PTR resource record returned for this example contains domain name |
|---|
| 67 | |
|---|
| 68 | :: |
|---|
| 69 | |
|---|
| 70 | adsl-69-107-0-14.dsl.pltn13.pacbell.net |
|---|
| 71 | |
|---|
| 72 | The client then looks up the SRV records at |
|---|
| 73 | |
|---|
| 74 | :: |
|---|
| 75 | |
|---|
| 76 | _bittorrent-tracker._tcp.adsl-69-107-0-14.dsl.pltn13.pacbell.net |
|---|
| 77 | |
|---|
| 78 | If no SRV record is found, one or more subsequent queries take place as |
|---|
| 79 | described in `Iterative Queries`_. |
|---|
| 80 | |
|---|
| 81 | The target field in each returned SRV resource record contains the |
|---|
| 82 | domain name of a tracker and the port on which the tracker runs. This |
|---|
| 83 | tracker is called a *local tracker*, but the protocol to talk to this |
|---|
| 84 | tracker is no different from the standard BitTorrent tracker protocol |
|---|
| 85 | described in [#BEP-3]_. |
|---|
| 86 | |
|---|
| 87 | When the BitTorrent client joins a swarm it announces to one or more |
|---|
| 88 | of the trackers referenced in the .torrent file and announces to the |
|---|
| 89 | local tracker. The local tracker returns peers which may be caches or |
|---|
| 90 | other peers that announced the same file to the local tracker. |
|---|
| 91 | |
|---|
| 92 | A client MAY treat nearby peers or caches preferentially. |
|---|
| 93 | |
|---|
| 94 | Reverse DNS lookups are described in RFC 1034 [#RFC-1034]_. |
|---|
| 95 | The SRV resource record type is described in RFC 2782 [#RFC-2782]_. |
|---|
| 96 | |
|---|
| 97 | |
|---|
| 98 | Iterative Queries |
|---|
| 99 | ================= |
|---|
| 100 | |
|---|
| 101 | The domain name returned from the reverse DNS lookup is specific to |
|---|
| 102 | the querying host. In the naive implementation in DNS, there would be |
|---|
| 103 | one SRV resource record for every querying host. This would work but |
|---|
| 104 | is burdensome. A natural, seemingly less burdensome, but incorrect |
|---|
| 105 | solution is to use a wildcard of the form:: |
|---|
| 106 | |
|---|
| 107 | *.pacbell.net |
|---|
| 108 | |
|---|
| 109 | If wildcards are implemented according to the algorithm in section |
|---|
| 110 | 4.3.2 in [#RFC-1034]_ then all subdomains of pacbell.net that do not |
|---|
| 111 | have an exact label match will match the wildcard. Thus unless there |
|---|
| 112 | is an exact match then queries for |
|---|
| 113 | |
|---|
| 114 | :: |
|---|
| 115 | |
|---|
| 116 | _bittorrent-tracker._tcp.adsl-69-107-0-14.dsl.pltn13.pacbell.net |
|---|
| 117 | |
|---|
| 118 | and |
|---|
| 119 | |
|---|
| 120 | :: |
|---|
| 121 | |
|---|
| 122 | _jabber._tcp.pacbell.net |
|---|
| 123 | |
|---|
| 124 | both match \*.pacbell.net and all SRV resource records with owner |
|---|
| 125 | \*.pacbell.net would be returned with the name set to the name in the |
|---|
| 126 | query. Thus it would be impossible to disambiguate Jabber from |
|---|
| 127 | BitTorrent SRV records without further information. This behavior is |
|---|
| 128 | implemented with BIND 9.4.1. |
|---|
| 129 | |
|---|
| 130 | Another natural but incorrect solution is to specify domain names of |
|---|
| 131 | the type |
|---|
| 132 | |
|---|
| 133 | :: |
|---|
| 134 | |
|---|
| 135 | _bittorrent-tracker._tcp.*.pacbell.net |
|---|
| 136 | |
|---|
| 137 | Section 4.3.3 in [#RFC-1034]_ specifies that wildcards only appear as |
|---|
| 138 | the first label in a domain name. This restriction was lifted in |
|---|
| 139 | [#RFC-4592]_, but not with semantics applicable to our use case. An |
|---|
| 140 | asterisk not at the beginning of a domain name is not treated like a |
|---|
| 141 | wildcard. Only a lookup for the exact domain name |
|---|
| 142 | |
|---|
| 143 | :: |
|---|
| 144 | |
|---|
| 145 | _bittorrent-tracker._tcp.*.pacbell.net |
|---|
| 146 | |
|---|
| 147 | matches. |
|---|
| 148 | |
|---|
| 149 | We propose an alternative that avoids wildcards and allows |
|---|
| 150 | suborganizations to override SRV records provided by parent |
|---|
| 151 | organizations: the peer starts by querying using its fully-qualified |
|---|
| 152 | domain name returned from the reverse DNS lookup, and if this fails |
|---|
| 153 | then it queries again after removing the most specific (leftmost) |
|---|
| 154 | label in the domain name. For example, if no SRV records are returned |
|---|
| 155 | when querying for |
|---|
| 156 | |
|---|
| 157 | :: |
|---|
| 158 | |
|---|
| 159 | _bittorrent-tracker._tcp.adsl-69-107-0-14.dsl.pltn13.pacbell.net |
|---|
| 160 | |
|---|
| 161 | then the client queries for |
|---|
| 162 | |
|---|
| 163 | :: |
|---|
| 164 | |
|---|
| 165 | _bittorrent-tracker._tcp.dsl.pltn13.pacbell.net |
|---|
| 166 | |
|---|
| 167 | and then |
|---|
| 168 | |
|---|
| 169 | :: |
|---|
| 170 | |
|---|
| 171 | _bittorrent-tracker._tcp.pltn13.pacbell.net |
|---|
| 172 | |
|---|
| 173 | The search removes one label at a time terminating when one or more |
|---|
| 174 | resource records are found or before querying the root domain or |
|---|
| 175 | top-level domains that are not ccTLDs, e.g., .com, .org, .net. We |
|---|
| 176 | avoid querying the root or top-level domains given the low likelihood |
|---|
| 177 | that caches would be defined globally, and thus clients would |
|---|
| 178 | unnecessarily burden the root domain name servers with queries |
|---|
| 179 | generating negative results. We considered stopping before querying |
|---|
| 180 | country-level domains, but a country providing public infrastructure |
|---|
| 181 | might choose to provide caches. |
|---|
| 182 | |
|---|
| 183 | |
|---|
| 184 | Network Address Translators |
|---|
| 185 | =========================== |
|---|
| 186 | |
|---|
| 187 | Many hosts on the Internet sit in private networks that connect to the |
|---|
| 188 | Internet via a Network Address Translator (NAT). Such hosts may have |
|---|
| 189 | an IP address allocated from one of the private IP address ranges |
|---|
| 190 | defined by IANA, e.g., ranges with prefixes 10/8, 172.16/12, and |
|---|
| 191 | 192.168/16. When communicating with hosts outside the private |
|---|
| 192 | network, the NAT translates the private IP to a globally-routable IP |
|---|
| 193 | address. This globally-routable address is the host's *external IP |
|---|
| 194 | address*. |
|---|
| 195 | |
|---|
| 196 | The BitTorrent client must use its host's external IP address. A |
|---|
| 197 | BitTorrent client MAY obtain its host's external IP either from the |
|---|
| 198 | *external ip* key returned from a tracker implementing BEP 24 |
|---|
| 199 | [#BEP-24]_ or from peers implementing the *yourip* extension defined |
|---|
| 200 | for the *Extension Protocol* proposed in [#BEP-10]_. |
|---|
| 201 | |
|---|
| 202 | Example |
|---|
| 203 | ======= |
|---|
| 204 | |
|---|
| 205 | In our example, we use AT&T's PacBell network. AT&T could implement |
|---|
| 206 | tracker discovery by adding the following lines to the zone file for |
|---|
| 207 | pacbell.net, |
|---|
| 208 | |
|---|
| 209 | :: |
|---|
| 210 | |
|---|
| 211 | ; name ttl cls rr pri weight port target |
|---|
| 212 | _bittorrent-tracker._tcp.pacbell.net. 600 IN SRV 5 0 6969 tracker |
|---|
| 213 | |
|---|
| 214 | Now when a client performs tracker discovery, it performs three DNS |
|---|
| 215 | queries removing labels before reaching the domain name pacbell.net, |
|---|
| 216 | at which point the SRV record is returned and the client queries |
|---|
| 217 | tracker.pacbell.net to obtain the domain names of caches. |
|---|
| 218 | |
|---|
| 219 | In Python, the local tracker's port and domain can be obtained using |
|---|
| 220 | PyDNS using the following code:: |
|---|
| 221 | |
|---|
| 222 | import DNS |
|---|
| 223 | |
|---|
| 224 | tlds = ["com", "net", "org"] # add more TLDs here. |
|---|
| 225 | |
|---|
| 226 | name = DNS.revlookup( "69.107.0.14" ) |
|---|
| 227 | names = name.split('.') |
|---|
| 228 | while names and names[0] not in tlds: |
|---|
| 229 | name = "_bittorrent-tracker._tcp." + ".".join(names) |
|---|
| 230 | req = DNS.Request( name=name, qtype="SRV", protocol="udp") |
|---|
| 231 | response = req.req() |
|---|
| 232 | if response.answers: |
|---|
| 233 | break |
|---|
| 234 | del names[0] |
|---|
| 235 | |
|---|
| 236 | print "response=", response.show() |
|---|
| 237 | |
|---|
| 238 | which might generate output like |
|---|
| 239 | |
|---|
| 240 | :: |
|---|
| 241 | |
|---|
| 242 | response= ; <<>> PDG.py 1.0 <<>> _bittorrent._tcp.pacbell.net SRV |
|---|
| 243 | ;; options: recurs |
|---|
| 244 | ;; got answer: |
|---|
| 245 | ;; ->>HEADER<<- opcode 0, status NOERROR, id 0 |
|---|
| 246 | ;; flags: qr aa rd ra; Ques: 1, Ans: 1, Auth: 2, Addit: 3 |
|---|
| 247 | ;; QUESTIONS: |
|---|
| 248 | ;; _bittorrent-tracker._tcp.pacbell.net, type = SRV, class = IN |
|---|
| 249 | |
|---|
| 250 | ;; ANSWERS: |
|---|
| 251 | _bittorrent-tracker._tcp.pacbell.net 600 SRV (5, 0, 6969, 'cache.pacbell.net') |
|---|
| 252 | |
|---|
| 253 | ;; AUTHORITY RECORDS: |
|---|
| 254 | pacbell.net 86400 NS ns1.pbi.net |
|---|
| 255 | pacbell.net 86400 NS ns2.pbi.net |
|---|
| 256 | |
|---|
| 257 | ;; ADDITIONAL RECORDS: |
|---|
| 258 | cache.pacbell.net 86400 A 69.107.0.1 |
|---|
| 259 | ns1.pacbell.net 86400 A 206.13.28.11 |
|---|
| 260 | ns2.pacbell.net 86400 A 206.13.29.11 |
|---|
| 261 | |
|---|
| 262 | ;; Total query time: 0 msec |
|---|
| 263 | ;; To SERVER: localhost |
|---|
| 264 | ;; WHEN: Mon May 19 16:00:12 2008 |
|---|
| 265 | |
|---|
| 266 | The answer above is fictional since AT&T does not at this time |
|---|
| 267 | implement SRV records for BitTorrent trackers. |
|---|
| 268 | |
|---|
| 269 | In Microsoft Windows, the port and domain name of the server can be |
|---|
| 270 | obtained using WinDNS (Dnsapi.lib) using DnsQuery(). In Unix, the |
|---|
| 271 | relevant call is res_query() from libresolv. |
|---|
| 272 | |
|---|
| 273 | References |
|---|
| 274 | ========== |
|---|
| 275 | |
|---|
| 276 | .. [#BEP-3] BEP_0003. The BitTorrent Protocol Specification, Cohen. |
|---|
| 277 | http://www.bittorrent.org/beps/bep_0003.html |
|---|
| 278 | |
|---|
| 279 | .. [#BEP-10] BEP_0010. Extension Protocol. Norberg, Strigeus, Hazel. |
|---|
| 280 | http://www.bittorrent.org/beps/bep_0010.html |
|---|
| 281 | |
|---|
| 282 | .. [#BEP-24] BEP_0024. Tracker Returns External IP. Harrison. |
|---|
| 283 | http://www.bittorrent.org/beps/bep_0024.html |
|---|
| 284 | |
|---|
| 285 | .. [#RFC-1034] RFC-1034. DOMAIN NAMES - CONCEPTS AND FACILITIES. Mockapetris, |
|---|
| 286 | November 1987. http://tools.ietf.org/html/rfc1034 |
|---|
| 287 | |
|---|
| 288 | .. [#RFC-2119] RFC-2119. http://www.ietf.org/rfc/rfc2119.txt |
|---|
| 289 | |
|---|
| 290 | .. [#RFC-2782] RFC-2782. A DNS RR for specifying the location of services (DNS |
|---|
| 291 | SRV). Gulbrandsen, Vixie, Esibov. February 2000. |
|---|
| 292 | http://tools.ietf.org/html/rfc2782 |
|---|
| 293 | |
|---|
| 294 | .. [#RFC-4592] RFC-4592. The Role of Wildcards in the Domain Name |
|---|
| 295 | System. Lewis. http://www.faqs.org/rfcs/rfc4592.html |
|---|
| 296 | |
|---|
| 297 | |
|---|
| 298 | |
|---|
| 299 | |
|---|
| 300 | Copyright |
|---|
| 301 | ========= |
|---|
| 302 | |
|---|
| 303 | This document has been placed in the public domain. |
|---|
| 304 | |
|---|
| 305 | |
|---|
| 306 | |
|---|
| 307 | .. |
|---|
| 308 | Local Variables: |
|---|
| 309 | mode: indented-text |
|---|
| 310 | indent-tabs-mode: nil |
|---|
| 311 | sentence-end-double-space: t |
|---|
| 312 | fill-column: 70 |
|---|
| 313 | coding: utf-8 |
|---|
| 314 | End: |
|---|