PageRenderTime 51ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/libtorrent-rasterbar-0.16.2/include/libtorrent/bt_peer_connection.hpp

#
C++ Header | 455 lines | 262 code | 75 blank | 118 comment | 3 complexity | c36e42c8b311ff20fb2ba120971027b1 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /*
  2. Copyright (c) 2003 - 2006, Arvid Norberg
  3. Copyright (c) 2007, Arvid Norberg, Un Shyam
  4. All rights reserved.
  5. Redistribution and use in source and binary forms, with or without
  6. modification, are permitted provided that the following conditions
  7. are met:
  8. * Redistributions of source code must retain the above copyright
  9. notice, this list of conditions and the following disclaimer.
  10. * Redistributions in binary form must reproduce the above copyright
  11. notice, this list of conditions and the following disclaimer in
  12. the documentation and/or other materials provided with the distribution.
  13. * Neither the name of the author nor the names of its
  14. contributors may be used to endorse or promote products derived
  15. from this software without specific prior written permission.
  16. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  20. LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  21. CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  22. SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  23. INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  24. CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  25. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  26. POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. #ifndef TORRENT_BT_PEER_CONNECTION_HPP_INCLUDED
  29. #define TORRENT_BT_PEER_CONNECTION_HPP_INCLUDED
  30. #include <ctime>
  31. #include <algorithm>
  32. #include <vector>
  33. #include <string>
  34. #include "libtorrent/debug.hpp"
  35. #ifdef _MSC_VER
  36. #pragma warning(push, 1)
  37. #endif
  38. #include <boost/smart_ptr.hpp>
  39. #include <boost/noncopyable.hpp>
  40. #include <boost/array.hpp>
  41. #include <boost/optional.hpp>
  42. #include <boost/cstdint.hpp>
  43. #ifdef _MSC_VER
  44. #pragma warning(pop)
  45. #endif
  46. #include "libtorrent/buffer.hpp"
  47. #include "libtorrent/peer_connection.hpp"
  48. #include "libtorrent/socket.hpp"
  49. #include "libtorrent/peer_id.hpp"
  50. #include "libtorrent/stat.hpp"
  51. #include "libtorrent/alert.hpp"
  52. #include "libtorrent/torrent.hpp"
  53. #include "libtorrent/peer_request.hpp"
  54. #include "libtorrent/piece_block_progress.hpp"
  55. #include "libtorrent/config.hpp"
  56. #include "libtorrent/pe_crypto.hpp"
  57. namespace libtorrent
  58. {
  59. class torrent;
  60. namespace detail
  61. {
  62. struct session_impl;
  63. }
  64. class TORRENT_EXTRA_EXPORT bt_peer_connection
  65. : public peer_connection
  66. {
  67. friend class invariant_access;
  68. public:
  69. // this is the constructor where the we are the active part.
  70. // The peer_conenction should handshake and verify that the
  71. // other end has the correct id
  72. bt_peer_connection(
  73. aux::session_impl& ses
  74. , boost::weak_ptr<torrent> t
  75. , boost::shared_ptr<socket_type> s
  76. , tcp::endpoint const& remote
  77. , policy::peer* peerinfo
  78. , bool outgoing = true);
  79. // with this constructor we have been contacted and we still don't
  80. // know which torrent the connection belongs to
  81. bt_peer_connection(
  82. aux::session_impl& ses
  83. , boost::shared_ptr<socket_type> s
  84. , tcp::endpoint const& remote
  85. , policy::peer* peerinfo);
  86. void start();
  87. enum
  88. {
  89. upload_only_msg = 2,
  90. holepunch_msg = 3,
  91. share_mode_msg = 4,
  92. dont_have_msg = 5,
  93. };
  94. ~bt_peer_connection();
  95. #ifndef TORRENT_DISABLE_ENCRYPTION
  96. bool supports_encryption() const
  97. { return m_encrypted; }
  98. bool rc4_encrypted() const
  99. { return m_rc4_encrypted; }
  100. #endif
  101. virtual int type() const { return peer_connection::bittorrent_connection; }
  102. enum message_type
  103. {
  104. // standard messages
  105. msg_choke = 0,
  106. msg_unchoke,
  107. msg_interested,
  108. msg_not_interested,
  109. msg_have,
  110. msg_bitfield,
  111. msg_request,
  112. msg_piece,
  113. msg_cancel,
  114. // DHT extension
  115. msg_dht_port,
  116. // FAST extension
  117. msg_suggest_piece = 0xd,
  118. msg_have_all,
  119. msg_have_none,
  120. msg_reject_request,
  121. msg_allowed_fast,
  122. // extension protocol message
  123. msg_extended = 20,
  124. num_supported_messages
  125. };
  126. enum hp_message_t
  127. {
  128. // msg_types
  129. hp_rendezvous = 0,
  130. hp_connect = 1,
  131. hp_failed = 2,
  132. // error codes
  133. hp_no_such_peer = 1,
  134. hp_not_connected = 2,
  135. hp_no_support = 3,
  136. hp_no_self = 4
  137. };
  138. // called from the main loop when this connection has any
  139. // work to do.
  140. void on_sent(error_code const& error
  141. , std::size_t bytes_transferred);
  142. void on_receive(error_code const& error
  143. , std::size_t bytes_transferred);
  144. virtual void get_specific_peer_info(peer_info& p) const;
  145. virtual bool in_handshake() const;
  146. #ifndef TORRENT_DISABLE_EXTENSIONS
  147. bool supports_holepunch() const { return m_holepunch_id != 0; }
  148. #endif
  149. bool support_extensions() const { return m_supports_extensions; }
  150. // the message handlers are called
  151. // each time a recv() returns some new
  152. // data, the last time it will be called
  153. // is when the entire packet has been
  154. // received, then it will no longer
  155. // be called. i.e. most handlers need
  156. // to check how much of the packet they
  157. // have received before any processing
  158. void on_keepalive();
  159. void on_choke(int received);
  160. void on_unchoke(int received);
  161. void on_interested(int received);
  162. void on_not_interested(int received);
  163. void on_have(int received);
  164. void on_bitfield(int received);
  165. void on_request(int received);
  166. void on_piece(int received);
  167. void on_cancel(int received);
  168. // DHT extension
  169. void on_dht_port(int received);
  170. // FAST extension
  171. void on_suggest_piece(int received);
  172. void on_have_all(int received);
  173. void on_have_none(int received);
  174. void on_reject_request(int received);
  175. void on_allowed_fast(int received);
  176. #ifndef TORRENT_DISABLE_EXTENSIONS
  177. void on_holepunch();
  178. #endif
  179. void on_extended(int received);
  180. void on_extended_handshake();
  181. typedef void (bt_peer_connection::*message_handler)(int received);
  182. // the following functions appends messages
  183. // to the send buffer
  184. void write_choke();
  185. void write_unchoke();
  186. void write_interested();
  187. void write_not_interested();
  188. void write_request(peer_request const& r);
  189. void write_cancel(peer_request const& r);
  190. void write_bitfield();
  191. void write_have(int index);
  192. void write_piece(peer_request const& r, disk_buffer_holder& buffer);
  193. void write_handshake();
  194. #ifndef TORRENT_DISABLE_EXTENSIONS
  195. void write_extensions();
  196. void write_upload_only();
  197. void write_share_mode();
  198. void write_holepunch_msg(int type, tcp::endpoint const& ep, int error);
  199. #endif
  200. void write_metadata(std::pair<int, int> req);
  201. void write_metadata_request(std::pair<int, int> req);
  202. void write_keepalive();
  203. // DHT extension
  204. void write_dht_port(int listen_port);
  205. // FAST extension
  206. void write_have_all();
  207. void write_have_none();
  208. void write_reject_request(peer_request const&);
  209. void write_allow_fast(int piece);
  210. void write_suggest(int piece);
  211. void on_connected();
  212. void on_metadata();
  213. #ifdef TORRENT_DEBUG
  214. void check_invariant() const;
  215. ptime m_last_choke;
  216. #endif
  217. private:
  218. bool dispatch_message(int received);
  219. // returns the block currently being
  220. // downloaded. And the progress of that
  221. // block. If the peer isn't downloading
  222. // a piece for the moment, the boost::optional
  223. // will be invalid.
  224. boost::optional<piece_block_progress> downloading_piece_progress() const;
  225. #ifndef TORRENT_DISABLE_ENCRYPTION
  226. // if (is_local()), we are 'a' otherwise 'b'
  227. //
  228. // 1. a -> b dhkey, pad
  229. // 2. b -> a dhkey, pad
  230. // 3. a -> b sync, payload
  231. // 4. b -> a sync, payload
  232. // 5. a -> b payload
  233. void write_pe1_2_dhkey();
  234. void write_pe3_sync();
  235. void write_pe4_sync(int crypto_select);
  236. void write_pe_vc_cryptofield(char* write_buf, int len
  237. , int crypto_field, int pad_size);
  238. // stream key (info hash of attached torrent)
  239. // secret is the DH shared secret
  240. // initializes m_enc_handler
  241. void init_pe_rc4_handler(char const* secret, sha1_hash const& stream_key);
  242. public:
  243. // these functions encrypt the send buffer if m_rc4_encrypted
  244. // is true, otherwise it passes the call to the
  245. // peer_connection functions of the same names
  246. virtual void append_const_send_buffer(char const* buffer, int size);
  247. virtual void send_buffer(char const* begin, int size, int flags = 0
  248. , void (*fun)(char*, int, void*) = 0, void* userdata = 0);
  249. template <class Destructor>
  250. void append_send_buffer(char* buffer, int size, Destructor const& destructor)
  251. {
  252. #ifndef TORRENT_DISABLE_ENCRYPTION
  253. if (m_rc4_encrypted)
  254. m_enc_handler->encrypt(buffer, size);
  255. #endif
  256. peer_connection::append_send_buffer(buffer, size, destructor, true);
  257. }
  258. private:
  259. // Returns offset at which bytestream (src, src + src_size)
  260. // matches bytestream(target, target + target_size).
  261. // If no sync found, return -1
  262. int get_syncoffset(char const* src, int src_size
  263. , char const* target, int target_size) const;
  264. #endif
  265. enum state
  266. {
  267. #ifndef TORRENT_DISABLE_ENCRYPTION
  268. read_pe_dhkey = 0,
  269. read_pe_syncvc,
  270. read_pe_synchash,
  271. read_pe_skey_vc,
  272. read_pe_cryptofield,
  273. read_pe_pad,
  274. read_pe_ia,
  275. init_bt_handshake,
  276. read_protocol_identifier,
  277. #else
  278. read_protocol_identifier = 0,
  279. #endif
  280. read_info_hash,
  281. read_peer_id,
  282. // handshake complete
  283. read_packet_size,
  284. read_packet
  285. };
  286. #ifndef TORRENT_DISABLE_ENCRYPTION
  287. enum
  288. {
  289. handshake_len = 68,
  290. dh_key_len = 96
  291. };
  292. #endif
  293. std::string m_client_version;
  294. // state of on_receive
  295. state m_state;
  296. static const message_handler m_message_handler[num_supported_messages];
  297. // this is a queue of ranges that describes
  298. // where in the send buffer actual payload
  299. // data is located. This is currently
  300. // only used to be able to gather statistics
  301. // seperately on payload and protocol data.
  302. struct range
  303. {
  304. range(int s, int l)
  305. : start(s)
  306. , length(l)
  307. {
  308. TORRENT_ASSERT(s >= 0);
  309. TORRENT_ASSERT(l > 0);
  310. }
  311. int start;
  312. int length;
  313. };
  314. static bool range_below_zero(const range& r)
  315. { return r.start < 0; }
  316. std::vector<range> m_payloads;
  317. // we have suggested these pieces to the peer
  318. // don't suggest it again
  319. bitfield m_sent_suggested_pieces;
  320. #ifndef TORRENT_DISABLE_EXTENSIONS
  321. // the message ID for upload only message
  322. // 0 if not supported
  323. boost::uint8_t m_upload_only_id;
  324. // the message ID for holepunch messages
  325. boost::uint8_t m_holepunch_id;
  326. // the message ID for don't-have message
  327. boost::uint8_t m_dont_have_id;
  328. // the message ID for share mode message
  329. // 0 if not supported
  330. boost::uint8_t m_share_mode_id;
  331. char m_reserved_bits[8];
  332. #endif
  333. // this is set to true if the handshake from
  334. // the peer indicated that it supports the
  335. // extension protocol
  336. bool m_supports_extensions:1;
  337. bool m_supports_dht_port:1;
  338. bool m_supports_fast:1;
  339. #ifndef TORRENT_DISABLE_ENCRYPTION
  340. // this is set to true after the encryption method has been
  341. // succesfully negotiated (either plaintext or rc4), to signal
  342. // automatic encryption/decryption.
  343. bool m_encrypted;
  344. // true if rc4, false if plaintext
  345. bool m_rc4_encrypted;
  346. // used to disconnect peer if sync points are not found within
  347. // the maximum number of bytes
  348. int m_sync_bytes_read;
  349. // initialized during write_pe1_2_dhkey, and destroyed on
  350. // creation of m_enc_handler. Cannot reinitialize once
  351. // initialized.
  352. boost::scoped_ptr<dh_key_exchange> m_dh_key_exchange;
  353. // if encryption is negotiated, this is used for
  354. // encryption/decryption during the entire session. Destroyed
  355. // if plaintext is selected
  356. boost::scoped_ptr<encryption_handler> m_enc_handler;
  357. // (outgoing only) synchronize verification constant with
  358. // remote peer, this will hold rc4_decrypt(vc). Destroyed
  359. // after the sync step.
  360. boost::scoped_array<char> m_sync_vc;
  361. // (incoming only) synchronize hash with remote peer, holds
  362. // the sync hash (hash("req1",secret)). Destroyed after the
  363. // sync step.
  364. boost::scoped_ptr<sha1_hash> m_sync_hash;
  365. #endif // #ifndef TORRENT_DISABLE_ENCRYPTION
  366. #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS
  367. // this is set to true when the client's
  368. // bitfield is sent to this peer
  369. bool m_sent_bitfield;
  370. bool m_in_constructor;
  371. bool m_sent_handshake;
  372. #endif
  373. };
  374. }
  375. #endif // TORRENT_BT_PEER_CONNECTION_HPP_INCLUDED