Struct stun_types::message::Message

source ·
pub struct Message<'a> { /* private fields */ }
Expand description

The structure that encapsulates the entirety of a STUN message

Contains the MessageType, a transaction ID, and a list of STUN Attribute

Implementations§

source§

impl<'a> Message<'a>

source

pub fn builder<'b>( mtype: MessageType, transaction_id: TransactionId, ) -> MessageBuilder<'b>

Create a new Message with the provided MessageType and transaction ID

Note you probably want to use one of the other helper constructors instead.

§Examples
let mtype = MessageType::from_class_method(MessageClass::Indication, BINDING);
let message = Message::builder(mtype, 0.into()).build();
let message = Message::from_bytes(&message).unwrap();
assert!(message.has_class(MessageClass::Indication));
assert!(message.has_method(BINDING));
source

pub fn builder_request<'b>(method: u16) -> MessageBuilder<'b>

Create a new request Message of the provided method

§Examples
let message = Message::builder_request(BINDING);
let data = message.build();
let message = Message::from_bytes(&data).unwrap();
assert!(message.has_class(MessageClass::Request));
assert!(message.has_method(BINDING));
source

pub fn builder_success<'b>(orig: &Message<'_>) -> MessageBuilder<'b>

Create a new success Message response from the provided request

§Panics

When a non-request Message is passed as the original input Message

§Examples
let message = Message::builder_request(BINDING);
let data = message.build();
let message = Message::from_bytes(&data).unwrap();
let success = Message::builder_success(&message).build();
let success = Message::from_bytes(&success).unwrap();
assert!(success.has_class(MessageClass::Success));
assert!(success.has_method(BINDING));
source

