take an estimate of the IP ACK traffic into account when rate limiting (allows setting rate limits closer to the capacity)
This commit is contained in:
parent
d15573ecc2
commit
e09457e4ab
|
@ -76,6 +76,8 @@ struct history_entry
|
||||||
history_entry(intrusive_ptr<PeerConnection> p, weak_ptr<Torrent> t
|
history_entry(intrusive_ptr<PeerConnection> p, weak_ptr<Torrent> t
|
||||||
, int a, ptime exp)
|
, int a, ptime exp)
|
||||||
: expires_at(exp), amount(a), peer(p), tor(t) {}
|
: expires_at(exp), amount(a), peer(p), tor(t) {}
|
||||||
|
history_entry(int a, ptime exp)
|
||||||
|
: expires_at(exp), amount(a), peer(), tor() {}
|
||||||
ptime expires_at;
|
ptime expires_at;
|
||||||
int amount;
|
int amount;
|
||||||
intrusive_ptr<PeerConnection> peer;
|
intrusive_ptr<PeerConnection> peer;
|
||||||
|
@ -111,6 +113,7 @@ struct bandwidth_manager
|
||||||
: m_ios(ios)
|
: m_ios(ios)
|
||||||
, m_history_timer(m_ios)
|
, m_history_timer(m_ios)
|
||||||
, m_limit(bandwidth_limit::inf)
|
, m_limit(bandwidth_limit::inf)
|
||||||
|
, m_drain_quota(0)
|
||||||
, m_current_quota(0)
|
, m_current_quota(0)
|
||||||
, m_channel(channel)
|
, m_channel(channel)
|
||||||
, m_in_hand_out_bandwidth(false)
|
, m_in_hand_out_bandwidth(false)
|
||||||
|
@ -123,6 +126,14 @@ struct bandwidth_manager
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drain(int bytes)
|
||||||
|
{
|
||||||
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
|
TORRENT_ASSERT(bytes >= 0);
|
||||||
|
m_drain_quota += bytes;
|
||||||
|
if (m_drain_quota > m_limit * 5) m_drain_quota = m_limit * 5;
|
||||||
|
}
|
||||||
|
|
||||||
void throttle(int limit)
|
void throttle(int limit)
|
||||||
{
|
{
|
||||||
mutex_t::scoped_lock l(m_mutex);
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
|
@ -288,6 +299,7 @@ private:
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
intrusive_ptr<PeerConnection> c = e.peer;
|
intrusive_ptr<PeerConnection> c = e.peer;
|
||||||
|
if (!c) continue;
|
||||||
shared_ptr<Torrent> t = e.tor.lock();
|
shared_ptr<Torrent> t = e.tor.lock();
|
||||||
l.unlock();
|
l.unlock();
|
||||||
if (!c->is_disconnecting()) c->expire_bandwidth(m_channel, e.amount);
|
if (!c->is_disconnecting()) c->expire_bandwidth(m_channel, e.amount);
|
||||||
|
@ -329,6 +341,15 @@ private:
|
||||||
|
|
||||||
if (amount <= 0) return;
|
if (amount <= 0) return;
|
||||||
|
|
||||||
|
if (m_drain_quota > 0)
|
||||||
|
{
|
||||||
|
int drain_amount = (std::min)(m_drain_quota, amount);
|
||||||
|
m_drain_quota -= drain_amount;
|
||||||
|
amount -= drain_amount;
|
||||||
|
add_history_entry(history_entry<PeerConnection, Torrent>(
|
||||||
|
drain_amount, now + bw_window_size));
|
||||||
|
}
|
||||||
|
|
||||||
queue_t tmp;
|
queue_t tmp;
|
||||||
while (!m_queue.empty() && amount > 0)
|
while (!m_queue.empty() && amount > 0)
|
||||||
{
|
{
|
||||||
|
@ -433,6 +454,10 @@ private:
|
||||||
// the rate limit (bytes per second)
|
// the rate limit (bytes per second)
|
||||||
int m_limit;
|
int m_limit;
|
||||||
|
|
||||||
|
// bytes to drain without handing out to a peer
|
||||||
|
// used to deduct the IP overhead
|
||||||
|
int m_drain_quota;
|
||||||
|
|
||||||
// the sum of all recently handed out bandwidth blocks
|
// the sum of all recently handed out bandwidth blocks
|
||||||
int m_current_quota;
|
int m_current_quota;
|
||||||
|
|
||||||
|
|
|
@ -230,6 +230,8 @@ namespace libtorrent
|
||||||
const stat& statistics() const { return m_statistics; }
|
const stat& statistics() const { return m_statistics; }
|
||||||
void add_stat(size_type downloaded, size_type uploaded);
|
void add_stat(size_type downloaded, size_type uploaded);
|
||||||
|
|
||||||
|
void calc_ip_overhead();
|
||||||
|
|
||||||
// is called once every second by the main loop
|
// is called once every second by the main loop
|
||||||
void second_tick(float tick_interval);
|
void second_tick(float tick_interval);
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,24 @@ namespace libtorrent
|
||||||
m_stat[upload_protocol].add(bytes_protocol);
|
m_stat[upload_protocol].add(bytes_protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// calculate ip protocol overhead
|
||||||
|
void calc_ip_overhead()
|
||||||
|
{
|
||||||
|
// traffic balance is the number of bytes we downloaded
|
||||||
|
// more than we uploaded
|
||||||
|
int traffic_balance = m_stat[download_protocol].counter()
|
||||||
|
+ m_stat[download_payload].counter()
|
||||||
|
- m_stat[upload_protocol].counter()
|
||||||
|
- m_stat[upload_payload].counter();
|
||||||
|
if (traffic_balance > 0)
|
||||||
|
m_stat[upload_ip_protocol].add(traffic_balance / 20);
|
||||||
|
else
|
||||||
|
m_stat[download_ip_protocol].add(-traffic_balance / 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
int upload_ip_overhead() const { return m_stat[upload_ip_protocol].counter(); }
|
||||||
|
int download_ip_overhead() const { return m_stat[download_ip_protocol].counter(); }
|
||||||
|
|
||||||
// should be called once every second
|
// should be called once every second
|
||||||
void second_tick(float tick_interval)
|
void second_tick(float tick_interval)
|
||||||
{
|
{
|
||||||
|
@ -150,13 +168,15 @@ namespace libtorrent
|
||||||
float upload_rate() const
|
float upload_rate() const
|
||||||
{
|
{
|
||||||
return m_stat[upload_payload].rate()
|
return m_stat[upload_payload].rate()
|
||||||
+ m_stat[upload_protocol].rate();
|
+ m_stat[upload_protocol].rate()
|
||||||
|
+ m_stat[upload_ip_protocol].rate();
|
||||||
}
|
}
|
||||||
|
|
||||||
float download_rate() const
|
float download_rate() const
|
||||||
{
|
{
|
||||||
return m_stat[download_payload].rate()
|
return m_stat[download_payload].rate()
|
||||||
+ m_stat[download_protocol].rate();
|
+ m_stat[download_protocol].rate()
|
||||||
|
+ m_stat[download_ip_protocol].rate();
|
||||||
}
|
}
|
||||||
|
|
||||||
float upload_payload_rate() const
|
float upload_payload_rate() const
|
||||||
|
@ -198,8 +218,10 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
upload_payload,
|
upload_payload,
|
||||||
upload_protocol,
|
upload_protocol,
|
||||||
|
upload_ip_protocol,
|
||||||
download_payload,
|
download_payload,
|
||||||
download_protocol,
|
download_protocol,
|
||||||
|
download_ip_protocol,
|
||||||
num_channels
|
num_channels
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2413,6 +2413,11 @@ namespace libtorrent
|
||||||
m_packet_size = packet_size;
|
m_packet_size = packet_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void peer_connection::calc_ip_overhead()
|
||||||
|
{
|
||||||
|
m_statistics.calc_ip_overhead();
|
||||||
|
}
|
||||||
|
|
||||||
void peer_connection::second_tick(float tick_interval)
|
void peer_connection::second_tick(float tick_interval)
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
|
@ -1046,6 +1046,10 @@ namespace aux {
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// drain the IP overhead from the bandwidth limiters
|
||||||
|
m_download_channel.drain(m_stat.download_ip_overhead());
|
||||||
|
m_upload_channel.drain(m_stat.upload_ip_overhead());
|
||||||
|
|
||||||
m_stat.second_tick(tick_interval);
|
m_stat.second_tick(tick_interval);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3489,6 +3489,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
peer_connection* p = *i;
|
peer_connection* p = *i;
|
||||||
++i;
|
++i;
|
||||||
|
p->calc_ip_overhead();
|
||||||
m_stat += p->statistics();
|
m_stat += p->statistics();
|
||||||
// updates the peer connection's ul/dl bandwidth
|
// updates the peer connection's ul/dl bandwidth
|
||||||
// resource requests
|
// resource requests
|
||||||
|
|
Loading…
Reference in New Issue