test(client): use protocol encoders in fake peers
This commit is contained in:
3 files changed
+76
-124
No files matched your search
@@ -215,9 +215,12 @@ fn trusted_zero_token_normal_reply_is_terminal() {
|
|||||||
let params = default_params();
|
let params = default_params();
|
||||||
let server = start_fake_server(move |socket, tx| {
|
let server = start_fake_server(move |socket, tx| {
|
||||||
let (_, peer) = recv_request(&socket, &tx);
|
let (_, peer) = recv_request(&socket, &tx);
|
||||||
socket
|
// encode_open_reply rejects a zero token without FLAG_CLOSE, so this
|
||||||
.send_to(&open_reply(FLAG_OPEN | FLAG_REPLY, 0, ¶ms, None), peer)
|
// deliberately non-compliant reply is built by encoding a normal
|
||||||
.unwrap();
|
// reply with a placeholder token and then zeroing the token field.
|
||||||
|
let mut reply = open_reply(FLAG_OPEN | FLAG_REPLY, TOKEN, ¶ms, None);
|
||||||
|
reply[HMAC_OFFSET..HMAC_OFFSET + 8].copy_from_slice(&0_u64.to_le_bytes());
|
||||||
|
socket.send_to(&reply, peer).unwrap();
|
||||||
});
|
});
|
||||||
let mut client = Client::connect(default_test_config(server.addr)).unwrap();
|
let mut client = Client::connect(default_test_config(server.addr)).unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use irtt_proto::{
|
use irtt_proto::{
|
||||||
compute_hmac_in_place, echo_packet_len as checked_echo_packet_len, flags::FLAG_HMAC,
|
echo_packet_len as checked_echo_packet_len, encode_echo_reply, encode_open_reply,
|
||||||
flags::FLAG_OPEN, flags::FLAG_REPLY, layout::PacketLayout, Clock, ReceivedStats, StampAt,
|
flags::FLAG_OPEN, flags::FLAG_REPLY, layout::PacketLayout, Clock, EchoReply, OpenReply,
|
||||||
HMAC_SIZE, MAGIC,
|
ReceivedStats, StampAt,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
net::UdpSocket,
|
net::UdpSocket,
|
||||||
@@ -61,18 +61,15 @@ pub(super) fn open_reply(
|
|||||||
params: &Params,
|
params: &Params,
|
||||||
hmac_key: Option<&[u8]>,
|
hmac_key: Option<&[u8]>,
|
||||||
) -> Vec<u8> {
|
) -> Vec<u8> {
|
||||||
let mut packet = Vec::new();
|
encode_open_reply(
|
||||||
packet.extend_from_slice(&MAGIC);
|
&OpenReply {
|
||||||
packet.push(flags | hmac_key.map_or(0, |_| FLAG_HMAC));
|
flags,
|
||||||
if hmac_key.is_some() {
|
token,
|
||||||
packet.extend_from_slice(&[0_u8; HMAC_SIZE]);
|
params: params.clone(),
|
||||||
}
|
},
|
||||||
packet.extend_from_slice(&token.to_le_bytes());
|
hmac_key,
|
||||||
packet.extend_from_slice(¶ms.encode());
|
)
|
||||||
if let Some(key) = hmac_key {
|
.unwrap()
|
||||||
compute_hmac_in_place(key, &mut packet, HMAC_OFFSET).unwrap();
|
|
||||||
}
|
|
||||||
packet
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn echo_packet_len(hmac: bool, params: &Params) -> usize {
|
pub(crate) fn echo_packet_len(hmac: bool, params: &Params) -> usize {
|
||||||
@@ -98,55 +95,28 @@ pub(super) fn echo_reply_packet_with_flags(
|
|||||||
hmac_key: Option<&[u8]>,
|
hmac_key: Option<&[u8]>,
|
||||||
flags: u8,
|
flags: u8,
|
||||||
) -> Vec<u8> {
|
) -> Vec<u8> {
|
||||||
let has_hmac = hmac_key.is_some();
|
let layout = PacketLayout::echo(hmac_key.is_some(), params);
|
||||||
let layout = PacketLayout::echo(has_hmac, params);
|
let reply = EchoReply {
|
||||||
let packet_len = echo_packet_len(has_hmac, params);
|
flags,
|
||||||
let mut packet = Vec::with_capacity(packet_len);
|
token,
|
||||||
|
sequence: seq,
|
||||||
let mut flags = flags;
|
recv_count: layout.recv_count.then_some(42),
|
||||||
if has_hmac {
|
recv_window: layout.recv_window.then_some(0x07),
|
||||||
flags |= FLAG_HMAC;
|
timestamps: TimestampFields {
|
||||||
}
|
recv_wall: layout.recv_wall.then(|| timestamps.recv_wall.unwrap_or(0)),
|
||||||
packet.extend_from_slice(&MAGIC);
|
recv_mono: layout.recv_mono.then(|| timestamps.recv_mono.unwrap_or(0)),
|
||||||
packet.push(flags);
|
midpoint_wall: layout
|
||||||
if has_hmac {
|
.midpoint_wall
|
||||||
packet.extend_from_slice(&[0_u8; HMAC_SIZE]);
|
.then(|| timestamps.midpoint_wall.unwrap_or(0)),
|
||||||
}
|
midpoint_mono: layout
|
||||||
packet.extend_from_slice(&token.to_le_bytes());
|
.midpoint_mono
|
||||||
packet.extend_from_slice(&seq.to_le_bytes());
|
.then(|| timestamps.midpoint_mono.unwrap_or(0)),
|
||||||
|
send_wall: layout.send_wall.then(|| timestamps.send_wall.unwrap_or(0)),
|
||||||
if layout.recv_count {
|
send_mono: layout.send_mono.then(|| timestamps.send_mono.unwrap_or(0)),
|
||||||
packet.extend_from_slice(&42_u32.to_le_bytes());
|
},
|
||||||
}
|
payload: Vec::new(),
|
||||||
if layout.recv_window {
|
};
|
||||||
packet.extend_from_slice(&0x07_u64.to_le_bytes());
|
encode_echo_reply(&reply, params, hmac_key).unwrap()
|
||||||
}
|
|
||||||
|
|
||||||
if layout.recv_wall {
|
|
||||||
packet.extend_from_slice(×tamps.recv_wall.unwrap_or(0).to_le_bytes());
|
|
||||||
}
|
|
||||||
if layout.recv_mono {
|
|
||||||
packet.extend_from_slice(×tamps.recv_mono.unwrap_or(0).to_le_bytes());
|
|
||||||
}
|
|
||||||
if layout.midpoint_wall {
|
|
||||||
packet.extend_from_slice(×tamps.midpoint_wall.unwrap_or(0).to_le_bytes());
|
|
||||||
}
|
|
||||||
if layout.midpoint_mono {
|
|
||||||
packet.extend_from_slice(×tamps.midpoint_mono.unwrap_or(0).to_le_bytes());
|
|
||||||
}
|
|
||||||
if layout.send_wall {
|
|
||||||
packet.extend_from_slice(×tamps.send_wall.unwrap_or(0).to_le_bytes());
|
|
||||||
}
|
|
||||||
if layout.send_mono {
|
|
||||||
packet.extend_from_slice(×tamps.send_mono.unwrap_or(0).to_le_bytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
packet.resize(packet_len, 0);
|
|
||||||
|
|
||||||
if let Some(key) = hmac_key {
|
|
||||||
compute_hmac_in_place(key, &mut packet, HMAC_OFFSET).unwrap();
|
|
||||||
}
|
|
||||||
packet
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn open_success_server(params: Params) -> FakeServer {
|
pub(super) fn open_success_server(params: Params) -> FakeServer {
|
||||||
|
|||||||
@@ -12,8 +12,9 @@ use std::{
|
|||||||
|
|
||||||
use irtt_client::{Client, ClientConfig, ClientEvent, NegotiatedParams, OpenOutcome, SocketConfig};
|
use irtt_client::{Client, ClientConfig, ClientEvent, NegotiatedParams, OpenOutcome, SocketConfig};
|
||||||
use irtt_proto::{
|
use irtt_proto::{
|
||||||
compute_hmac_in_place, echo_packet_len, flags, verify_hmac, Clock, Params, ProtoError,
|
compute_hmac_in_place, echo_packet_len, encode_echo_reply, encode_open_reply, flags,
|
||||||
ReceivedStats, ServerFill, StampAt, TimestampFields, HMAC_SIZE, MAGIC, PROTOCOL_VERSION,
|
verify_hmac, Clock, EchoReply, OpenReply, PacketLayout, Params, ProtoError, ReceivedStats,
|
||||||
|
ServerFill, StampAt, TimestampFields, HMAC_SIZE, MAGIC, PROTOCOL_VERSION,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use real_irtt::RealIrtServer;
|
pub use real_irtt::RealIrtServer;
|
||||||
@@ -495,6 +496,8 @@ fn observe_close_request(packet: &[u8], hmac_key: &[u8]) -> ServerObservation {
|
|||||||
ServerObservation::Close { hmac: true, token }
|
ServerObservation::Close { hmac: true, token }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// irtt-proto has no encode_close_reply/CloseReply API yet, so this stays a
|
||||||
|
// manual encoder. Migrate it once server-side close encoding is added.
|
||||||
fn close_reply(token: u64, hmac_key: &[u8]) -> Vec<u8> {
|
fn close_reply(token: u64, hmac_key: &[u8]) -> Vec<u8> {
|
||||||
let mut packet = Vec::new();
|
let mut packet = Vec::new();
|
||||||
packet.extend_from_slice(&MAGIC);
|
packet.extend_from_slice(&MAGIC);
|
||||||
@@ -506,18 +509,15 @@ fn close_reply(token: u64, hmac_key: &[u8]) -> Vec<u8> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn open_reply(flags: u8, token: u64, params: &Params, hmac_key: Option<&[u8]>) -> Vec<u8> {
|
fn open_reply(flags: u8, token: u64, params: &Params, hmac_key: Option<&[u8]>) -> Vec<u8> {
|
||||||
let mut packet = Vec::new();
|
encode_open_reply(
|
||||||
packet.extend_from_slice(&MAGIC);
|
&OpenReply {
|
||||||
packet.push(flags | hmac_key.map_or(0, |_| flags::FLAG_HMAC));
|
flags,
|
||||||
if hmac_key.is_some() {
|
token,
|
||||||
packet.extend_from_slice(&[0_u8; HMAC_SIZE]);
|
params: params.clone(),
|
||||||
}
|
},
|
||||||
packet.extend_from_slice(&token.to_le_bytes());
|
hmac_key,
|
||||||
packet.extend_from_slice(¶ms.encode());
|
)
|
||||||
if let Some(key) = hmac_key {
|
.unwrap()
|
||||||
compute_hmac_in_place(key, &mut packet, HMAC_OFFSET).unwrap();
|
|
||||||
}
|
|
||||||
packet
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn test_echo_packet_len(hmac: bool, params: &Params) -> usize {
|
pub(super) fn test_echo_packet_len(hmac: bool, params: &Params) -> usize {
|
||||||
@@ -532,49 +532,28 @@ fn echo_reply_packet(
|
|||||||
timestamps: &TimestampFields,
|
timestamps: &TimestampFields,
|
||||||
hmac_key: Option<&[u8]>,
|
hmac_key: Option<&[u8]>,
|
||||||
) -> Vec<u8> {
|
) -> Vec<u8> {
|
||||||
let has_hmac = hmac_key.is_some();
|
let layout = PacketLayout::echo(hmac_key.is_some(), params);
|
||||||
let layout = irtt_proto::PacketLayout::echo(has_hmac, params);
|
let reply = EchoReply {
|
||||||
let packet_len = test_echo_packet_len(has_hmac, params);
|
flags: flags::FLAG_REPLY,
|
||||||
let mut packet = Vec::with_capacity(packet_len);
|
token,
|
||||||
|
sequence: seq,
|
||||||
packet.extend_from_slice(&MAGIC);
|
recv_count: layout.recv_count.then_some(RECV_COUNT),
|
||||||
packet.push(flags::FLAG_REPLY | hmac_key.map_or(0, |_| flags::FLAG_HMAC));
|
recv_window: layout.recv_window.then_some(RECV_WINDOW),
|
||||||
if has_hmac {
|
timestamps: TimestampFields {
|
||||||
packet.extend_from_slice(&[0_u8; HMAC_SIZE]);
|
recv_wall: layout.recv_wall.then(|| timestamps.recv_wall.unwrap_or(0)),
|
||||||
}
|
recv_mono: layout.recv_mono.then(|| timestamps.recv_mono.unwrap_or(0)),
|
||||||
packet.extend_from_slice(&token.to_le_bytes());
|
midpoint_wall: layout
|
||||||
packet.extend_from_slice(&seq.to_le_bytes());
|
.midpoint_wall
|
||||||
|
.then(|| timestamps.midpoint_wall.unwrap_or(0)),
|
||||||
if layout.recv_count {
|
midpoint_mono: layout
|
||||||
packet.extend_from_slice(&RECV_COUNT.to_le_bytes());
|
.midpoint_mono
|
||||||
}
|
.then(|| timestamps.midpoint_mono.unwrap_or(0)),
|
||||||
if layout.recv_window {
|
send_wall: layout.send_wall.then(|| timestamps.send_wall.unwrap_or(0)),
|
||||||
packet.extend_from_slice(&RECV_WINDOW.to_le_bytes());
|
send_mono: layout.send_mono.then(|| timestamps.send_mono.unwrap_or(0)),
|
||||||
}
|
},
|
||||||
if layout.recv_wall {
|
payload: Vec::new(),
|
||||||
packet.extend_from_slice(×tamps.recv_wall.unwrap_or(0).to_le_bytes());
|
};
|
||||||
}
|
encode_echo_reply(&reply, params, hmac_key).unwrap()
|
||||||
if layout.recv_mono {
|
|
||||||
packet.extend_from_slice(×tamps.recv_mono.unwrap_or(0).to_le_bytes());
|
|
||||||
}
|
|
||||||
if layout.midpoint_wall {
|
|
||||||
packet.extend_from_slice(×tamps.midpoint_wall.unwrap_or(0).to_le_bytes());
|
|
||||||
}
|
|
||||||
if layout.midpoint_mono {
|
|
||||||
packet.extend_from_slice(×tamps.midpoint_mono.unwrap_or(0).to_le_bytes());
|
|
||||||
}
|
|
||||||
if layout.send_wall {
|
|
||||||
packet.extend_from_slice(×tamps.send_wall.unwrap_or(0).to_le_bytes());
|
|
||||||
}
|
|
||||||
if layout.send_mono {
|
|
||||||
packet.extend_from_slice(×tamps.send_mono.unwrap_or(0).to_le_bytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
packet.resize(packet_len, 0);
|
|
||||||
if let Some(key) = hmac_key {
|
|
||||||
compute_hmac_in_place(key, &mut packet, HMAC_OFFSET).unwrap();
|
|
||||||
}
|
|
||||||
packet
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn materialize_wall_timestamps(mut timestamps: TimestampFields) -> TimestampFields {
|
fn materialize_wall_timestamps(mut timestamps: TimestampFields) -> TimestampFields {
|
||||||
|
|||||||
Reference in new issue
Block a user