pub mod address;
pub mod error;
use std::{fmt::Debug, net::SocketAddr};
use bytes::{Buf, BufMut};
use num_enum::TryFromPrimitive;
use super::{
Error,
attributes::{
address::{IpFamily, XAddress},
error::ErrorType,
},
};
#[repr(u16)]
#[derive(Default, Clone, Copy, PartialEq, Eq, Hash, Debug, TryFromPrimitive)]
pub enum AttributeType {
#[default]
Unknown = 0x0000,
MappedAddress = 0x0001,
UserName = 0x0006,
MessageIntegrity = 0x0008,
ErrorCode = 0x0009,
ChannelNumber = 0x000C,
Lifetime = 0x000D,
XorPeerAddress = 0x0012,
Data = 0x0013,
Realm = 0x0014,
Nonce = 0x0015,
XorRelayedAddress = 0x0016,
RequestedAddressFamily = 0x0017,
EvenPort = 0x0018,
RequestedTransport = 0x0019,
DontFragment = 0x001A,
AccessToken = 0x001B,
MessageIntegritySha256 = 0x001C,
PasswordAlgorithm = 0x001D,
UserHash = 0x001E,
XorMappedAddress = 0x0020,
ReservationToken = 0x0022,
Priority = 0x0024,
UseCandidate = 0x0025,
Padding = 0x0026,
ResponsePort = 0x0027,
ConnectionId = 0x002A,
AdditionalAddressFamily = 0x8000,
AddressErrorCode = 0x8001,
PasswordAlgorithms = 0x8002,
AlternateDomain = 0x8003,
Icmp = 0x8004,
Software = 0x8022,
AlternateServer = 0x8023,
TransactionTransmitCounter = 0x8025,
CacheTimeout = 0x8027,
Fingerprint = 0x8028,
IceControlled = 0x8029,
IceControlling = 0x802A,
ResponseOrigin = 0x802B,
OtherAddress = 0x802C,
EcnCheck = 0x802D,
ThirdPartyAuathorization = 0x802E,
MobilityTicket = 0x8030,
}
pub trait Attribute<'a> {
type Error: Debug;
type Item;
const TYPE: AttributeType;
#[allow(unused_variables)]
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, transaction_id: &'a [u8]) {}
fn deserialize(bytes: &'a [u8], transaction_id: &'a [u8]) -> Result<Self::Item, Self::Error>;
}
#[derive(Debug, Clone, Copy)]
pub struct UserName;
impl<'a> Attribute<'a> for UserName {
type Error = Error;
type Item = &'a str;
const TYPE: AttributeType = AttributeType::UserName;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put(value.as_bytes());
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Ok(std::str::from_utf8(bytes)?)
}
}
#[derive(Debug, Clone, Copy)]
pub struct UserHash;
impl<'a> Attribute<'a> for UserHash {
type Error = Error;
type Item = &'a [u8];
const TYPE: AttributeType = AttributeType::UserHash;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put(value);
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Ok(bytes)
}
}
#[derive(Debug, Clone, Copy)]
pub struct Data;
impl<'a> Attribute<'a> for Data {
type Error = Error;
type Item = &'a [u8];
const TYPE: AttributeType = AttributeType::Data;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put(value);
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Ok(bytes)
}
}
#[derive(Debug, Clone, Copy)]
pub struct Realm;
impl<'a> Attribute<'a> for Realm {
type Error = Error;
type Item = &'a str;
const TYPE: AttributeType = AttributeType::Realm;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put(value.as_bytes());
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Ok(std::str::from_utf8(bytes)?)
}
}
#[derive(Debug, Clone, Copy)]
pub struct Nonce;
impl<'a> Attribute<'a> for Nonce {
type Error = Error;
type Item = &'a str;
const TYPE: AttributeType = AttributeType::Nonce;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put(value.as_bytes());
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Ok(std::str::from_utf8(bytes)?)
}
}
#[derive(Debug, Clone, Copy)]
pub struct Software;
impl<'a> Attribute<'a> for Software {
type Error = Error;
type Item = &'a str;
const TYPE: AttributeType = AttributeType::Software;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put(value.as_bytes());
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Ok(std::str::from_utf8(bytes)?)
}
}
#[derive(Debug, Clone, Copy)]
pub struct MessageIntegrity;
impl<'a> Attribute<'a> for MessageIntegrity {
type Error = Error;
type Item = &'a [u8];
const TYPE: AttributeType = AttributeType::MessageIntegrity;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put(value);
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Ok(bytes)
}
}
#[derive(Debug, Clone, Copy)]
pub struct MessageIntegritySha256;
impl<'a> Attribute<'a> for MessageIntegritySha256 {
type Error = Error;
type Item = &'a [u8];
const TYPE: AttributeType = AttributeType::MessageIntegritySha256;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put(value);
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Ok(bytes)
}
}
#[repr(u16)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum PasswordAlgorithm {
Md5 = 0x0001,
Sha256 = 0x0002,
}
impl<'a> Attribute<'a> for PasswordAlgorithm {
type Error = Error;
type Item = Self;
const TYPE: AttributeType = AttributeType::PasswordAlgorithm;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put_u16(value as u16);
bytes.put_u16(0);
}
fn deserialize(mut bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
if bytes.len() < 4 {
return Err(Error::InvalidInput);
}
let ty = match bytes.get_u16() {
0x0001 => Self::Md5,
0x0002 => Self::Sha256,
_ => return Err(Error::InvalidInput),
};
let size = bytes.get_u16();
bytes.advance(super::alignment_32(size as usize));
Ok(ty)
}
}
pub struct PasswordAlgorithms;
impl<'a> Attribute<'a> for PasswordAlgorithms {
type Error = Error;
type Item = Vec<PasswordAlgorithm>;
const TYPE: AttributeType = AttributeType::PasswordAlgorithms;
fn serialize<B: BufMut>(algorithms: Self::Item, bytes: &mut B, transaction_id: &'a [u8]) {
for algorithm in algorithms {
PasswordAlgorithm::serialize(algorithm, bytes, transaction_id);
}
}
fn deserialize(mut bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
let mut algorithms = Vec::new();
loop {
if bytes.len() < 4 {
break;
}
let ty = match bytes.get_u16() {
0x0001 => PasswordAlgorithm::Md5,
0x0002 => PasswordAlgorithm::Sha256,
_ => break,
};
let size = bytes.get_u16();
bytes.advance(super::alignment_32(size as usize));
algorithms.push(ty);
}
Ok(algorithms)
}
}
#[derive(Debug, Clone, Copy)]
pub struct XorPeerAddress;
impl<'a> Attribute<'a> for XorPeerAddress {
type Error = Error;
type Item = SocketAddr;
const TYPE: AttributeType = AttributeType::XorPeerAddress;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, transaction_id: &'a [u8]) {
XAddress::serialize(&value, transaction_id, bytes, true)
}
fn deserialize(bytes: &'a [u8], transaction_id: &'a [u8]) -> Result<Self::Item, Self::Error> {
XAddress::deserialize(bytes, transaction_id, true)
}
}
#[derive(Debug, Clone, Copy)]
pub struct XorRelayedAddress;
impl<'a> Attribute<'a> for XorRelayedAddress {
type Error = Error;
type Item = SocketAddr;
const TYPE: AttributeType = AttributeType::XorRelayedAddress;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, transaction_id: &'a [u8]) {
XAddress::serialize(&value, transaction_id, bytes, true)
}
fn deserialize(bytes: &'a [u8], transaction_id: &'a [u8]) -> Result<Self::Item, Self::Error> {
XAddress::deserialize(bytes, transaction_id, true)
}
}
#[derive(Debug, Clone, Copy)]
pub struct XorMappedAddress;
impl<'a> Attribute<'a> for XorMappedAddress {
type Error = Error;
type Item = SocketAddr;
const TYPE: AttributeType = AttributeType::XorMappedAddress;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, transaction_id: &'a [u8]) {
XAddress::serialize(&value, transaction_id, bytes, true)
}
fn deserialize(bytes: &'a [u8], transaction_id: &'a [u8]) -> Result<Self::Item, Self::Error> {
XAddress::deserialize(bytes, transaction_id, true)
}
}
#[derive(Debug, Clone, Copy)]
pub struct MappedAddress;
impl<'a> Attribute<'a> for MappedAddress {
type Error = Error;
type Item = SocketAddr;
const TYPE: AttributeType = AttributeType::MappedAddress;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, transaction_id: &'a [u8]) {
XAddress::serialize(&value, transaction_id, bytes, false)
}
fn deserialize(bytes: &'a [u8], transaction_id: &'a [u8]) -> Result<Self::Item, Self::Error> {
XAddress::deserialize(bytes, transaction_id, false)
}
}
#[derive(Debug, Clone, Copy)]
pub struct ResponseOrigin;
impl<'a> Attribute<'a> for ResponseOrigin {
type Error = Error;
type Item = SocketAddr;
const TYPE: AttributeType = AttributeType::ResponseOrigin;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, transaction_id: &'a [u8]) {
XAddress::serialize(&value, transaction_id, bytes, false)
}
fn deserialize(bytes: &'a [u8], transaction_id: &'a [u8]) -> Result<Self::Item, Self::Error> {
XAddress::deserialize(bytes, transaction_id, false)
}
}
#[derive(Debug, Clone, Copy)]
pub struct ErrorCode<'a> {
pub code: u16,
pub message: &'a str,
}
impl<'a> Attribute<'a> for ErrorCode<'a> {
type Error = Error;
type Item = Self;
const TYPE: AttributeType = AttributeType::ErrorCode;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
value.serialize(bytes);
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Self::try_from(bytes)
}
}
impl From<ErrorType> for ErrorCode<'_> {
fn from(value: ErrorType) -> Self {
Self {
code: value as u16,
message: value.into(),
}
}
}
impl ErrorCode<'_> {
pub fn serialize<B: BufMut>(self, bytes: &mut B) {
bytes.put_u16(0x0000);
bytes.put_u16(self.code);
bytes.put(self.message.as_bytes());
}
}
impl<'a> TryFrom<&'a [u8]> for ErrorCode<'a> {
type Error = Error;
fn try_from(packet: &'a [u8]) -> Result<Self, Self::Error> {
if packet.len() < 4 {
return Err(Error::InvalidInput);
}
if u16::from_be_bytes(packet[..2].try_into()?) != 0x0000 {
return Err(Error::InvalidInput);
}
Ok(Self {
code: u16::from_be_bytes(packet[2..4].try_into()?),
message: std::str::from_utf8(&packet[4..])?,
})
}
}
impl Eq for ErrorCode<'_> {}
impl PartialEq for ErrorCode<'_> {
fn eq(&self, other: &Self) -> bool {
self.code == other.code
}
}
#[derive(Debug, Clone, Copy)]
pub struct Lifetime;
impl<'a> Attribute<'a> for Lifetime {
type Error = Error;
type Item = u32;
const TYPE: AttributeType = AttributeType::Lifetime;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put_u32(value)
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Ok(u32::from_be_bytes(bytes.try_into()?))
}
}
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
pub enum RequestedTransport {
Tcp = 0x06000000,
Udp = 0x11000000,
}
impl<'a> Attribute<'a> for RequestedTransport {
type Error = Error;
type Item = Self;
const TYPE: AttributeType = AttributeType::RequestedTransport;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put_u32(value as u32)
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Self::try_from(u32::from_be_bytes(bytes.try_into()?)).map_err(|_| Error::InvalidInput)
}
}
#[derive(Debug, Clone, Copy)]
pub struct Fingerprint;
impl<'a> Attribute<'a> for Fingerprint {
type Error = Error;
type Item = u32;
const TYPE: AttributeType = AttributeType::Fingerprint;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put_u32(value)
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Ok(u32::from_be_bytes(bytes.try_into()?))
}
}
#[derive(Debug, Clone, Copy)]
pub struct ChannelNumber;
impl<'a> Attribute<'a> for ChannelNumber {
type Error = Error;
type Item = u16;
const TYPE: AttributeType = AttributeType::ChannelNumber;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put_u16(value)
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Ok(u16::from_be_bytes(bytes[..2].try_into()?))
}
}
#[derive(Debug, Clone, Copy)]
pub struct IceControlling;
impl<'a> Attribute<'a> for IceControlling {
type Error = Error;
type Item = u64;
const TYPE: AttributeType = AttributeType::IceControlling;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put_u64(value)
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Ok(u64::from_be_bytes(bytes.try_into()?))
}
}
#[derive(Debug, Clone, Copy)]
pub struct UseCandidate;
impl<'a> Attribute<'a> for UseCandidate {
type Error = Error;
type Item = ();
const TYPE: AttributeType = AttributeType::UseCandidate;
fn serialize<B: BufMut>(_: Self::Item, _: &mut B, _: &'a [u8]) {}
fn deserialize(_: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Ok(())
}
}
#[derive(Debug, Clone, Copy)]
pub struct IceControlled;
impl<'a> Attribute<'a> for IceControlled {
type Error = Error;
type Item = u64;
const TYPE: AttributeType = AttributeType::IceControlled;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put_u64(value)
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Ok(u64::from_be_bytes(bytes.try_into()?))
}
}
#[derive(Debug, Clone, Copy)]
pub struct Priority;
impl<'a> Attribute<'a> for Priority {
type Error = Error;
type Item = u32;
const TYPE: AttributeType = AttributeType::Priority;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put_u32(value)
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Ok(u32::from_be_bytes(bytes.try_into()?))
}
}
#[derive(Debug, Clone, Copy)]
pub struct ReservationToken;
impl<'a> Attribute<'a> for ReservationToken {
type Error = Error;
type Item = u64;
const TYPE: AttributeType = AttributeType::ReservationToken;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put_u64(value)
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Ok(u64::from_be_bytes(bytes.try_into()?))
}
}
#[derive(Debug, Clone, Copy)]
pub struct EvenPort;
impl<'a> Attribute<'a> for EvenPort {
type Error = Error;
type Item = bool;
const TYPE: AttributeType = AttributeType::EvenPort;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put_u8(if value { 0b10000000 } else { 0b00000000 })
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
if bytes.is_empty() {
return Err(Error::InvalidInput);
}
Ok(bytes[0] == 0b10000000)
}
}
#[derive(Debug, Clone, Copy)]
pub struct RequestedAddressFamily;
impl<'a> Attribute<'a> for RequestedAddressFamily {
type Error = Error;
type Item = IpFamily;
const TYPE: AttributeType = AttributeType::RequestedAddressFamily;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put_u8(value as u8)
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
if bytes.is_empty() {
return Err(Error::InvalidInput);
}
IpFamily::try_from(bytes[0]).map_err(|_| Error::InvalidInput)
}
}
#[derive(Debug, Clone, Copy)]
pub struct AdditionalAddressFamily;
impl<'a> Attribute<'a> for AdditionalAddressFamily {
type Error = Error;
type Item = IpFamily;
const TYPE: AttributeType = AttributeType::AdditionalAddressFamily;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put_u8(value as u8)
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
if bytes.is_empty() {
return Err(Error::InvalidInput);
}
IpFamily::try_from(bytes[0]).map_err(|_| Error::InvalidInput)
}
}
#[derive(Debug, Clone, Copy)]
pub struct DontFragment;
impl<'a> Attribute<'a> for DontFragment {
type Error = Error;
type Item = ();
const TYPE: AttributeType = AttributeType::DontFragment;
fn deserialize(_: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Ok(())
}
}
#[derive(Debug, Clone, Copy)]
pub struct ThirdPartyAuathorization;
impl<'a> Attribute<'a> for ThirdPartyAuathorization {
type Error = Error;
type Item = &'a str;
const TYPE: AttributeType = AttributeType::ThirdPartyAuathorization;
fn serialize<B: BufMut>(value: Self::Item, bytes: &mut B, _: &'a [u8]) {
bytes.put(value.as_bytes());
}
fn deserialize(bytes: &'a [u8], _: &'a [u8]) -> Result<Self::Item, Self::Error> {
Ok(std::str::from_utf8(bytes)?)
}
}