3
Copyright (c) 2003 - 2006, Arvid Norberg
4
Copyright (c) 2007, Arvid Norberg, Un Shyam
7
Redistribution and use in source and binary forms, with or without
8
modification, are permitted provided that the following conditions
11
* Redistributions of source code must retain the above copyright
12
notice, this list of conditions and the following disclaimer.
13
* Redistributions in binary form must reproduce the above copyright
14
notice, this list of conditions and the following disclaimer in
15
the documentation and/or other materials provided with the distribution.
16
* Neither the name of the author nor the names of its
17
contributors may be used to endorse or promote products derived
18
from this software without specific prior written permission.
20
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
POSSIBILITY OF SUCH DAMAGE.
34
#ifndef TORRENT_BT_PEER_CONNECTION_HPP_INCLUDED
35
#define TORRENT_BT_PEER_CONNECTION_HPP_INCLUDED
43
#include "libtorrent/debug.hpp"
46
#pragma warning(push, 1)
49
#include <boost/smart_ptr.hpp>
50
#include <boost/noncopyable.hpp>
51
#include <boost/array.hpp>
52
#include <boost/optional.hpp>
53
#include <boost/cstdint.hpp>
59
#include "libtorrent/buffer.hpp"
60
#include "libtorrent/peer_connection.hpp"
61
#include "libtorrent/socket.hpp"
62
#include "libtorrent/peer_id.hpp"
63
#include "libtorrent/storage.hpp"
64
#include "libtorrent/stat.hpp"
65
#include "libtorrent/alert.hpp"
66
#include "libtorrent/torrent_handle.hpp"
67
#include "libtorrent/torrent.hpp"
68
#include "libtorrent/peer_request.hpp"
69
#include "libtorrent/piece_block_progress.hpp"
70
#include "libtorrent/config.hpp"
71
#include "libtorrent/pe_crypto.hpp"
82
class TORRENT_EXPORT bt_peer_connection
83
: public peer_connection
85
friend class invariant_access;
88
// this is the constructor where the we are the active part.
89
// The peer_conenction should handshake and verify that the
90
// other end has the correct id
92
aux::session_impl& ses
93
, boost::weak_ptr<torrent> t
94
, boost::shared_ptr<socket_type> s
95
, tcp::endpoint const& remote
96
, policy::peer* peerinfo);
98
// with this constructor we have been contacted and we still don't
99
// know which torrent the connection belongs to
101
aux::session_impl& ses
102
, boost::shared_ptr<socket_type> s
103
, policy::peer* peerinfo);
105
~bt_peer_connection();
107
#ifndef TORRENT_DISABLE_ENCRYPTION
108
bool supports_encryption() const
109
{ return m_encrypted; }
127
msg_suggest_piece = 0xd,
133
// extension protocol message
136
num_supported_messages
139
// called from the main loop when this connection has any
142
void on_sent(asio::error_code const& error
143
, std::size_t bytes_transferred);
144
void on_receive(asio::error_code const& error
145
, std::size_t bytes_transferred);
147
virtual void get_specific_peer_info(peer_info& p) const;
148
virtual bool in_handshake() const;
150
#ifndef TORRENT_DISABLE_EXTENSIONS
151
bool support_extensions() const { return m_supports_extensions; }
154
T* supports_extension() const
156
for (extension_list_t::const_iterator i = m_extensions.begin()
157
, end(m_extensions.end()); i != end; ++i)
159
T* ret = dynamic_cast<T*>(i->get());
166
// the message handlers are called
167
// each time a recv() returns some new
168
// data, the last time it will be called
169
// is when the entire packet has been
170
// received, then it will no longer
171
// be called. i.e. most handlers need
172
// to check how much of the packet they
173
// have received before any processing
175
void on_choke(int received);
176
void on_unchoke(int received);
177
void on_interested(int received);
178
void on_not_interested(int received);
179
void on_have(int received);
180
void on_bitfield(int received);
181
void on_request(int received);
182
void on_piece(int received);
183
void on_cancel(int received);
186
void on_dht_port(int received);
189
void on_suggest_piece(int received);
190
void on_have_all(int received);
191
void on_have_none(int received);
192
void on_reject_request(int received);
193
void on_allowed_fast(int received);
195
void on_extended(int received);
197
void on_extended_handshake();
199
typedef void (bt_peer_connection::*message_handler)(int received);
201
// the following functions appends messages
202
// to the send buffer
204
void write_unchoke();
205
void write_interested();
206
void write_not_interested();
207
void write_request(peer_request const& r);
208
void write_cancel(peer_request const& r);
209
void write_bitfield(std::vector<bool> const& bitfield);
210
void write_have(int index);
211
void write_piece(peer_request const& r, char* buffer);
212
void write_handshake();
213
#ifndef TORRENT_DISABLE_EXTENSIONS
214
void write_extensions();
216
void write_chat_message(const std::string& msg);
217
void write_metadata(std::pair<int, int> req);
218
void write_metadata_request(std::pair<int, int> req);
219
void write_keepalive();
222
void write_dht_port(int listen_port);
225
void write_have_all();
226
void write_have_none();
227
void write_reject_request(peer_request const&);
228
void write_allow_fast(int piece);
234
void check_invariant() const;
240
bool dispatch_message(int received);
241
// returns the block currently being
242
// downloaded. And the progress of that
243
// block. If the peer isn't downloading
244
// a piece for the moment, the boost::optional
246
boost::optional<piece_block_progress> downloading_piece_progress() const;
248
#ifndef TORRENT_DISABLE_ENCRYPTION
250
// if (is_local()), we are 'a' otherwise 'b'
252
// 1. a -> b dhkey, pad
253
// 2. b -> a dhkey, pad
254
// 3. a -> b sync, payload
255
// 4. b -> a sync, payload
258
void write_pe1_2_dhkey();
259
void write_pe3_sync();
260
void write_pe4_sync(int crypto_select);
262
void write_pe_vc_cryptofield(buffer::interval& write_buf,
263
int crypto_field, int pad_size);
265
// stream key (info hash of attached torrent)
266
// secret is the DH shared secret
267
// initializes m_RC4_handler
268
void init_pe_RC4_handler(char const* secret, sha1_hash const& stream_key);
270
// these functions encrypt the send buffer if m_rc4_encrypted
271
// is true, otherwise it passes the call to the
272
// peer_connection functions of the same names
273
void send_buffer(char* buf, int size);
274
buffer::interval allocate_send_buffer(int size);
275
template <class Destructor>
276
void append_send_buffer(char* buffer, int size, Destructor const& destructor)
278
#ifndef TORRENT_DISABLE_ENCRYPTION
280
m_RC4_handler->encrypt(buffer, size);
282
peer_connection::append_send_buffer(buffer, size, destructor);
286
// Returns offset at which bytestream (src, src + src_size)
287
// matches bytestream(target, target + target_size).
288
// If no sync found, return -1
289
int get_syncoffset(char const* src, int src_size,
290
char const* target, int target_size) const;
295
#ifndef TORRENT_DISABLE_ENCRYPTION
304
read_protocol_identifier,
306
read_protocol_identifier = 0,
311
// handshake complete
316
#ifndef TORRENT_DISABLE_ENCRYPTION
324
std::string m_client_version;
326
// state of on_receive
329
// the timeout in seconds
332
static const message_handler m_message_handler[num_supported_messages];
334
// this is a queue of ranges that describes
335
// where in the send buffer actual payload
336
// data is located. This is currently
337
// only used to be able to gather statistics
338
// seperately on payload and protocol data.
345
TORRENT_ASSERT(s >= 0);
346
TORRENT_ASSERT(l > 0);
351
static bool range_below_zero(const range& r)
352
{ return r.start < 0; }
353
std::deque<range> m_payloads;
355
#ifndef TORRENT_DISABLE_EXTENSIONS
356
// this is set to true if the handshake from
357
// the peer indicated that it supports the
358
// extension protocol
359
bool m_supports_extensions;
361
bool m_supports_dht_port;
362
bool m_supports_fast;
364
#ifndef TORRENT_DISABLE_ENCRYPTION
365
// this is set to true after the encryption method has been
366
// succesfully negotiated (either plaintext or rc4), to signal
367
// automatic encryption/decryption.
370
// true if rc4, false if plaintext
371
bool m_rc4_encrypted;
373
// used to disconnect peer if sync points are not found within
374
// the maximum number of bytes
375
int m_sync_bytes_read;
377
// hold information about latest allocated send buffer
378
// need to check for non zero (begin, end) for operations with this
379
buffer::interval m_enc_send_buffer;
381
// initialized during write_pe1_2_dhkey, and destroyed on
382
// creation of m_RC4_handler. Cannot reinitialize once
384
boost::scoped_ptr<DH_key_exchange> m_DH_key_exchange;
386
// if RC4 is negotiated, this is used for
387
// encryption/decryption during the entire session. Destroyed
388
// if plaintext is selected
389
boost::scoped_ptr<RC4_handler> m_RC4_handler;
391
// (outgoing only) synchronize verification constant with
392
// remote peer, this will hold RC4_decrypt(vc). Destroyed
393
// after the sync step.
394
boost::scoped_array<char> m_sync_vc;
396
// (incoming only) synchronize hash with remote peer, holds
397
// the sync hash (hash("req1",secret)). Destroyed after the
399
boost::scoped_ptr<sha1_hash> m_sync_hash;
400
#endif // #ifndef TORRENT_DISABLE_ENCRYPTION
403
// this is set to true when the client's
404
// bitfield is sent to this peer
405
bool m_sent_bitfield;
407
bool m_in_constructor;
409
bool m_sent_handshake;
415
#endif // TORRENT_BT_PEER_CONNECTION_HPP_INCLUDED