feat(proto): add directional open and close codecs
This commit is contained in:
5 files changed
+240
-7
No files matched your search
@@ -0,0 +1,135 @@
|
||||
use irtt_proto::{
|
||||
decode_close_request, decode_open_reply, decode_open_request, encode_close_request,
|
||||
encode_open_reply, encode_open_request, CloseRequest, OpenReply, OpenRequest, Params,
|
||||
ProtoError, FLAG_CLOSE, FLAG_HMAC, FLAG_OPEN, FLAG_REPLY, MAGIC,
|
||||
};
|
||||
|
||||
const KEY: &[u8] = b"testkey";
|
||||
const TOKEN: u64 = 0x7896_b6ab_8771_5213;
|
||||
|
||||
#[test]
|
||||
fn authenticated_open_reply_encoder_sets_hmac_from_key() {
|
||||
let reply = OpenReply {
|
||||
flags: FLAG_OPEN | FLAG_REPLY,
|
||||
token: TOKEN,
|
||||
params: Params {
|
||||
protocol_version: 1,
|
||||
..Params::default()
|
||||
},
|
||||
};
|
||||
let packet = encode_open_reply(&reply, Some(KEY)).unwrap();
|
||||
|
||||
assert_eq!(packet[3], FLAG_OPEN | FLAG_REPLY | FLAG_HMAC);
|
||||
assert_eq!(
|
||||
decode_open_reply(&packet, Some(KEY)),
|
||||
Ok(OpenReply {
|
||||
flags: FLAG_OPEN | FLAG_REPLY | FLAG_HMAC,
|
||||
..reply
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejected_open_reply_round_trips_and_zero_token_requires_close() {
|
||||
let rejected = OpenReply {
|
||||
flags: FLAG_OPEN | FLAG_REPLY | FLAG_CLOSE,
|
||||
token: 0,
|
||||
params: Params {
|
||||
protocol_version: 1,
|
||||
..Params::default()
|
||||
},
|
||||
};
|
||||
let packet = encode_open_reply(&rejected, None).unwrap();
|
||||
assert_eq!(decode_open_reply(&packet, None), Ok(rejected.clone()));
|
||||
|
||||
assert_eq!(
|
||||
encode_open_reply(
|
||||
&OpenReply {
|
||||
flags: FLAG_OPEN | FLAG_REPLY,
|
||||
..rejected
|
||||
},
|
||||
None,
|
||||
),
|
||||
Err(ProtoError::ZeroToken)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn open_and_close_codecs_enforce_directional_flags() {
|
||||
let params = Params::default();
|
||||
let open_reply_packet = encode_open_reply(
|
||||
&OpenReply {
|
||||
flags: FLAG_OPEN | FLAG_REPLY,
|
||||
token: TOKEN,
|
||||
params: params.clone(),
|
||||
},
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
decode_open_request(&open_reply_packet, None),
|
||||
Err(ProtoError::UnexpectedFlag(FLAG_REPLY))
|
||||
);
|
||||
assert_eq!(
|
||||
encode_open_reply(
|
||||
&OpenReply {
|
||||
flags: FLAG_REPLY,
|
||||
token: TOKEN,
|
||||
params: params.clone(),
|
||||
},
|
||||
None,
|
||||
),
|
||||
Err(ProtoError::MissingFlag(FLAG_OPEN))
|
||||
);
|
||||
|
||||
let no_test_packet = encode_open_request(
|
||||
&OpenRequest {
|
||||
params,
|
||||
close: true,
|
||||
},
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
decode_close_request(&no_test_packet, None),
|
||||
Err(ProtoError::UnexpectedFlag(FLAG_OPEN))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn open_and_close_malformed_bodies_and_exact_lengths_are_rejected() {
|
||||
let mut malformed_open_request = MAGIC.to_vec();
|
||||
malformed_open_request.push(FLAG_OPEN);
|
||||
malformed_open_request.extend_from_slice(&[1, 0x80]);
|
||||
assert_eq!(
|
||||
decode_open_request(&malformed_open_request, None),
|
||||
Err(ProtoError::TruncatedVarint)
|
||||
);
|
||||
|
||||
let mut malformed_open_reply = MAGIC.to_vec();
|
||||
malformed_open_reply.push(FLAG_OPEN | FLAG_REPLY);
|
||||
malformed_open_reply.extend_from_slice(&TOKEN.to_le_bytes());
|
||||
malformed_open_reply.extend_from_slice(&[1, 0x80]);
|
||||
assert_eq!(
|
||||
decode_open_reply(&malformed_open_reply, None),
|
||||
Err(ProtoError::TruncatedVarint)
|
||||
);
|
||||
|
||||
let close_packet = encode_close_request(&CloseRequest { token: TOKEN }, None).unwrap();
|
||||
assert_eq!(
|
||||
decode_close_request(&close_packet[..11], None),
|
||||
Err(ProtoError::PacketLengthMismatch {
|
||||
expected: 12,
|
||||
actual: 11,
|
||||
})
|
||||
);
|
||||
let mut long_close_packet = close_packet;
|
||||
long_close_packet.push(0);
|
||||
assert_eq!(
|
||||
decode_close_request(&long_close_packet, None),
|
||||
Err(ProtoError::PacketLengthMismatch {
|
||||
expected: 12,
|
||||
actual: 13,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
use irtt_proto::{
|
||||
decode_echo_reply, decode_open_reply, encode_close_request, encode_echo_request,
|
||||
encode_open_request, verify_hmac, Clock, CloseRequest, EchoRequest, OpenRequest, Params,
|
||||
ReceivedStats, StampAt,
|
||||
decode_close_request, decode_echo_reply, decode_open_reply, decode_open_request,
|
||||
encode_close_request, encode_echo_request, encode_open_reply, encode_open_request, verify_hmac,
|
||||
Clock, CloseRequest, EchoRequest, OpenRequest, Params, ReceivedStats, StampAt,
|
||||
};
|
||||
|
||||
fn hex(input: &str) -> Vec<u8> {
|
||||
@@ -50,6 +50,13 @@ fn vector_1_open_request_no_hmac() {
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(packet, expected);
|
||||
assert_eq!(
|
||||
decode_open_request(&expected, None),
|
||||
Ok(OpenRequest {
|
||||
params: default_params_3s(),
|
||||
close: false,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -59,6 +66,7 @@ fn vector_2_open_reply_no_hmac() {
|
||||
let reply = decode_open_reply(&packet, None).unwrap();
|
||||
assert_eq!(reply.token, 0x7896_b6ab_8771_5213);
|
||||
assert_eq!(reply.params, default_params_3s());
|
||||
assert_eq!(encode_open_reply(&reply, None).unwrap(), packet);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -103,6 +111,12 @@ fn vector_5_close_request_no_hmac() {
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(packet, expected);
|
||||
assert_eq!(
|
||||
decode_close_request(&expected, None),
|
||||
Ok(CloseRequest {
|
||||
token: 0x7896_b6ab_8771_5213,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -120,6 +134,13 @@ fn vector_6_hmac_open_request() {
|
||||
.unwrap();
|
||||
assert_eq!(packet, expected);
|
||||
verify_hmac(b"testkey", &packet, 4).unwrap();
|
||||
assert_eq!(
|
||||
decode_open_request(&expected, Some(b"testkey")),
|
||||
Ok(OpenRequest {
|
||||
params: hmac_params_2s(),
|
||||
close: false,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -154,6 +175,12 @@ fn vector_8_hmac_close_request() {
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(packet, expected);
|
||||
assert_eq!(
|
||||
decode_close_request(&expected, Some(b"testkey")),
|
||||
Ok(CloseRequest {
|
||||
token: 0x4387_e9eb_5d3f_ca59,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -169,6 +196,13 @@ fn vector_9_no_test_open_close_request() {
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(packet, expected);
|
||||
assert_eq!(
|
||||
decode_open_request(&expected, None),
|
||||
Ok(OpenRequest {
|
||||
params: default_params_60s(),
|
||||
close: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -179,6 +213,7 @@ fn vector_10_no_test_open_close_reply() {
|
||||
let reply = decode_open_reply(&packet, None).unwrap();
|
||||
assert_eq!(reply.token, 0);
|
||||
assert_eq!(reply.params, default_params_60s());
|
||||
assert_eq!(encode_open_reply(&reply, None).unwrap(), packet);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user