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
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; }
bool failed() const { return m_failed; }
@ -540,6 +544,11 @@ namespace libtorrent
// this peer
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
std::vector<bool> m_have_piece;

View File

@ -98,6 +98,7 @@ namespace libtorrent
, max_failcount(3)
, min_reconnect_time(60)
, peer_connect_timeout(10)
, ignore_limits_on_local_network(true)
#ifndef TORRENT_DISABLE_DHT
, use_dht_as_fallback(true)
#endif
@ -202,6 +203,10 @@ namespace libtorrent
// connection is dropped. The time is specified in seconds.
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
// while this is true, the dht will note be used unless the
// tracker is online

View File

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

View File

@ -1215,7 +1215,11 @@ namespace libtorrent
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

View File

@ -105,6 +105,7 @@ namespace libtorrent
, m_interesting(false)
, m_choked(true)
, m_failed(false)
, m_ignore_bandwidth_limits(false)
, m_num_pieces(0)
, m_desired_queue_size(2)
, m_free_upload(0)
@ -176,6 +177,7 @@ namespace libtorrent
, m_interesting(false)
, m_choked(true)
, m_failed(false)
, m_ignore_bandwidth_limits(false)
, m_num_pieces(0)
, m_desired_queue_size(2)
, m_free_upload(0)
@ -1667,6 +1669,16 @@ namespace libtorrent
- 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)
{
INVARIANT_CHECK;
@ -1707,6 +1719,9 @@ namespace libtorrent
}
#endif
m_ignore_bandwidth_limits = m_ses.settings().ignore_limits_on_local_network
&& on_local_network();
m_statistics.second_tick(tick_interval);
if (!t->valid_metadata()) return;
@ -1949,12 +1964,13 @@ namespace libtorrent
if (m_writing) return;
shared_ptr<torrent> t = m_torrent.lock();
if (m_bandwidth_limit[upload_channel].quota_left() == 0
&& (!m_send_buffer[m_current_send_buffer].empty()
|| !m_send_buffer[(m_current_send_buffer + 1) & 1].empty())
&& !m_connecting
&& t)
&& t
&& !m_ignore_bandwidth_limits)
{
// in this case, we have data to send, but no
// bandwidth. So, we simply request bandwidth
@ -1990,13 +2006,17 @@ namespace libtorrent
// send the actual buffer
if (!m_send_buffer[sending_buffer].empty())
{
int amount_to_send
= std::min(m_bandwidth_limit[upload_channel].quota_left()
, (int)m_send_buffer[sending_buffer].size() - m_write_pos);
int amount_to_send = (int)m_send_buffer[sending_buffer].size() - m_write_pos;
int quota_left = m_bandwidth_limit[upload_channel].quota_left();
if (!m_ignore_bandwidth_limits && amount_to_send > quota_left)
amount_to_send = quota_left;
assert(amount_to_send > 0);
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_send_buffer[sending_buffer][m_write_pos], amount_to_send)
, bind(&peer_connection::on_send_data, self(), _1, _2));
@ -2017,7 +2037,8 @@ namespace libtorrent
if (m_bandwidth_limit[download_channel].quota_left() == 0
&& !m_connecting
&& t)
&& t
&& !m_ignore_bandwidth_limits)
{
if (m_bandwidth_limit[download_channel].max_assignable() > 0)
{
@ -2033,9 +2054,11 @@ namespace libtorrent
if (!can_read()) return;
assert(m_packet_size > 0);
int max_receive = std::min(
m_bandwidth_limit[download_channel].quota_left()
, m_packet_size - m_recv_pos);
int max_receive = m_packet_size - m_recv_pos;
int quota_left = m_bandwidth_limit[download_channel].quota_left();
if (!m_ignore_bandwidth_limits && max_receive > quota_left)
max_receive = quota_left;
assert(max_receive > 0);
assert(m_recv_pos >= 0);
@ -2043,6 +2066,9 @@ namespace libtorrent
assert(max_receive > 0);
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]
, max_receive), bind(&peer_connection::on_receive_data, self(), _1, _2));
m_reading = true;
@ -2105,6 +2131,10 @@ namespace libtorrent
assert(m_reading);
m_reading = false;
#ifdef TORRENT_VERBOSE_LOGGING
(*m_logger) << "read " << bytes_transferred << " bytes\n";
#endif
if (error)
{
#ifdef TORRENT_VERBOSE_LOGGING
@ -2117,7 +2147,8 @@ namespace libtorrent
do
{
// 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;
@ -2142,17 +2173,21 @@ namespace libtorrent
std::vector<char>(m_packet_size).swap(m_recv_buffer);
}
int max_receive = std::min(
m_bandwidth_limit[download_channel].quota_left()
, m_packet_size - m_recv_pos);
int max_receive = m_packet_size - m_recv_pos;
int quota_left = m_bandwidth_limit[download_channel].quota_left();
if (!m_ignore_bandwidth_limits && max_receive > quota_left)
max_receive = quota_left;
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]
, max_receive), ec);
if (ec && ec != asio::error::would_block)
throw asio::system_error(ec);
#ifdef TORRENT_VERBOSE_LOGGING
(*m_logger) << "read_some " << bytes_transferred << " bytes\n";
#endif
}
while (bytes_transferred > 0);
@ -2198,7 +2233,8 @@ namespace libtorrent
// we want to send data
return (!m_send_buffer[m_current_send_buffer].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;
}
@ -2206,7 +2242,8 @@ namespace libtorrent
{
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;
}
@ -2215,7 +2252,8 @@ namespace libtorrent
INVARIANT_CHECK;
#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
m_connection_ticket = ticket;
@ -2303,7 +2341,13 @@ namespace libtorrent
assert(m_writing);
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;
if (error)
@ -2382,7 +2426,8 @@ namespace libtorrent
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);
}

View File

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

View File

@ -1706,7 +1706,8 @@ namespace libtorrent
peer_iterator i_ = m_connections.find(peerinfo->ip);
assert(i_ == m_connections.end()
|| 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
assert(want_more_peers());