#include "congestion_control.hpp" #include "VpnPeer.hpp" #include "util.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(); clock_gettime(CLOCK_MONOTONIC, &_last_bucket_update); clock_gettime(CLOCK_MONOTONIC, &_loss_based.prev_time); 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; struct timespec cur_time; clock_gettime(CLOCK_MONOTONIC, &cur_time); uint64_t cur_sent = _peer.get_tot_bytes_sent(); double instant_bandwidth = /* byte per second */ (double)(cur_sent - _loss_based.prev_tot_sent) / (double)(timespec_us_diff(cur_time, _loss_based.prev_time)) * 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(); if(_bucket_level > _bucket_max_level) _bucket_level = _bucket_max_level; }