option to ignore bandwidth limits for local peers. fixed some asserts when allowing multiple connections per IP

This commit is contained in:
Arvid Norberg 2007-05-25 17:06:30 +00:00
parent c48bba388e
commit 685f79b82f
7 changed files with 91 additions and 23 deletions

View File

@ -272,6 +272,10 @@ namespace libtorrent
// if it was an incoming connection, it is remote // if it was an incoming connection, it is remote
bool is_local() const { return m_active; } bool is_local() const { return m_active; }
bool on_local_network() const;
bool ignore_bandwidth_limits() const
{ return m_ignore_bandwidth_limits; }
void set_failed() { m_failed = true; } void set_failed() { m_failed = true; }
bool failed() const { return m_failed; } bool failed() const { return m_failed; }
@ -540,6 +544,11 @@ namespace libtorrent
// this peer // this peer
bool m_failed; bool m_failed;
// 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.
bool m_ignore_bandwidth_limits;
// the pieces the other end have // the pieces the other end have
std::vector<bool> m_have_piece; std::vector<bool> m_have_piece;

View File

@ -98,6 +98,7 @@ namespace libtorrent
, max_failcount(3) , max_failcount(3)
, min_reconnect_time(60) , min_reconnect_time(60)
, peer_connect_timeout(10) , peer_connect_timeout(10)
, ignore_limits_on_local_network(true)
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
, use_dht_as_fallback(true) , use_dht_as_fallback(true)
#endif #endif
@ -202,6 +203,10 @@ namespace libtorrent
// connection is dropped. The time is specified in seconds. // connection is dropped. The time is specified in seconds.
int peer_connect_timeout; int peer_connect_timeout;
// if set to true, upload, download and unchoke limits
// are ignored for peers on the local network
bool ignore_limits_on_local_network;
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
// while this is true, the dht will note be used unless the // while this is true, the dht will note be used unless the
// tracker is online // tracker is online

View File

@ -71,6 +71,8 @@ namespace libtorrent
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
assert(!peer->ignore_bandwidth_limits());
// make sure this peer isn't already in line // make sure this peer isn't already in line
// waiting for bandwidth // waiting for bandwidth
#ifndef NDEBUG #ifndef NDEBUG

View File

@ -1215,7 +1215,11 @@ namespace libtorrent
throw protocol_error("duplicate peer-id, connection closed"); throw protocol_error("duplicate peer-id, connection closed");
} }
} }
}
if (pid == m_ses.get_peer_id())
{
throw protocol_error("closing connection to ourself");
} }
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT

View File

