From 9d93d02b4820e081dc93fca6b8fbe35927f6ae55 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 21 Sep 2023 16:31:11 +1000 Subject: [PATCH] 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 :partying_face: --- rust/Cargo.lock | 4 +- rust/relay/Cargo.toml | 2 +- rust/relay/src/lib.rs | 4 +- rust/relay/src/net_ext.rs | 2 +- rust/relay/src/rfc8656.rs | 320 ------------------------ rust/relay/src/server.rs | 36 +-- rust/relay/src/server/client_message.rs | 37 +-- rust/relay/src/stun_codec_ext.rs | 41 --- rust/relay/tests/regression.rs | 25 +- 9 files changed, 54 insertions(+), 417 deletions(-) delete mode 100644 rust/relay/src/rfc8656.rs delete mode 100644 rust/relay/src/stun_codec_ext.rs diff --git a/rust/Cargo.lock b/rust/Cargo.lock index a759c52f9..2768f6e00 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -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", diff --git a/rust/relay/Cargo.toml b/rust/relay/Cargo.toml index 9060242ba..62afb8f70 100644 --- a/rust/relay/Cargo.toml +++ b/rust/relay/Cargo.toml @@ -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"] } diff --git a/rust/relay/src/lib.rs b/rust/relay/src/lib.rs index a3c0a09fa..ba096dd54 100644 --- a/rust/relay/src/lib.rs +++ b/rust/relay/src/lib.rs @@ -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; diff --git a/rust/relay/src/net_ext.rs b/rust/relay/src/net_ext.rs index 8807a2664..09df59293 100644 --- a/rust/relay/src/net_ext.rs +++ b/rust/relay/src/net_ext.rs @@ -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; diff --git a/rust/relay/src/rfc8656.rs b/rust/relay/src/rfc8656.rs deleted file mode 100644 index aa613be55..000000000 --- a/rust/relay/src/rfc8656.rs +++ /dev/null @@ -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 { - track!(self.0.decode(buf, eos)) - } - - fn finish_decoding(&mut self) -> Result { - 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 { - 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 { - 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 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 { - self.family.decode(buf, eos) - } - - fn finish_decoding(&mut self) -> Result { - 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 { - 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 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); - } -} diff --git a/rust/relay/src/server.rs b/rust/relay/src/server.rs index df120878f..957440314 100644 --- a/rust/relay/src/server.rs +++ b/rust/relay/src/server.rs @@ -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, 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 { let mut message = Message::new(MessageClass::SuccessResponse, REFRESH, transaction_id); - message.add_attribute(effective_lifetime.into()); + message.add_attribute(effective_lifetime); message } diff --git a/rust/relay/src/server/client_message.rs b/rust/relay/src/server/client_message.rs index 227d8ad25..7d27a0466 100644 --- a/rust/relay/src/server/client_message.rs +++ b/rust/relay/src/server/client_message.rs @@ -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::::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::::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::::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::::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 { let mut message = Message::new(MessageClass::ErrorResponse, method, transaction_id); - message.add_attribute(error_code.into()); + message.add_attribute(error_code); message } diff --git a/rust/relay/src/stun_codec_ext.rs b/rust/relay/src/stun_codec_ext.rs deleted file mode 100644 index 5f40ef6f4..000000000 --- a/rust/relay/src/stun_codec_ext.rs +++ /dev/null @@ -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", - } - } -} diff --git a/rust/relay/tests/regression.rs b/rust/relay/tests/regression.rs index 0a4bf8975..35925a91f 100644 --- a/rust/relay/tests/regression.rs +++ b/rust/relay/tests/regression.rs @@ -571,7 +571,7 @@ fn binding_response( ) -> Message { let mut message = Message::::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 { let mut message = Message::::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 { let mut message = Message::::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 { let mut message = Message::::new(MessageClass::SuccessResponse, REFRESH, transaction_id); - message.add_attribute(lifetime.into()); + message.add_attribute(lifetime); message }