Skip to main content

Module attribute

Module attribute 

Source
Expand description

STUN Attributes

Provides implementations for generating, parsing and manipulating STUN attributes as specified in one of RFC8489, RFC5389, or RFC3489.

There are two levels of attribute implementations:

  1. A generic RawAttribute which contains the AttributeHeader (type and length) and the byte sequence of data (either borrowed or owned). Parsing a Message will only perform zerocopy parsing to this level. Any attribute-specific restrictions on the actual contents of the data should be performed by concrete attribute implementations.
  2. Concrete implementations based on implementing Attribute, and AttributeStaticType. These concrete attribute implementations have much more ergonomic API specific to their particular needs. A concrete attribute implementation may have restrictions on what data is allowed to be parsed from a RawAttribute that should return errors when calling AttributeFromRaw::from_raw_ref.

§Examples

§Parse and write an already defined Attribute

use stun_types::attribute::{RawAttribute, Software};
let software_name = "stun-types";
let software = Software::new(software_name).unwrap();
assert_eq!(software.software(), software_name);

let attribute_data = [
    0x80, 0x22, 0x00, 0x0a, // Attribute type (0x8022: Software) and length (0x000a)
    0x73, 0x74, 0x75, 0x6E, // s t u n
    0x2D, 0x74, 0x79, 0x70, // - t y p
    0x65, 0x73, 0x00, 0x00  // e s
];

let raw = RawAttribute::from(&software);
assert_eq!(raw.to_bytes(), attribute_data);

// Can also parse data into a typed attribute as needed
let software = Software::from_raw(raw).unwrap();
assert_eq!(software.software(), software_name);

§Defining your own Attribute

use byteorder::{BigEndian, ByteOrder};
use stun_types::attribute::{AttributeType, RawAttribute};
use stun_types::message::StunParseError;
#[derive(Debug)]
struct MyAttribute {
   value: u32,
}
impl AttributeStaticType for MyAttribute {
   const TYPE: AttributeType = AttributeType::new(0x8851);
}
impl Attribute for MyAttribute {
   fn get_type(&self) -> AttributeType {
       Self::TYPE
   }

   fn length(&self) -> u16 {
       4
   }
}
impl AttributeWrite for MyAttribute {
    fn to_raw(&self) -> RawAttribute<'_> {
        let mut ret = [0; 4];
        BigEndian::write_u32(&mut ret, self.value);
        RawAttribute::new(MyAttribute::TYPE, &ret).into_owned()
    }
    fn write_into_unchecked(&self, dest: &mut [u8]) {
        self.write_header_unchecked(dest);
        BigEndian::write_u32(&mut dest[4..], self.value);
    }
}
impl AttributeFromRaw<'_> for MyAttribute {
    fn from_raw_ref(raw: &RawAttribute) -> Result<Self, StunParseError>
    where
        Self: Sized,
    {
        raw.check_type_and_len(Self::TYPE, 4..=4)?;
        let value = BigEndian::read_u32(&raw.value);
        Ok(Self {
            value,
        })
    }
}

// Optional: if you want this attribute to be displayed nicely when the corresponding
// `RawAttribute` (based on `AttributeType`) is formatted using `RawAttribute`'s `Display`
// implementation.
impl core::fmt::Display for MyAttribute {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "MyAttribute: {}", self.value)
    }
}
stun_types::attribute_display!(MyAttribute);
MyAttribute::TYPE.add_name("MY-ATTRIBUTE");

let my_attr = MyAttribute { value: 0x4729 };
let raw = RawAttribute::from(&my_attr);

let attribute_data = [
    0x88, 0x51, 0x00, 0x04,
    0x00, 0x00, 0x47, 0x29,
];
assert_eq!(raw.to_bytes(), attribute_data);

let my_attr = MyAttribute::from_raw(raw).unwrap();
assert_eq!(my_attr.value, 0x4729);

Structs§

AlternateDomain
The AlternateDomain Attribute.
AlternateServer
The AlternateServer Attribute.
AttributeHeader
Structure for holding the header of a STUN attribute.
AttributeType
The type of an Attribute in a STUN Message.
ErrorCode
The ErrorCode Attribute.
Fingerprint
The Fingerprint Attribute.
MappedSocketAddr
Helper struct for SocketAddrs that are stored as an attribute.
MessageIntegrity
The MessageIntegrity Attribute.
MessageIntegritySha256
The MessageIntegritySha256 Attribute.
Nonce
The Nonce Attribute.
PasswordAlgorithm
The PasswordAlgorithm Attribute.
PasswordAlgorithms
The PasswordAlgorithms Attribute.
RawAttribute
The header and raw bytes of an unparsed Attribute.
Realm
The Realm Attribute.
Software
The Software Attribute.
UnknownAttributes
The UnknownAttributes Attribute.
Userhash
The Userhash Attribute.
Username
The username Attribute.
XorMappedAddress
The XorMappedAddress Attribute.
XorSocketAddr
Helper struct for SocketAddr that are stored as an Attribute after an XOR operation with the TransactionId of a Message.

Enums§

PasswordAlgorithmValue
The hashing algorithm for the password.

Traits§

Attribute
A STUN attribute for use in Messages.
AttributeExt
Automatically implemented trait providing some helper functions for Attributes.
AttributeFromRaw
A trait for converting from a RawAttribute to a concrete Attribute.
AttributeStaticType
A static type for an Attribute.
AttributeWrite
Trait required when implementing writing an Attribute to a sequence of bytes
AttributeWriteExt
Automatically implemented trait providing helper functionality for writing an Attribute to a sequence of bytes.

Functions§

add_display_implstd
Adds an externally provided Display implementation for a particular AttributeType.
pad_attribute_len
Computes the padded length of an attribute value to a multiple of 4 bytes.

Type Aliases§

AttributeDisplay
A closure definition for an externally provided Display implementation for a RawAttribute.