Only keep track of total packet loss so far
Remove the packet loss history for last 128 packets
This commit is contained in:
parent
a08808344e
commit
15f9625a6d
3 changed files with 35 additions and 68 deletions
35
VpnPeer.cpp
35
VpnPeer.cpp
|
@ -63,44 +63,57 @@ void VpnPeer::make_rtta_for(const VpnTlvRTTQ& rttq) {
|
|||
rtta.set_recv_ts(rttq.get_packet().get_reception_timestamp());
|
||||
}
|
||||
|
||||
PacketLossLogger::PacketLossLogger() : _cur_seqno(0) {}
|
||||
PacketLossLogger::PacketLossLogger() :
|
||||
_cur_seqno(0), _tot_losses(0), _last_window_losses(0), _win_start_losses(0)
|
||||
{}
|
||||
|
||||
void PacketLossLogger::log_packet(uint32_t seqno) {
|
||||
uint32_t m_seqno = seqno % PACKET_LOSS_HISTSIZE;
|
||||
int64_t diff = (int64_t)seqno - _cur_seqno;
|
||||
|
||||
if(diff == 1) {
|
||||
_cur_seqno++;
|
||||
_packet_loss_hist.reset(m_seqno);
|
||||
maybe_start_window();
|
||||
while(_received_ahead.test((_cur_seqno + 1) % PACKET_LOST_AFTER)) {
|
||||
_cur_seqno++;
|
||||
_packet_loss_hist.reset(_cur_seqno % PACKET_LOSS_HISTSIZE);
|
||||
_received_ahead.reset(_cur_seqno % PACKET_LOST_AFTER);
|
||||
maybe_start_window();
|
||||
}
|
||||
} else if(LIKELY(diff > 1)) {
|
||||
if(diff < PACKET_LOST_AFTER)
|
||||
_received_ahead.set(seqno % PACKET_LOST_AFTER);
|
||||
else if(diff < PACKET_LOSS_HISTSIZE) {
|
||||
else if(diff < PACKET_LOSS_WINDOW) {
|
||||
// Packet too much forwards -- consider _cur_seqno lost
|
||||
for(int offs=1; offs < PACKET_LOST_AFTER; ++offs) {
|
||||
_packet_loss_hist[(_cur_seqno + offs) % PACKET_LOSS_HISTSIZE] =
|
||||
!_received_ahead[(_cur_seqno + offs) % PACKET_LOST_AFTER];
|
||||
if(_cur_seqno % PACKET_LOSS_WINDOW > seqno % PACKET_LOSS_WINDOW) {
|
||||
// This loss crosses a window border
|
||||
for(int offs=0; offs < PACKET_LOST_AFTER; ++offs) {
|
||||
maybe_start_window(offs);
|
||||
if(!_received_ahead[(_cur_seqno + offs) % PACKET_LOST_AFTER])
|
||||
_tot_losses++;
|
||||
}
|
||||
} else {
|
||||
_tot_losses += PACKET_LOST_AFTER - _received_ahead.count();
|
||||
}
|
||||
_received_ahead.reset();
|
||||
_cur_seqno = seqno;
|
||||
_packet_loss_hist.reset(m_seqno);
|
||||
} else
|
||||
reboot(); // This is a huge gap -- reboot
|
||||
} else {
|
||||
if(diff < - 2*PACKET_LOSS_HISTSIZE)
|
||||
if(diff < - 2*PACKET_LOSS_WINDOW)
|
||||
reboot(); // this is too much backwards -- something's wrong, reboot
|
||||
// else: ignore, we've moved forward and counted the packet as lost
|
||||
}
|
||||
}
|
||||
|
||||
void PacketLossLogger::reboot() {
|
||||
_packet_loss_hist.reset();
|
||||
_received_ahead.reset();
|
||||
// _tot_losses unchanged
|
||||
}
|
||||
|
||||
void PacketLossLogger::maybe_start_window(int offs) {
|
||||
if(_cur_seqno + offs % PACKET_LOSS_WINDOW == 0) {
|
||||
_last_window_losses = _win_start_losses;
|
||||
_win_start_losses = _tot_losses;
|
||||
}
|
||||
}
|
||||
|
||||
RTTLogger::RTTLogger() :
|
||||
|
|
20
VpnPeer.hpp
20
VpnPeer.hpp
|
@ -10,18 +10,15 @@
|
|||
|
||||
class UdpVpn;
|
||||
|
||||
const int PACKET_LOSS_HISTSIZE = 128, PACKET_LOST_AFTER = 8;
|
||||
const int PACKET_LOSS_WINDOW = 128, PACKET_LOST_AFTER = 8;
|
||||
|
||||
class PacketLossLogger {
|
||||
public:
|
||||
PacketLossLogger();
|
||||
void log_packet(uint32_t seqno);
|
||||
double get_loss_rate() const {
|
||||
return (double)_packet_loss_hist.count() / PACKET_LOSS_HISTSIZE;
|
||||
}
|
||||
|
||||
const std::bitset<PACKET_LOSS_HISTSIZE> get_loss_hist() const {
|
||||
return _packet_loss_hist;
|
||||
return (double)(_win_start_losses - _last_window_losses)
|
||||
/ (double)PACKET_LOSS_WINDOW;
|
||||
}
|
||||
|
||||
const std::bitset<PACKET_LOST_AFTER> get_received_ahead() const {
|
||||
|
@ -29,13 +26,18 @@ class PacketLossLogger {
|
|||
}
|
||||
|
||||
uint32_t get_cur_seqno() const { return _cur_seqno; }
|
||||
unsigned int get_tot_losses() const { return _tot_losses; }
|
||||
|
||||
private:
|
||||
void reboot(); ///< completely reset the internal state
|
||||
|
||||
std::bitset<PACKET_LOSS_HISTSIZE> _packet_loss_hist;
|
||||
/// roll loss window values if `_cur_seqno + offs` is a window start.
|
||||
void maybe_start_window(int offs=0);
|
||||
|
||||
std::bitset<PACKET_LOST_AFTER> _received_ahead;
|
||||
uint32_t _cur_seqno;
|
||||
unsigned int _tot_losses;
|
||||
unsigned int _last_window_losses, _win_start_losses;
|
||||
};
|
||||
|
||||
/** Round-trip time logger. All timestamps/delays are in microseconds. */
|
||||
|
@ -83,8 +85,8 @@ class VpnPeer {
|
|||
|
||||
void set_int_addr(const in6_addr& int_addr);
|
||||
|
||||
const PacketLossLogger& get_loss_logger() { return _packet_loss; }
|
||||
const RTTLogger& get_rtt() { return _rtt; }
|
||||
const PacketLossLogger& get_loss_logger() const { return _packet_loss; }
|
||||
const RTTLogger& get_rtt() const { return _rtt; }
|
||||
|
||||
void log_rtta(const VpnTlvRTTA& rtta) { _rtt.log(rtta); }
|
||||
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include "VpnPeer.hpp"
|
||||
|
||||
template<int len>
|
||||
std::string bitset_to_string(
|
||||
const std::bitset<len>& bs,
|
||||
char c_f, char c_t, size_t mark_pos, char cm_f, char cm_t)
|
||||
{
|
||||
std::string out;
|
||||
for(size_t pos=0; pos < len; ++pos) {
|
||||
if(pos == mark_pos)
|
||||
out += bs[pos] ? cm_t : cm_f;
|
||||
else
|
||||
out += bs[pos] ? c_t : c_f;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void dump(PacketLossLogger& pllog, int received) {
|
||||
printf("%03d, %.03lf ## %s ## %s\n",
|
||||
received,
|
||||
pllog.get_loss_rate(),
|
||||
bitset_to_string<PACKET_LOSS_HISTSIZE>(
|
||||
pllog.get_loss_hist(), '_', 'X',
|
||||
pllog.get_cur_seqno() % PACKET_LOSS_HISTSIZE,
|
||||
'|', '#').c_str(),
|
||||
bitset_to_string<PACKET_LOST_AFTER>(
|
||||
pllog.get_received_ahead(), '_', 'X',
|
||||
pllog.get_cur_seqno() % PACKET_LOST_AFTER,
|
||||
'|', '#').c_str());
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
PacketLossLogger pllog;
|
||||
std::vector<int> sequence({
|
||||
1, 2, 3, 5, 6, 4, 8, 7, 8, 9,
|
||||
12, 13, 14, 15, 16, 17, 18, 19, 20, 10, 21
|
||||
});
|
||||
|
||||
dump(pllog, 0);
|
||||
for(auto val=sequence.begin(); val != sequence.end(); ++val) {
|
||||
pllog.log_packet(*val);
|
||||
dump(pllog, *val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue