changed the way connections are disconnected. improved logging. Does not depend on exceptions anymore
This commit is contained in:
parent
4271eda751
commit
cf4036310b
|
@ -194,10 +194,18 @@ namespace libtorrent
|
|||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(
|
||||
torrent*, void*)> ext);
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
bool has_peer(peer_connection const* p) const
|
||||
{
|
||||
return std::find_if(m_connections.begin(), m_connections.end()
|
||||
, boost::bind(&boost::intrusive_ptr<peer_connection>::get, _1) == p)
|
||||
!= m_connections.end();
|
||||
}
|
||||
#endif
|
||||
void operator()();
|
||||
|
||||
void open_listen_port() throw();
|
||||
void open_listen_port();
|
||||
|
||||
// if we are listening on an IPv6 interface
|
||||
// this will return one of the IPv6 addresses on this
|
||||
|
@ -216,9 +224,8 @@ namespace libtorrent
|
|||
boost::weak_ptr<torrent> find_torrent(const sha1_hash& info_hash);
|
||||
peer_id const& get_peer_id() const { return m_peer_id; }
|
||||
|
||||
void close_connection(boost::intrusive_ptr<peer_connection> const& p);
|
||||
void connection_failed(boost::intrusive_ptr<peer_connection> const& p
|
||||
, tcp::endpoint const& a, char const* message);
|
||||
void close_connection(peer_connection const* p
|
||||
, char const* message);
|
||||
|
||||
void set_settings(session_settings const& s);
|
||||
session_settings const& settings() const { return m_settings; }
|
||||
|
|
|
@ -224,7 +224,7 @@ namespace libtorrent
|
|||
void add_stat(size_type downloaded, size_type uploaded);
|
||||
|
||||
// is called once every second by the main loop
|
||||
void second_tick(float tick_interval) throw();
|
||||
void second_tick(float tick_interval);
|
||||
|
||||
boost::shared_ptr<socket_type> get_socket() const { return m_socket; }
|
||||
tcp::endpoint const& remote() const { return m_remote; }
|
||||
|
@ -235,7 +235,7 @@ namespace libtorrent
|
|||
|
||||
void timed_out();
|
||||
// this will cause this peer_connection to be disconnected.
|
||||
void disconnect();
|
||||
void disconnect(char const* message);
|
||||
bool is_disconnecting() const { return m_disconnecting; }
|
||||
|
||||
// this is called when the connection attempt has succeeded
|
||||
|
|
|
@ -85,10 +85,13 @@ namespace libtorrent
|
|||
// the tracker, pex, lsd or dht.
|
||||
policy::peer* peer_from_tracker(const tcp::endpoint& remote, const peer_id& pid
|
||||
, int source, char flags);
|
||||
void update_peer_port(int port, policy::peer* p, int src);
|
||||
|
||||
// false means duplicate connection
|
||||
bool update_peer_port(int port, policy::peer* p, int src);
|
||||
|
||||
// called when an incoming connection is accepted
|
||||
void new_connection(peer_connection& c);
|
||||
// false means the connection was refused or failed
|
||||
bool new_connection(peer_connection& c);
|
||||
|
||||
// the given connection was just closed
|
||||
void connection_closed(const peer_connection& c) throw();
|
||||
|
|
|
@ -133,6 +133,11 @@ namespace libtorrent
|
|||
, void* userdata);
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool has_peer(peer_connection* p) const
|
||||
{ return m_connections.find(p) != m_connections.end(); }
|
||||
#endif
|
||||
|
||||
// this is called when the torrent has metadata.
|
||||
// it will initialize the storage and the piece-picker
|
||||
void init();
|
||||
|
|
|
@ -790,7 +790,10 @@ namespace libtorrent
|
|||
|
||||
TORRENT_ASSERT(received > 0);
|
||||
if (packet_size() != 1)
|
||||
throw protocol_error("'choke' message size != 1");
|
||||
{
|
||||
disconnect("'choke' message size != 1");
|
||||
return;
|
||||
}
|
||||
m_statistics.received_bytes(0, received);
|
||||
if (!packet_finished()) return;
|
||||
|
||||
|
@ -821,7 +824,10 @@ namespace libtorrent
|
|||
|
||||
TORRENT_ASSERT(received > 0);
|
||||
if (packet_size() != 1)
|
||||
throw protocol_error("'unchoke' message size != 1");
|
||||
{
|
||||
disconnect("'unchoke' message size != 1");
|
||||
return;
|
||||
}
|
||||
m_statistics.received_bytes(0, received);
|
||||
if (!packet_finished()) return;
|
||||
|
||||
|
@ -838,7 +844,10 @@ namespace libtorrent
|
|||
|
||||
TORRENT_ASSERT(received > 0);
|
||||
if (packet_size() != 1)
|
||||
throw protocol_error("'interested' message size != 1");
|
||||
{
|
||||
disconnect("'interested' message size != 1");
|
||||
return;
|
||||
}
|
||||
m_statistics.received_bytes(0, received);
|
||||
if (!packet_finished()) return;
|
||||
|
||||
|
@ -855,7 +864,10 @@ namespace libtorrent
|
|||
|
||||
TORRENT_ASSERT(received > 0);
|
||||
if (packet_size() != 1)
|
||||
throw protocol_error("'not interested' message size != 1");
|
||||
{
|
||||
disconnect("'not interested' message size != 1");
|
||||
return;
|
||||
}
|
||||
m_statistics.received_bytes(0, received);
|
||||
if (!packet_finished()) return;
|
||||
|
||||
|
@ -872,7 +884,10 @@ namespace libtorrent
|
|||
|
||||
TORRENT_ASSERT(received > 0);
|
||||
if (packet_size() != 5)
|
||||
throw protocol_error("'have' message size != 5");
|
||||
{
|
||||
disconnect("'have' message size != 5");
|
||||
return;
|
||||
}
|
||||
m_statistics.received_bytes(0, received);
|
||||
if (!packet_finished()) return;
|
||||
|
||||
|
@ -901,7 +916,10 @@ namespace libtorrent
|
|||
// verify the bitfield size
|
||||
if (t->valid_metadata()
|
||||
&& packet_size() - 1 != ((int)get_bitfield().size() + 7) / 8)
|
||||
throw protocol_error("bitfield with invalid size");
|
||||
{
|
||||
disconnect("bitfield with invalid size");
|
||||
return;
|
||||
}
|
||||
|
||||
m_statistics.received_bytes(0, received);
|
||||
if (!packet_finished()) return;
|
||||
|
@ -935,7 +953,10 @@ namespace libtorrent
|
|||
|
||||
TORRENT_ASSERT(received > 0);
|
||||
if (packet_size() != 13)
|
||||
throw protocol_error("'request' message size != 13");
|
||||
{
|
||||
disconnect("'request' message size != 13");
|
||||
return;
|
||||
}
|
||||
m_statistics.received_bytes(0, received);
|
||||
if (!packet_finished()) return;
|
||||
|
||||
|
@ -1004,7 +1025,10 @@ namespace libtorrent
|
|||
|
||||
TORRENT_ASSERT(received > 0);
|
||||
if (packet_size() != 13)
|
||||
throw protocol_error("'cancel' message size != 13");
|
||||
{
|
||||
disconnect("'cancel' message size != 13");
|
||||
return;
|
||||
}
|
||||
m_statistics.received_bytes(0, received);
|
||||
if (!packet_finished()) return;
|
||||
|
||||
|
@ -1028,11 +1052,17 @@ namespace libtorrent
|
|||
INVARIANT_CHECK;
|
||||
|
||||
if (!m_supports_dht_port)
|
||||
throw protocol_error("got 'dht_port' message from peer that doesn't support it");
|
||||
{
|
||||
disconnect("got 'dht_port' message from peer that doesn't support it");
|
||||
return;
|
||||
}
|
||||
|
||||
TORRENT_ASSERT(received > 0);
|
||||
if (packet_size() != 3)
|
||||
throw protocol_error("'dht_port' message size != 3");
|
||||
{
|
||||
disconnect("'dht_port' message size != 3");
|
||||
return;
|
||||
}
|
||||
m_statistics.received_bytes(0, received);
|
||||
if (!packet_finished()) return;
|
||||
|
||||
|
@ -1049,7 +1079,10 @@ namespace libtorrent
|
|||
INVARIANT_CHECK;
|
||||
|
||||
if (!m_supports_fast)
|
||||
throw protocol_error("got 'suggest_piece' without FAST extension support");
|
||||
{
|
||||
disconnect("got 'suggest_piece' without FAST excension support");
|
||||
return;
|
||||
}
|
||||
|
||||
m_statistics.received_bytes(0, received);
|
||||
if (!packet_finished()) return;
|
||||
|
@ -1066,7 +1099,10 @@ namespace libtorrent
|
|||
INVARIANT_CHECK;
|
||||
|
||||
if (!m_supports_fast)
|
||||
throw protocol_error("got 'have_all' without FAST extension support");
|
||||
{
|
||||
disconnect("got 'have_all' without FAST extension support");
|
||||
return;
|
||||
}
|
||||
m_statistics.received_bytes(0, received);
|
||||
incoming_have_all();
|
||||
}
|
||||
|
@ -1076,7 +1112,10 @@ namespace libtorrent
|
|||
INVARIANT_CHECK;
|
||||
|
||||
if (!m_supports_fast)
|
||||
throw protocol_error("got 'have_none' without FAST extension support");
|
||||
{
|
||||
disconnect("got 'have_none' without FAST extension support");
|
||||
return;
|
||||
}
|
||||
m_statistics.received_bytes(0, received);
|
||||
incoming_have_none();
|
||||
}
|
||||
|
@ -1086,7 +1125,10 @@ namespace libtorrent
|
|||
INVARIANT_CHECK;
|
||||
|
||||
if (!m_supports_fast)
|
||||
throw protocol_error("got 'reject_request' without FAST extension support");
|
||||
{
|
||||
disconnect("got 'reject_request' without FAST extension support");
|
||||
return;
|
||||
}
|
||||
|
||||
m_statistics.received_bytes(0, received);
|
||||
if (!packet_finished()) return;
|
||||
|
@ -1107,7 +1149,10 @@ namespace libtorrent
|
|||
INVARIANT_CHECK;
|
||||
|
||||
if (!m_supports_fast)
|
||||
throw protocol_error("got 'allowed_fast' without FAST extension support");
|
||||
{
|
||||
disconnect("got 'allowed_fast' without FAST extension support");
|
||||
return;
|
||||
}
|
||||
|
||||
m_statistics.received_bytes(0, received);
|
||||
if (!packet_finished()) return;
|
||||
|
@ -1129,10 +1174,16 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(received > 0);
|
||||
m_statistics.received_bytes(0, received);
|
||||
if (packet_size() < 2)
|
||||
throw protocol_error("'extended' message smaller than 2 bytes");
|
||||
{
|
||||
disconnect("'extended' message smaller than 2 bytes");
|
||||
return;
|
||||
}
|
||||
|
||||
if (associated_torrent().expired())
|
||||
throw protocol_error("'extended' message sent before proper handshake");
|
||||
{
|
||||
disconnect("'extended' message sent before proper handshake");
|
||||
return;
|
||||
}
|
||||
|
||||
buffer::const_interval recv_buffer = receive_buffer();
|
||||
if (recv_buffer.left() < 2) return;
|
||||
|
@ -1158,8 +1209,10 @@ namespace libtorrent
|
|||
}
|
||||
#endif
|
||||
|
||||
throw protocol_error("unknown extended message id: "
|
||||
+ boost::lexical_cast<std::string>(extended_id));
|
||||
std::stringstream msg;
|
||||
msg << "unknown extended message id: " << extended_id;
|
||||
disconnect(msg.str().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
void bt_peer_connection::on_extended_handshake()
|
||||
|
@ -1258,9 +1311,10 @@ namespace libtorrent
|
|||
}
|
||||
#endif
|
||||
|
||||
throw protocol_error("unknown message id: "
|
||||
+ boost::lexical_cast<std::string>(packet_type)
|
||||
+ " size: " + boost::lexical_cast<std::string>(packet_size()));
|
||||
std::stringstream msg;
|
||||
msg << "unkown message id: " << packet_type << " size: " << packet_size();
|
||||
disconnect(msg.str().c_str());
|
||||
return packet_finished();
|
||||
}
|
||||
|
||||
TORRENT_ASSERT(m_message_handler[packet_type] != 0);
|
||||
|
@ -1712,10 +1766,7 @@ namespace libtorrent
|
|||
if (recv_buffer.left() < 20)
|
||||
{
|
||||
if (packet_finished())
|
||||
{
|
||||
throw protocol_error ("sync hash not found");
|
||||
}
|
||||
// else
|
||||
disconnect("sync hash not found");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1740,7 +1791,10 @@ namespace libtorrent
|
|||
std::size_t bytes_processed = recv_buffer.left() - 20;
|
||||
m_sync_bytes_read += bytes_processed;
|
||||
if (m_sync_bytes_read >= 512)
|
||||
throw protocol_error("sync hash not found within 532 bytes");
|
||||
{
|
||||
disconnect("sync hash not found within 532 bytes");
|
||||
return;
|
||||
}
|
||||
|
||||
cut_receive_buffer(bytes_processed, (std::min)(packet_size(), (512+20) - m_sync_bytes_read));
|
||||
|
||||
|
@ -1807,6 +1861,8 @@ namespace libtorrent
|
|||
if (!t)
|
||||
{
|
||||
attach_to_torrent(info_hash);
|
||||
if (is_disconnecting()) return;
|
||||
|
||||
t = associated_torrent().lock();
|
||||
TORRENT_ASSERT(t);
|
||||
}
|
||||
|
@ -1820,7 +1876,10 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
if (!m_RC4_handler.get())
|
||||
throw protocol_error("invalid streamkey identifier (info hash) in encrypted handshake");
|
||||
{
|
||||
disconnect("invalid streamkey identifier (info hash) in encrypted handshake");
|
||||
return;
|
||||
}
|
||||
|
||||
// verify constant
|
||||
buffer::interval wr_recv_buf = wr_recv_buffer();
|
||||
|
@ -1830,7 +1889,8 @@ namespace libtorrent
|
|||
const char sh_vc[] = {0,0,0,0, 0,0,0,0};
|
||||
if (!std::equal(sh_vc, sh_vc+8, recv_buffer.begin + 20))
|
||||
{
|
||||
throw protocol_error("unable to verify constant");
|
||||
disconnect("unable to verify constant");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
|
@ -1851,10 +1911,7 @@ namespace libtorrent
|
|||
if (recv_buffer.left() < 8)
|
||||
{
|
||||
if (packet_finished())
|
||||
{
|
||||
throw protocol_error ("sync verification constant not found");
|
||||
}
|
||||
// else
|
||||
disconnect("sync verification constant not found");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1878,7 +1935,10 @@ namespace libtorrent
|
|||
std::size_t bytes_processed = recv_buffer.left() - 8;
|
||||
m_sync_bytes_read += bytes_processed;
|
||||
if (m_sync_bytes_read >= 512)
|
||||
throw protocol_error("sync verification constant not found within 520 bytes");
|
||||
{
|
||||
disconnect("sync verification constant not found within 520 bytes");
|
||||
return;
|
||||
}
|
||||
|
||||
cut_receive_buffer(bytes_processed, (std::min)(packet_size(), (512+8) - m_sync_bytes_read));
|
||||
|
||||
|
@ -1939,14 +1999,20 @@ namespace libtorrent
|
|||
case (pe_settings::plaintext):
|
||||
{
|
||||
if (!(crypto_field & 0x01))
|
||||
throw protocol_error("plaintext not provided");
|
||||
{
|
||||
disconnect("plaintext not provided");
|
||||
return;
|
||||
}
|
||||
crypto_select = 0x01;
|
||||
}
|
||||
break;
|
||||
case (pe_settings::rc4):
|
||||
{
|
||||
if (!(crypto_field & 0x02))
|
||||
throw protocol_error("rc4 not provided");
|
||||
{
|
||||
disconnect("rc4 not provided");
|
||||
return;
|
||||
}
|
||||
crypto_select = 0x02;
|
||||
}
|
||||
break;
|
||||
|
@ -1967,7 +2033,10 @@ namespace libtorrent
|
|||
crypto_select = 0x02;
|
||||
}
|
||||
if (!crypto_select)
|
||||
throw protocol_error("rc4/plaintext not provided");
|
||||
{
|
||||
disconnect("rc4/plaintext not provided");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} // switch
|
||||
|
||||
|
@ -1982,22 +2051,34 @@ namespace libtorrent
|
|||
if (crypto_field == 0x02)
|
||||
{
|
||||
if (allowed_enc_level == pe_settings::plaintext)
|
||||
throw protocol_error("rc4 selected by peer when not provided");
|
||||
{
|
||||
disconnect("rc4 selected by peer when not provided");
|
||||
return;
|
||||
}
|
||||
m_rc4_encrypted = true;
|
||||
}
|
||||
else if (crypto_field == 0x01)
|
||||
{
|
||||
if (allowed_enc_level == pe_settings::rc4)
|
||||
throw protocol_error("plaintext selected by peer when not provided");
|
||||
{
|
||||
disconnect("plaintext selected by peer when not provided");
|
||||
return;
|
||||
}
|
||||
m_rc4_encrypted = false;
|
||||
}
|
||||
else
|
||||
throw protocol_error("unsupported crypto method selected by peer");
|
||||
{
|
||||
disconnect("unsupported crypto method selected by peer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int len_pad = detail::read_int16(recv_buffer.begin);
|
||||
if (len_pad < 0 || len_pad > 512)
|
||||
throw protocol_error("invalid pad length");
|
||||
{
|
||||
disconnect("invalid pad length");
|
||||
return;
|
||||
}
|
||||
|
||||
m_state = read_pe_pad;
|
||||
if (!is_local())
|
||||
|
@ -2031,7 +2112,11 @@ namespace libtorrent
|
|||
recv_buffer.begin += pad_size;
|
||||
int len_ia = detail::read_int16(recv_buffer.begin);
|
||||
|
||||
if (len_ia < 0) throw protocol_error("invalid len_ia in handshake");
|
||||
if (len_ia < 0)
|
||||
{
|
||||
disconnect("invalid len_ia in handshake");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
(*m_logger) << " len(IA) : " << len_ia << "\n";
|
||||
|
@ -2141,7 +2226,10 @@ namespace libtorrent
|
|||
{
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
if (!is_local() && m_ses.get_pe_settings().in_enc_policy == pe_settings::disabled)
|
||||
throw protocol_error("encrypted incoming connections disabled");
|
||||
{
|
||||
disconnect("encrypted incoming connections disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't attempt to perform an encrypted handshake
|
||||
// within an encrypted connection
|
||||
|
@ -2158,7 +2246,8 @@ namespace libtorrent
|
|||
|
||||
assert ((!is_local() && m_encrypted) || is_local());
|
||||
#endif // #ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
throw protocol_error("incorrect protocol identifier");
|
||||
disconnect("incorrect protocol identifier");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
|
@ -2167,7 +2256,10 @@ namespace libtorrent
|
|||
if (!is_local() &&
|
||||
(m_ses.get_pe_settings().in_enc_policy == pe_settings::forced) &&
|
||||
!m_encrypted)
|
||||
throw protocol_error("non encrypted incoming connections disabled");
|
||||
{
|
||||
disconnect("non encrypted incoming connections disabled");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
|
@ -2226,6 +2318,7 @@ namespace libtorrent
|
|||
, (char*)info_hash.begin());
|
||||
|
||||
attach_to_torrent(info_hash);
|
||||
if (is_disconnecting()) return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2236,7 +2329,8 @@ namespace libtorrent
|
|||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
(*m_logger) << " received invalid info_hash\n";
|
||||
#endif
|
||||
throw protocol_error("invalid info-hash in handshake");
|
||||
disconnect("invalid info-hash in handshake");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
|
@ -2253,6 +2347,8 @@ namespace libtorrent
|
|||
// if (t->valid_metadata())
|
||||
// write_bitfield(t->pieces());
|
||||
|
||||
if (is_disconnecting()) return;
|
||||
|
||||
TORRENT_ASSERT(t->get_policy().has_connection(this));
|
||||
|
||||
m_state = read_peer_id;
|
||||
|
@ -2310,18 +2406,20 @@ namespace libtorrent
|
|||
// if not, we should close the outgoing one.
|
||||
if (pid < m_ses.get_peer_id() && is_local())
|
||||
{
|
||||
i->second.connection->disconnect();
|
||||
i->second.connection->disconnect("duplicate peer-id, connection closed");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw protocol_error("duplicate peer-id, connection closed");
|
||||
disconnect("duplicate peer-id, connection closed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pid == m_ses.get_peer_id())
|
||||
{
|
||||
throw protocol_error("closing connection to ourself");
|
||||
disconnect("closing connection to ourself");
|
||||
return;
|
||||
}
|
||||
|
||||
m_client_version = identify_client(pid);
|
||||
|
@ -2335,7 +2433,10 @@ namespace libtorrent
|
|||
// disconnect if the peer has the same peer-id as ourself
|
||||
// since it most likely is ourself then
|
||||
if (pid == m_ses.get_peer_id())
|
||||
throw std::runtime_error("closing connection to ourself");
|
||||
{
|
||||
disconnect("closing connection to ourself");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
for (extension_list_t::iterator i = m_extensions.begin()
|
||||
|
@ -2405,9 +2506,10 @@ namespace libtorrent
|
|||
if (packet_size > 1024*1024 || packet_size < 0)
|
||||
{
|
||||
// packet too large
|
||||
throw std::runtime_error("packet > 1 MB ("
|
||||
+ boost::lexical_cast<std::string>(
|
||||
(unsigned int)packet_size) + " bytes)");
|
||||
std::stringstream msg;
|
||||
msg << "packet > 1 MB (" << (unsigned int)packet_size << " bytes)";
|
||||
disconnect(msg.str().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (packet_size == 0)
|
||||
|
|
|
@ -208,15 +208,26 @@ namespace libtorrent
|
|||
#endif
|
||||
{
|
||||
tcp::socket::non_blocking_io ioc(true);
|
||||
m_socket->io_control(ioc);
|
||||
asio::error_code ec;
|
||||
m_socket->io_control(ioc, ec);
|
||||
if (ec)
|
||||
{
|
||||
disconnect(ec.message().c_str());
|
||||
return;
|
||||
}
|
||||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
||||
std::fill(m_country, m_country + 2, 0);
|
||||
#endif
|
||||
m_remote = m_socket->remote_endpoint();
|
||||
m_remote = m_socket->remote_endpoint(ec);
|
||||
if (ec)
|
||||
{
|
||||
disconnect(ec.message().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
TORRENT_ASSERT(m_socket->remote_endpoint() == remote());
|
||||
m_logger = m_ses.create_log(remote().address().to_string() + "_"
|
||||
TORRENT_ASSERT(m_socket->remote_endpoint() == remote() || ec);
|
||||
m_logger = m_ses.create_log(remote().address().to_string(ec) + "_"
|
||||
+ boost::lexical_cast<std::string>(remote().port()), m_ses.listen_port());
|
||||
(*m_logger) << "*** INCOMING CONNECTION\n";
|
||||
#endif
|
||||
|
@ -354,7 +365,8 @@ namespace libtorrent
|
|||
// if we're a seed too, disconnect
|
||||
if (t->is_finished())
|
||||
{
|
||||
throw std::runtime_error("seed to seed connection redundant, disconnecting");
|
||||
disconnect("seed to seed connection redundant");
|
||||
return;
|
||||
}
|
||||
m_num_pieces = num_pieces;
|
||||
t->peer_has_all();
|
||||
|
@ -396,7 +408,11 @@ namespace libtorrent
|
|||
<< " *** CONNECTION CLOSED\n";
|
||||
}
|
||||
#endif
|
||||
TORRENT_ASSERT(!m_ses.has_peer(this));
|
||||
#ifndef NDEBUG
|
||||
for (aux::session_impl::torrent_map::const_iterator i = m_ses.m_torrents.begin()
|
||||
, end(m_ses.m_torrents.end()); i != end; ++i)
|
||||
TORRENT_ASSERT(!i->second->has_peer(this));
|
||||
if (m_peer_info)
|
||||
TORRENT_ASSERT(m_peer_info->connection == 0);
|
||||
|
||||
|
@ -486,7 +502,11 @@ namespace libtorrent
|
|||
for (extension_list_t::iterator i = m_extensions.begin()
|
||||
, end(m_extensions.end()); i != end; ++i)
|
||||
{
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
(*i)->on_piece_pass(index);
|
||||
#else
|
||||
try { (*i)->on_piece_pass(index); } catch (std::exception&) {}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -499,7 +519,11 @@ namespace libtorrent
|
|||
for (extension_list_t::iterator i = m_extensions.begin()
|
||||
, end(m_extensions.end()); i != end; ++i)
|
||||
{
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
(*i)->on_piece_failed(index);
|
||||
#else
|
||||
try { (*i)->on_piece_failed(index); } catch (std::exception&) {}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -587,7 +611,8 @@ namespace libtorrent
|
|||
(*m_logger) << " " << i->second->torrent_file().info_hash() << "\n";
|
||||
}
|
||||
#endif
|
||||
throw std::runtime_error("got info-hash that is not in our session");
|
||||
disconnect("got invalid info-hash");
|
||||
return;
|
||||
}
|
||||
|
||||
if (t->is_paused())
|
||||
|
@ -597,7 +622,8 @@ namespace libtorrent
|
|||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
(*m_logger) << " rejected connection to paused torrent\n";
|
||||
#endif
|
||||
throw std::runtime_error("connection rejected by paused torrent");
|
||||
disconnect("connection rejected bacause torrent is paused");
|
||||
return;
|
||||
}
|
||||
|
||||
TORRENT_ASSERT(m_torrent.expired());
|
||||
|
@ -929,8 +955,10 @@ namespace libtorrent
|
|||
|
||||
// if we got an invalid message, abort
|
||||
if (index >= int(m_have_piece.size()) || index < 0)
|
||||
throw protocol_error("got 'have'-message with higher index "
|
||||
"than the number of pieces");
|
||||
{
|
||||
disconnect("got 'have'-message with higher index than the number of pieces");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_have_piece[index])
|
||||
{
|
||||
|
@ -974,7 +1002,8 @@ namespace libtorrent
|
|||
m_peer_info->seed = true;
|
||||
if (t->is_finished())
|
||||
{
|
||||
throw protocol_error("seed to seed connection redundant, disconnecting");
|
||||
disconnect("seed to seed connection redundant");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1014,11 +1043,14 @@ namespace libtorrent
|
|||
// verify the bitfield size
|
||||
if (t->valid_metadata()
|
||||
&& (bitfield.size() / 8) != (m_have_piece.size() / 8))
|
||||
throw protocol_error("got bitfield with invalid size: "
|
||||
+ boost::lexical_cast<std::string>(bitfield.size() / 8)
|
||||
+ "bytes. expected: "
|
||||
+ boost::lexical_cast<std::string>(m_have_piece.size() / 8)
|
||||
+ "bytes");
|
||||
{
|
||||
std::stringstream msg;
|
||||
msg << "got bitfield with invalid size: " << (bitfield.size() / 8)
|
||||
<< "bytes. expected: " << (m_have_piece.size() / 8)
|
||||
<< " bytes";
|
||||
disconnect(msg.str().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// if we don't have metadata yet
|
||||
// just remember the bitmask
|
||||
|
@ -1045,7 +1077,8 @@ namespace libtorrent
|
|||
// if we're a seed too, disconnect
|
||||
if (t->is_finished())
|
||||
{
|
||||
throw protocol_error("seed to seed connection redundant, disconnecting");
|
||||
disconnect("seed to seed connection redundant, disconnecting");
|
||||
return;
|
||||
}
|
||||
|
||||
std::fill(m_have_piece.begin(), m_have_piece.end(), true);
|
||||
|
@ -1325,7 +1358,8 @@ namespace libtorrent
|
|||
"start: " << p.start << " | "
|
||||
"length: " << p.length << " ]\n";
|
||||
#endif
|
||||
throw protocol_error("got invalid piece packet");
|
||||
disconnect("got invalid piece packet");
|
||||
return;
|
||||
}
|
||||
|
||||
// if we're already seeding, don't bother,
|
||||
|
@ -1433,8 +1467,8 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(m_outstanding_writing_bytes >= 0);
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_ses.m_logger) << time_now_string() << " *** DISK_WRITE_COMPLETE [ p: "
|
||||
<< p.piece << " o: " << p.start << " ]\n";
|
||||
// (*m_ses.m_logger) << time_now_string() << " *** DISK_WRITE_COMPLETE [ p: "
|
||||
// << p.piece << " o: " << p.start << " ]\n";
|
||||
#endif
|
||||
// in case the outstanding bytes just dropped down
|
||||
// to allow to receive more data
|
||||
|
@ -1448,7 +1482,7 @@ namespace libtorrent
|
|||
|
||||
if (!t)
|
||||
{
|
||||
m_ses.connection_failed(self(), remote(), j.str.c_str());
|
||||
disconnect(j.str.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1474,11 +1508,6 @@ namespace libtorrent
|
|||
block_finished.block_index, block_finished.piece_index, "block finished"));
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
try
|
||||
{
|
||||
#endif
|
||||
|
||||
// did we just finish the piece?
|
||||
if (picker.is_piece_finished(p.piece))
|
||||
{
|
||||
|
@ -1489,15 +1518,6 @@ namespace libtorrent
|
|||
, p.piece, _1));
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
std::cerr << e.what() << std::endl;
|
||||
TORRENT_ASSERT(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!t->is_seed() && !m_torrent.expired())
|
||||
{
|
||||
// this is a free function defined in policy.cpp
|
||||
|
@ -1614,7 +1634,10 @@ namespace libtorrent
|
|||
|
||||
// if we're a seed too, disconnect
|
||||
if (t->is_finished())
|
||||
throw protocol_error("seed to seed connection redundant, disconnecting");
|
||||
{
|
||||
disconnect("seed to seed connection redundant, disconnecting");
|
||||
return;
|
||||
}
|
||||
|
||||
TORRENT_ASSERT(!m_have_piece.empty());
|
||||
std::fill(m_have_piece.begin(), m_have_piece.end(), true);
|
||||
|
@ -2004,7 +2027,8 @@ namespace libtorrent
|
|||
|
||||
void close_socket_ignore_error(boost::shared_ptr<socket_type> s)
|
||||
{
|
||||
try { s->close(); } catch (std::exception& e) {}
|
||||
asio::error_code ec;
|
||||
s->close(ec);
|
||||
}
|
||||
|
||||
void peer_connection::timed_out()
|
||||
|
@ -2013,14 +2037,17 @@ namespace libtorrent
|
|||
(*m_ses.m_logger) << time_now_string() << " CONNECTION TIMED OUT: " << m_remote.address().to_string()
|
||||
<< "\n";
|
||||
#endif
|
||||
m_ses.connection_failed(self(), m_remote, "timed out");
|
||||
disconnect("timed out");
|
||||
}
|
||||
|
||||
void peer_connection::disconnect()
|
||||
void peer_connection::disconnect(char const* message)
|
||||
{
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
|
||||
boost::intrusive_ptr<peer_connection> me(this);
|
||||
#if defined(TORRENT_VERBOSE_LOGGING)
|
||||
(*m_logger) << "*** CONNECTION FAILED " << message << "\n";
|
||||
#endif
|
||||
// boost::intrusive_ptr<peer_connection> me(this);
|
||||
|
||||
INVARIANT_CHECK;
|
||||
|
||||
|
@ -2033,6 +2060,15 @@ namespace libtorrent
|
|||
|
||||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||
|
||||
if (message && m_ses.m_alerts.should_post(alert::debug))
|
||||
{
|
||||
m_ses.m_alerts.post_alert(
|
||||
peer_error_alert(
|
||||
remote()
|
||||
, pid()
|
||||
, message));
|
||||
}
|
||||
|
||||
if (t)
|
||||
{
|
||||
if (t->has_picker())
|
||||
|
@ -2055,7 +2091,7 @@ namespace libtorrent
|
|||
m_torrent.reset();
|
||||
}
|
||||
|
||||
m_ses.close_connection(me);
|
||||
m_ses.close_connection(this, message);
|
||||
}
|
||||
|
||||
void peer_connection::set_upload_limit(int limit)
|
||||
|
@ -2207,7 +2243,7 @@ namespace libtorrent
|
|||
if (m_packet_size >= m_recv_pos) m_recv_buffer.resize(m_packet_size);
|
||||
}
|
||||
|
||||
void peer_connection::second_tick(float tick_interval) throw()
|
||||
void peer_connection::second_tick(float tick_interval)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
|
@ -2365,7 +2401,7 @@ namespace libtorrent
|
|||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
(*m_logger) << "**ERROR**: " << e.what() << "\n";
|
||||
#endif
|
||||
m_ses.connection_failed(self(), remote(), e.what());
|
||||
disconnect(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2415,7 +2451,7 @@ namespace libtorrent
|
|||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||
if (!t)
|
||||
{
|
||||
m_ses.connection_failed(self(), remote(), j.str.c_str());
|
||||
disconnect(j.str.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2714,7 +2750,9 @@ namespace libtorrent
|
|||
#endif
|
||||
set_failed();
|
||||
on_receive(error, bytes_transferred);
|
||||
throw std::runtime_error(error.message());
|
||||
set_failed();
|
||||
disconnect(error.message().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
do
|
||||
|
@ -2757,7 +2795,10 @@ namespace libtorrent
|
|||
bytes_transferred = m_socket->read_some(asio::buffer(&m_recv_buffer[m_recv_pos]
|
||||
, max_receive), ec);
|
||||
if (ec && ec != asio::error::would_block)
|
||||
throw asio::system_error(ec);
|
||||
{
|
||||
disconnect(ec.message().c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (bytes_transferred > 0);
|
||||
|
||||
|
@ -2770,7 +2811,7 @@ namespace libtorrent
|
|||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||
if (!t)
|
||||
{
|
||||
m_ses.connection_failed(self(), remote(), e.what());
|
||||
disconnect(e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2785,14 +2826,14 @@ namespace libtorrent
|
|||
catch (std::exception& e)
|
||||
{
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
m_ses.connection_failed(self(), remote(), e.what());
|
||||
disconnect(e.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// all exceptions should derive from std::exception
|
||||
TORRENT_ASSERT(false);
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
m_ses.connection_failed(self(), remote(), "connection failed for unknown reason");
|
||||
disconnect("connection failed for unknown reason");
|
||||
}
|
||||
|
||||
bool peer_connection::can_write() const
|
||||
|
@ -2828,8 +2869,9 @@ namespace libtorrent
|
|||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
asio::error_code ec;
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_ses.m_logger) << time_now_string() << " CONNECTING: " << m_remote.address().to_string()
|
||||
(*m_ses.m_logger) << time_now_string() << " CONNECTING: " << m_remote.address().to_string(ec)
|
||||
<< ":" << m_remote.port() << "\n";
|
||||
#endif
|
||||
|
||||
|
@ -2839,13 +2881,28 @@ namespace libtorrent
|
|||
|
||||
m_queued = false;
|
||||
TORRENT_ASSERT(m_connecting);
|
||||
m_socket->open(t->get_interface().protocol());
|
||||
m_socket->open(t->get_interface().protocol(), ec);
|
||||
if (ec)
|
||||
{
|
||||
disconnect(ec.message().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// set the socket to non-blocking, so that we can
|
||||
// read the entire buffer on each read event we get
|
||||
tcp::socket::non_blocking_io ioc(true);
|
||||
m_socket->io_control(ioc);
|
||||
m_socket->bind(t->get_interface());
|
||||
m_socket->io_control(ioc, ec);
|
||||
if (ec)
|
||||
{
|
||||
disconnect(ec.message().c_str());
|
||||
return;
|
||||
}
|
||||
m_socket->bind(t->get_interface(), ec);
|
||||
if (ec)
|
||||
{
|
||||
disconnect(ec.message().c_str());
|
||||
return;
|
||||
}
|
||||
m_socket->async_connect(m_remote
|
||||
, bind(&peer_connection::on_connection_complete, self(), _1));
|
||||
|
||||
|
@ -2874,7 +2931,7 @@ namespace libtorrent
|
|||
<< ": " << e.message() << "\n";
|
||||
#endif
|
||||
set_failed();
|
||||
m_ses.connection_failed(self(), m_remote, e.message().c_str());
|
||||
disconnect(e.message().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2894,14 +2951,14 @@ namespace libtorrent
|
|||
catch (std::exception& ex)
|
||||
{
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
m_ses.connection_failed(self(), remote(), ex.what());
|
||||
disconnect(ex.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// all exceptions should derive from std::exception
|
||||
TORRENT_ASSERT(false);
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
m_ses.connection_failed(self(), remote(), "connection failed for unkown reason");
|
||||
disconnect("connection failed for unkown reason");
|
||||
}
|
||||
|
||||
// --------------------------
|
||||
|
@ -2935,7 +2992,8 @@ namespace libtorrent
|
|||
(*m_logger) << "**ERROR**: " << error.message() << " [in peer_connection::on_send_data]\n";
|
||||
#endif
|
||||
set_failed();
|
||||
throw std::runtime_error(error.message());
|
||||
disconnect(error.message().c_str());
|
||||
return;
|
||||
}
|
||||
if (m_disconnecting) return;
|
||||
|
||||
|
@ -2952,17 +3010,16 @@ namespace libtorrent
|
|||
catch (std::exception& e)
|
||||
{
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
m_ses.connection_failed(self(), remote(), e.what());
|
||||
disconnect(e.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// all exceptions should derive from std::exception
|
||||
TORRENT_ASSERT(false);
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
m_ses.connection_failed(self(), remote(), "connection failed for unknown reason");
|
||||
disconnect("connection failed for unknown reason");
|
||||
}
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
void peer_connection::check_invariant() const
|
||||
{
|
||||
|
|
|
@ -361,7 +361,7 @@ namespace libtorrent
|
|||
|
||||
if (i->second.connection)
|
||||
{
|
||||
i->second.connection->disconnect();
|
||||
i->second.connection->disconnect("peer banned by IP filter");
|
||||
if (ses.m_alerts.should_post(alert::info))
|
||||
{
|
||||
ses.m_alerts.post_alert(peer_blocked_alert(i->second.ip.address()
|
||||
|
@ -914,7 +914,7 @@ namespace libtorrent
|
|||
return ret;
|
||||
}
|
||||
|
||||
void policy::new_connection(peer_connection& c)
|
||||
bool policy::new_connection(peer_connection& c)
|
||||
{
|
||||
TORRENT_ASSERT(!c.is_local());
|
||||
|
||||
|
@ -926,13 +926,15 @@ namespace libtorrent
|
|||
|
||||
// TODO: only allow _one_ connection to use this
|
||||
// override at a time
|
||||
TORRENT_ASSERT(c.remote() == c.get_socket()->remote_endpoint());
|
||||
asio::error_code ec;
|
||||
TORRENT_ASSERT(c.remote() == c.get_socket()->remote_endpoint(ec) || ec);
|
||||
|
||||
if (m_torrent->num_peers() >= m_torrent->max_connections()
|
||||
&& m_torrent->session().num_connections() >= m_torrent->session().max_connections()
|
||||
&& c.remote().address() != m_torrent->current_tracker().address())
|
||||
{
|
||||
throw protocol_error("too many connections, refusing incoming connection"); // cause a disconnect
|
||||
c.disconnect("too many connections, refusing incoming connection");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
|
@ -960,7 +962,10 @@ namespace libtorrent
|
|||
if (i != m_peers.end())
|
||||
{
|
||||
if (i->second.banned)
|
||||
throw protocol_error("ip address banned, closing");
|
||||
{
|
||||
c.disconnect("ip address banned, closing");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (i->second.connection != 0)
|
||||
{
|
||||
|
@ -969,7 +974,8 @@ namespace libtorrent
|
|||
// or the current one is already connected
|
||||
if (!i->second.connection->is_connecting() || c.is_local())
|
||||
{
|
||||
throw protocol_error("duplicate connection, closing");
|
||||
c.disconnect("duplicate connection, closing");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -978,7 +984,8 @@ namespace libtorrent
|
|||
" is connecting and this connection is incoming. closing existing "
|
||||
"connection in favour of this one");
|
||||
#endif
|
||||
i->second.connection->disconnect();
|
||||
i->second.connection->disconnect("incoming duplicate connection "
|
||||
"with higher priority, closing");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -986,7 +993,8 @@ namespace libtorrent
|
|||
{
|
||||
// we don't have any info about this peer.
|
||||
// add a new entry
|
||||
TORRENT_ASSERT(c.remote() == c.get_socket()->remote_endpoint());
|
||||
asio::error_code ec;
|
||||
TORRENT_ASSERT(c.remote() == c.get_socket()->remote_endpoint(ec) || ec);
|
||||
|
||||
peer p(c.remote(), peer::not_connectable, 0);
|
||||
i = m_peers.insert(std::make_pair(c.remote().address(), p));
|
||||
|
@ -1002,12 +1010,15 @@ namespace libtorrent
|
|||
if (!c.fast_reconnect())
|
||||
i->second.connected = time_now();
|
||||
// m_last_optimistic_disconnect = time_now();
|
||||
return true;
|
||||
}
|
||||
|
||||
void policy::update_peer_port(int port, policy::peer* p, int src)
|
||||
bool policy::update_peer_port(int port, policy::peer* p, int src)
|
||||
{
|
||||
TORRENT_ASSERT(p != 0);
|
||||
if (p->ip.port() == port) return;
|
||||
TORRENT_ASSERT(p->connection);
|
||||
|
||||
if (p->ip.port() == port) return true;
|
||||
|
||||
if (m_torrent->settings().allow_multiple_connections_per_ip)
|
||||
{
|
||||
|
@ -1020,7 +1031,8 @@ namespace libtorrent
|
|||
policy::peer& pp = i->second;
|
||||
if (pp.connection)
|
||||
{
|
||||
throw protocol_error("duplicate connection");
|
||||
p->connection->disconnect("duplicate connection");
|
||||
return false;
|
||||
}
|
||||
if (m_torrent->has_picker())
|
||||
m_torrent->picker().clear_peer(&i->second);
|
||||
|
@ -1033,6 +1045,7 @@ namespace libtorrent
|
|||
}
|
||||
p->ip.port(port);
|
||||
p->source |= src;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool policy::has_peer(policy::peer const* p) const
|
||||
|
@ -1362,7 +1375,7 @@ namespace libtorrent
|
|||
(*p->second.connection->m_logger) << "*** CLOSING CONNECTION 'too many connections'\n";
|
||||
#endif
|
||||
|
||||
p->second.connection->disconnect();
|
||||
p->second.connection->disconnect("too many connections, closing");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -754,7 +754,7 @@ namespace detail
|
|||
#ifndef NDEBUG
|
||||
int conn = m_connections.size();
|
||||
#endif
|
||||
(*m_connections.begin())->disconnect();
|
||||
(*m_connections.begin())->disconnect("stopping torrent");
|
||||
TORRENT_ASSERT(conn == int(m_connections.size()) + 1);
|
||||
}
|
||||
|
||||
|
@ -895,7 +895,7 @@ namespace detail
|
|||
return s;
|
||||
}
|
||||
|
||||
void session_impl::open_listen_port() throw()
|
||||
void session_impl::open_listen_port()
|
||||
{
|
||||
// close the open listen sockets
|
||||
m_listen_sockets.clear();
|
||||
|
@ -1110,70 +1110,62 @@ namespace detail
|
|||
c->m_in_constructor = false;
|
||||
#endif
|
||||
|
||||
m_connections.insert(c);
|
||||
if (!c->is_disconnecting()) m_connections.insert(c);
|
||||
}
|
||||
catch (std::exception& exc)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
std::string err = exc.what();
|
||||
#endif
|
||||
};
|
||||
|
||||
void session_impl::connection_failed(boost::intrusive_ptr<peer_connection> const& peer
|
||||
, tcp::endpoint const& a, char const* message)
|
||||
#ifndef NDEBUG
|
||||
try
|
||||
#endif
|
||||
{
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
// too expensive
|
||||
// INVARIANT_CHECK;
|
||||
|
||||
connection_map::iterator p = m_connections.find(peer);
|
||||
|
||||
// the connection may have been disconnected in the receive or send phase
|
||||
if (p == m_connections.end()) return;
|
||||
if (m_alerts.should_post(alert::debug))
|
||||
{
|
||||
m_alerts.post_alert(
|
||||
peer_error_alert(
|
||||
a
|
||||
, (*p)->pid()
|
||||
, message));
|
||||
}
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING)
|
||||
(*(*p)->m_logger) << "*** CONNECTION FAILED " << message << "\n";
|
||||
#endif
|
||||
(*p)->set_failed();
|
||||
(*p)->disconnect();
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
catch (...)
|
||||
{
|
||||
TORRENT_ASSERT(false);
|
||||
};
|
||||
#endif
|
||||
|
||||
void session_impl::close_connection(boost::intrusive_ptr<peer_connection> const& p)
|
||||
/*
|
||||
namespace
|
||||
{
|
||||
struct compare_peer_ptr
|
||||
{
|
||||
bool operator()(peer_connection const* lhs
|
||||
, intrusive_ptr<peer_connection const> const& rhs)
|
||||
{
|
||||
return lhs < rhs.get();
|
||||
}
|
||||
|
||||
bool operator()(intrusive_ptr<peer_connection const> const& lhs
|
||||
, peer_connection const* rhs)
|
||||
{
|
||||
return lhs.get() < rhs;
|
||||
}
|
||||
};
|
||||
}
|
||||
*/
|
||||
void session_impl::close_connection(peer_connection const* p
|
||||
, char const* message)
|
||||
{
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
// too expensive
|
||||
// INVARIANT_CHECK;
|
||||
|
||||
#ifndef NDEBUG
|
||||
// for (aux::session_impl::torrent_map::const_iterator i = m_torrents.begin()
|
||||
// , end(m_torrents.end()); i != end; ++i)
|
||||
// TORRENT_ASSERT(!i->second->has_peer((peer_connection*)p));
|
||||
#endif
|
||||
|
||||
#if defined(TORRENT_LOGGING)
|
||||
(*m_logger) << time_now_string() << " CLOSING CONNECTION " << p->remote() << "\n";
|
||||
(*m_logger) << time_now_string() << " CLOSING CONNECTION "
|
||||
<< p->remote() << " : " << message << "\n";
|
||||
#endif
|
||||
|
||||
TORRENT_ASSERT(p->is_disconnecting());
|
||||
connection_map::iterator i = m_connections.find(p);
|
||||
if (i != m_connections.end())
|
||||
{
|
||||
if (!(*i)->is_choked()) --m_num_unchoked;
|
||||
m_connections.erase(i);
|
||||
}
|
||||
|
||||
if (!p->is_choked()) --m_num_unchoked;
|
||||
// connection_map::iterator i = std::lower_bound(m_connections.begin(), m_connections.end()
|
||||
// , p, bind(&boost::intrusive_ptr<peer_connection>::get, _1) < p);
|
||||
// if (i->get() != p) i == m_connections.end();
|
||||
connection_map::iterator i = std::find_if(m_connections.begin(), m_connections.end()
|
||||
, bind(&boost::intrusive_ptr<peer_connection>::get, _1) == p);
|
||||
if (i != m_connections.end()) m_connections.erase(i);
|
||||
}
|
||||
|
||||
void session_impl::set_peer_id(peer_id const& id)
|
||||
|
@ -1334,7 +1326,7 @@ namespace detail
|
|||
#endif
|
||||
|
||||
c.set_failed();
|
||||
c.disconnect();
|
||||
c.disconnect("timed out");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -205,7 +205,7 @@ namespace libtorrent { namespace
|
|||
<< " | ip: " << p->ip << " ]\n";
|
||||
#endif
|
||||
p->banned = true;
|
||||
if (p->connection) p->connection->disconnect();
|
||||
if (p->connection) p->connection->disconnect("banning peer for sending bad data");
|
||||
}
|
||||
// we already have this exact entry in the map
|
||||
// we don't have to insert it
|
||||
|
@ -267,7 +267,7 @@ namespace libtorrent { namespace
|
|||
<< " | ip: " << p->ip << " ]\n";
|
||||
#endif
|
||||
p->banned = true;
|
||||
if (p->connection) p->connection->disconnect();
|
||||
if (p->connection) p->connection->disconnect("banning peer for sending bad data");
|
||||
}
|
||||
|
||||
torrent& m_torrent;
|
||||
|
|
|
@ -1086,7 +1086,7 @@ namespace libtorrent
|
|||
<< " ] 'too many corrupt pieces'\n";
|
||||
#endif
|
||||
#endif
|
||||
p->connection->disconnect();
|
||||
p->connection->disconnect("too many corrupt pieces, banning peer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1828,10 +1828,7 @@ namespace libtorrent
|
|||
#endif
|
||||
|
||||
// TODO: post an error alert!
|
||||
// std::map<tcp::endpoint, peer_connection*>::iterator i = m_connections.find(a);
|
||||
// if (i != m_connections.end()) m_connections.erase(i);
|
||||
m_ses.connection_failed(c, a, e.what());
|
||||
c->disconnect();
|
||||
c->disconnect(e.what());
|
||||
}
|
||||
}
|
||||
catch (std::exception& exc)
|
||||
|
@ -2130,8 +2127,7 @@ namespace libtorrent
|
|||
std::set<peer_connection*>::iterator i
|
||||
= m_connections.find(boost::get_pointer(c));
|
||||
if (i != m_connections.end()) m_connections.erase(i);
|
||||
m_ses.connection_failed(c, a, e.what());
|
||||
c->disconnect();
|
||||
c->disconnect(e.what());
|
||||
return false;
|
||||
}
|
||||
peerinfo->connection = c.get();
|
||||
|
@ -2216,7 +2212,11 @@ namespace libtorrent
|
|||
#endif
|
||||
TORRENT_ASSERT(m_connections.find(p) == ci);
|
||||
TORRENT_ASSERT(*ci == p);
|
||||
m_policy.new_connection(**ci);
|
||||
if (!m_policy.new_connection(**ci))
|
||||
{
|
||||
m_connections.erase(ci);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
|
@ -2261,7 +2261,7 @@ namespace libtorrent
|
|||
#ifndef NDEBUG
|
||||
std::size_t size = m_connections.size();
|
||||
#endif
|
||||
p->disconnect();
|
||||
p->disconnect(m_abort?"stopping torrent":"pausing torrent");
|
||||
TORRENT_ASSERT(m_connections.size() <= size);
|
||||
}
|
||||
}
|
||||
|
@ -2371,7 +2371,7 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
std::for_each(seeds.begin(), seeds.end()
|
||||
, bind(&peer_connection::disconnect, _1));
|
||||
, bind(&peer_connection::disconnect, _1, "torrent finished, disconnecting seed"));
|
||||
|
||||
TORRENT_ASSERT(m_storage);
|
||||
// we need to keep the object alive during this operation
|
||||
|
@ -2586,7 +2586,7 @@ namespace libtorrent
|
|||
// the connection failed, close it
|
||||
torrent::peer_iterator j = i;
|
||||
++j;
|
||||
m_ses.connection_failed(*i, (*i)->remote(), e.what());
|
||||
(*i)->disconnect(e.what());
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
|
@ -2663,6 +2663,8 @@ namespace libtorrent
|
|||
std::map<piece_block, int> num_requests;
|
||||
for (const_peer_iterator i = begin(); i != end(); ++i)
|
||||
{
|
||||
// make sure this peer is not a dangling pointer
|
||||
TORRENT_ASSERT(m_ses.has_peer(*i));
|
||||
peer_connection const& p = *(*i);
|
||||
for (std::deque<piece_block>::const_iterator i = p.request_queue().begin()
|
||||
, end(p.request_queue().end()); i != end; ++i)
|
||||
|
@ -2997,7 +2999,7 @@ namespace libtorrent
|
|||
(*p->m_logger) << "**ERROR**: " << e.what() << "\n";
|
||||
#endif
|
||||
p->set_failed();
|
||||
p->disconnect();
|
||||
p->disconnect(e.what());
|
||||
}
|
||||
}
|
||||
accumulator += m_stat;
|
||||
|
|
|
@ -348,7 +348,10 @@ namespace libtorrent
|
|||
m_statistics.received_bytes(payload, protocol);
|
||||
|
||||
if (error)
|
||||
throw std::runtime_error("failed to parse HTTP response");
|
||||
{
|
||||
disconnect("failed to parse HTTP response");
|
||||
return;
|
||||
}
|
||||
|
||||
TORRENT_ASSERT(recv_buffer.left() == 0 || *recv_buffer.begin == 'H');
|
||||
|
||||
|
@ -377,7 +380,8 @@ namespace libtorrent
|
|||
m_ses.m_alerts.post_alert(url_seed_alert(t->get_handle(), url()
|
||||
, error_msg));
|
||||
}
|
||||
throw std::runtime_error(error_msg);
|
||||
disconnect(error_msg.c_str());
|
||||
return;
|
||||
}
|
||||
if (!m_parser.header_finished()) break;
|
||||
|
||||
|
@ -402,7 +406,8 @@ namespace libtorrent
|
|||
{
|
||||
// we should not try this server again.
|
||||
t->remove_url_seed(m_url);
|
||||
throw std::runtime_error("got HTTP redirection status without location header");
|
||||
disconnect("got HTTP redirection status without location header");
|
||||
return;
|
||||
}
|
||||
|
||||
bool single_file_request = false;
|
||||
|
@ -422,14 +427,20 @@ namespace libtorrent
|
|||
if (i == std::string::npos)
|
||||
{
|
||||
t->remove_url_seed(m_url);
|
||||
throw std::runtime_error("got invalid HTTP redirection location (\"" + location + "\") "
|
||||
"expected it to end with: " + path);
|
||||
std::stringstream msg;
|
||||
msg << "got invalid HTTP redirection location (\"" << location << "\") "
|
||||
"expected it to end with: " << path;
|
||||
disconnect(msg.str().c_str());
|
||||
return;
|
||||
}
|
||||
location.resize(i);
|
||||
}
|
||||
t->add_url_seed(location);
|
||||
t->remove_url_seed(m_url);
|
||||
throw std::runtime_error("redirecting to " + location);
|
||||
std::stringstream msg;
|
||||
msg << "redirecting to \"" << location << "\"";
|
||||
disconnect(msg.str().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
std::string const& server_version = m_parser.header("server");
|
||||
|
@ -462,7 +473,10 @@ namespace libtorrent
|
|||
{
|
||||
// we should not try this server again.
|
||||
t->remove_url_seed(m_url);
|
||||
throw std::runtime_error("invalid range in HTTP response: " + range_str.str());
|
||||
std::stringstream msg;
|
||||
msg << "invalid range in HTTP response: " << range_str;
|
||||
disconnect(msg.str().c_str());
|
||||
return;
|
||||
}
|
||||
// the http range is inclusive
|
||||
range_end++;
|
||||
|
@ -475,7 +489,8 @@ namespace libtorrent
|
|||
{
|
||||
// we should not try this server again.
|
||||
t->remove_url_seed(m_url);
|
||||
throw std::runtime_error("no content-length in HTTP response");
|
||||
disconnect("no content-length in HTTP response");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -485,7 +500,10 @@ namespace libtorrent
|
|||
torrent_info const& info = t->torrent_file();
|
||||
|
||||
if (m_requests.empty() || m_file_requests.empty())
|
||||
throw std::runtime_error("unexpected HTTP response");
|
||||
{
|
||||
disconnect("unexpected HTTP response");
|
||||
return;
|
||||
}
|
||||
|
||||
int file_index = m_file_requests.front();
|
||||
peer_request in_range = info.map_file(file_index, range_start
|
||||
|
@ -516,7 +534,8 @@ namespace libtorrent
|
|||
{
|
||||
// this means the end of the incoming request ends _before_ the
|
||||
// first expected byte (fs + m_piece.size())
|
||||
throw std::runtime_error("invalid range in HTTP response");
|
||||
disconnect("invalid range in HTTP response");
|
||||
return;
|
||||
}
|
||||
|
||||
// if the request is contained in the range (i.e. the entire request
|
||||
|
|
Loading…
Reference in New Issue