diff --git a/include/libtorrent/bt_peer_connection.hpp b/include/libtorrent/bt_peer_connection.hpp index f85490b26..1ea3bbd4d 100644 --- a/include/libtorrent/bt_peer_connection.hpp +++ b/include/libtorrent/bt_peer_connection.hpp @@ -344,10 +344,44 @@ private: }; #endif - std::string m_client_version; - // state of on_receive - state m_state; + boost::uint8_t m_state; + + // this is set to true if the handshake from + // the peer indicated that it supports the + // extension protocol + bool m_supports_extensions:1; + bool m_supports_dht_port:1; + bool m_supports_fast:1; + +#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS + // this is set to true when the client's + // bitfield is sent to this peer + bool m_sent_bitfield:1; + + bool m_in_constructor:1; + + bool m_sent_handshake:1; +#endif + +#ifndef TORRENT_DISABLE_ENCRYPTION + // this is set to true after the encryption method has been + // succesfully negotiated (either plaintext or rc4), to signal + // automatic encryption/decryption. + bool m_encrypted:1; + + // true if rc4, false if plaintext + bool m_rc4_encrypted:1; + + // the message ID for upload only message + // 0 if not supported + boost::uint8_t m_upload_only_id; + + // the message ID for holepunch messages + boost::uint8_t m_holepunch_id; +#endif + + std::string m_client_version; static const message_handler m_message_handler[num_supported_messages]; @@ -376,43 +410,7 @@ private: // don't suggest it again bitfield m_sent_suggested_pieces; -#ifndef TORRENT_DISABLE_EXTENSIONS - // the message ID for upload only message - // 0 if not supported - boost::uint8_t m_upload_only_id; - - // the message ID for holepunch messages - boost::uint8_t m_holepunch_id; - - // the message ID for don't-have message - boost::uint8_t m_dont_have_id; - - // the message ID for share mode message - // 0 if not supported - boost::uint8_t m_share_mode_id; - - char m_reserved_bits[8]; -#endif - // this is set to true if the handshake from - // the peer indicated that it supports the - // extension protocol - bool m_supports_extensions:1; - bool m_supports_dht_port:1; - bool m_supports_fast:1; - #ifndef TORRENT_DISABLE_ENCRYPTION - // this is set to true after the encryption method has been - // succesfully negotiated (either plaintext or rc4), to signal - // automatic encryption/decryption. - bool m_encrypted; - - // true if rc4, false if plaintext - bool m_rc4_encrypted; - - // used to disconnect peer if sync points are not found within - // the maximum number of bytes - int m_sync_bytes_read; - // initialized during write_pe1_2_dhkey, and destroyed on // creation of m_enc_handler. Cannot reinitialize once // initialized. @@ -432,18 +430,23 @@ private: // the sync hash (hash("req1",secret)). Destroyed after the // sync step. boost::scoped_ptr m_sync_hash; + + // used to disconnect peer if sync points are not found within + // the maximum number of bytes + int m_sync_bytes_read; + + // the message ID for don't-have message + boost::uint8_t m_dont_have_id; + + // the message ID for share mode message + // 0 if not supported + boost::uint8_t m_share_mode_id; + + // the reserved bits received from the other peer + // in the bittorrent handshake + char m_reserved_bits[8]; #endif // #ifndef TORRENT_DISABLE_ENCRYPTION -#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS - // this is set to true when the client's - // bitfield is sent to this peer - bool m_sent_bitfield; - - bool m_in_constructor; - - bool m_sent_handshake; -#endif - }; } diff --git a/include/libtorrent/config.hpp b/include/libtorrent/config.hpp index 387e61b49..3b3847982 100644 --- a/include/libtorrent/config.hpp +++ b/include/libtorrent/config.hpp @@ -518,7 +518,8 @@ inline int snprintf(char* buf, int len, char const* fmt, ...) # ifdef _GLIBCXX_DEBUG # define TORRENT_READ_HANDLER_MAX_SIZE 400 # else -# define TORRENT_READ_HANDLER_MAX_SIZE 330 +// if this is not divisible by 8, we're wasting space +# define TORRENT_READ_HANDLER_MAX_SIZE 336 # endif #endif @@ -526,7 +527,8 @@ inline int snprintf(char* buf, int len, char const* fmt, ...) # ifdef _GLIBCXX_DEBUG # define TORRENT_WRITE_HANDLER_MAX_SIZE 400 # else -# define TORRENT_WRITE_HANDLER_MAX_SIZE 330 +// if this is not divisible by 8, we're wasting space +# define TORRENT_WRITE_HANDLER_MAX_SIZE 336 # endif #endif diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index 0d77768a8..05905ec69 100644 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -293,7 +293,7 @@ namespace libtorrent // tells if this connection has data it want to send // and has enough upload bandwidth quota left to send it. bool can_write() const; - bool can_read(char* state = 0) const; + bool can_read(boost::uint8_t* state = 0) const; bool is_seed() const; int num_have_pieces() const { return m_num_pieces; } @@ -625,10 +625,6 @@ namespace libtorrent time_t last_seen_complete() const { return m_last_seen_complete; } void set_last_seen_complete(int ago) { m_last_seen_complete = time(0) - ago; } - // upload and download channel state - // enum from peer_info::bw_state - char m_channel_state[2]; - size_type uploaded_in_last_round() const { return m_statistics.total_payload_upload() - m_uploaded_at_last_round; } @@ -722,6 +718,98 @@ namespace libtorrent void update_desired_queue_size(); + void set_timeout(int s) { m_timeout = s; } + + boost::intrusive_ptr self() + { + TORRENT_ASSERT(!m_in_constructor); + return boost::intrusive_ptr(this); + } + + // TODO: make this private + public: + + // upload and download channel state + // enum from peer_info::bw_state + boost::uint8_t m_channel_state[2]; + + private: + + // is true if we learn the incoming connections listening + // during the extended handshake + bool m_received_listen_port:1; + + // this is set to true when a have_all + // message is received. This information + // is used to fill the bitmask in init() + bool m_have_all:1; + + // other side says that it's interested in downloading + // from us. + bool m_peer_interested:1; + + // the other side has told us that it won't send anymore + // data to us for a while + bool m_peer_choked:1; + + // the peer has pieces we are interested in + bool m_interesting:1; + + // we have choked the upload to the peer + bool m_choked:1; + + // this is set to true if the connection timed + // out or closed the connection. In that + // case we will not try to reconnect to + // this peer + bool m_failed:1; + + // this is true if this connection has been added + // to the list of connections that will be closed. + bool m_disconnecting:1; + + // this is set to true once the bitfield is received + bool m_bitfield_received:1; + + // this is set to true if the last time we tried to + // pick a piece to download, we could only find + // blocks that were already requested from other + // peers. In this case, we should not try to pick + // another piece until the last one we requested is done + bool m_endgame_mode:1; + + // set to true when we've sent the first round of suggests + bool m_sent_suggests:1; + + // set to true while we're trying to holepunch + bool m_holepunch_mode:1; + + // when this is set, the transfer stats for this connection + // is not included in the torrent or session stats + bool m_ignore_stats:1; + + // when this is set, the peer_connection socket is + // corked, similar to the linux TCP feature TCP_CORK. + // we won't send anything to the actual socket, just + // buffer messages up in the application layer send + // buffer, and send it once we're uncorked. + bool m_corked:1; + + // set to true if this peer has metadata, and false + // otherwise. + bool m_has_metadata:1; + + // this is set to true if this peer was accepted exceeding + // the connection limit. It means it has to disconnect + // itself, or some other peer, as soon as it's completed + // the handshake. We need to wait for the handshake in + // order to know which torrent it belongs to, to know which + // other peers to compare it to. + bool m_exceeded_limit:1; + + // TODO: make these private as well + protected: + // number of bytes this peer can send and receive int m_quota[2]; @@ -750,14 +838,6 @@ namespace libtorrent sliding_average<20> m_piece_rate; sliding_average<20> m_send_rate; - void set_timeout(int s) { m_timeout = s; } - - boost::intrusive_ptr self() - { - TORRENT_ASSERT(!m_in_constructor); - return boost::intrusive_ptr(this); - } - private: std::pair preferred_caching() const; @@ -894,7 +974,7 @@ namespace libtorrent // the pieces the other end have bitfield m_have_piece; - + // the queue of requests we have got // from this peer that haven't been issued // to the disk thread yet @@ -947,13 +1027,13 @@ namespace libtorrent // connected to, in case we use a proxy tcp::endpoint m_remote; - // remote peer's id - peer_id m_peer_id; - // the bandwidth channels, upload and download // keeps track of the current quotas bandwidth_channel m_bandwidth_channel[num_channels]; + // remote peer's id + peer_id m_peer_id; + // if the timeout is extended for the outstanding // requests, this is the number of seconds it was // extended. @@ -1059,12 +1139,6 @@ namespace libtorrent int m_download_rate_peak; int m_upload_rate_peak; - // when using the BitTyrant choker, this is our - // estimated reciprocation rate. i.e. the rate - // we need to send to this peer for it to unchoke - // us - int m_est_reciprocation_rate; - // this is the limit on the number of outstanding requests // we have to this peer. This is initialized to the settings // in the session_settings structure. But it may be lowered @@ -1073,6 +1147,12 @@ namespace libtorrent // web seeds also has a limit on the queue size. int m_max_out_request_queue; + // when using the BitTyrant choker, this is our + // estimated reciprocation rate. i.e. the rate + // we need to send to this peer for it to unchoke + // us + int m_est_reciprocation_rate; + // estimated round trip time to this peer // based on the time from when async_connect // was called to when on_connection_complete @@ -1111,30 +1191,6 @@ namespace libtorrent // could be considered: true = local, false = remote bool m_outgoing:1; - // is true if we learn the incoming connections listening - // during the extended handshake - bool m_received_listen_port:1; - - // other side says that it's interested in downloading - // from us. - bool m_peer_interested:1; - - // the other side has told us that it won't send anymore - // data to us for a while - bool m_peer_choked:1; - - // the peer has pieces we are interested in - bool m_interesting:1; - - // we have choked the upload to the peer - bool m_choked:1; - - // this is set to true if the connection timed - // out or closed the connection. In that - // case we will not try to reconnect to - // this peer - bool m_failed:1; - // if this is set to true, the peer will not // request bandwidth from the limiter, but instead // just send and receive as much as possible. @@ -1145,15 +1201,6 @@ namespace libtorrent // unchoker bool m_ignore_unchoke_slots:1; - // this is set to true when a have_all - // message is received. This information - // is used to fill the bitmask in init() - bool m_have_all:1; - - // this is true if this connection has been added - // to the list of connections that will be closed. - bool m_disconnecting:1; - // this is true until this socket has become // writable for the first time (i.e. the // connection completed). While connecting @@ -1188,49 +1235,10 @@ namespace libtorrent // is set to 1 bool m_snubbed:1; - // this is set to true once the bitfield is received - bool m_bitfield_received:1; - // if this is set to true, the client will not // pick any pieces from this peer bool m_no_download:1; - // this is set to true if the last time we tried to - // pick a piece to download, we could only find - // blocks that were already requested from other - // peers. In this case, we should not try to pick - // another piece until the last one we requested is done - bool m_endgame_mode:1; - - // set to true when we've sent the first round of suggests - bool m_sent_suggests:1; - - // set to true while we're trying to holepunch - bool m_holepunch_mode:1; - - // when this is set, the transfer stats for this connection - // is not included in the torrent or session stats - bool m_ignore_stats:1; - - // when this is set, the peer_connection socket is - // corked, similar to the linux TCP feature TCP_CORK. - // we won't send anything to the actual socket, just - // buffer messages up in the application layer send - // buffer, and send it once we're uncorked. - bool m_corked:1; - - // set to true if this peer has metadata, and false - // otherwise. - bool m_has_metadata:1; - - // this is set to true if this peer was accepted exceeding - // the connection limit. It means it has to disconnect - // itself, or some other peer, as soon as it's completed - // the handshake. We need to wait for the handshake in - // order to know which torrent it belongs to, to know which - // other peers to compare it to. - bool m_exceeded_limit:1; - template struct allocating_handler { diff --git a/include/libtorrent/session_settings.hpp b/include/libtorrent/session_settings.hpp index 616de5f1f..31492a04b 100644 --- a/include/libtorrent/session_settings.hpp +++ b/include/libtorrent/session_settings.hpp @@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/config.hpp" #include "libtorrent/version.hpp" +#include #include namespace libtorrent @@ -46,8 +47,8 @@ namespace libtorrent // direct certain traffic to a proxy. struct TORRENT_EXPORT proxy_settings { - proxy_settings() : port(0), type(none) - , proxy_hostnames(true) + proxy_settings() : type(none) + , port(0), proxy_hostnames(true) , proxy_peer_connections(true) {} @@ -55,7 +56,6 @@ namespace libtorrent // port number the proxy listens to. If required, ``username`` and ``password`` // can be set to authenticate with the proxy. std::string hostname; - int port; std::string username; std::string password; @@ -100,7 +100,10 @@ namespace libtorrent // tells libtorrent what kind of proxy server it is. See proxy_type // enum for options - proxy_type type; + boost::uint8_t type; + + // the port the proxy server is running on + boost::uint16_t port; // defaults to true. It means that hostnames should be // attempted to be resolved through the proxy instead of using the local DNS @@ -1521,14 +1524,14 @@ namespace libtorrent // control the settings for incoming // and outgoing connections respectively. // see enc_policy enum for the available options. - enc_policy out_enc_policy; - enc_policy in_enc_policy; + boost::uint8_t out_enc_policy; + boost::uint8_t in_enc_policy; // determines the encryption level of the // connections. This setting will adjust which encryption scheme is // offered to the other peer, as well as which encryption scheme is // selected by the client. See enc_level enum for options. - enc_level allowed_enc_level; + boost::uint8_t allowed_enc_level; // if the allowed encryption level is both, setting this to // true will prefer rc4 if both methods are offered, plaintext diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index bc235389d..99c47166a 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -104,24 +104,22 @@ namespace libtorrent : peer_connection(ses, tor, s, remote , peerinfo, outgoing) , m_state(read_protocol_identifier) -#ifndef TORRENT_DISABLE_EXTENSIONS - , m_upload_only_id(0) - , m_holepunch_id(0) - , m_dont_have_id(0) - , m_share_mode_id(0) , m_supports_extensions(false) -#endif , m_supports_dht_port(false) , m_supports_fast(false) -#ifndef TORRENT_DISABLE_ENCRYPTION - , m_encrypted(false) - , m_rc4_encrypted(false) - , m_sync_bytes_read(0) -#endif #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS , m_sent_bitfield(false) , m_in_constructor(true) , m_sent_handshake(false) +#endif +#ifndef TORRENT_DISABLE_ENCRYPTION + , m_encrypted(false) + , m_rc4_encrypted(false) + , m_upload_only_id(0) + , m_holepunch_id(0) + , m_sync_bytes_read(0) + , m_dont_have_id(0) + , m_share_mode_id(0) #endif { #ifdef TORRENT_VERBOSE_LOGGING @@ -153,7 +151,7 @@ namespace libtorrent { #ifndef TORRENT_DISABLE_ENCRYPTION - pe_settings::enc_policy out_enc_policy = m_ses.get_pe_settings().out_enc_policy; + boost::uint8_t out_enc_policy = m_ses.get_pe_settings().out_enc_policy; #ifdef TORRENT_USE_OPENSSL // never try an encrypted connection when already using SSL @@ -481,7 +479,7 @@ namespace libtorrent // write the verification constant and crypto field int encrypt_size = sizeof(msg) - 512 + pad_size - 40; - pe_settings::enc_level crypto_provide = m_ses.get_pe_settings().allowed_enc_level; + boost::uint8_t crypto_provide = m_ses.get_pe_settings().allowed_enc_level; // this is an invalid setting, but let's just make the best of the situation if ((crypto_provide & pe_settings::both) == 0) crypto_provide = pe_settings::both; diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 584fd7c78..014a8af45 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -112,7 +112,23 @@ namespace libtorrent , tcp::endpoint const& endp , policy::peer* peerinfo , bool outgoing) - : m_ses(ses) + : m_received_listen_port(false) + , m_have_all(false) + , m_peer_interested(false) + , m_peer_choked(true) + , m_interesting(false) + , m_choked(true) + , m_failed(false) + , m_disconnecting(false) + , m_bitfield_received(false) + , m_endgame_mode(false) + , m_sent_suggests(false) + , m_holepunch_mode(false) + , m_ignore_stats(false) + , m_corked(false) + , m_has_metadata(true) + , m_exceeded_limit(false) + , m_ses(ses) , m_work(ses.m_io_service) , m_last_piece(time_now()) , m_last_request(time_now()) @@ -166,31 +182,15 @@ namespace libtorrent , m_desired_queue_size(2) , m_fast_reconnect(false) , m_outgoing(outgoing) - , m_received_listen_port(false) - , m_peer_interested(false) - , m_peer_choked(true) - , m_interesting(false) - , m_choked(true) - , m_failed(false) , m_ignore_bandwidth_limits(false) , m_ignore_unchoke_slots(false) - , m_have_all(false) - , m_disconnecting(false) , m_connecting(outgoing) , m_queued(outgoing) , m_request_large_blocks(false) , m_share_mode(false) , m_upload_only(false) , m_snubbed(false) - , m_bitfield_received(false) , m_no_download(false) - , m_endgame_mode(false) - , m_sent_suggests(false) - , m_holepunch_mode(false) - , m_ignore_stats(false) - , m_corked(false) - , m_has_metadata(true) - , m_exceeded_limit(false) #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS , m_in_constructor(true) , m_disconnect_started(false) @@ -5392,7 +5392,7 @@ namespace libtorrent && !m_connecting; } - bool peer_connection::can_read(char* state) const + bool peer_connection::can_read(boost::uint8_t* state) const { boost::shared_ptr t = m_torrent.lock(); diff --git a/test/test_pe_crypto.cpp b/test/test_pe_crypto.cpp index ecae87bfd..d43ce49e7 100644 --- a/test/test_pe_crypto.cpp +++ b/test/test_pe_crypto.cpp @@ -42,7 +42,7 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef TORRENT_DISABLE_ENCRYPTION -char const* pe_policy(libtorrent::pe_settings::enc_policy policy) +char const* pe_policy(boost::uint8_t policy) { using namespace libtorrent;