fix(client): validate packet length configuration
This commit is contained in:
1 parent
1a98858b7a
commit
e3bb28c559
5 files changed
+38
-5
No files matched your search
@@ -13,13 +13,11 @@ use clap::{Parser, ValueEnum};
|
|||||||
use irtt_client::{
|
use irtt_client::{
|
||||||
ClientConfig, ClientEvent, NegotiatedParams, NegotiationPolicy, OneWayDelaySample, PacketMeta,
|
ClientConfig, ClientEvent, NegotiatedParams, NegotiationPolicy, OneWayDelaySample, PacketMeta,
|
||||||
ReceivedStatsSample, RttSample, ServerTiming, SocketConfig, WarningKind, MAX_DSCP_CODEPOINT,
|
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};
|
use irtt_proto::{Clock, ReceivedStats, StampAt};
|
||||||
|
|
||||||
const DEFAULT_RECV_TIMEOUT: Duration = Duration::from_millis(20);
|
const DEFAULT_RECV_TIMEOUT: Duration = Duration::from_millis(20);
|
||||||
const MAX_UDP_PAYLOAD_LENGTH: u32 = 65_507;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Parser)]
|
#[derive(Debug, Clone, Parser)]
|
||||||
#[command(name = "irtt-rs", about = "Minimal IRTT-compatible client")]
|
#[command(name = "irtt-rs", about = "Minimal IRTT-compatible client")]
|
||||||
pub struct CliArgs {
|
pub struct CliArgs {
|
||||||
|
|||||||
@@ -11,7 +11,10 @@ use irtt_proto::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
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,
|
error::ClientError,
|
||||||
event::{
|
event::{
|
||||||
ClientEvent, OneWayDelaySample, OpenOutcome, ReceivedStatsSample, RttSample, ServerTiming,
|
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}"),
|
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 {
|
if let Some(fill) = &config.server_fill {
|
||||||
let len = fill.len();
|
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()));
|
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]
|
#[test]
|
||||||
fn params_from_config_encodes_continuous_duration_as_zero() {
|
fn params_from_config_encodes_continuous_duration_as_zero() {
|
||||||
let config = ClientConfig {
|
let config = ClientConfig {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use irtt_proto::{Clock, ReceivedStats, StampAt};
|
|||||||
pub(crate) const DEFAULT_PORT: u16 = 2112;
|
pub(crate) const DEFAULT_PORT: u16 = 2112;
|
||||||
pub const MAX_DSCP_CODEPOINT: u8 = 63;
|
pub const MAX_DSCP_CODEPOINT: u8 = 63;
|
||||||
pub const MAX_TTL: u32 = 255;
|
pub const MAX_TTL: u32 = 255;
|
||||||
|
pub const MAX_UDP_PAYLOAD_LENGTH: u32 = 65_507;
|
||||||
pub const MAX_SERVER_FILL_BYTES: usize = 32;
|
pub const MAX_SERVER_FILL_BYTES: usize = 32;
|
||||||
pub(crate) const DEFAULT_DURATION: Duration = Duration::from_secs(3);
|
pub(crate) const DEFAULT_DURATION: Duration = Duration::from_secs(3);
|
||||||
pub(crate) const DEFAULT_INTERVAL: Duration = Duration::from_secs(1);
|
pub(crate) const DEFAULT_INTERVAL: Duration = Duration::from_secs(1);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ mod timing;
|
|||||||
pub use client::Client;
|
pub use client::Client;
|
||||||
pub use config::{
|
pub use config::{
|
||||||
ClientConfig, NegotiationPolicy, RecvBudget, RunMode, SocketConfig, MAX_DSCP_CODEPOINT,
|
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 error::{ClientError, EventSubscriptionError};
|
||||||
pub use event::{
|
pub use event::{
|
||||||
|
|||||||
Reference in new issue
Block a user