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>
impl<'a> Message<'a>
sourcepub fn builder<'b>(
mtype: MessageType,
transaction_id: TransactionId,
) -> MessageBuilder<'b>
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));sourcepub fn builder_request<'b>(method: u16) -> MessageBuilder<'b>
pub fn builder_request<'b>(method: u16) -> MessageBuilder<'b>
sourcepub fn builder_success<'b>(orig: &Message<'_>) -> MessageBuilder<'b>
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));sourcepub fn builder_error(orig: &Message<'_>) -> MessageBuilder<'a>
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));sourcepub fn get_type(&self) -> MessageType
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));sourcepub fn class(&self) -> MessageClass
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);sourcepub fn has_class(&self, cls: MessageClass) -> bool
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));sourcepub fn is_response(&self) -> bool
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);sourcepub fn has_method(&self, method: u16) -> bool
pub fn has_method(&self, method: u16) -> bool
sourcepub fn transaction_id(&self) -> TransactionId
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);sourcepub fn from_bytes(data: &'a [u8]) -> Result<Self, StunParseError>
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());sourcepub fn validate_integrity(
&self,
credentials: &MessageIntegrityCredentials,
) -> Result<(), StunParseError>
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());sourcepub fn raw_attribute(&self, atype: AttributeType) -> Option<RawAttribute<'_>>
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);sourcepub fn attribute<A: AttributeFromRaw<StunParseError>>(
&self,
) -> Result<A, StunParseError>
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);sourcepub fn iter_attributes(&self) -> impl Iterator<Item = RawAttribute<'_>>
pub fn iter_attributes(&self) -> impl Iterator<Item = RawAttribute<'_>>
Returns an iterator over the attributes in the Message.
sourcepub fn check_attribute_types<'b>(
msg: &Message<'_>,
supported: &[AttributeType],
required_in_msg: &[AttributeType],
) -> Option<MessageBuilder<'b>>
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));sourcepub fn unknown_attributes<'b>(
src: &Message<'_>,
attributes: &[AttributeType],
) -> MessageBuilder<'b>
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));sourcepub fn bad_request<'b>(src: &Message<'_>) -> MessageBuilder<'b>
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);sourcepub fn has_attribute(&self, atype: AttributeType) -> bool
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§
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§default unsafe fn clone_to_uninit(&self, dst: *mut T)
default unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit)