only allow cwnd to be reduced so often
This commit is contained in:
parent
33fa7454d0
commit
786d78b6c9
|
@ -1608,6 +1608,11 @@ namespace libtorrent
|
||||||
// systems.
|
// systems.
|
||||||
close_file_interval,
|
close_file_interval,
|
||||||
|
|
||||||
|
// When uTP experiences packet loss, it will reduce the congestion
|
||||||
|
// window, and not reduce it again for this many milliseconds, even if
|
||||||
|
// experiencing another lost packet.
|
||||||
|
utp_cwnd_reduce_timer,
|
||||||
|
|
||||||
max_int_setting_internal
|
max_int_setting_internal
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,7 @@ namespace libtorrent
|
||||||
int connect_timeout() const { return m_sett.get_int(settings_pack::utp_connect_timeout); }
|
int connect_timeout() const { return m_sett.get_int(settings_pack::utp_connect_timeout); }
|
||||||
int min_timeout() const { return m_sett.get_int(settings_pack::utp_min_timeout); }
|
int min_timeout() const { return m_sett.get_int(settings_pack::utp_min_timeout); }
|
||||||
int loss_multiplier() const { return m_sett.get_int(settings_pack::utp_loss_multiplier); }
|
int loss_multiplier() const { return m_sett.get_int(settings_pack::utp_loss_multiplier); }
|
||||||
|
int cwnd_reduce_timer() const { return m_sett.get_int(settings_pack::utp_cwnd_reduce_timer); }
|
||||||
|
|
||||||
void mtu_for_dest(address const& addr, int& link_mtu, int& utp_mtu);
|
void mtu_for_dest(address const& addr, int& link_mtu, int& utp_mtu);
|
||||||
void set_sock_buf(int size);
|
void set_sock_buf(int size);
|
||||||
|
|
|
@ -366,6 +366,7 @@ namespace libtorrent
|
||||||
SET_NOPREV(urlseed_max_request_bytes, 16 * 1024 * 1024, 0),
|
SET_NOPREV(urlseed_max_request_bytes, 16 * 1024 * 1024, 0),
|
||||||
SET_NOPREV(web_seed_name_lookup_retry, 1800, 0),
|
SET_NOPREV(web_seed_name_lookup_retry, 1800, 0),
|
||||||
SET_NOPREV(close_file_interval, CLOSE_FILE_INTERVAL, &session_impl::update_close_file_interval),
|
SET_NOPREV(close_file_interval, CLOSE_FILE_INTERVAL, &session_impl::update_close_file_interval),
|
||||||
|
SET_NOPREV(utp_cwnd_reduce_timer, 100, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef SET
|
#undef SET
|
||||||
|
|
|
@ -359,7 +359,7 @@ struct utp_socket_impl
|
||||||
bool consume_incoming_data(
|
bool consume_incoming_data(
|
||||||
utp_header const* ph, boost::uint8_t const* ptr, int payload_size, time_point now);
|
utp_header const* ph, boost::uint8_t const* ptr, int payload_size, time_point now);
|
||||||
void update_mtu_limits();
|
void update_mtu_limits();
|
||||||
void experienced_loss(int seq_nr);
|
void experienced_loss(int seq_nr, time_point now);
|
||||||
|
|
||||||
void set_state(int s);
|
void set_state(int s);
|
||||||
|
|
||||||
|
@ -467,6 +467,10 @@ public:
|
||||||
// the last time we stepped the timestamp history
|
// the last time we stepped the timestamp history
|
||||||
time_point m_last_history_step;
|
time_point m_last_history_step;
|
||||||
|
|
||||||
|
// the next time we allow a lost packet to halve cwnd. We only do this once every
|
||||||
|
// 100 ms
|
||||||
|
time_point m_next_loss;
|
||||||
|
|
||||||
// the max number of bytes in-flight. This is a fixed point
|
// the max number of bytes in-flight. This is a fixed point
|
||||||
// value, to get the true number of bytes, shift right 16 bits
|
// value, to get the true number of bytes, shift right 16 bits
|
||||||
// the value is always >= 0, but the calculations performed on
|
// the value is always >= 0, but the calculations performed on
|
||||||
|
@ -1648,7 +1652,7 @@ void utp_socket_impl::parse_sack(boost::uint16_t const packet_ack, boost::uint8_
|
||||||
// the logic to handle a lost MTU probe is in resend_packet()
|
// the logic to handle a lost MTU probe is in resend_packet()
|
||||||
if (cut_cwnd && (pkt_seq != m_mtu_seq || m_mtu_seq == 0))
|
if (cut_cwnd && (pkt_seq != m_mtu_seq || m_mtu_seq == 0))
|
||||||
{
|
{
|
||||||
experienced_loss(pkt_seq);
|
experienced_loss(pkt_seq, now);
|
||||||
cut_cwnd = false;
|
cut_cwnd = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2360,7 +2364,7 @@ bool utp_socket_impl::resend_packet(packet* p, bool fast_resend)
|
||||||
return !m_stalled;
|
return !m_stalled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void utp_socket_impl::experienced_loss(int const seq_nr)
|
void utp_socket_impl::experienced_loss(int const seq_nr, time_point const now)
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
|
@ -2380,11 +2384,17 @@ void utp_socket_impl::experienced_loss(int const seq_nr)
|
||||||
// same packet again, ignore it.
|
// same packet again, ignore it.
|
||||||
if (compare_less_wrap(seq_nr, m_loss_seq_nr + 1, ACK_MASK)) return;
|
if (compare_less_wrap(seq_nr, m_loss_seq_nr + 1, ACK_MASK)) return;
|
||||||
|
|
||||||
|
// don't reduce cwnd more than once every 100ms
|
||||||
|
if (m_next_loss >= now) return;
|
||||||
|
|
||||||
|
m_next_loss = now + milliseconds(m_sm->cwnd_reduce_timer());
|
||||||
|
|
||||||
// cut window size in 2
|
// cut window size in 2
|
||||||
m_cwnd = std::max(m_cwnd * m_sm->loss_multiplier() / 100
|
m_cwnd = std::max(m_cwnd * m_sm->loss_multiplier() / 100
|
||||||
, boost::int64_t(m_mtu) * (1 << 16));
|
, boost::int64_t(m_mtu) * (1 << 16));
|
||||||
m_loss_seq_nr = m_seq_nr;
|
m_loss_seq_nr = m_seq_nr;
|
||||||
UTP_LOGV("%8p: Lost packet %d caused cwnd cut\n", static_cast<void*>(this), seq_nr);
|
UTP_LOGV("%8p: Lost packet %d caused cwnd cut. m_loss_seq_nr:%d\n"
|
||||||
|
, static_cast<void*>(this), seq_nr, m_seq_nr);
|
||||||
|
|
||||||
// if we happen to be in slow-start mode, we need to leave it
|
// if we happen to be in slow-start mode, we need to leave it
|
||||||
// note that we set ssthres to the window size _after_ reducing it. Next slow
|
// note that we set ssthres to the window size _after_ reducing it. Next slow
|
||||||
|
@ -3071,7 +3081,7 @@ bool utp_socket_impl::incoming_packet(boost::uint8_t const* buf, int size
|
||||||
{
|
{
|
||||||
// don't consider a lost probe as proper loss, it doesn't necessarily
|
// don't consider a lost probe as proper loss, it doesn't necessarily
|
||||||
// signal congestion
|
// signal congestion
|
||||||
if (!p->mtu_probe) experienced_loss(m_fast_resend_seq_nr);
|
if (!p->mtu_probe) experienced_loss(m_fast_resend_seq_nr, receive_time);
|
||||||
resend_packet(p, true);
|
resend_packet(p, true);
|
||||||
if (m_state == UTP_STATE_ERROR_WAIT || m_state == UTP_STATE_DELETE) return true;
|
if (m_state == UTP_STATE_ERROR_WAIT || m_state == UTP_STATE_DELETE) return true;
|
||||||
}
|
}
|
||||||
|
@ -3281,6 +3291,8 @@ bool utp_socket_impl::incoming_packet(boost::uint8_t const* buf, int size
|
||||||
if (m_state == UTP_STATE_ERROR_WAIT || m_state == UTP_STATE_DELETE) return true;
|
if (m_state == UTP_STATE_ERROR_WAIT || m_state == UTP_STATE_DELETE) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TORRENT_ASSERT(!compare_less_wrap(m_seq_nr, m_acked_seq_nr, ACK_MASK));
|
||||||
|
|
||||||
#if TORRENT_UTP_LOG
|
#if TORRENT_UTP_LOG
|
||||||
if (sample && acked_bytes && prev_bytes_in_flight)
|
if (sample && acked_bytes && prev_bytes_in_flight)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue