option to ignore bandwidth limits for local peers. fixed some asserts when allowing multiple connections per IP
This commit is contained in:
parent
c48bba388e
commit
685f79b82f
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
Loading…
Reference in New Issue