deps(relay): bump to stun-codec 0.3.3 (#2088)

I've opened several PRs upstream for code that was missing in
`stun-codec` for our purposes. Those have been accepted and released, so
we can bump to that version now and remove that code.

Related: https://github.com/sile/stun_codec/pull/14.
Related: https://github.com/sile/stun_codec/pull/15.
Related: https://github.com/sile/stun_codec/pull/16.
Related: https://github.com/sile/stun_codec/pull/17.

A big thanks to @sile for the crate and being responsive maintainer
🥳
This commit is contained in:
Thomas Eizinger
2023-09-21 16:31:11 +10:00
committed by GitHub
parent e635ee3774
commit 9d93d02b48
9 changed files with 54 additions and 417 deletions

4
rust/Cargo.lock generated
View File

@@ -3327,9 +3327,9 @@ dependencies = [
[[package]]
name = "stun_codec"
version = "0.3.2"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4089f66744a63bc909eed6ece965b493030ca896f21c24d9f26c659926c7e05b"
checksum = "1eff17d3ec0a1d210cbe5c870857c306823417f468bebde28e8c29970f6a1da4"
dependencies = [
"bytecodec",
"byteorder",

View File

@@ -11,7 +11,7 @@ futures = "0.3.28"
hex = "0.4.3"
hex-literal = "0.4.1"
rand = "0.8.5"
stun_codec = "0.3.1"
stun_codec = "0.3.3"
tokio = { version = "1.32.0", features = ["macros", "rt-multi-thread", "net", "time"] }
tracing = { version = "0.1.37", features = ["log"] }
tracing-subscriber = { version = "0.3", features = ["env-filter", "json", "fmt"] }

View File

@@ -1,10 +1,8 @@
mod allocation;
mod auth;
mod net_ext;
mod rfc8656;
mod server;
mod sleep;
mod stun_codec_ext;
mod time_events;
mod udp_socket;
@@ -14,12 +12,12 @@ pub mod proptest;
pub use allocation::Allocation;
pub use net_ext::{IpAddrExt, SocketAddrExt};
pub use rfc8656::AddressFamily;
pub use server::{
Allocate, AllocationId, Attribute, Binding, ChannelBind, ChannelData, ClientMessage, Command,
CreatePermission, Refresh, Server,
};
pub use sleep::Sleep;
pub use stun_codec::rfc8656::attributes::AddressFamily;
pub use udp_socket::UdpSocket;
pub(crate) use time_events::TimeEvents;

View File

@@ -1,5 +1,5 @@
use crate::rfc8656::AddressFamily;
use std::net::{IpAddr, SocketAddr};
use stun_codec::rfc8656::attributes::AddressFamily;
pub trait IpAddrExt {
fn family(&self) -> AddressFamily;

View File

@@ -1,320 +0,0 @@
//! Additions to the `stun-codec` crate for RFC 8656.
//
// TODO: Upstream this to `stun-codec`.
use bytecodec::fixnum::{U32beDecoder, U32beEncoder};
use bytecodec::{ByteCount, Decode, Encode, Eos, ErrorKind, Result, SizedEncode, TryTaggedDecode};
use std::fmt;
use stun_codec::rfc5389::attributes::ErrorCode;
use stun_codec::{Attribute, AttributeType};
use trackable::{track, track_panic};
macro_rules! impl_decode {
($decoder:ty, $item:ident, $and_then:expr) => {
impl Decode for $decoder {
type Item = $item;
fn decode(&mut self, buf: &[u8], eos: Eos) -> Result<usize> {
track!(self.0.decode(buf, eos))
}
fn finish_decoding(&mut self) -> Result<Self::Item> {
track!(self.0.finish_decoding()).and_then($and_then)
}
fn requiring_bytes(&self) -> ByteCount {
self.0.requiring_bytes()
}
fn is_idle(&self) -> bool {
self.0.is_idle()
}
}
impl TryTaggedDecode for $decoder {
type Tag = AttributeType;
fn try_start_decoding(&mut self, attr_type: Self::Tag) -> Result<bool> {
Ok(attr_type.as_u16() == $item::CODEPOINT)
}
}
};
}
macro_rules! impl_encode {
($encoder:ty, $item:ty, $map_from:expr) => {
impl Encode for $encoder {
type Item = $item;
fn encode(&mut self, buf: &mut [u8], eos: Eos) -> Result<usize> {
track!(self.0.encode(buf, eos))
}
fn start_encoding(&mut self, item: Self::Item) -> Result<()> {
track!(self.0.start_encoding($map_from(item).into()))
}
fn requiring_bytes(&self) -> ByteCount {
self.0.requiring_bytes()
}
fn is_idle(&self) -> bool {
self.0.is_idle()
}
}
impl SizedEncode for $encoder {
fn exact_requiring_bytes(&self) -> u64 {
self.0.exact_requiring_bytes()
}
}
};
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct PeerAddressFamilyMismatch;
impl PeerAddressFamilyMismatch {
/// The codepoint of the error.
pub const CODEPOINT: u16 = 443;
}
impl From<PeerAddressFamilyMismatch> for ErrorCode {
fn from(_: PeerAddressFamilyMismatch) -> Self {
ErrorCode::new(
PeerAddressFamilyMismatch::CODEPOINT,
"Peer Address Family Mismatch".to_owned(),
)
.expect("never fails")
}
}
/// The family of an IP address, either IPv4 or IPv6.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum AddressFamily {
V4,
V6,
}
impl fmt::Display for AddressFamily {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AddressFamily::V4 => write!(f, "IPv4"),
AddressFamily::V6 => write!(f, "IPv6"),
}
}
}
const FAMILY_IPV4: u8 = 1;
const FAMILY_IPV6: u8 = 2;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RequestedAddressFamily(AddressFamily);
impl RequestedAddressFamily {
/// The codepoint of the type of the attribute.
pub const CODEPOINT: u16 = 0x0017;
/// Makes a new `RequestedAddressFamily` instance.
pub fn new(fam: AddressFamily) -> Self {
RequestedAddressFamily(fam)
}
/// Returns the requested address family.
pub fn address_family(&self) -> AddressFamily {
self.0
}
}
impl Attribute for RequestedAddressFamily {
type Decoder = RequestedAddressFamilyDecoder;
type Encoder = RequestedAddressFamilyEncoder;
fn get_type(&self) -> AttributeType {
AttributeType::new(Self::CODEPOINT)
}
}
/// [`RequestedAddressFamily`] decoder.
#[derive(Debug, Default)]
pub struct RequestedAddressFamilyDecoder(AddressFamilyDecoder);
impl RequestedAddressFamilyDecoder {
/// Makes a new `RequestedAddressFamilyDecoder` instance.
pub fn new() -> Self {
Self::default()
}
}
impl_decode!(
RequestedAddressFamilyDecoder,
RequestedAddressFamily,
|item| Ok(RequestedAddressFamily(item))
);
/// [`RequestedAddressFamily`] encoder.
#[derive(Debug, Default)]
pub struct RequestedAddressFamilyEncoder(AddressFamilyEncoder);
impl RequestedAddressFamilyEncoder {
/// Makes a new `RequestedAddressFamilyEncoder` instance.
pub fn new() -> Self {
Self::default()
}
}
impl_encode!(
RequestedAddressFamilyEncoder,
RequestedAddressFamily,
|item: Self::Item| { item.0 }
);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct AdditionalAddressFamily(AddressFamily);
impl AdditionalAddressFamily {
/// The codepoint of the type of the attribute.
pub const CODEPOINT: u16 = 0x8000;
/// Makes a new `AdditionalAddressFamily` instance.
pub fn new(fam: AddressFamily) -> Self {
AdditionalAddressFamily(fam)
}
/// Returns the requested address family.
pub fn address_family(&self) -> AddressFamily {
self.0
}
}
impl Attribute for AdditionalAddressFamily {
type Decoder = AdditionalAddressFamilyDecoder;
type Encoder = AdditionalAddressFamilyEncoder;
fn get_type(&self) -> AttributeType {
AttributeType::new(Self::CODEPOINT)
}
}
/// [`AdditionalAddressFamily`] decoder.
#[derive(Debug, Default)]
pub struct AdditionalAddressFamilyDecoder(AddressFamilyDecoder);
impl_decode!(
AdditionalAddressFamilyDecoder,
AdditionalAddressFamily,
|item| Ok(AdditionalAddressFamily(item))
);
/// [`AdditionalAddressFamily`] encoder.
#[derive(Debug, Default)]
pub struct AdditionalAddressFamilyEncoder(AddressFamilyEncoder);
impl_encode!(
AdditionalAddressFamilyEncoder,
AdditionalAddressFamily,
|item: Self::Item| { item.0 }
);
/// [`RequestedAddressFamily`] decoder.
#[derive(Debug, Default)]
pub struct AddressFamilyDecoder {
family: U32beDecoder,
}
impl Decode for AddressFamilyDecoder {
type Item = AddressFamily;
fn decode(&mut self, buf: &[u8], eos: Eos) -> Result<usize> {
self.family.decode(buf, eos)
}
fn finish_decoding(&mut self) -> Result<Self::Item> {
let [fam, _, _, _] = self.family.finish_decoding()?.to_be_bytes();
match fam {
FAMILY_IPV4 => Ok(AddressFamily::V4),
FAMILY_IPV6 => Ok(AddressFamily::V6),
family => track_panic!(
ErrorKind::InvalidInput,
"Unknown address family: {}",
family
),
}
}
fn requiring_bytes(&self) -> ByteCount {
self.family.requiring_bytes()
}
fn is_idle(&self) -> bool {
self.family.is_idle()
}
}
/// [`RequestedAddressFamily`] decoder.
#[derive(Debug, Default)]
pub struct AddressFamilyEncoder {
family: U32beEncoder,
}
impl Encode for AddressFamilyEncoder {
type Item = AddressFamily;
fn encode(&mut self, buf: &mut [u8], eos: Eos) -> Result<usize> {
self.family.encode(buf, eos)
}
fn start_encoding(&mut self, item: Self::Item) -> Result<()> {
let fam_byte = match item {
AddressFamily::V4 => FAMILY_IPV4,
AddressFamily::V6 => FAMILY_IPV6,
};
let bytes = [fam_byte, 0, 0, 0];
self.family.start_encoding(u32::from_be_bytes(bytes))
}
fn requiring_bytes(&self) -> ByteCount {
ByteCount::Finite(self.exact_requiring_bytes())
}
}
impl SizedEncode for AddressFamilyEncoder {
fn exact_requiring_bytes(&self) -> u64 {
self.family.exact_requiring_bytes()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct AddressFamilyNotSupported;
impl AddressFamilyNotSupported {
/// The codepoint of the error.
pub const CODEPOINT: u16 = 440;
}
impl From<AddressFamilyNotSupported> for ErrorCode {
fn from(_: AddressFamilyNotSupported) -> Self {
ErrorCode::new(
AddressFamilyNotSupported::CODEPOINT,
"Address Family not Supported".to_string(),
)
.expect("never fails")
}
}
#[cfg(test)]
mod tests {
use super::*;
use bytecodec::{DecodeExt, EncodeExt};
#[test]
fn address_family_encoder_works() {
let mut encoder = AddressFamilyEncoder::default();
let bytes = encoder.encode_into_bytes(AddressFamily::V4).unwrap();
assert_eq!(bytes, [1, 0, 0, 0]);
let bytes = encoder.encode_into_bytes(AddressFamily::V6).unwrap();
assert_eq!(bytes, [2, 0, 0, 0]);
}
#[test]
fn address_family_decoder_works() {
let mut decoder = AddressFamilyDecoder::default();
let fam = decoder.decode_from_bytes(&[1, 0, 0, 0]).unwrap();
assert_eq!(fam, AddressFamily::V4);
let fam = decoder.decode_from_bytes(&[2, 0, 0, 0]).unwrap();
assert_eq!(fam, AddressFamily::V6);
}
}

View File

@@ -8,11 +8,6 @@ pub use crate::server::client_message::{
use crate::auth::{MessageIntegrityExt, Nonces, FIREZONE};
use crate::net_ext::IpAddrExt;
use crate::rfc8656::{
AdditionalAddressFamily, AddressFamily, AddressFamilyNotSupported, PeerAddressFamilyMismatch,
RequestedAddressFamily,
};
use crate::stun_codec_ext::{MessageClassExt, MethodExt};
use crate::{IpStack, TimeEvents};
use anyhow::Result;
use bytecodec::EncodeExt;
@@ -34,6 +29,10 @@ use stun_codec::rfc5766::attributes::{
};
use stun_codec::rfc5766::errors::{AllocationMismatch, InsufficientCapacity};
use stun_codec::rfc5766::methods::{ALLOCATE, CHANNEL_BIND, CREATE_PERMISSION, REFRESH};
use stun_codec::rfc8656::attributes::{
AdditionalAddressFamily, AddressFamily, RequestedAddressFamily,
};
use stun_codec::rfc8656::errors::{AddressFamilyNotSupported, PeerAddressFamilyMismatch};
use stun_codec::{Message, MessageClass, MessageEncoder, Method, TransactionId};
use tracing::{field, log, Span};
use uuid::Uuid;
@@ -291,8 +290,8 @@ where
self.add_nonce(new_nonce);
error_response.add_attribute(Nonce::new(new_nonce.to_string()).unwrap().into());
error_response.add_attribute((*FIREZONE).clone().into());
error_response.add_attribute(Nonce::new(new_nonce.to_string()).unwrap());
error_response.add_attribute((*FIREZONE).clone());
}
self.send_message(error_response, sender);
@@ -421,7 +420,7 @@ where
BINDING,
message.transaction_id(),
);
message.add_attribute(XorMappedAddress::new(sender).into());
message.add_attribute(XorMappedAddress::new(sender));
self.send_message(message, sender);
}
@@ -476,16 +475,19 @@ where
let port = allocation.port;
message
.add_attribute(XorRelayAddress::new(SocketAddr::new(first_relay_address, port)).into());
message.add_attribute(XorRelayAddress::new(SocketAddr::new(
first_relay_address,
port,
)));
if let Some(second_relay_address) = maybe_second_relay_addr {
message.add_attribute(
XorRelayAddress::new(SocketAddr::new(second_relay_address, port)).into(),
);
message.add_attribute(XorRelayAddress::new(SocketAddr::new(
second_relay_address,
port,
)));
}
message.add_attribute(XorMappedAddress::new(sender).into());
message.add_attribute(effective_lifetime.clone().into());
message.add_attribute(XorMappedAddress::new(sender));
message.add_attribute(effective_lifetime.clone());
let wake_deadline = self.time_events.add(
allocation.expires_at,
@@ -822,7 +824,7 @@ where
fn send_message(&mut self, message: Message<Attribute>, recipient: SocketAddr) {
let method = message.method();
let class = message.class();
tracing::trace!(target: "relay", method = %message.method().as_str(), class = %message.class().as_str(), "Sending message");
tracing::trace!(target: "relay", method = %message.method(), class = %message.class(), "Sending message");
let Ok(bytes) = self.encoder.encode_into_bytes(message) else {
debug_assert!(false, "Encoding should never fail");
@@ -917,7 +919,7 @@ fn refresh_success_response(
transaction_id: TransactionId,
) -> Message<Attribute> {
let mut message = Message::new(MessageClass::SuccessResponse, REFRESH, transaction_id);
message.add_attribute(effective_lifetime.into());
message.add_attribute(effective_lifetime);
message
}

View File

@@ -1,8 +1,6 @@
use crate::auth::{generate_password, split_username, systemtime_from_unix, FIREZONE};
use crate::rfc8656::{AdditionalAddressFamily, AddressFamily, RequestedAddressFamily};
use crate::server::channel_data::ChannelData;
use crate::server::UDP_TRANSPORT;
use crate::stun_codec_ext::MethodExt;
use crate::Attribute;
use bytecodec::DecodeExt;
use std::io;
@@ -14,6 +12,9 @@ use stun_codec::rfc5766::attributes::{
ChannelNumber, Lifetime, RequestedTransport, XorPeerAddress,
};
use stun_codec::rfc5766::methods::{ALLOCATE, CHANNEL_BIND, CREATE_PERMISSION, REFRESH};
use stun_codec::rfc8656::attributes::{
AdditionalAddressFamily, AddressFamily, RequestedAddressFamily,
};
use stun_codec::{Message, MessageClass, Method, TransactionId};
use uuid::Uuid;
@@ -45,7 +46,7 @@ impl Decoder {
let transaction_id = broken_message.transaction_id();
let error = broken_message.error().clone();
tracing::debug!(transaction_id = %hex::encode(transaction_id.as_bytes()), method = %method.as_str(), %error, "Failed to decode attributes of message");
tracing::debug!(transaction_id = %hex::encode(transaction_id.as_bytes()), %method, %error, "Failed to decode attributes of message");
let error_code = ErrorCode::from(error);
@@ -207,10 +208,10 @@ impl Allocate {
let mut message =
Message::<Attribute>::new(MessageClass::Request, ALLOCATE, transaction_id);
message.add_attribute(requested_transport.clone().into());
message.add_attribute(requested_transport.clone());
if let Some(lifetime) = &lifetime {
message.add_attribute(lifetime.clone().into());
message.add_attribute(lifetime.clone());
}
Self {
@@ -238,16 +239,16 @@ impl Allocate {
let mut message =
Message::<Attribute>::new(MessageClass::Request, ALLOCATE, transaction_id);
message.add_attribute(requested_transport.clone().into());
message.add_attribute(username.clone().into());
message.add_attribute(nonce.clone().into());
message.add_attribute(requested_transport.clone());
message.add_attribute(username.clone());
message.add_attribute(nonce.clone());
if let Some(requested_address_family) = requested_address_family {
message.add_attribute(requested_address_family.into());
message.add_attribute(requested_address_family);
}
if let Some(lifetime) = &lifetime {
message.add_attribute(lifetime.clone().into());
message.add_attribute(lifetime.clone());
}
let (expiry, salt) = split_username(username.name()).expect("a valid username");
@@ -338,11 +339,11 @@ impl Refresh {
let nonce = Nonce::new(nonce.as_hyphenated().to_string()).expect("len(uuid) < 128");
let mut message = Message::<Attribute>::new(MessageClass::Request, REFRESH, transaction_id);
message.add_attribute(username.clone().into());
message.add_attribute(nonce.clone().into());
message.add_attribute(username.clone());
message.add_attribute(nonce.clone());
if let Some(lifetime) = &lifetime {
message.add_attribute(lifetime.clone().into());
message.add_attribute(lifetime.clone());
}
let (expiry, salt) = split_username(username.name()).expect("a valid username");
@@ -422,10 +423,10 @@ impl ChannelBind {
let mut message =
Message::<Attribute>::new(MessageClass::Request, CHANNEL_BIND, transaction_id);
message.add_attribute(username.clone().into());
message.add_attribute(channel_number.into());
message.add_attribute(xor_peer_address.clone().into());
message.add_attribute(nonce.clone().into());
message.add_attribute(username.clone());
message.add_attribute(channel_number);
message.add_attribute(xor_peer_address.clone());
message.add_attribute(nonce.clone());
let (expiry, salt) = split_username(username.name()).expect("a valid username");
let expiry_systemtime = systemtime_from_unix(expiry);
@@ -559,7 +560,7 @@ fn error_response(
error_code: ErrorCode,
) -> Message<Attribute> {
let mut message = Message::new(MessageClass::ErrorResponse, method, transaction_id);
message.add_attribute(error_code.into());
message.add_attribute(error_code);
message
}

View File

@@ -1,41 +0,0 @@
use stun_codec::rfc5389::methods::BINDING;
use stun_codec::rfc5766::methods::{
ALLOCATE, CHANNEL_BIND, CREATE_PERMISSION, DATA, REFRESH, SEND,
};
use stun_codec::{MessageClass, Method};
// TODO: Upstream as `fmt::Display` impls
pub trait MethodExt {
fn as_str(&self) -> &'static str;
}
pub trait MessageClassExt {
fn as_str(&self) -> &'static str;
}
impl MethodExt for Method {
fn as_str(&self) -> &'static str {
match *self {
BINDING => "binding",
ALLOCATE => "allocate",
REFRESH => "refresh",
CHANNEL_BIND => "channel bind",
CREATE_PERMISSION => "create permission",
DATA => "data",
SEND => "send",
_ => "unknown",
}
}
}
impl MessageClassExt for MessageClass {
fn as_str(&self) -> &'static str {
match self {
MessageClass::Request => "request",
MessageClass::Indication => "indication",
MessageClass::SuccessResponse => "success response",
MessageClass::ErrorResponse => "error response",
}
}
}

View File

@@ -571,7 +571,7 @@ fn binding_response(
) -> Message<Attribute> {
let mut message =
Message::<Attribute>::new(MessageClass::SuccessResponse, BINDING, transaction_id);
message.add_attribute(XorMappedAddress::new(address.into()).into());
message.add_attribute(XorMappedAddress::new(address.into()));
message
}
@@ -585,11 +585,12 @@ fn allocate_response(
) -> Message<Attribute> {
let mut message =
Message::<Attribute>::new(MessageClass::SuccessResponse, ALLOCATE, transaction_id);
message.add_attribute(
XorRelayAddress::new(SocketAddr::new(public_relay_addr.into(), port)).into(),
);
message.add_attribute(XorMappedAddress::new(source.into()).into());
message.add_attribute(lifetime.clone().into());
message.add_attribute(XorRelayAddress::new(SocketAddr::new(
public_relay_addr.into(),
port,
)));
message.add_attribute(XorMappedAddress::new(source.into()));
message.add_attribute(lifetime.clone());
message
}
@@ -600,13 +601,9 @@ fn unauthorized_allocate_response(
) -> Message<Attribute> {
let mut message =
Message::<Attribute>::new(MessageClass::ErrorResponse, ALLOCATE, transaction_id);
message.add_attribute(ErrorCode::from(Unauthorized).into());
message.add_attribute(
Nonce::new(nonce.as_hyphenated().to_string())
.unwrap()
.into(),
);
message.add_attribute(Realm::new("firezone".to_owned()).unwrap().into());
message.add_attribute(ErrorCode::from(Unauthorized));
message.add_attribute(Nonce::new(nonce.as_hyphenated().to_string()).unwrap());
message.add_attribute(Realm::new("firezone".to_owned()).unwrap());
message
}
@@ -614,7 +611,7 @@ fn unauthorized_allocate_response(
fn refresh_response(transaction_id: TransactionId, lifetime: Lifetime) -> Message<Attribute> {
let mut message =
Message::<Attribute>::new(MessageClass::SuccessResponse, REFRESH, transaction_id);
message.add_attribute(lifetime.into());
message.add_attribute(lifetime);
message
}