@ -105,6 +105,7 @@ namespace libtorrent
, m_interesting(false) , m_interesting(false)
, m_choked(true) , m_choked(true)
, m_failed(false) , m_failed(false)
, m_ignore_bandwidth_limits(false)
, m_num_pieces(0) , m_num_pieces(0)
, m_desired_queue_size(2) , m_desired_queue_size(2)
, m_free_upload(0) , m_free_upload(0)
@ -176,6 +177,7 @@ namespace libtorrent
, m_interesting(false) , m_interesting(false)
, m_choked(true) , m_choked(true)
, m_failed(false) , m_failed(false)
, m_ignore_bandwidth_limits(false)
, m_num_pieces(0) , m_num_pieces(0)
, m_desired_queue_size(2) , m_desired_queue_size(2)
, m_free_upload(0) , m_free_upload(0)
@ -1667,6 +1669,16 @@ namespace libtorrent
- m_statistics.total_payload_upload(); - m_statistics.total_payload_upload();
} }
// defined in upnp.cpp
bool is_local(address const& a);
bool peer_connection::on_local_network() const
{
if (libtorrent::is_local(m_remote.address())) return true;
return false;
}
void peer_connection::cut_receive_buffer(int size, int packet_size) void peer_connection::cut_receive_buffer(int size, int packet_size)
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
@ -1707,6 +1719,9 @@ namespace libtorrent
} }
#endif #endif
m_ignore_bandwidth_limits = m_ses.settings().ignore_limits_on_local_network
&& on_local_network();
m_statistics.second_tick(tick_interval); m_statistics.second_tick(tick_interval);
if (!t->valid_metadata()) return; if (!t->valid_metadata()) return;
@ -1949,12 +1964,13 @@ namespace libtorrent
if (m_writing) return; if (m_writing) return;
shared_ptr<torrent> t = m_torrent.lock(); shared_ptr<torrent> t = m_torrent.lock();
if (m_bandwidth_limit[upload_channel].quota_left() == 0 if (m_bandwidth_limit[upload_channel].quota_left() == 0
&& (!m_send_buffer[m_current_send_buffer].empty() && (!m_send_buffer[m_current_send_buffer].empty()
|| !m_send_buffer[(m_current_send_buffer + 1) & 1].empty()) || !m_send_buffer[(m_current_send_buffer + 1) & 1].empty())
&& !m_connecting && !m_connecting
&& t) && t
&& !m_ignore_bandwidth_limits)
{ {
// in this case, we have data to send, but no // in this case, we have data to send, but no
// bandwidth. So, we simply request bandwidth // bandwidth. So, we simply request bandwidth
@ -1990,13 +2006,17 @@ namespace libtorrent
// send the actual buffer // send the actual buffer
if (!m_send_buffer[sending_buffer].empty()) if (!m_send_buffer[sending_buffer].empty())
{ {
int amount_to_send int amount_to_send = (int)m_send_buffer[sending_buffer].size() - m_write_pos;
= std::min(m_bandwidth_limit[upload_channel].quota_left() int quota_left = m_bandwidth_limit[upload_channel].quota_left();
, (int)m_send_buffer[sending_buffer].size() - m_write_pos); if (!m_ignore_bandwidth_limits && amount_to_send > quota_left)
amount_to_send = quota_left;
assert(amount_to_send > 0); assert(amount_to_send > 0);
assert(m_write_pos < (int)m_send_buffer[sending_buffer].size()); assert(m_write_pos < (int)m_send_buffer[sending_buffer].size());
#ifdef TORRENT_VERBOSE_LOGGING
(*m_logger) << "async_write " << amount_to_send << " bytes\n";
#endif
m_socket->async_write_some(asio::buffer( m_socket->async_write_some(asio::buffer(
&m_send_buffer[sending_buffer][m_write_pos], amount_to_send) &m_send_buffer[sending_buffer][m_write_pos], amount_to_send)
, bind(&peer_connection::on_send_data, self(), _1, _2)); , bind(&peer_connection::on_send_data, self(), _1, _2));
@ -2017,7 +2037,8 @@ namespace libtorrent
if (m_bandwidth_limit[download_channel].quota_left() == 0 if (m_bandwidth_limit[download_channel].quota_left() == 0
&& !m_connecting && !m_connecting
&& t) && t
&& !m_ignore_bandwidth_limits)
{ {
if (m_bandwidth_limit[download_channel].max_assignable() > 0) if (m_bandwidth_limit[download_channel].max_assignable() > 0)
{ {
@ -2033,9 +2054,11 @@ namespace libtorrent
if (!can_read()) return; if (!can_read()) return;
assert(m_packet_size > 0); assert(m_packet_size > 0);
int max_receive = std::min( int max_receive = m_packet_size - m_recv_pos;
m_bandwidth_limit[download_channel].quota_left() int quota_left = m_bandwidth_limit[download_channel].quota_left();
, m_packet_size - m_recv_pos); if (!m_ignore_bandwidth_limits && max_receive > quota_left)
max_receive = quota_left;
assert(max_receive > 0); assert(max_receive > 0);
assert(m_recv_pos >= 0); assert(m_recv_pos >= 0);
@ -2043,6 +2066,9 @@ namespace libtorrent
assert(max_receive > 0); assert(max_receive > 0);
assert(can_read()); assert(can_read());
#ifdef TORRENT_VERBOSE_LOGGING
(*m_logger) << "async_read " << max_receive << " bytes\n";
#endif
m_socket->async_read_some(asio::buffer(&m_recv_buffer[m_recv_pos] m_socket->async_read_some(asio::buffer(&m_recv_buffer[m_recv_pos]
, max_receive), bind(&peer_connection::on_receive_data, self(), _1, _2)); , max_receive), bind(&peer_connection::on_receive_data, self(), _1, _2));
m_reading = true; m_reading = true;
@ -2105,6 +2131,10 @@ namespace libtorrent
assert(m_reading); assert(m_reading);
m_reading = false; m_reading = false;
#ifdef TORRENT_VERBOSE_LOGGING
(*m_logger) << "read " << bytes_transferred << " bytes\n";
#endif
if (error) if (error)
{ {
#ifdef TORRENT_VERBOSE_LOGGING #ifdef TORRENT_VERBOSE_LOGGING
@ -2117,7 +2147,8 @@ namespace libtorrent
do do
{ {
// correct the dl quota usage, if not all of the buffer was actually read // correct the dl quota usage, if not all of the buffer was actually read
m_bandwidth_limit[download_channel].use_quota(bytes_transferred); if (!m_ignore_bandwidth_limits)
m_bandwidth_limit[download_channel].use_quota(bytes_transferred);
if (m_disconnecting) return; if (m_disconnecting) return;
@ -2142,17 +2173,21 @@ namespace libtorrent
std::vector<char>(m_packet_size).swap(m_recv_buffer); std::vector<char>(m_packet_size).swap(m_recv_buffer);
} }
int max_receive = std::min( int max_receive = m_packet_size - m_recv_pos;
m_bandwidth_limit[download_channel].quota_left() int quota_left = m_bandwidth_limit[download_channel].quota_left();
, m_packet_size - m_recv_pos); if (!m_ignore_bandwidth_limits && max_receive > quota_left)
max_receive = quota_left;
if (max_receive == 0) break; if (max_receive == 0) break;
asio::error_code ec; asio::error_code ec;
bytes_transferred = m_socket->read_some(asio::buffer(&m_recv_buffer[m_recv_pos] bytes_transferred = m_socket->read_some(asio::buffer(&m_recv_buffer[m_recv_pos]
, max_receive), ec); , max_receive), ec);
if (ec && ec != asio::error::would_block) if (ec && ec != asio::error::would_block)
throw asio::system_error(ec); throw asio::system_error(ec);
#ifdef TORRENT_VERBOSE_LOGGING
(*m_logger) << "read_some " << bytes_transferred << " bytes\n";
#endif
} }
while (bytes_transferred > 0); while (bytes_transferred > 0);
@ -2198,7 +2233,8 @@ namespace libtorrent
// we want to send data // we want to send data
return (!m_send_buffer[m_current_send_buffer].empty() return (!m_send_buffer[m_current_send_buffer].empty()
|| !m_send_buffer[(m_current_send_buffer + 1) & 1].empty()) || !m_send_buffer[(m_current_send_buffer + 1) & 1].empty())
&& m_bandwidth_limit[upload_channel].quota_left() > 0 && (m_bandwidth_limit[upload_channel].quota_left() > 0
|| m_ignore_bandwidth_limits)
&& !m_connecting; && !m_connecting;
} }
@ -2206,7 +2242,8 @@ namespace libtorrent
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
return m_bandwidth_limit[download_channel].quota_left() > 0 return (m_bandwidth_limit[download_channel].quota_left() > 0
|| m_ignore_bandwidth_limits)
&& !m_connecting; && !m_connecting;
} }
@ -2215,7 +2252,8 @@ namespace libtorrent
INVARIANT_CHECK; INVARIANT_CHECK;
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
(*m_ses.m_logger) << "CONNECTING: " << m_remote.address().to_string() << "\n"; (*m_ses.m_logger) << "CONNECTING: " << m_remote.address().to_string()
<< ":" << m_remote.port() << "\n";
#endif #endif
m_connection_ticket = ticket; m_connection_ticket = ticket;
@ -2303,7 +2341,13 @@ namespace libtorrent
assert(m_writing); assert(m_writing);
m_writing = false; m_writing = false;
m_bandwidth_limit[upload_channel].use_quota(bytes_transferred); if (!m_ignore_bandwidth_limits)
m_bandwidth_limit[upload_channel].use_quota(bytes_transferred);
#ifdef TORRENT_VERBOSE_LOGGING
(*m_logger) << "wrote " << bytes_transferred << " bytes\n";
#endif
m_write_pos += bytes_transferred; m_write_pos += bytes_transferred;
if (error) if (error)
@ -2382,7 +2426,8 @@ namespace libtorrent
return; return;
} }
if (!m_in_constructor && t->connection_for(remote()) != this) if (!m_in_constructor && t->connection_for(remote()) != this
&& !m_ses.settings().allow_multiple_connections_per_ip)
{ {
assert(false); assert(false);
} }

View File

@ -1346,7 +1346,8 @@ namespace libtorrent
for (const_iterator i = m_peers.begin(); for (const_iterator i = m_peers.begin();
i != m_peers.end(); ++i) i != m_peers.end(); ++i)
{ {
assert(unique_test.find(i->ip.address()) == unique_test.end()); if (!m_torrent->settings().allow_multiple_connections_per_ip)
assert(unique_test.find(i->ip.address()) == unique_test.end());
unique_test.insert(i->ip.address()); unique_test.insert(i->ip.address());
++total_connections; ++total_connections;
if (!i->connection) continue; if (!i->connection) continue;
@ -1379,12 +1380,13 @@ namespace libtorrent
// When there's an outgoing connection, it will first // When there's an outgoing connection, it will first
// be added to the torrent and then to the policy. // be added to the torrent and then to the policy.
// that's why the two second cases are in there. // that's why the two second cases are in there.
/*
assert(connected_peers == num_torrent_peers assert(connected_peers == num_torrent_peers
|| (connected_peers == num_torrent_peers + 1 || (connected_peers == num_torrent_peers + 1
&& connected_peers > 0) && connected_peers > 0)
|| (connected_peers + 1 == num_torrent_peers || (connected_peers + 1 == num_torrent_peers
&& num_torrent_peers > 0)); && num_torrent_peers > 0));
*/
} }
#endif #endif

View File

@ -1706,7 +1706,8 @@ namespace libtorrent
peer_iterator i_ = m_connections.find(peerinfo->ip); peer_iterator i_ = m_connections.find(peerinfo->ip);
assert(i_ == m_connections.end() assert(i_ == m_connections.end()
|| i_->second->is_disconnecting() || i_->second->is_disconnecting()
|| dynamic_cast<bt_peer_connection*>(i_->second) == 0); || dynamic_cast<bt_peer_connection*>(i_->second) == 0
|| m_ses.settings().allow_multiple_connections_per_ip);
#endif #endif
assert(want_more_peers()); assert(want_more_peers());