Struct stun_types::message::Message
source · pub struct Message { /* 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 Message
impl Message
sourcepub fn new(mtype: MessageType, transaction: TransactionId) -> Self
pub fn new(mtype: MessageType, transaction: TransactionId) -> Self
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::new(mtype, 0.into());
assert!(message.has_class(MessageClass::Indication));
assert!(message.has_method(BINDING));sourcepub fn new_request(method: u16) -> Self
pub fn new_request(method: u16) -> Self
sourcepub fn new_success(orig: &Message) -> Self
pub fn new_success(orig: &Message) -> Self
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::new_request(BINDING);
let success = Message::new_success(&message);
assert!(success.has_class(MessageClass::Success));
assert!(success.has_method(BINDING));sourcepub fn new_error(orig: &Message) -> Self
pub fn new_error(orig: &Message) -> Self
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::new_request(BINDING);
let success = Message::new_error(&message);
assert!(success.has_class(MessageClass::Error));
assert!(success.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::new_request(BINDING);
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::new_request(BINDING);
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::new_request(BINDING);
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::new_request(BINDING);
assert_eq!(message.is_response(), false);
let error = Message::new_error(&message);
assert_eq!(error.is_response(), true);
let success = Message::new_success(&message);
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
pub fn generate_transaction() -> TransactionId
sourcepub fn to_bytes(&self) -> Vec<u8>
pub fn to_bytes(&self) -> Vec<u8>
Serialize a Message to network bytes
§Examples
let mut message = Message::new(MessageType::from_class_method(MessageClass::Request, BINDING), 1000.into());
let attr = RawAttribute::new(1.into(), &[3]);
assert!(message.add_attribute(attr).is_ok());
assert_eq!(message.to_bytes(), 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]);sourcepub fn from_bytes(data: &[u8]) -> Result<Self, StunParseError>
pub fn from_bytes(data: &[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 mut 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,
orig_data: &[u8],
credentials: &MessageIntegrityCredentials,
) -> Result<(), StunParseError>
pub fn validate_integrity( &self, orig_data: &[u8], credentials: &MessageIntegrityCredentials, ) -> Result<(), StunParseError>
sourcepub fn add_message_integrity(
&mut self,
credentials: &MessageIntegrityCredentials,
algorithm: IntegrityAlgorithm,
) -> Result<(), StunWriteError>
pub fn add_message_integrity( &mut self, credentials: &MessageIntegrityCredentials, algorithm: IntegrityAlgorithm, ) -> Result<(), StunWriteError>
Adds MESSAGE_INTEGRITY attribute to a Message using the provided credentials
§Errors
- If a MESSAGE_INTEGRITY attribute is already present
- If a MESSAGE_INTEGRITY_SHA256 attribute is already present
- If a FINGERPRINT attribute is already present
§Examples
MessageIntegrityCredentials, ShortTermCredentials, IntegrityAlgorithm};
let mut message = Message::new_request(BINDING);
let credentials = MessageIntegrityCredentials::ShortTerm(ShortTermCredentials { password:
"pass".to_owned() });
assert!(message.add_message_integrity(&credentials, IntegrityAlgorithm::Sha1).is_ok());
let data = message.to_bytes();
assert!(message.validate_integrity(&data, &credentials).is_ok());
// duplicate MESSAGE_INTEGRITY is an error
assert!(message.add_message_integrity(&credentials, IntegrityAlgorithm::Sha1).is_err());sourcepub fn add_fingerprint(&mut self) -> Result<(), StunWriteError>
pub fn add_fingerprint(&mut self) -> Result<(), StunWriteError>
sourcepub fn add_attribute(
&mut self,
attr: impl Into<RawAttribute>,
) -> Result<(), StunWriteError>
pub fn add_attribute( &mut self, attr: impl Into<RawAttribute>, ) -> Result<(), StunWriteError>
Add a Attribute to this Message. Only one AttributeType can be added for each
Attribute. Attempting to add multiple Atributes of the same AttributeType` will fail.
§Errors
- if a MESSAGE_INTEGRITY attribute is attempted to be added. Use
Message::add_message_integrityinstead. - if a FINGERPRINT attribute is attempted to be added. Use
Message::add_fingerprintinstead. - If the attribute already exists within the message
- If attempting to add attributes when MESSAGE_INTEGRITY or FINGERPRINT atributes already exist
§Examples
Add an Attribute
let mut message = Message::new_request(BINDING);
let attr = RawAttribute::new(1.into(), &[3]);
assert!(message.add_attribute(attr.clone()).is_ok());
assert!(message.add_attribute(attr).is_err());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::new_request(BINDING);
let attr = RawAttribute::new(1.into(), &[3]);
assert!(message.add_attribute(attr.clone()).is_ok());
assert_eq!(message.raw_attribute(1.into()).unwrap(), &attr);sourcepub fn attribute<A: AttributeFromRaw<StunParseError>>(&self) -> Option<A>
pub fn attribute<A: AttributeFromRaw<StunParseError>>(&self) -> Option<A>
Retrieve an Attribute from this Message.
§Examples
Retrieve an Attribute
let mut message = Message::new_request(BINDING);
let attr = Software::new("stun-types").unwrap();
assert!(message.add_attribute(attr.clone()).is_ok());
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(
msg: &Message,
supported: &[AttributeType],
required_in_msg: &[AttributeType],
) -> Option<Message>
pub fn check_attribute_types( msg: &Message, supported: &[AttributeType], required_in_msg: &[AttributeType], ) -> Option<Message>
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 message = Message::new_request(BINDING);
// 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 and 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_code = error_msg.attribute::<ErrorCode>().unwrap();
assert_eq!(error_code.code(), 400);
message.add_attribute(Username::new("user").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();
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(
src: &Message,
attributes: &[AttributeType],
) -> Message
pub fn unknown_attributes( src: &Message, attributes: &[AttributeType], ) -> Message
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::new_request(BINDING);
let error_msg = Message::unknown_attributes(&msg, &[Username::TYPE]);
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(src: &Message) -> Message
pub fn bad_request(src: &Message) -> Message
Generate an error message with an ErrorCode attribute signalling a ‘Bad Request’
§Examples
let msg = Message::new_request(BINDING);
let error_msg = Message::bad_request(&msg);
assert!(error_msg.has_attribute(ErrorCode::TYPE));
let error_code = error_msg.attribute::<ErrorCode>().unwrap();
assert_eq!(error_code.code(), 400);