pub fn builder_error(orig: &Message<'_>) -> MessageBuilder<'a>

Create a new error Message response from the provided request

§Panics

When a non-request Message is passed as the original input Message

§Examples
let message = Message::builder_request(BINDING);
let data = message.build();
let message = Message::from_bytes(&data).unwrap();
let error = Message::builder_error(&message).build();
let error = Message::from_bytes(&error).unwrap();
assert!(error.has_class(MessageClass::Error));
assert!(error.has_method(BINDING));
source

pub fn get_type(&self) -> MessageType

Retrieve the MessageType of a Message

§Examples
let message = Message::builder_request(BINDING);
let data = message.build();
let message = Message::from_bytes(&data).unwrap();
assert!(message.get_type().has_class(MessageClass::Request));
assert!(message.get_type().has_method(BINDING));
source

pub fn class(&self) -> MessageClass

Retrieve the MessageClass of a Message

§Examples
let message = Message::builder_request(BINDING).build();
let message = Message::from_bytes(&message).unwrap();
assert_eq!(message.class(), MessageClass::Request);
source

pub fn has_class(&self, cls: MessageClass) -> bool

Returns whether the Message is of the specified MessageClass

§Examples
let message = Message::builder_request(BINDING).build();
let message = Message::from_bytes(&message).unwrap();
assert!(message.has_class(MessageClass::Request));
source

pub fn is_response(&self) -> bool

Returns whether the Message is a response

This means that the Message has a class of either success or error

§Examples
let message = Message::builder_request(BINDING).build();
let message = Message::from_bytes(&message).unwrap();
assert_eq!(message.is_response(), false);

let error = Message::builder_error(&message).build();
let error = Message::from_bytes(&error).unwrap();
assert_eq!(error.is_response(), true);

let success = Message::builder_success(&message).build();
let success = Message::from_bytes(&success).unwrap();
assert_eq!(success.is_response(), true);
source

pub fn method(&self) -> u16

Retrieves the method of the Message

§Examples
let message = Message::builder_request(BINDING).build();
let message = Message::from_bytes(&message).unwrap();
assert_eq!(message.method(), BINDING);
source

pub fn has_method(&self, method: u16) -> bool

Returns whether the Message is of the specified method

§Examples
let message = Message::builder_request(BINDING).build();
let message = Message::from_bytes(&message).unwrap();
assert_eq!(message.has_method(BINDING), true);
assert_eq!(message.has_method(0), false);
source

pub fn transaction_id(&self) -> TransactionId

Retrieves the 96-bit transaction ID of the Message

§Examples
let mtype = MessageType::from_class_method(MessageClass::Request, BINDING);
let transaction_id = TransactionId::generate();
let message = Message::builder(mtype, transaction_id).build();
let message = Message::from_bytes(&message).unwrap();
assert_eq!(message.transaction_id(), transaction_id);
source

pub fn from_bytes(data: &'a [u8]) -> Result<Self, StunParseError>

Deserialize a Message

§Examples
let msg_data = vec![0, 1, 0, 8, 33, 18, 164, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 232, 0, 1, 0, 1, 3, 0, 0, 0];
let message = Message::from_bytes(&msg_data).unwrap();
let attr = RawAttribute::new(1.into(), &[3]);
let msg_attr = message.raw_attribute(1.into()).unwrap();
assert_eq!(msg_attr, attr);
assert_eq!(message.get_type(), MessageType::from_class_method(MessageClass::Request, BINDING));
assert_eq!(message.transaction_id(), 1000.into());
source

pub fn validate_integrity( &self, credentials: &MessageIntegrityCredentials, ) -> Result<(), StunParseError>

Validates the MESSAGE_INTEGRITY attribute with the provided credentials

The Original data that was used to construct this Message must be provided in order to successfully validate the Message

§Examples
    MessageIntegrityCredentials, LongTermCredentials, IntegrityAlgorithm};
let mut message = Message::builder_request(BINDING);
let credentials = LongTermCredentials::new(
    "user".to_owned(),
    "pass".to_owned(),
    "realm".to_owned()
).into();
assert!(message.add_message_integrity(&credentials, IntegrityAlgorithm::Sha256).is_ok());
let data = message.build();
let message = Message::from_bytes(&data).unwrap();
assert!(message.validate_integrity(&credentials).is_ok());
source

pub fn raw_attribute(&self, atype: AttributeType) -> Option<RawAttribute<'_>>

Retrieve a RawAttribute from this Message.

§Examples

Retrieve aRawAttribute

let mut message = Message::builder_request(BINDING);
let attr = RawAttribute::new(1.into(), &[3]);
assert!(message.add_attribute(attr.clone()).is_ok());
let message = message.build();
let message = Message::from_bytes(&message).unwrap();
assert_eq!(message.raw_attribute(1.into()).unwrap(), attr);
source

pub fn attribute<A: AttributeFromRaw<StunParseError>>( &self, ) -> Result<A, StunParseError>

Retrieve a concrete Attribute from this Message.

This will error with StunParseError::MissingAttribute if the attribute does not exist. Otherwise, other parsing errors of the data may be returned specific to the attribute implementation provided.

§Examples

Retrieve an Attribute

let mut message = Message::builder_request(BINDING);
let attr = Software::new("stun-types").unwrap();
assert!(message.add_attribute(&attr).is_ok());
let message = message.build();
let message = Message::from_bytes(&message).unwrap();
assert_eq!(message.attribute::<Software>().unwrap(), attr);
source

pub fn iter_attributes(&self) -> impl Iterator<Item = RawAttribute<'_>>

Returns an iterator over the attributes in the Message.

source

pub fn check_attribute_types<'b>( msg: &Message<'_>, supported: &[AttributeType], required_in_msg: &[AttributeType], ) -> Option<MessageBuilder<'b>>

Check that a message Message only contains required attributes that are supported and have at least some set of required attributes. Returns an appropriate error message on failure to meet these requirements.

§Examples
let mut builder = Message::builder_request(BINDING);
let message = builder.build();
let message = Message::from_bytes(&message).unwrap();
// If nothing is required, no error response is returned
assert!(matches!(Message::check_attribute_types(&message, &[], &[]), None));

