congestvpn/congestion_control.cpp

43 lines
1.5 KiB
C++

#include "congestion_control.hpp"
#include "VpnPeer.hpp"
CongestionController::CongestionController(const VpnPeer& peer):
_peer(peer)
{
_last_seqno = _peer.get_loss_logger().get_cur_seqno();
_loss_based.bandwidth = 3e5; // 300kBps seems a good value to start with
_loss_based.prev_tot_sent = _peer.get_tot_bytes_sent();
_loss_based.prev_time = std::chrono::steady_clock::now();
}
void CongestionController::update_lossbased() {
const VpnPeer::LossReports& loss_rep = _peer.get_loss_reports();
uint32_t delta_seqno = loss_rep.last_seqno - loss_rep.prev_seqno;
unsigned int delta_losses = loss_rep.last_losses - loss_rep.prev_losses;
double loss_rate = (double)delta_losses / (double)delta_seqno;
auto cur_time = std::chrono::steady_clock::now();
uint64_t cur_sent = _peer.get_tot_bytes_sent();
double instant_bandwidth = /* byte per second */
(double)(cur_sent - _loss_based.prev_tot_sent)
/ (double)(std::chrono::duration_cast<std::chrono::microseconds>(
cur_time - _loss_based.prev_time).count())
* 1e6;
_loss_based.prev_time = cur_time;
_loss_based.prev_tot_sent = cur_sent;
if(loss_rate < 0.02) {
if(instant_bandwidth > 0.75 * _loss_based.bandwidth)
_loss_based.bandwidth *= 1.05;
}
else if(loss_rate >= 0.1)
_loss_based.bandwidth *= (1 - 0.5 * loss_rate);
}
uint64_t CongestionController::get_bandwidth() const {
return _loss_based.bandwidth;
}