public:
void Handle(const UDPpacket &);
+ // called as soon as the remote end ack'd given packet
+ virtual void OnPacketReceived(std::uint16_t) { }
+ // called if the remote end probably didn't get given packet
virtual void OnPacketLost(std::uint16_t) { }
virtual void OnTimeout() { }
std::uint16_t seq;
std::uint16_t ack;
std::uint32_t hist;
+
+ // true if this contains an ack for given (remote) seq
+ bool Acks(std::uint16_t) const noexcept;
+ std::uint16_t AckBegin() const noexcept { return ack; }
+ std::uint16_t AckEnd() const noexcept { return ack + std::uint16_t(33); }
};
struct Header {
}
}
}
+ // check for newly ack'd packets
+ for (uint16_t s = ctrl_new.AckBegin(); s != ctrl_new.AckEnd(); ++s) {
+ if (ctrl_new.Acks(s) && !ctrl_in.Acks(s)) {
+ Handler().OnPacketReceived(s);
+ }
+ }
ctrl_in = ctrl_new;
}
}
+bool Packet::TControl::Acks(uint16_t s) const noexcept {
+ int16_t diff = int16_t(ack) - int16_t(s);
+ if (diff == 0) return true;
+ if (diff < 0 || diff > 32) return false;
+ return (hist & (1 << (diff - 1))) != 0;
+}
+
uint16_t Connection::SendPing(UDPpacket &udp_pack, UDPsocket sock) {
Packet::Make<Packet::Ping>(udp_pack);
return Send(udp_pack, sock);