added some precautionary checks in bdecoder
[libtorrent.git] / include / libtorrent / bt_peer_connection.hpp
bloba900bfc7ec646848401fa91525ce967e8e8258e3
1 /*
3 Copyright (c) 2003 - 2006, Arvid Norberg
4 Copyright (c) 2007, Arvid Norberg, Un Shyam
5 All rights reserved.
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
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
37 #include <ctime>
38 #include <algorithm>
39 #include <vector>
40 #include <deque>
41 #include <string>
43 #include "libtorrent/debug.hpp"
45 #ifdef _MSC_VER
46 #pragma warning(push, 1)
47 #endif
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>
55 #ifdef _MSC_VER
56 #pragma warning(pop)
57 #endif
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"
73 namespace libtorrent
75 class torrent;
77 namespace detail
79 struct session_impl;
82 class TORRENT_EXPORT bt_peer_connection
83 : public peer_connection
85 friend class invariant_access;
86 public:
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
91 bt_peer_connection(
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
100 bt_peer_connection(
101 aux::session_impl& ses
102 , boost::shared_ptr<socket_type> s
103 , tcp::endpoint const& remote
104 , policy::peer* peerinfo);
106 void start();
108 ~bt_peer_connection();
110 #ifndef TORRENT_DISABLE_ENCRYPTION
111 bool supports_encryption() const
112 { return m_encrypted; }
113 #endif
115 enum message_type
117 // standard messages
118 msg_choke = 0,
119 msg_unchoke,
120 msg_interested,
121 msg_not_interested,
122 msg_have,
123 msg_bitfield,
124 msg_request,
125 msg_piece,
126 msg_cancel,
127 // DHT extension
128 msg_dht_port,
129 // FAST extension
130 msg_suggest_piece = 0xd,
131 msg_have_all,
132 msg_have_none,
133 msg_reject_request,
134 msg_allowed_fast,
136 // extension protocol message
137 msg_extended = 20,
139 num_supported_messages
142 // called from the main loop when this connection has any
143 // work to do.
145 void on_sent(error_code const& error
146 , std::size_t bytes_transferred);
147 void on_receive(error_code const& error
148 , std::size_t bytes_transferred);
150 virtual void get_specific_peer_info(peer_info& p) const;
151 virtual bool in_handshake() const;
153 #ifndef TORRENT_DISABLE_EXTENSIONS
154 bool support_extensions() const { return m_supports_extensions; }
156 template <class T>
157 T* supports_extension() const
159 for (extension_list_t::const_iterator i = m_extensions.begin()
160 , end(m_extensions.end()); i != end; ++i)
162 T* ret = dynamic_cast<T*>(i->get());
163 if (ret) return ret;
165 return 0;
167 #endif
169 // the message handlers are called
170 // each time a recv() returns some new
171 // data, the last time it will be called
172 // is when the entire packet has been
173 // received, then it will no longer
174 // be called. i.e. most handlers need
175 // to check how much of the packet they
176 // have received before any processing
177 void on_keepalive();
178 void on_choke(int received);
179 void on_unchoke(int received);
180 void on_interested(int received);
181 void on_not_interested(int received);
182 void on_have(int received);
183 void on_bitfield(int received);
184 void on_request(int received);
185 void on_piece(int received);
186 void on_cancel(int received);
188 // DHT extension
189 void on_dht_port(int received);
191 // FAST extension
192 void on_suggest_piece(int received);
193 void on_have_all(int received);
194 void on_have_none(int received);
195 void on_reject_request(int received);
196 void on_allowed_fast(int received);
198 void on_extended(int received);
200 void on_extended_handshake();
202 typedef void (bt_peer_connection::*message_handler)(int received);
204 // the following functions appends messages
205 // to the send buffer
206 void write_choke();
207 void write_unchoke();
208 void write_interested();
209 void write_not_interested();
210 void write_request(peer_request const& r);
211 void write_cancel(peer_request const& r);
212 void write_bitfield();
213 void write_have(int index);
214 void write_piece(peer_request const& r, disk_buffer_holder& buffer);
215 void write_handshake();
216 #ifndef TORRENT_DISABLE_EXTENSIONS
217 void write_extensions();
218 #endif
219 void write_chat_message(const std::string& msg);
220 void write_metadata(std::pair<int, int> req);
221 void write_metadata_request(std::pair<int, int> req);
222 void write_keepalive();
224 // DHT extension
225 void write_dht_port(int listen_port);
227 // FAST extension
228 void write_have_all();
229 void write_have_none();
230 void write_reject_request(peer_request const&);
231 void write_allow_fast(int piece);
233 void on_connected();
234 void on_metadata();
236 #ifndef NDEBUG
237 void check_invariant() const;
238 ptime m_last_choke;
239 #endif
241 private:
243 bool dispatch_message(int received);
244 // returns the block currently being
245 // downloaded. And the progress of that
246 // block. If the peer isn't downloading
247 // a piece for the moment, the boost::optional
248 // will be invalid.
249 boost::optional<piece_block_progress> downloading_piece_progress() const;
251 #ifndef TORRENT_DISABLE_ENCRYPTION
253 // if (is_local()), we are 'a' otherwise 'b'
255 // 1. a -> b dhkey, pad
256 // 2. b -> a dhkey, pad
257 // 3. a -> b sync, payload
258 // 4. b -> a sync, payload
259 // 5. a -> b payload
261 void write_pe1_2_dhkey();
262 void write_pe3_sync();
263 void write_pe4_sync(int crypto_select);
265 void write_pe_vc_cryptofield(buffer::interval& write_buf,
266 int crypto_field, int pad_size);
268 // stream key (info hash of attached torrent)
269 // secret is the DH shared secret
270 // initializes m_RC4_handler
271 void init_pe_RC4_handler(char const* secret, sha1_hash const& stream_key);
273 public:
275 // these functions encrypt the send buffer if m_rc4_encrypted
276 // is true, otherwise it passes the call to the
277 // peer_connection functions of the same names
278 void send_buffer(char* buf, int size, int flags = 0);
279 buffer::interval allocate_send_buffer(int size);
280 template <class Destructor>
281 void append_send_buffer(char* buffer, int size, Destructor const& destructor)
283 #ifndef TORRENT_DISABLE_ENCRYPTION
284 if (m_rc4_encrypted)
285 m_RC4_handler->encrypt(buffer, size);
286 #endif
287 peer_connection::append_send_buffer(buffer, size, destructor);
289 void setup_send();
291 private:
293 // Returns offset at which bytestream (src, src + src_size)
294 // matches bytestream(target, target + target_size).
295 // If no sync found, return -1
296 int get_syncoffset(char const* src, int src_size,
297 char const* target, int target_size) const;
298 #endif
300 enum state
302 #ifndef TORRENT_DISABLE_ENCRYPTION
303 read_pe_dhkey = 0,
304 read_pe_syncvc,
305 read_pe_synchash,
306 read_pe_skey_vc,
307 read_pe_cryptofield,
308 read_pe_pad,
309 read_pe_ia,
310 init_bt_handshake,
311 read_protocol_identifier,
312 #else
313 read_protocol_identifier = 0,
314 #endif
315 read_info_hash,
316 read_peer_id,
318 // handshake complete
319 read_packet_size,
320 read_packet
323 #ifndef TORRENT_DISABLE_ENCRYPTION
324 enum
326 handshake_len = 68,
327 dh_key_len = 96
329 #endif
331 std::string m_client_version;
333 // state of on_receive
334 state m_state;
336 // the timeout in seconds
337 int m_timeout;
339 static const message_handler m_message_handler[num_supported_messages];
341 // this is a queue of ranges that describes
342 // where in the send buffer actual payload
343 // data is located. This is currently
344 // only used to be able to gather statistics
345 // seperately on payload and protocol data.
346 struct range
348 range(int s, int l)
349 : start(s)
350 , length(l)
352 TORRENT_ASSERT(s >= 0);
353 TORRENT_ASSERT(l > 0);
355 int start;
356 int length;
358 static bool range_below_zero(const range& r)
359 { return r.start < 0; }
360 std::deque<range> m_payloads;
362 #ifndef TORRENT_DISABLE_EXTENSIONS
363 // this is set to true if the handshake from
364 // the peer indicated that it supports the
365 // extension protocol
366 bool m_supports_extensions;
367 char m_reserved_bits[20];
368 #endif
369 bool m_supports_dht_port;
370 bool m_supports_fast;
372 #ifndef TORRENT_DISABLE_ENCRYPTION
373 // this is set to true after the encryption method has been
374 // succesfully negotiated (either plaintext or rc4), to signal
375 // automatic encryption/decryption.
376 bool m_encrypted;
378 // true if rc4, false if plaintext
379 bool m_rc4_encrypted;
381 // used to disconnect peer if sync points are not found within
382 // the maximum number of bytes
383 int m_sync_bytes_read;
385 // hold information about latest allocated send buffer
386 // need to check for non zero (begin, end) for operations with this
387 buffer::interval m_enc_send_buffer;
389 // initialized during write_pe1_2_dhkey, and destroyed on
390 // creation of m_RC4_handler. Cannot reinitialize once
391 // initialized.
392 boost::scoped_ptr<dh_key_exchange> m_dh_key_exchange;
394 // if RC4 is negotiated, this is used for
395 // encryption/decryption during the entire session. Destroyed
396 // if plaintext is selected
397 boost::scoped_ptr<RC4_handler> m_RC4_handler;
399 // (outgoing only) synchronize verification constant with
400 // remote peer, this will hold RC4_decrypt(vc). Destroyed
401 // after the sync step.
402 boost::scoped_array<char> m_sync_vc;
404 // (incoming only) synchronize hash with remote peer, holds
405 // the sync hash (hash("req1",secret)). Destroyed after the
406 // sync step.
407 boost::scoped_ptr<sha1_hash> m_sync_hash;
408 #endif // #ifndef TORRENT_DISABLE_ENCRYPTION
410 #ifndef NDEBUG
411 // this is set to true when the client's
412 // bitfield is sent to this peer
413 bool m_sent_bitfield;
415 bool m_in_constructor;
417 bool m_sent_handshake;
418 #endif
423 #endif // TORRENT_BT_PEER_CONNECTION_HPP_INCLUDED