#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(); _last_bucket_update = _loss_based.prev_time = std::chrono::steady_clock::now(); update_params(); } 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( 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); update_params(); } void CongestionController::update_params() { _bandwidth = _loss_based.bandwidth; // meant to integrate other controllers _bucket_max_level = _bandwidth * _peer.get_rtt().avg_rtt(); _bucket_level = std::min(_bucket_level, _bucket_max_level); }