Files
stund/src/protocol/mod.rs
T
2024-01-07 03:45:35 +02:00

104 lines
2.9 KiB
Rust

//! RFC8489 protocol data types and handling functions.
//!
//! The main module contains the Rust-friendly types, while the raw specifics
//! of the actual RFC-specified protocol are defined in the [rfc8489] module.
use std::net::SocketAddr;
use enum_repr::EnumRepr;
pub mod convert;
pub mod rfc8489;
/// Message limit imposed on both receive/send functions
pub const MESSAGE_SIZE_LIMIT: usize = 512;
/// Request/indication methods defined by the RFC
#[EnumRepr(type = "u16")]
#[derive(Debug, PartialEq, Clone, Copy)]
#[non_exhaustive]
pub enum Method {
Reserved = 0,
Binding = 1,
}
/// Classes defined by the RFC. Although there are four defined, only two types are
/// used by STUN: request/response transactions and indication messages.
#[EnumRepr(type = "u16")]
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum Class {
Request = 0,
Indication = 1,
SuccessResponse = 2,
ErrorResponse = 3,
}
/// Error codes reported by the server
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum ErrorCode {
UnknownAttribute,
BadRequest,
}
/// Defines main attributes handled by the server
#[derive(Debug)]
pub enum Attribute {
/// XOR-MAPPED-ADDRESS attribute, contains the address to be "echoed back"
/// to the requesting Agent
XorMappedAddress(SocketAddr),
/// ERROR-CODE, used to report an error
ErrorCode(ErrorCode),
/// UNKNOWN-ATTRIBUTES, MUST be present when reporting [ErrorCode::UnknownAttribute]
UnknownAttributes(Vec<u16>),
}
/// Defines a single message received by the server
#[derive(Debug)]
pub struct IncomingMessage {
/// Method of the message/transaction
pub method: Method,
/// Class of the message/transaction
pub class: Class,
/// Transaction ID, gets "echoed back" to the requesting Agent
pub transaction_id: [u32; 3],
/// Attributes coming from the requesting Agent
pub attributes: Vec<Attribute>,
}
/// Defines a response generated by the server
#[derive(Default, Debug)]
pub struct Response {
success: bool,
attributes: Vec<Attribute>,
}
impl IncomingMessage {
/// Dummy message used when a full message could not be received from the requesting Agent
pub fn invalid() -> Self {
Self {
method: Method::Reserved,
class: Class::Request,
attributes: vec![],
transaction_id: [0; 3],
}
}
}
impl Response {
/// Creates a new [Response], with its actual [Class] code being based on the `success`
/// parameter:
///
/// * If `success` is `true`, [Class::SuccessResponse] (2) is used.
/// * Otherwise, [Class::ErrorResponse] (3) is used.
pub fn new(success: bool) -> Self {
Self {
success,
attributes: vec![],
}
}
/// Pushes an attribute to the response's attribute list
pub fn add_attribute(&mut self, attr: Attribute) {
self.attributes.push(attr);
}
}