stun_coder/message/
message.rs

1pub use super::errors::{IntegrityKeyGenerationError, MessageDecodeError, MessageEncodeError};
2
3use crate::attribute::StunAttribute;
4use crate::header::StunHeader;
5
6/// [STUN message](https://tools.ietf.org/html/rfc5389#section-6).
7///
8/// An example of creating and encoding a STUN binding request:
9///```
10/// // Create a request message
11/// let message = stun_coder::StunMessage::create_request()
12///             .add_attribute(stun_coder::StunAttribute::Software {
13///                 description: String::from("rust-stun-coder"),
14///             })
15///             .add_message_integrity()
16///             .add_fingerprint();
17///
18/// // Encode it into bytes
19/// let encoded_message = message.encode(Some("TEST_PASS")).unwrap();
20///
21/// println!("{:#X?}", encoded_message);
22///
23///```
24///
25/// An example that decodes a sample request with Long-Term Authentication
26/// ```
27/// // Encoded message
28/// let msg_bytes: Vec<u8> = vec![
29///     0x01, 0x01, 0x00, 0x48, 0x21, 0x12, 0xa4, 0x42, 0xb7, 0xe7, 0xa7, 0x01, 0xbc, 0x34,
30///     0xd6, 0x86, 0xfa, 0x87, 0xdf, 0xae, 0x80, 0x22, 0x00, 0x0b, 0x74, 0x65, 0x73, 0x74,
31///     0x20, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x20, 0x00, 0x14, 0x00, 0x02,
32///     0xa1, 0x47, 0x01, 0x13, 0xa9, 0xfa, 0xa5, 0xd3, 0xf1, 0x79, 0xbc, 0x25, 0xf4, 0xb5,
33///     0xbe, 0xd2, 0xb9, 0xd9, 0x00, 0x08, 0x00, 0x14, 0xBD, 0x3, 0x6D, 0x6A, 0x33, 0x17,
34///     0x50, 0xDF, 0xE2, 0xED, 0xC5, 0x8E, 0x64, 0x34, 0x55, 0xCF, 0xF5, 0xC8, 0xE2, 0x64,
35///     0x80, 0x28, 0x00, 0x04, 0x4F, 0x26, 0x02, 0x93,
36/// ];
37///
38/// // Integrity key used for verification
39/// let integrity_key = Some("VOkJxbRl1RmTxUk/WvJxBt");
40///
41/// // Decode the message
42/// let decoded_msg = stun_coder::StunMessage::decode(&msg_bytes, integrity_key).unwrap();
43///
44/// println!("{:?}", decoded_msg);
45///```
46///
47///
48///   STUN messages are encoded in binary using network-oriented format
49///   (most significant byte or octet first, also commonly known as big-
50///   endian).  The transmission order is described in detail in Appendix B
51///   of [RFC0791](https://tools.ietf.org/html/rfc791). Unless otherwise noted, numeric constants are
52///   in decimal (base 10).
53///
54///   All STUN messages MUST start with a 20-byte header followed by zero
55///   or more Attributes.  The STUN header contains a STUN message type,
56///   magic cookie, transaction ID, and message length.
57///```text
58///        0                   1                   2                   3
59///        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
60///       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61///       |0 0|     STUN Message Type     |         Message Length        |
62///       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63///       |                         Magic Cookie                          |
64///       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
65///       |                                                               |
66///       |                     Transaction ID (96 bits)                  |
67///       |                                                               |
68///       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69///
70///                   Figure 2: Format of STUN Message Header
71///```
72///   The most significant 2 bits of every STUN message MUST be zeroes.
73///   This can be used to differentiate STUN packets from other protocols
74///   when STUN is multiplexed with other protocols on the same port.
75///
76///   The message type defines the message class (request, success
77///   response, failure response, or indication) and the message method
78///   (the primary function) of the STUN message.  Although there are four
79///   message classes, there are only two types of transactions in STUN:
80///   request/response transactions (which consist of a request message and
81///   a response message) and indication transactions (which consist of a
82///   single indication message).  Response classes are split into error
83///   and success responses to aid in quickly processing the STUN message.
84///
85///   The message type field is decomposed further into the following
86///   structure:
87///```text
88///                        0                 1
89///                        2  3  4 5 6 7 8 9 0 1 2 3 4 5
90///
91///                       +--+--+-+-+-+-+-+-+-+-+-+-+-+-+
92///                       |M |M |M|M|M|C|M|M|M|C|M|M|M|M|
93///                       |11|10|9|8|7|1|6|5|4|0|3|2|1|0|
94///                       +--+--+-+-+-+-+-+-+-+-+-+-+-+-+
95///
96///                Figure 3: Format of STUN Message Type Field
97///```
98///   Here the bits in the message type field are shown as most significant
99///   (M11) through least significant (M0).  M11 through M0 represent a 12-
100///   bit encoding of the method.  C1 and C0 represent a 2-bit encoding of
101///   the class.  A class of 0b00 is a request, a class of 0b01 is an
102///   indication, a class of 0b10 is a success response, and a class of
103///   0b11 is an error response.  This specification defines a single
104///   method, Binding.  The method and class are orthogonal, so that for
105///   each method, a request, success response, error response, and
106///   indication are possible for that method.  Extensions defining new
107///   methods MUST indicate which classes are permitted for that method.
108///
109///   For example, a Binding request has class=0b00 (request) and
110///   method=0b000000000001 (Binding) and is encoded into the first 16 bits
111///   as 0x0001.  A Binding response has class=0b10 (success response) and
112///   method=0b000000000001, and is encoded into the first 16 bits as
113///   0x0101.
114///```text
115///      Note: This unfortunate encoding is due to assignment of values in
116///      [RFC3489](https://tools.ietf.org/html/rfc3489) that did not consider encoding Indications, Success, and
117///      Errors using bit fields.
118///```
119///   The magic cookie field MUST contain the fixed value 0x2112A442 in
120///   network byte order.  In [RFC3489](https://tools.ietf.org/html/rfc3489), this field was part of
121///   the transaction ID; placing the magic cookie in this location allows
122///   a server to detect if the client will understand certain attributes
123///   that were added in this revised specification.  In addition, it aids
124///   in distinguishing STUN packets from packets of other protocols when
125///   STUN is multiplexed with those other protocols on the same port.
126///
127///   The transaction ID is a 96-bit identifier, used to uniquely identify
128///   STUN transactions.  For request/response transactions, the
129///   transaction ID is chosen by the STUN client for the request and
130///   echoed by the server in the response.  For indications, it is chosen
131///   by the agent sending the indication.  It primarily serves to
132///   correlate requests with responses, though it also plays a small role
133///
134///   in helping to prevent certain types of attacks.  The server also uses
135///   the transaction ID as a key to identify each transaction uniquely
136///   across all clients.  As such, the transaction ID MUST be uniformly
137///   and randomly chosen from the interval 0 .. 2**96-1, and SHOULD be
138///   cryptographically random.  Resends of the same request reuse the same
139///   transaction ID, but the client MUST choose a new transaction ID for
140///   new transactions unless the new request is bit-wise identical to the
141///   previous request and sent from the same transport address to the same
142///   IP address.  Success and error responses MUST carry the same
143///   transaction ID as their corresponding request.  When an agent is
144///   acting as a STUN server and STUN client on the same port, the
145///   transaction IDs in requests sent by the agent have no relationship to
146///   the transaction IDs in requests received by the agent.
147///
148///   The message length MUST contain the size, in bytes, of the message
149///   not including the 20-byte STUN header.  Since all STUN attributes are
150///   padded to a multiple of 4 bytes, the last 2 bits of this field are
151///   always zero.  This provides another way to distinguish STUN packets
152///   from packets of other protocols.
153///
154///   Following the STUN fixed portion of the header are zero or more
155///   attributes.  Each attribute is TLV (Type-Length-Value) encoded.  The
156///   details of the encoding, and of the attributes themselves are given
157///   in [Section 15](https://tools.ietf.org/html/rfc5389#section-15).
158
159#[derive(Debug, Clone)]
160pub struct StunMessage {
161    /// STUN message header
162    pub(super) header: StunHeader,
163    /// STUN message attributes
164    pub(super) attributes: Vec<StunAttribute>,
165}