fix(client): validate packet length configuration

This commit is contained in:
Nils Andreas Svee committed 2026-05-07 21:25:51 +07:00
1 parent 2ed0677286
commit e479d51dc3
5 files changed
+38 -5

No files matched your search

+1 -3
View File
@@ -13,13 +13,11 @@ use clap::{Parser, ValueEnum};
use irtt_client::{
ClientConfig, ClientEvent, NegotiatedParams, NegotiationPolicy, OneWayDelaySample, PacketMeta,
ReceivedStatsSample, RttSample, ServerTiming, SocketConfig, WarningKind, MAX_DSCP_CODEPOINT,
MAX_SERVER_FILL_BYTES, MAX_TTL,
MAX_SERVER_FILL_BYTES, MAX_TTL, MAX_UDP_PAYLOAD_LENGTH,
};
use irtt_proto::{Clock, ReceivedStats, StampAt};
const DEFAULT_RECV_TIMEOUT: Duration = Duration::from_millis(20);
const MAX_UDP_PAYLOAD_LENGTH: u32 = 65_507;
#[derive(Debug, Clone, Parser)]
#[command(name = "irtt-rs", about = "Minimal IRTT-compatible client")]
pub struct CliArgs {
+9 -1
View File
@@ -11,7 +11,10 @@ use irtt_proto::{
};
use crate::{
config::{ClientConfig, RecvBudget, RunMode, MAX_DSCP_CODEPOINT, MAX_SERVER_FILL_BYTES},
config::{
ClientConfig, RecvBudget, RunMode, MAX_DSCP_CODEPOINT, MAX_SERVER_FILL_BYTES,
MAX_UDP_PAYLOAD_LENGTH,
},
error::ClientError,
event::{
ClientEvent, OneWayDelaySample, OpenOutcome, ReceivedStatsSample, RttSample, ServerTiming,
@@ -782,6 +785,11 @@ fn validate_protocol_config(config: &ClientConfig) -> Result<(), ClientError> {
reason: format!("dscp must be <= {MAX_DSCP_CODEPOINT}"),
});
}
if config.length > MAX_UDP_PAYLOAD_LENGTH {
return Err(ClientError::InvalidConfig {
reason: format!("packet length must be <= {MAX_UDP_PAYLOAD_LENGTH}"),
});
}
if let Some(fill) = &config.server_fill {
let len = fill.len();
@@ -50,6 +50,32 @@ fn params_from_config_maps_compatibility_fields() {
assert_eq!(config.hmac_key.as_deref(), Some(b"secret".as_slice()));
}
#[test]
fn params_from_config_accepts_udp_payload_length_boundary_values() {
for length in [0, 1, 1472, 4096, MAX_UDP_PAYLOAD_LENGTH] {
let config = ClientConfig {
length,
..ClientConfig::default()
};
assert_eq!(
params_from_config(&config).unwrap().length,
i64::from(length)
);
}
}
#[test]
fn params_from_config_rejects_oversized_udp_payload_length() {
let config = ClientConfig {
length: MAX_UDP_PAYLOAD_LENGTH + 1,
..ClientConfig::default()
};
assert!(matches!(
params_from_config(&config),
Err(ClientError::InvalidConfig { reason }) if reason.contains("packet length")
));
}
#[test]
fn params_from_config_encodes_continuous_duration_as_zero() {
let config = ClientConfig {
+1
View File
@@ -5,6 +5,7 @@ use irtt_proto::{Clock, ReceivedStats, StampAt};
pub(crate) const DEFAULT_PORT: u16 = 2112;
pub const MAX_DSCP_CODEPOINT: u8 = 63;
pub const MAX_TTL: u32 = 255;
pub const MAX_UDP_PAYLOAD_LENGTH: u32 = 65_507;
pub const MAX_SERVER_FILL_BYTES: usize = 32;
pub(crate) const DEFAULT_DURATION: Duration = Duration::from_secs(3);
pub(crate) const DEFAULT_INTERVAL: Duration = Duration::from_secs(1);
+1 -1
View File
@@ -20,7 +20,7 @@ mod timing;
pub use client::Client;
pub use config::{
ClientConfig, NegotiationPolicy, RecvBudget, RunMode, SocketConfig, MAX_DSCP_CODEPOINT,
MAX_SERVER_FILL_BYTES, MAX_TTL,
MAX_SERVER_FILL_BYTES, MAX_TTL, MAX_UDP_PAYLOAD_LENGTH,
};
pub use error::{ClientError, EventSubscriptionError};
pub use event::{