mirror of https://github.com/ospab/ostp.git
fix: immediately ACK duplicate packets instead of silently dropping them to unblock client retries when ACKs are lost
This commit is contained in:
parent
b670ba9e48
commit
5bd653e9d2
|
|
@ -745,7 +745,7 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
|||
|
||||
[[package]]
|
||||
name = "ostp"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
|
|
@ -762,7 +762,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ostp-client"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
|
|
@ -780,7 +780,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ostp-core"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
|
|
@ -813,7 +813,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ostp-server"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
|
|
@ -828,7 +828,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ostp-tun-helper"
|
||||
version = "0.1.57"
|
||||
version = "0.1.58"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
|
|
|
|||
|
|
@ -229,7 +229,11 @@ impl ProtocolMachine {
|
|||
let nonce = u64::from_be_bytes(raw_vec[4..12].try_into().unwrap());
|
||||
|
||||
if nonce < self.expected_recv_nonce {
|
||||
// Duplicate or delayed packet already processed, drop silently
|
||||
// Duplicate packet! The ACK we sent was likely lost or delayed.
|
||||
// We MUST trigger an immediate ACK to unblock the sender's congestion window.
|
||||
if let Some(ack_frame) = self.force_build_ack()? {
|
||||
return Ok(ProtocolAction::SendDatagram(ack_frame));
|
||||
}
|
||||
return Ok(ProtocolAction::Noop);
|
||||
}
|
||||
|
||||
|
|
@ -469,6 +473,19 @@ impl ProtocolMachine {
|
|||
Ok(Some(frame))
|
||||
}
|
||||
|
||||
fn force_build_ack(&mut self) -> Result<Option<Bytes>, ProtocolError> {
|
||||
let payload = self.build_ack_payload();
|
||||
if payload.is_empty() {
|
||||
self.ack_pending = false;
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let frame = self.build_control_datagram(0, FrameKind::Ack, payload)?;
|
||||
self.ack_pending = false;
|
||||
self.last_ack_sent = Instant::now();
|
||||
Ok(Some(frame))
|
||||
}
|
||||
|
||||
fn build_ack_payload(&self) -> Bytes {
|
||||
const MAX_RANGES: usize = 8;
|
||||
let mut ranges = Vec::new();
|
||||
|
|
|
|||
Loading…
Reference in New Issue