// If an atttribute is required that is not in the message, then an error response message
// is generated
let error_msg = Message::check_attribute_types(
    &message,
    &[],
    &[Software::TYPE]
).unwrap();
assert!(error_msg.has_attribute(ErrorCode::TYPE));
let error_msg = error_msg.build();
let error_msg = Message::from_bytes(&error_msg).unwrap();
let error_code = error_msg.attribute::<ErrorCode>().unwrap();
assert_eq!(error_code.code(), 400);

let username = Username::new("user").unwrap();
builder.add_attribute(&username).unwrap();
let message = builder.build();
let message = Message::from_bytes(&message).unwrap();
// If a Username is in the message but is not advertised as supported then an
// 'UNKNOWN-ATTRIBUTES' error response is returned
let error_msg = Message::check_attribute_types(&message, &[], &[]).unwrap();
let error_msg = error_msg.build();
let error_msg = Message::from_bytes(&error_msg).unwrap();
assert!(error_msg.is_response());
assert!(error_msg.has_attribute(ErrorCode::TYPE));
let error_code : ErrorCode = error_msg.attribute::<ErrorCode>().unwrap();
assert_eq!(error_code.code(), 420);
assert!(error_msg.has_attribute(UnknownAttributes::TYPE));
source

pub fn unknown_attributes<'b>( src: &Message<'_>, attributes: &[AttributeType], ) -> MessageBuilder<'b>

Generate an error message with an ErrorCode attribute signalling ‘Unknown Attribute’ and an UnknownAttributes attribute containing the attributes that are unknown.

§Examples
let msg = Message::builder_request(BINDING).build();
let msg = Message::from_bytes(&msg).unwrap();
let error_msg = Message::unknown_attributes(&msg, &[Username::TYPE]).build();
let error_msg = Message::from_bytes(&error_msg).unwrap();
assert!(error_msg.is_response());
assert!(error_msg.has_attribute(ErrorCode::TYPE));
let error_code = error_msg.attribute::<ErrorCode>().unwrap();
assert_eq!(error_code.code(), 420);
let unknown = error_msg.attribute::<UnknownAttributes>().unwrap();
assert!(unknown.has_attribute(Username::TYPE));
source

pub fn bad_request<'b>(src: &Message<'_>) -> MessageBuilder<'b>

Generate an error message with an ErrorCode attribute signalling a ‘Bad Request’

§Examples
let msg = Message::builder_request(BINDING).build();
let msg = Message::from_bytes(&msg).unwrap();
let error_msg = Message::bad_request(&msg).build();
let error_msg = Message::from_bytes(&error_msg).unwrap();
assert!(error_msg.has_attribute(ErrorCode::TYPE));
let error_code =  error_msg.attribute::<ErrorCode>().unwrap();
assert_eq!(error_code.code(), 400);
source

pub fn has_attribute(&self, atype: AttributeType) -> bool

Whether this message contains an attribute of the specified type.

§Examples
let mut msg = Message::builder_request(BINDING);
let attr = Software::new("stun-types").unwrap();
assert!(msg.add_attribute(&attr).is_ok());
let msg = msg.build();
let msg = Message::from_bytes(&msg).unwrap();
assert!(msg.has_attribute(Software::TYPE));

Trait Implementations§

source§

impl<'a> Clone for Message<'a>

source§

fn clone(&self) -> Message<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for Message<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> Display for Message<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> TryFrom<&'a [u8]> for Message<'a>

§

type Error = StunParseError

The type returned in the event of a conversion error.
source§

fn try_from(value: &'a [u8]) -> Result<Self, Self::Error>

Performs the conversion.

Auto Trait Implementations§

§

impl<'a> Freeze for Message<'a>

§

impl<'a> RefUnwindSafe for Message<'a>

§

impl<'a> Send for Message<'a>

§

impl<'a> Sync for Message<'a>

§

impl<'a> Unpin for Message<'a>

§

impl<'a> UnwindSafe for Message<'a>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> CloneToUninit for T
where T: Clone,

source§

default unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

source§

fn vzip(self) -> V

source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more