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]]
|
[[package]]
|
||||||
name = "ostp"
|
name = "ostp"
|
||||||
version = "0.1.57"
|
version = "0.1.58"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
|
|
@ -762,7 +762,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ostp-client"
|
name = "ostp-client"
|
||||||
version = "0.1.57"
|
version = "0.1.58"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
|
@ -780,7 +780,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ostp-core"
|
name = "ostp-core"
|
||||||
version = "0.1.57"
|
version = "0.1.58"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
|
@ -813,7 +813,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ostp-server"
|
name = "ostp-server"
|
||||||
version = "0.1.57"
|
version = "0.1.58"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
|
@ -828,7 +828,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ostp-tun-helper"
|
name = "ostp-tun-helper"
|
||||||
version = "0.1.57"
|
version = "0.1.58"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
|
|
||||||
|
|
@ -229,7 +229,11 @@ impl ProtocolMachine {
|
||||||
let nonce = u64::from_be_bytes(raw_vec[4..12].try_into().unwrap());
|
let nonce = u64::from_be_bytes(raw_vec[4..12].try_into().unwrap());
|
||||||
|
|
||||||
if nonce < self.expected_recv_nonce {
|
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);
|
return Ok(ProtocolAction::Noop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -469,6 +473,19 @@ impl ProtocolMachine {
|
||||||
Ok(Some(frame))
|
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 {
|
fn build_ack_payload(&self) -> Bytes {
|
||||||
const MAX_RANGES: usize = 8;
|
const MAX_RANGES: usize = 8;
|
||||||
let mut ranges = Vec::new();
|
let mut ranges = Vec::new();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue