fix(client): reject runtime-invalid negotiated dscp

This commit is contained in:
Nils Andreas Svee committed 2026-05-10 20:56:43 +07:00
1 parent dfdc43292a
commit 8374a51054
3 files changed
+29 -2

No files matched your search

@@ -52,3 +52,19 @@ fn strict_negotiation_rejects_negative_returned_length() {
Err(ClientError::NegotiationRejected { reason }) if reason == "length must be non-negative" Err(ClientError::NegotiationRejected { reason }) if reason == "length must be non-negative"
)); ));
} }
#[test]
fn loose_negotiation_rejects_runtime_invalid_returned_dscp() {
let config = ClientConfig::default();
let requested = params_from_config(&config).unwrap();
for dscp in [-1, 64] {
let mut returned = requested.clone();
returned.dscp = dscp;
assert!(matches!(
validate_negotiated_params(&requested, &returned, NegotiationPolicy::Loose),
Err(ClientError::NegotiationRejected { reason })
if reason == "dscp must be in range 0..=63"
));
}
}
+12 -1
View File
@@ -3,7 +3,7 @@ use std::time::Instant;
use irtt_proto::{Params, PROTOCOL_VERSION}; use irtt_proto::{Params, PROTOCOL_VERSION};
use crate::{ use crate::{
config::NegotiationPolicy, config::{NegotiationPolicy, MAX_DSCP_CODEPOINT},
error::ClientError, error::ClientError,
probe::{CompletedSet, PendingMap, TimedOutMap}, probe::{CompletedSet, PendingMap, TimedOutMap},
}; };
@@ -63,6 +63,7 @@ pub(crate) fn validate_negotiated_params(
reason: "interval must be positive".to_owned(), reason: "interval must be positive".to_owned(),
}); });
} }
validate_dscp_restriction(returned.dscp)?;
if policy == NegotiationPolicy::Strict && returned != requested { if policy == NegotiationPolicy::Strict && returned != requested {
return Err(ClientError::NegotiationRejected { return Err(ClientError::NegotiationRejected {
@@ -94,6 +95,16 @@ fn validate_duration_restriction(requested: i64, returned: i64) -> Result<(), Cl
Ok(()) Ok(())
} }
fn validate_dscp_restriction(returned: i64) -> Result<(), ClientError> {
if !(0..=i64::from(MAX_DSCP_CODEPOINT)).contains(&returned) {
return Err(ClientError::NegotiationRejected {
reason: format!("dscp must be in range 0..={MAX_DSCP_CODEPOINT}"),
});
}
Ok(())
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
+1 -1
View File
@@ -272,7 +272,7 @@ mod tests {
#[test] #[test]
fn params_round_trip_dscp_codepoints_without_shifting() { fn params_round_trip_dscp_codepoints_without_shifting() {
for dscp in [0, 46, 63] { for dscp in [0, 46, 63, 64, 184, -1] {
let params = Params { let params = Params {
protocol_version: 1, protocol_version: 1,
dscp, dscp,