root / dotorg / v4 / html / beps / bep_0006.rst

Revision 10528, 10.2 kB (checked in by dave, 10 months ago)

Change revision number to automatically updated $Revision$ in all .rst files.
Change last-modified date to automatically updated $Date$ in all .rst files.
Add "Local Variables" to the end of all .rst files.
Fix BEP numbers.
Make header formatting in all .rst files conform to PEP-style rst formatting requirements.

Remove some HTML markup from the bep_0003.rst, the BitTorrent? protocol standard.

Line 
1BEP: 6
2Title: Fast Extension
3Version: $Revision$
4Last-Modified: $Date$
5Author:  David Harrison <dave@bittorrent.com>, Bram Cohen <bram@bittorrent.com>
6Status:  Draft
7Type:    Standards Track
8Created: 01-Feb-2008
9Post-History:
10
11The Fast Extension packages several extensions: *Have None/Have All*,
12*Reject Requests*, *Suggestions* and *Allowed Fast.*
13These are enabled by setting the third least significant bit of the
14last reserved byte in the BitTorrent handshake:
15
16::
17
18  reserved[7] |= 0x04
19
20The extension is enabled only if both ends of the connection set this bit.
21
22The following proposed messages adhere to the syntax of messages found
23in v1.0 of the BitTorrent protocol.  All integers are four bytes
24big-endian.  All messages start with an integer message length.  All
25messages but the Keep-Alive follow the message length with a single
26byte opcode and zero or more opcode-dependant arguments.
27
28The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
29NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and
30"OPTIONAL" in this document are to be interpreted as described in
31IETF `RFC 2119`_.
32
33Modifications to Semantics of Existing Messages
34===============================================
35
36The Fast Extension modifies the semantics of the
37*Request*, *Choke*, *Unchoke*, and *Cancel*
38messages, and adds a *Reject Request.*  Now, every request
39is guaranteed to result in EXACTLY ONE response
40which is either the corresponding reject or corresponding piece
41message.  Even when a request is cancelled, the peer receiving
42the cancel should respond with either the corresponding reject or
43the corresponding piece: requests that are being processed are
44allowed to complete.
45
46Choke no longer implicitly rejects all pending requests,
47thus eliminating some race conditions which could cause pieces
48to be needlessly requested multiple times.
49
50Additionally, if a peer receives a piece that was never requested,
51the peer MUST close the connection.
52
53
54Have All/Have None
55==================
56
57::
58
59  *Have All*: <len=0x0001> <op=0x0E>
60
61::
62
63  *Have None*: <len=0x0001><op=0x0F>
64
65*Have All* and *Have None* specify that the message sender
66has all or none of the pieces respectively.  When present, *Have All*
67or *Have None* replace the *Have Bitfield.*  Exactly one of *Have All*,
68*Have None*, or *Have Bitfield* MUST appear and only immediately after
69the handshake.  The reason for these messages is to save bandwidth.  Also
70slightly to remove the idiosyncrasy of sending no message when a peer
71has no pieces.
72
73When the fast extension is disabled, if a peer receives *Have All* or
74*Have None* then the peer MUST close the connection.
75
76
77Suggest Piece
78=============
79
80::
81
82  *Suggest Piece*: <len=0x0005><op=0x0D><index>
83
84*Suggest Piece* is an advisory message meaning "you might like to
85download this piece."  The intended usage is for 'super-seeding'
86without throughput reduction, to avoid redundant downloads, and so that
87a seed which is disk I/O bound can upload continguous or identical
88pieces to avoid excessive disk seeks.  In all cases, the seed SHOULD
89operate to maintain a roughly equal number of copies of each piece in
90the network.  A peer MAY send more than one *suggest piece* message at
91any given time.  A peer receiving multiple *suggest piece* messages
92MAY interpret this as meaning that all of the suggested pieces
93are equally appropriate.
94
95When the fast extension is disabled, if a peer receives a
96*Suggest Piece* message, the peer MUST close the connection.
97
98
99Reject Request
100==============
101
102::
103
104  *Reject Request*: <len=0x000D><op=0x10><index><begin><offset>
105
106*Reject Request* notifies a requesting peer that its request will not be satisfied.
107
108If the fast extension is disabled and a peer receives a reject
109request then the peer MUST close the connection.
110
111When the fast extension is enabled:
112
113- If a peer receives a reject for a request that was never sent then
114  the peer SHOULD close the connection.
115
116- If a peer sends a choke, it MUST reject all requests from the peer
117  to whom the choke was sent except it SHOULD NOT reject requests for
118  pieces that are in the *allowed fast set.* A peer SHOULD choke first
119  and then reject requests so that the peer receiving the choke does not
120  re-request the pieces.
121
122- If a peer receives a request from a peer its choking, the peer
123  receiving the request SHOULD send a reject unless the piece is in the
124  *allowed fast set.*
125
126- If a peer receives an excessive number of requests from a peer it is
127  choking, the peer receiving the requests MAY close the connection
128  rather than reject the request.  However, consider that it can take
129  several seconds for buffers to drain and messages to propagate once a
130  peer is choked.
131
132Allowed Fast
133============
134
135::
136
137* Allowed Fast: <len=0x0005><op=0x11><index>*
138
139With the BitTorrent protocol specified in `BEP 0002`_, new peers take
140several minutes to ramp up before they can effectively engage in
141BitTorrent's tit-for-tat. The reason is simple: starting peers have
142few pieces to trade.
143
144*Allowed Fast* is an advisory message which means "if you ask for this
145piece, I'll give it to you even if you're choked." *Allowed Fast* thus
146shortens the awkward stage during which the peer obtains occasional
147optimistic unchokes but cannot sufficiently reciprocate to remain
148unchoked.
149
150The pieces that can be downloaded when choked constitute a peer's
151*allowed fast set.* The set is generated using a canonical algorithm
152that produces piece indices unique to the message receiver so that if
153two peers offer *k* pieces fast it will be the same *k*, and if one
154offers *k+1* it will be the same *k* plus one more. *k* should be
155small enough to avoid abuse, but large enough to ramp up
156tit-for-tat. We currently set *k* to 10, but peers are free to change
157this number, e.g., to suit load.
158
159The message sender MAY list pieces that the message sender does not
160have. The receiver MUST NOT interpret an Allowed Fast message as
161meaning that the message sender has the piece. This allows peers to
162generate and communicate allowed fast sets at the beginning of a
163connection. However, a peer MAY send Allowed Fast messages at any
164time.
165
166A peer SHOULD send Allowed Fast messages to any starting peer unless
167the local peer lacks sufficient resources. A peer MAY reject requests
168for already Allowed Fast pieces if the local peer lacks sufficient
169resources, if the requested piece has already been sent to the
170requesting peer, or if the requesting peer is not a starting peer. Our
171current implementation rejects requests for Allowed Fast messages
172whenever the requesting peer has more than * k * pieces.
173
174 When the fast extension is disabled, if a peer recieves an Allowed
175 Fast message then the peer MUST close the connection.
176
177Allowed Fast Set Generation
178===========================
179
180The canonical algorithm for computing a peer *P'*s *allowed fast set*
181follows.  All integers in this pseudocode are four bytes represented
182in network (big-endian) byte order.  *[a:b]* denotes the sequence of
183consecutive bytes from *a* to *b* excluding *b*, i.e., *(a, a+1,
184a+2,..., b-1)*. *x[a:b]* denotes a subsequence of elements in an array
185*x* starting from index *a* to but not including index *b*.
186
187Let *ip* denote *P'*s IPv4 address.  We currently have no
188provisions for IPv6. If a peer is behind a Network Address Translator
189(NAT) then *ip* should be the externally facing IP address of the
190NAT.  Since the node sending the *Allowed Fast* messages computes
191the set, the correct *ip* is usually the *ip* address on the other
192end of the connection.  The host computing the set MAY use the *ip*
193address on the other end of the connection regardless
194
195Let *sz* denote the number of pieces in the torrent.
196
197Let *a* denote the allowed fast set.
198
199Let *k* denote the final number of pieces in the allowed fast set.
200
201
202::
203
204 x = 0xFFFFFF00 & ip                           (1)
205 x.append(infohash)                            (2)
206 while |a| < k:
207   x = SHA1(x)                                 (3)
208   for i in [0:5] and |a| < k:                 (4)
209     j = i*4                                   (5)
210     y = x[j:j+4]                              (6)
211     index = y % sz                            (7)
212     if index not in a:                        (8)
213       add index to a                          (9)
214
215Step (1) selects the most significant octets in peer *P'*s
216ip address.  We do this to prevent a user that obtains more than one
217IP address on the same network from obtaining more than one
218*allowed fast set.*  Use of three bytes is heuristic and
219historical.
220
221Step (3) generates a 20-byte random number on each call.  By
222performing a SHA-1 hash on the previous iteration's hash, we can
223generate an arbitrarily long pseudorandom sequence.
224
225Steps (4) through (9) partition the 20-byte hash into piece indices
226and add them to the allowed fast set.
227
228Example Implementation
229======================
230
231The following C++ implementation was provided by CacheLogic:
232
233
234::
235
236  void generate_fast_set(
237    uint32 k,     // number of pieces in set
238    uint32 sz,    // number of pieces in torrent
239    const char infohash[20], // infohash of torrent
240    uint32 ip, // in host byte order, ie localhost is 0x7f000001
241    std::
242  vector<uint32> &a) // generated set of piece indices
243  {
244     a.clear();
245     std::string x;
246     char buf[4];
247     *(uint32*)buf = htonl(ip & 0xffffff00);
248     x.assign(buf, 4);
249     x.append(infohash, 20); // (3)
250     while (a.size()<k) {
251       x = SHA1(x); // (4)
252       for ( int i=0&nbsp;; i<5 && a.size()<k; i++ ) { // (5)
253         int j = i*4; // (6)
254         uint32 y = ntohl(*(uint32*)(x.data()+j)); // (7)
255         uint32 index = y % sz; // (8)
256         if (std::find(a.begin(), a.end(), index)==a.end()) { // (9)
257           a.push_back(index); // (10)
258         }
259       }
260     }
261  }
262
263Example results generated by this function:
264
265
266::
267
268 7 piece allowed fast set for torrent with 1313 pieces and hex infohash
269 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa for node with IP 80.4.4.200:
270   1059,431,808,1217,287,376,1188
271 9 piece allowed fast set for torrent with 1313 pieces and hex infohash
272 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa for node with IP 80.4.4.200:
273   1059,431,808,1217,287,376,1188,353,508
274
275.. _`RFC 2119`: http://www.ietf.org/rfc/rfc2119.txt
276.. _`BEP 0002`: http://www.bittorrent.org/beps/bep_0002.html
277
278
279
280
281..
282   Local Variables:
283   mode: indented-text
284   indent-tabs-mode: nil
285   sentence-end-double-space: t
286   fill-column: 70
287   coding: utf-8
288   End:
Note: See TracBrowser for help on using the browser.