The BitTorrent friends protocol extension allows BitTorrent clients to exchange download credit. In other words, if I help you to download a file now, the friends extension provides a way for me to ask you to help me download in the future.
The friends extension slightly modifies the normal BT handshake. Instead of sending 8 zeros for the reserved bytes, bit 7 of the last byte is set to 1. This indicates that the peer supports the friends protocol. Bit 6 may also be set, and if it is, this indicates that this peer is running as a repeater, and is not trying to download the entire torrent.
All of the usual peer messages must be supported by a BT friend. The additional messages added to this protocol are:
24 – client_id
25 – form_friendship
26 – signed_request
27 – help_friend
In addition, there is a new peer protocol specifically for inviting friends to join a torrent, called the invitation protocol. It's messages are:
20 – request_help
21 – get_info
22 – info
21 – will_help
This protocol is discussed in the section below titled “Asking for Help”.
Friends are recognized by their client ids, which are generated once, and used for each future session. Client ids should not be confused with peer ids, which are generated for each download session.
The first message that should be sent after the usual handshake should be the client_id message. The load of this message is the 20-byte client id.
Some messages request a significant effort from the friend. Any such message is signed by concatenating it with the friendship key, computing the SHA1 of the result, and appending this hash value to the message. The signature proves that the author of the message knows the friendship key and that the data has not been tampered with.
If a BT friend connection is established with an unrecognized peer, a new friendship is formed. Both peers exchange form_friendship messages, who's load is 20 random bytes. These values are bitwise XOR-ed to compute the mutually agreed upon friendship key. This is saved to disk for future communication with this friend.
The signed_request message is identical to the normal request message, except that it is signed. Any piece requests between friends should be signed.
When in need, a client can ask its friends to help with a download. To ask a friend to join a torrent, a TCP connection is formed, and the request_help message is sent. This message is only sent to friends who are not already connected in the torrent where help is needed. Thus, this will be the first message sent over the connection, and will precede the handshake. If the friend does not have the torrent file you've specified, he can send a 'get_info' message. The response message, 'info', contains the info-blob from the torrent file.
The 'request_help' message starts with the byte 20, and is followed by the characters “BT friend needs help”. Next comes four bytes encoding the entire length of the message. The load is a bencoded dictionary containing the following keys:
name – A suggested name for the torrent.
announce – The URL of the tracker of the torrent where help is needed.
client_id – The client id of the friend. Used to help verify the signature.
info_hash – The 20 byte sha1 hash of the bencoded form of the info value from the metainfo file. This is needed in order to communicate with the tracker.
This message must be signed.
If the friend decides to help, but needs the torrent file, he will send a 'get_info' message. Both the 'get_info' and 'info' messages are prefixed with the length, just like messages in the usual peer protocol. The 'get_info' message has no load. The load of the 'info' message will be the info-blob from the torrent file, which is a bencoded dictionary. The 'get_info' and 'info' messages are not signed. They may be called by peers which do not support the friends protocol.
Once the 'request_help' message and optionally the get_info/info messages have been sent, the friend indicates that he's willing to help by sending a 'will_help' message, which is also prefixed with it's length. If the friend is not willing or able to help, he should close the connection. After the 'will_help' message has been received, the usual BitTorrent peer handshake should begin, reusing the connection.
Part of the motivation for sending the entire info-blob up-front is that the BT2 version of the BitTorrent protocol is expected to greatly reduce the size of torrent files through the use of Merkle hash trees. Having the whole torrent file greatly simplifies joining a torrent to help a friend.
A friend may declare that someone else is the one needing help downloading, rather than himself. This is done with a 'help_friend' message. It's load is a bencoded dictionary containing the following keys:
'ip' – the IP address of the master, and 'port' – the port of the master.
The main intended use for this is to have friends enabled clients to request help for other clients. This way, you can continue to use your existing client, and install a friends compliant client as a demon that runs in the background. The demon will make friends, build up good will, and ask them to help your BT client program when you ask it to.
This message must be signed.