#pragma once /** A peer of a bound (server) instance of UdpVpn */ #include #include #include "util.hpp" #include "VpnPacket.hpp" class UdpVpn; const int PACKET_LOSS_HISTSIZE = 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 get_loss_hist() const { return _packet_loss_hist; } const std::bitset get_received_ahead() const { return _received_ahead; } uint32_t get_cur_seqno() const { return _cur_seqno; } private: void reboot(); ///< completely reset the internal state std::bitset _packet_loss_hist; std::bitset _received_ahead; uint32_t _cur_seqno; }; class VpnPeer { public: class NetError : public MsgException { public: NetError( const std::string& msg, int code=0, bool is_perror=false) : MsgException(msg, code, is_perror) {} }; VpnPeer(UdpVpn* vpn, const sockaddr_in6& ext_addr, const in6_addr& int_addr); const sockaddr_in6& get_ext_addr() const { return _ext_addr; } const in6_addr& get_int_addr() const { return _int_addr; } void set_int_addr(const in6_addr& int_addr); const PacketLossLogger& get_loss_logger() { return _packet_loss; } size_t write(const char* data, size_t len); size_t write(const VpnPacket& packet); uint32_t peek_next_seqno() const { return _next_send_seqno; } uint32_t next_seqno() { return _next_send_seqno++; } void got_inbound_packet(const VpnPacket& packet); private: UdpVpn* _vpn; sockaddr_in6 _ext_addr; in6_addr _int_addr; uint32_t _next_send_seqno; PacketLossLogger _packet_loss; };