stun_format/
format.rs

1use r_ex::prelude::*;
2
3pub struct Msg<'a> {
4    byte_msg: stun_bytes::ByteMsg<'a>,
5}
6
7impl<'a> From<&'a [u8]> for Msg<'a> {
8    fn from(buf: &'a [u8]) -> Self {
9        Self {
10            byte_msg: stun_bytes::ByteMsg::from(buf)
11        }
12    }
13}
14
15impl<'a> Msg<'a> {
16    pub fn typ(&self) -> Option<MsgType> {
17        self.byte_msg.typ()
18            .map(MsgType::from_ref)
19    }
20
21    #[cfg(any(feature = "rfc5349", feature = "rfc8489"))]
22    pub fn cookie(&self) -> Option<u32> {
23        Some(self.byte_msg.tid()?
24            .carved()?
25            .as_be())
26    }
27
28    pub fn tid(&self) -> Option<u128> {
29        let mut tid = self.byte_msg.tid()
30            .map(u128::from_be_ref);
31
32        if cfg!(any(feature = "rfc5349", feature = "rfc8489")) {
33            tid = tid.map(|val| val & ((1u128 << 96) - 1));
34        }
35
36        tid
37    }
38
39    pub fn attrs_iter(&self) -> AttrIter {
40        AttrIter {
41            byte_iter: self.byte_msg.attrs_iter(),
42            tid: self.byte_msg.tid().unwrap_or(&[0u8; 16]),
43        }
44    }
45}
46
47pub struct MsgBuilder<'a> {
48    byte_msg: stun_bytes::ByteMsgMut<'a>,
49}
50
51impl<'a> From<&'a mut [u8]> for MsgBuilder<'a> {
52    fn from(buf: &'a mut [u8]) -> Self {
53        Self {
54            byte_msg: stun_bytes::ByteMsgMut::from(buf)
55        }
56    }
57}
58
59impl<'a> MsgBuilder<'a> {
60    pub fn typ(&mut self, typ: MsgType) -> Option<()> {
61        self.byte_msg.typ()?.set_be(u16::from(typ));
62        Some(())
63    }
64
65    pub fn tid(&mut self, mut tid: u128) -> Option<()> {
66        if cfg!(any(feature = "rfc5349", feature = "rfc8489")) {
67            tid = (0x2112A442 << 96) | (tid & (u128::MAX >> 32));
68        }
69        self.byte_msg.tid()?.set_be(tid);
70        Some(())
71    }
72
73    pub fn add_attr(&mut self, attr: Attr) -> Option<()> {
74        let tid = self.byte_msg.tid()?.clone();
75        self.byte_msg.add_attr2(|typ, len, val| {
76            attr.into_buf(typ, len, val, &tid)
77        })
78    }
79
80    pub fn as_bytes(&mut self) -> &mut [u8] {
81        self.byte_msg.as_bytes()
82    }
83}
84
85#[cfg(feature = "fmt")]
86impl<'a> core::fmt::Debug for Msg<'a> {
87    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
88        f.write_str("Msg {\n")?;
89        f.write_fmt(format_args!("  Type: {:?}\n", self.typ()))?;
90        if cfg!(any(feature = "rfc5349", feature = "rfc8489")) {
91            f.write_fmt(format_args!("  Cookie: {:?}\n", self.cookie()))?;
92        }
93        f.write_fmt(format_args!("  Transaction Id: {:?}\n", self.tid()))?;
94        f.write_fmt(format_args!("  Attributes: {:?}\n", self.attrs_iter()))?;
95        f.write_str("}")?;
96        Ok(())
97    }
98}
99
100#[cfg_attr(feature = "fmt", derive(core::fmt::Debug))]
101pub enum MsgType {
102    #[cfg(any(feature = "rfc3489", feature = "rfc5349", feature = "rfc8489"))]
103    BindingRequest,
104
105    #[cfg(any(feature = "rfc3489", feature = "rfc5349", feature = "rfc8489"))]
106    BindingResponse,
107
108    #[cfg(any(feature = "rfc5349", feature = "rfc8489"))]
109    BindingIndication,
110
111    #[cfg(any(feature = "rfc3489", feature = "rfc5349", feature = "rfc8489"))]
112    BindingErrorResponse,
113
114    #[cfg(feature = "rfc3489")]
115    SharedSecretRequest,
116
117    #[cfg(feature = "rfc3489")]
118    SharedSecretResponse,
119
120    #[cfg(feature = "rfc3489")]
121    SharedSecretErrorResponse,
122
123    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
124    AllocateRequest,
125
126    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
127    AllocateResponse,
128
129    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
130    AllocateErrorResponse,
131
132    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
133    RefreshRequest,
134
135    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
136    RefreshResponse,
137
138    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
139    RefreshErrorResponse,
140
141    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
142    SendIndication,
143
144    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
145    DataIndication,
146
147    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
148    CreatePermissionRequest,
149
150    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
151    CreatePermissionResponse,
152
153    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
154    CreatePermissionErrorResponse,
155
156    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
157    ChannelBindRequest,
158
159    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
160    ChannelBindResponse,
161
162    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
163    ChannelBindErrorResponse,
164
165    #[cfg(any(feature = "rfc6062"))]
166    ConnectRequest,
167
168    #[cfg(any(feature = "rfc6062"))]
169    ConnectResponse,
170
171    #[cfg(any(feature = "rfc6062"))]
172    ConnectErrorResponse,
173
174    #[cfg(any(feature = "rfc6062"))]
175    ConnectionBindRequest,
176
177    #[cfg(any(feature = "rfc6062"))]
178    ConnectionBindResponse,
179
180    #[cfg(any(feature = "rfc6062"))]
181    ConnectionBindErrorResponse,
182
183    #[cfg(any(feature = "rfc6062"))]
184    ConnectionAttemptIndication,
185
186    Other(u16),
187}
188
189impl From<[u8; 2]> for MsgType {
190    fn from(val: [u8; 2]) -> Self {
191        let val: u16 = val.as_be();
192        MsgType::from(val)
193    }
194}
195
196impl From<u16> for MsgType {
197    fn from(val: u16) -> Self {
198        use crate::consts::msg_type::*;
199
200        match val {
201            #[cfg(any(feature = "rfc3489", feature = "rfc5349", feature = "rfc8489"))]
202            BINDING_REQUEST => Self::BindingRequest,
203
204            #[cfg(any(feature = "rfc3489", feature = "rfc5349", feature = "rfc8489"))]
205            BINDING_RESPONSE => Self::BindingResponse,
206
207            #[cfg(any(feature = "rfc5349", feature = "rfc8489"))]
208            BINDING_INDICATION => Self::BindingIndication,
209
210            #[cfg(any(feature = "rfc3489", feature = "rfc5349", feature = "rfc8489"))]
211            BINDING_ERROR_RESPONSE => Self::BindingErrorResponse,
212
213            #[cfg(feature = "rfc3489")]
214            SHARED_SECRET_REQUEST => Self::SharedSecretRequest,
215
216            #[cfg(feature = "rfc3489")]
217            SHARED_SECRET_RESPONSE => Self::SharedSecretResponse,
218
219            #[cfg(feature = "rfc3489")]
220            SHARED_SECRET_ERROR_RESPONSE => Self::SharedSecretErrorResponse,
221
222            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
223            ALLOCATE_REQUEST => Self::AllocateRequest,
224
225            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
226            ALLOCATE_RESPONSE => Self::AllocateResponse,
227
228            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
229            ALLOCATE_ERROR_RESPONSE => Self::AllocateErrorResponse,
230
231            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
232            REFRESH_REQUEST => Self::RefreshRequest,
233
234            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
235            REFRESH_RESPONSE => Self::RefreshResponse,
236
237            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
238            REFRESH_ERROR_RESPONSE => Self::RefreshErrorResponse,
239
240            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
241            SEND_INDICATION => Self::SendIndication,
242
243            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
244            DATA_INDICATION => Self::DataIndication,
245
246            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
247            CREATE_PERMISSION_REQUEST => Self::CreatePermissionRequest,
248
249            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
250            CREATE_PERMISSION_RESPONSE => Self::CreatePermissionResponse,
251
252            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
253            CREATE_PERMISSION_ERROR_RESPONSE => Self::CreatePermissionErrorResponse,
254
255            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
256            CHANNEL_BIND_REQUEST => Self::ChannelBindRequest,
257
258            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
259            CHANNEL_BIND_RESPONSE => Self::ChannelBindResponse,
260
261            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
262            CHANNEL_BIND_ERROR_RESPONSE => Self::ChannelBindErrorResponse,
263
264            #[cfg(any(feature = "rfc6062"))]
265            CONNECT_REQUEST => Self::ConnectRequest,
266
267            #[cfg(any(feature = "rfc6062"))]
268            CONNECT_RESPONSE => Self::ConnectResponse,
269
270            #[cfg(any(feature = "rfc6062"))]
271            CONNECT_ERROR_RESPONSE => Self::ConnectErrorResponse,
272
273            #[cfg(any(feature = "rfc6062"))]
274            CONNECTION_BIND_REQUEST => Self::ConnectionBindRequest,
275
276            #[cfg(any(feature = "rfc6062"))]
277            CONNECTION_BIND_RESPONSE => Self::ConnectionBindResponse,
278
279            #[cfg(any(feature = "rfc6062"))]
280            CONNECTION_BIND_ERROR_RESPONSE => Self::ConnectionBindErrorResponse,
281
282            #[cfg(any(feature = "rfc6062"))]
283            CONNECTION_ATTEMPT_INDICATION => Self::ConnectionAttemptIndication,
284
285            val => Self::Other(val),
286        }
287    }
288}
289
290impl From<MsgType> for u16 {
291    fn from(typ: MsgType) -> Self {
292        use crate::consts::msg_type::*;
293
294        match typ {
295            #[cfg(any(feature = "rfc3489", feature = "rfc5349", feature = "rfc8489"))]
296            MsgType::BindingRequest => BINDING_REQUEST,
297
298            #[cfg(any(feature = "rfc3489", feature = "rfc5349", feature = "rfc8489"))]
299            MsgType::BindingResponse => BINDING_RESPONSE,
300
301            #[cfg(any(feature = "rfc5349", feature = "rfc8489"))]
302            MsgType::BindingIndication => BINDING_INDICATION,
303
304            #[cfg(any(feature = "rfc3489", feature = "rfc5349", feature = "rfc8489"))]
305            MsgType::BindingErrorResponse => BINDING_ERROR_RESPONSE,
306
307            #[cfg(feature = "rfc3489")]
308            MsgType::SharedSecretRequest => SHARED_SECRET_REQUEST,
309
310            #[cfg(feature = "rfc3489")]
311            MsgType::SharedSecretResponse => SHARED_SECRET_RESPONSE,
312
313            #[cfg(feature = "rfc3489")]
314            MsgType::SharedSecretErrorResponse => SHARED_SECRET_ERROR_RESPONSE,
315
316            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
317            MsgType::AllocateRequest => ALLOCATE_REQUEST,
318
319            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
320            MsgType::AllocateResponse => ALLOCATE_RESPONSE,
321
322            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
323            MsgType::AllocateErrorResponse => ALLOCATE_ERROR_RESPONSE,
324
325            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
326            MsgType::RefreshRequest => REFRESH_REQUEST,
327
328            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
329            MsgType::RefreshResponse => REFRESH_RESPONSE,
330
331            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
332            MsgType::RefreshErrorResponse => REFRESH_ERROR_RESPONSE,
333
334            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
335            MsgType::SendIndication => SEND_INDICATION,
336
337            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
338            MsgType::DataIndication => DATA_INDICATION,
339
340            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
341            MsgType::CreatePermissionRequest => CREATE_PERMISSION_REQUEST,
342
343            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
344            MsgType::CreatePermissionResponse => CREATE_PERMISSION_RESPONSE,
345
346            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
347            MsgType::CreatePermissionErrorResponse => CREATE_PERMISSION_ERROR_RESPONSE,
348
349            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
350            MsgType::ChannelBindRequest => CHANNEL_BIND_REQUEST,
351
352            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
353            MsgType::ChannelBindResponse => CHANNEL_BIND_RESPONSE,
354
355            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
356            MsgType::ChannelBindErrorResponse => CHANNEL_BIND_ERROR_RESPONSE,
357
358            #[cfg(any(feature = "rfc6062"))]
359            MsgType::ConnectRequest => CONNECT_REQUEST,
360
361            #[cfg(any(feature = "rfc6062"))]
362            MsgType::ConnectResponse => CONNECT_RESPONSE,
363
364            #[cfg(any(feature = "rfc6062"))]
365            MsgType::ConnectErrorResponse => CONNECT_ERROR_RESPONSE,
366
367            #[cfg(any(feature = "rfc6062"))]
368            MsgType::ConnectionBindRequest => CONNECTION_BIND_REQUEST,
369
370            #[cfg(any(feature = "rfc6062"))]
371            MsgType::ConnectionBindResponse => CONNECTION_BIND_RESPONSE,
372
373            #[cfg(any(feature = "rfc6062"))]
374            MsgType::ConnectionBindErrorResponse => CONNECTION_BIND_ERROR_RESPONSE,
375
376            #[cfg(any(feature = "rfc6062"))]
377            MsgType::ConnectionAttemptIndication => CONNECTION_ATTEMPT_INDICATION,
378
379            MsgType::Other(val) => val,
380        }
381    }
382}
383
384impl From<MsgType> for [u8; 2] {
385    fn from(typ: MsgType) -> Self {
386        u16::from(typ).to_be_bytes()
387    }
388}
389
390#[cfg_attr(feature = "fmt", derive(core::fmt::Debug))]
391#[derive(Copy, Clone)]
392pub enum SocketAddr {
393    V4([u8; 4], u16),
394    V6([u8; 16], u16),
395}
396
397impl SocketAddr {
398    pub fn addr_family(&self) -> AddressFamily {
399        match self {
400            SocketAddr::V4(_, _) => AddressFamily::IPv4,
401            SocketAddr::V6(_, _) => AddressFamily::IPv6,
402        }
403    }
404}
405
406#[cfg_attr(feature = "fmt", derive(core::fmt::Debug))]
407#[derive(Copy, Clone)]
408pub enum AddressFamily {
409    IPv4,
410    IPv6,
411    Other(u8),
412}
413
414impl From<u8> for AddressFamily {
415    fn from(fam: u8) -> Self {
416        use crate::consts::addr_family::*;
417
418        match fam {
419            IP4 => AddressFamily::IPv4,
420            IP6 => AddressFamily::IPv6,
421            other => AddressFamily::Other(other),
422        }
423    }
424}
425
426impl From<AddressFamily> for u8 {
427    fn from(fam: AddressFamily) -> Self {
428        use crate::consts::addr_family::*;
429
430        match fam {
431            AddressFamily::IPv4 => IP4,
432            AddressFamily::IPv6 => IP6,
433            AddressFamily::Other(other) => other,
434        }
435    }
436}
437
438#[cfg_attr(feature = "fmt", derive(core::fmt::Debug))]
439#[derive(Copy, Clone)]
440pub enum TransportProtocol {
441    UDP,
442    Other(u8),
443}
444
445impl From<u8> for TransportProtocol {
446    fn from(proto: u8) -> Self {
447        use crate::consts::transport_proto::*;
448
449        match proto {
450            UDP => Self::UDP,
451            proto => Self::Other(proto),
452        }
453    }
454}
455
456impl From<TransportProtocol> for u8 {
457    fn from(proto: TransportProtocol) -> Self {
458        use crate::consts::transport_proto::*;
459
460        match proto {
461            TransportProtocol::UDP => UDP,
462            TransportProtocol::Other(other) => other,
463        }
464    }
465}
466
467#[cfg_attr(feature = "fmt", derive(core::fmt::Debug))]
468#[derive(Copy, Clone)]
469pub enum ErrorCode {
470    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
471    TryAlternate,
472
473    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
474    BadRequest,
475
476    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
477    Unauthorised,
478
479    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
480    Forbidden,
481
482    #[cfg(any(feature = "rfc8016"))]
483    MobilityForbidden,
484
485    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
486    UnknownAttribute,
487
488    #[cfg(any(feature = "rfc3489"))]
489    StaleCredentials,
490
491    #[cfg(any(feature = "rfc3489"))]
492    IntegrityCheckFailure,
493
494    #[cfg(any(feature = "rfc3489"))]
495    MissingUsername,
496
497    #[cfg(any(feature = "rfc3489"))]
498    UseTls,
499
500    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
501    AllocationMismatch,
502
503    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
504    StaleNonce,
505
506    #[cfg(any(feature = "rfc8656"))]
507    AddressFamilyNotSupported,
508
509    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
510    WrongCredentials,
511
512    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
513    UnsupportedTransportProtocol,
514
515    #[cfg(any(feature = "rfc8656"))]
516    PeerAddressFamilyMismatch,
517
518    #[cfg(any(feature = "rfc6062"))]
519    ConnectionAlreadyExists,
520
521    #[cfg(any(feature = "rfc6062"))]
522    ConnectionTimeoutOrFailure,
523
524    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
525    AllocationQuotaReached,
526
527    #[cfg(any(feature = "rfc5245", feature = "rfc8445"))]
528    RoleConflict,
529
530    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
531    ServerError,
532
533    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
534    InsufficientCapacity,
535
536    #[cfg(any(feature = "rfc3489"))]
537    GlobalFailure,
538
539    Other(u16),
540}
541
542impl From<u16> for ErrorCode {
543    fn from(val: u16) -> Self {
544        use crate::consts::error_code::*;
545
546        match val {
547            #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
548            TRY_ALTERNATE => Self::TryAlternate,
549
550            #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
551            BAD_REQUEST => Self::BadRequest,
552
553            #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
554            UNAUTHORISED => Self::Unauthorised,
555
556            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
557            FORBIDDEN => Self::Forbidden,
558
559            #[cfg(any(feature = "rfc8016"))]
560            MOBILITY_FORBIDDEN => Self::MobilityForbidden,
561
562            #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
563            UNKNOWN_ATTRIBUTE => Self::UnknownAttribute,
564
565            #[cfg(any(feature = "rfc3489"))]
566            STALE_CREDENTIALS => Self::StaleCredentials,
567
568            #[cfg(any(feature = "rfc3489"))]
569            INTEGRITY_CHECK_FAILURE => Self::IntegrityCheckFailure,
570
571            #[cfg(any(feature = "rfc3489"))]
572            MISSING_USERNAME => Self::MissingUsername,
573
574            #[cfg(any(feature = "rfc3489"))]
575            USE_TLS => Self::UseTls,
576
577            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
578            ALLOCATION_MISMATCH => Self::AllocationMismatch,
579
580            #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
581            STALE_NONCE => Self::StaleNonce,
582
583            #[cfg(any(feature = "rfc8656"))]
584            ADDRESS_FAMILY_NOT_SUPPORTED => Self::AddressFamilyNotSupported,
585
586            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
587            WRONG_CREDENTIALS => Self::WrongCredentials,
588
589            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
590            UNSUPPORTED_TRANSPORT_PROTOCOL => Self::UnsupportedTransportProtocol,
591
592            #[cfg(any(feature = "rfc8656"))]
593            PEER_ADDRESS_FAMILY_MISMATCH => Self::PeerAddressFamilyMismatch,
594
595            #[cfg(any(feature = "rfc6062"))]
596            CONNECTION_ALREADY_EXISTS => Self::ConnectionAlreadyExists,
597
598            #[cfg(any(feature = "rfc6062"))]
599            CONNECTION_TIMEOUT_OR_FAILURE => Self::ConnectionTimeoutOrFailure,
600
601            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
602            ALLOCATION_QUOTA_REACHED => Self::AllocationQuotaReached,
603
604            #[cfg(any(feature = "rfc5245", feature = "rfc8445"))]
605            ROLE_CONFLICT => Self::RoleConflict,
606
607            #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
608            SERVER_ERROR => Self::ServerError,
609
610            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
611            INSUFFICIENT_CAPACITY => Self::InsufficientCapacity,
612
613            #[cfg(any(feature = "rfc3489"))]
614            GLOBAL_FAILURE => Self::GlobalFailure,
615
616            code => Self::Other(code),
617        }
618    }
619}
620
621impl From<[u8; 2]> for ErrorCode {
622    fn from(val: [u8; 2]) -> Self {
623        let class = val[0] as u16 >> 5; // we only care about 3 MSB
624        let num = val[1] as u16;
625
626        let code = class * 100 + num;
627        ErrorCode::from(code)
628    }
629}
630
631impl From<ErrorCode> for u16 {
632    fn from(code: ErrorCode) -> Self {
633        use crate::consts::error_code::*;
634
635        match code {
636            #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
637            ErrorCode::TryAlternate => TRY_ALTERNATE,
638
639            #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
640            ErrorCode::BadRequest => BAD_REQUEST,
641
642            #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
643            ErrorCode::Unauthorised => UNAUTHORISED,
644
645            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
646            ErrorCode::Forbidden => FORBIDDEN,
647
648            #[cfg(any(feature = "rfc8016"))]
649            ErrorCode::MobilityForbidden => MOBILITY_FORBIDDEN,
650
651            #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
652            ErrorCode::UnknownAttribute => UNKNOWN_ATTRIBUTE,
653
654            #[cfg(any(feature = "rfc3489"))]
655            ErrorCode::StaleCredentials => STALE_CREDENTIALS,
656
657            #[cfg(any(feature = "rfc3489"))]
658            ErrorCode::IntegrityCheckFailure => INTEGRITY_CHECK_FAILURE,
659
660            #[cfg(any(feature = "rfc3489"))]
661            ErrorCode::MissingUsername => MISSING_USERNAME,
662
663            #[cfg(any(feature = "rfc3489"))]
664            ErrorCode::UseTls => USE_TLS,
665
666            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
667            ErrorCode::AllocationMismatch => ALLOCATION_MISMATCH,
668
669            #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
670            ErrorCode::StaleNonce => STALE_NONCE,
671
672            #[cfg(any(feature = "rfc8656"))]
673            ErrorCode::AddressFamilyNotSupported => ADDRESS_FAMILY_NOT_SUPPORTED,
674
675            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
676            ErrorCode::WrongCredentials => WRONG_CREDENTIALS,
677
678            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
679            ErrorCode::UnsupportedTransportProtocol => UNSUPPORTED_TRANSPORT_PROTOCOL,
680
681            #[cfg(any(feature = "rfc8656"))]
682            ErrorCode::PeerAddressFamilyMismatch => PEER_ADDRESS_FAMILY_MISMATCH,
683
684            #[cfg(any(feature = "rfc6062"))]
685            ErrorCode::ConnectionAlreadyExists => CONNECTION_ALREADY_EXISTS,
686
687            #[cfg(any(feature = "rfc6062"))]
688            ErrorCode::ConnectionTimeoutOrFailure => CONNECTION_TIMEOUT_OR_FAILURE,
689
690            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
691            ErrorCode::AllocationQuotaReached => ALLOCATION_QUOTA_REACHED,
692
693            #[cfg(any(feature = "rfc5245", feature = "rfc8445"))]
694            ErrorCode::RoleConflict => ROLE_CONFLICT,
695
696            #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
697            ErrorCode::ServerError => SERVER_ERROR,
698
699            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
700            ErrorCode::InsufficientCapacity => INSUFFICIENT_CAPACITY,
701
702            #[cfg(any(feature = "rfc3489"))]
703            ErrorCode::GlobalFailure => GLOBAL_FAILURE,
704
705            ErrorCode::Other(code) => code,
706        }
707    }
708}
709
710impl From<ErrorCode> for [u8; 2] {
711    fn from(code: ErrorCode) -> Self {
712        let code = u16::from(code);
713        let code_100s = code / 100;
714        [(code_100s as u8) << 5, (code - code_100s * 100) as u8]
715    }
716}
717
718#[cfg_attr(feature = "fmt", derive(core::fmt::Debug))]
719#[derive(Copy, Clone)]
720pub enum Attr<'a> {
721    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
722    MappedAddress(SocketAddr),
723
724    #[cfg(feature = "rfc3489")]
725    ResponseAddress(SocketAddr),
726
727    #[cfg(any(feature = "rfc3489", feature = "rfc5780"))]
728    ChangeRequest { change_ip: bool, change_port: bool },
729
730    #[cfg(feature = "rfc3489")]
731    SourceAddress(SocketAddr),
732
733    #[cfg(feature = "rfc3489")]
734    ChangedAddress(SocketAddr),
735
736    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
737    Username(&'a str),
738
739    #[cfg(feature = "rfc3489")]
740    Password(&'a str),
741
742    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
743    Realm(&'a str),
744
745    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
746    Nonce(&'a str),
747
748    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
749    MessageIntegrity(&'a [u8; 20]),
750
751    #[cfg(any(feature = "rfc8489"))]
752    MessageIntegritySha256(&'a [u8; 32]),
753
754    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
755    Fingerprint(u32),
756
757    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
758    XorMappedAddress(SocketAddr),
759
760    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
761    Software(&'a str),
762
763    #[cfg(any(feature = "rfc3489"))]
764    OptXorMappedAddress(SocketAddr),
765
766    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
767    AlternateServer(SocketAddr),
768
769    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
770    ErrorCode { code: ErrorCode, desc: &'a str },
771
772    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
773    UnknownAttributes(UnknownAttrIter<'a>),
774
775    #[cfg(feature = "rfc3489")]
776    ReflectedFrom(SocketAddr),
777
778    #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
779    Priority(u32),
780
781    #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
782    UseCandidate,
783
784    #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
785    IceControlled(u64),
786
787    #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
788    IceControlling(u64),
789
790    #[cfg(any(feature = "rfc5780"))]
791    ResponseOrigin(SocketAddr),
792
793    #[cfg(any(feature = "rfc5780"))]
794    OtherAddress(SocketAddr),
795
796    #[cfg(any(feature = "rfc5780"))]
797    ResponsePort(u16),
798
799    #[cfg(any(feature = "rfc5780"))]
800    Padding(&'a [u8]),
801
802    #[cfg(any(feature = "rfc5780"))]
803    CacheTimeout(core::time::Duration),
804
805    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
806    ChannelNumber(u16),
807
808    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
809    Lifetime(core::time::Duration),
810
811    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
812    XorPeerAddress(SocketAddr),
813
814    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
815    Data(&'a [u8]),
816
817    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
818    XorRelayedAddress(SocketAddr),
819
820    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
821    EvenPort(bool),
822
823    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
824    RequestedTransport(TransportProtocol),
825
826    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
827    DontFragment,
828
829    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
830    ReservationToken(u64),
831
832    #[cfg(any(feature = "rfc8656"))]
833    RequestedAddressFamily(AddressFamily),
834
835    #[cfg(any(feature = "rfc8656"))]
836    AdditionalAddressFamily(AddressFamily),
837
838    #[cfg(any(feature = "rfc8656"))]
839    AddressErrorCode { family: AddressFamily, code: ErrorCode, desc: &'a str },
840
841    #[cfg(any(feature = "rfc8656"))]
842    Icmp { typ: u8, code: u8, data: u32 }, // maybe can be narrowed down
843
844    #[cfg(any(feature = "rfc8489"))]
845    Userhash(&'a [u8; 32]),
846
847    #[cfg(any(feature = "rfc8489"))]
848    PasswordAlgorithm(PasswordAlgorithm<'a>),
849
850    #[cfg(any(feature = "rfc8489"))]
851    PasswordAlgorithms(PasswordAlgorithmIter<'a>),
852
853    #[cfg(any(feature = "rfc8489"))]
854    AlternateDomain(&'a str),
855
856    #[cfg(any(feature = "rfc6679"))]
857    EcnCheck { valid: bool, val: u8 },
858
859    #[cfg(any(feature = "rfc7635"))]
860    ThirdPartyAuthorisation(&'a str),
861
862    #[cfg(any(feature = "rfc7635"))]
863    AccessToken { nonce: &'a [u8], mac: &'a [u8], timestamp: core::time::Duration, lifetime: core::time::Duration },
864
865    #[cfg(any(feature = "rfc8016"))]
866    MobilityTicket(&'a [u8]),
867
868    #[cfg(any(feature = "rfc6062"))]
869    ConnectionId(u32),
870
871    #[cfg(any(feature = "rfc7982"))]
872    TransactionTransmitCounter { req: u8, res: u8 },
873
874    Other { typ: u16, val: &'a [u8] },
875}
876
877impl<'a> Attr<'a> {
878    fn from_buf(typ_buf: &'a [u8; 2], len_buf: &'a [u8; 2], val_buf: &'a [u8], tid_buf: &'a [u8; 16]) -> Option<Attr<'a>> {
879        let typ = typ_buf.as_be();
880        let len: u16 = len_buf.as_be();
881        let val = val_buf.get(0..len as usize)?;
882
883        use crate::consts::attr_type::*;
884
885        Some(match typ {
886            #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
887            MAPPED_ADDRESS => Self::MappedAddress(Self::read_address(val)?),
888
889            #[cfg(feature = "rfc3489")]
890            RESPONSE_ADDRESS => Self::ResponseAddress(Self::read_address(val)?),
891
892            #[cfg(any(feature = "rfc3489", feature = "rfc5780"))]
893            CHANGE_REQUEST => {
894                let (change_ip, change_port) = Self::read_change_request(val)?;
895                Self::ChangeRequest { change_ip, change_port }
896            }
897
898            #[cfg(feature = "rfc3489")]
899            SOURCE_ADDRESS => Self::SourceAddress(Self::read_address(val)?),
900
901            #[cfg(feature = "rfc3489")]
902            CHANGED_ADDRESS => Self::ChangedAddress(Self::read_address(val)?),
903
904            #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
905            USERNAME => Self::Username(Self::read_string(val)?),
906
907            #[cfg(feature = "rfc3489")]
908            PASSWORD => Self::Password(Self::read_string(val)?),
909
910            #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
911            MESSAGE_INTEGRITY => Self::MessageIntegrity(val.carved()?),
912
913            #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
914            ERROR_CODE => {
915                let (code, desc) = Self::read_error_code(val)?;
916                Self::ErrorCode { code, desc }
917            }
918
919            #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
920            UNKNOWN_ATTRIBUTES => Self::UnknownAttributes(UnknownAttrIter::from(val)),
921
922            #[cfg(feature = "rfc3489")]
923            REFLECTED_FROM => Self::ReflectedFrom(Self::read_address(val)?),
924
925            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
926            CHANNEL_NUMBER => Self::ChannelNumber(val.carved().map(u16::from_be_ref)?),
927
928            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
929            LIFETIME => Self::Lifetime(core::time::Duration::from_secs(val.carved().map(u32::from_be_ref)? as u64)),
930
931            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
932            XOR_PEER_ADDRESS => Self::XorPeerAddress(Self::read_xor_address(val, tid_buf)?),
933
934            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
935            DATA => Self::Data(val),
936
937            #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
938            REALM => Self::Realm(Self::read_string(val)?),
939
940            #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
941            NONCE => Self::Nonce(Self::read_string(val)?),
942
943            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
944            XOR_RELAYED_ADDRESS => Self::XorRelayedAddress(Self::read_xor_address(val, tid_buf)?),
945
946            #[cfg(any(feature = "rfc8656"))]
947            REQUESTED_ADDRESS_FAMILY => Self::RequestedAddressFamily(val.get(0).map(AddressFamily::from_ref)?),
948
949            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
950            EVEN_PORT => Self::EvenPort(val.get(0).map(|val| val & 1 == 1)?),
951
952            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
953            REQUESTED_TRANSPORT => Self::RequestedTransport(val.get(0).map(TransportProtocol::from_ref)?),
954
955            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
956            DONT_FRAGMENT => Self::DontFragment,
957
958            #[cfg(any(feature = "rfc7635"))]
959            ACCESS_TOKEN => {
960                let (nonce, mac, timestamp, lifetime) = Self::read_access_token(val)?;
961                Self::AccessToken {
962                    nonce,
963                    mac,
964                    timestamp,
965                    lifetime,
966                }
967            }
968
969            #[cfg(any(feature = "rfc8489"))]
970            MESSAGE_INTEGRITY_SHA256 => Self::MessageIntegritySha256(val.carved()?),
971
972            #[cfg(any(feature = "rfc8489"))]
973            PASSWORD_ALGORITHM => Self::PasswordAlgorithm(Self::read_password_algorithm(val)?),
974
975            #[cfg(any(feature = "rfc8489"))]
976            USERHASH => Self::Userhash(val.carved()?),
977
978            #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
979            XOR_MAPPED_ADDRESS => Self::XorMappedAddress(Self::read_xor_address(val, tid_buf)?),
980
981            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
982            RESERVATION_TOKEN => Self::ReservationToken(val.carved().map(u64::from_be_ref)?),
983
984            #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
985            PRIORITY => Self::Priority(val.carved().map(u32::from_be_ref)?),
986
987            #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
988            USE_CANDIDATE => Self::UseCandidate,
989
990            #[cfg(any(feature = "rfc5780"))]
991            PADDING => Self::Padding(val),
992
993            #[cfg(any(feature = "rfc5780"))]
994            RESPONSE_PORT => Self::ResponsePort(val.carved().map(u16::from_be_ref)?),
995
996            #[cfg(any(feature = "rfc6062"))]
997            CONNECTION_ID => Self::ConnectionId(val.carved().map(u32::from_be_ref)?),
998
999            #[cfg(any(feature = "rfc8656"))]
1000            ADDITIONAL_ADDRESS_FAMILY => Self::AdditionalAddressFamily(val.get(0).map(AddressFamily::from_ref)?),
1001
1002            #[cfg(any(feature = "rfc8656"))]
1003            ADDRESS_ERROR_CODE => {
1004                let (family, code, desc) = Self::read_address_error_code(val)?;
1005                Self::AddressErrorCode {
1006                    family,
1007                    code,
1008                    desc,
1009                }
1010            }
1011
1012            #[cfg(any(feature = "rfc8489"))]
1013            PASSWORD_ALGORITHMS => {
1014                Self::PasswordAlgorithms(PasswordAlgorithmIter {
1015                    byte_iter: stun_bytes::ByteAttrIter::from(val),
1016                })
1017            }
1018
1019            #[cfg(any(feature = "rfc8489"))]
1020            ALTERNATE_DOMAIN => Self::AlternateDomain(Self::read_string(val)?),
1021
1022            #[cfg(any(feature = "rfc8656"))]
1023            ICMP => Self::Icmp {
1024                typ: *val.get(2)?,
1025                code: *val.get(3)?,
1026                data: val.carve(4).map(u32::from_be_ref)?,
1027            },
1028
1029            #[cfg(any(feature = "rfc3489"))]
1030            OPT_XOR_MAPPED_ADDRESS => Self::OptXorMappedAddress(Self::read_xor_address(val, tid_buf)?), // Vovida.org encodes XorMappedAddress as 0x8020 for backwards compat with RFC3489
1031
1032            #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
1033            SOFTWARE => Self::Software(Self::read_string(val)?),
1034
1035            #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
1036            ALTERNATE_SERVER => Self::AlternateServer(Self::read_address(val)?),
1037
1038            #[cfg(any(feature = "rfc7982"))]
1039            TRANSACTION_TRANSMIT_COUNTER => Self::TransactionTransmitCounter {
1040                req: *val.get(2)?,
1041                res: *val.get(3)?,
1042            },
1043
1044            #[cfg(any(feature = "rfc5780"))]
1045            CACHE_TIMEOUT => {
1046                let timeout = val.carved()
1047                    .map(u32::from_be_ref)
1048                    .map(|val| val as u64)
1049                    .map(core::time::Duration::from_secs)?;
1050
1051                Self::CacheTimeout(timeout)
1052            }
1053
1054            #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
1055            FINGERPRINT => Self::Fingerprint(Self::read_fingerprint(val)?),
1056
1057            #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
1058            ICE_CONTROLLED => Self::IceControlled(val.carved().map(u64::from_be_ref)?),
1059
1060            #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
1061            ICE_CONTROLLING => Self::IceControlling(val.carved().map(u64::from_be_ref)?),
1062
1063            #[cfg(any(feature = "rfc5780"))]
1064            RESPONSE_ORIGIN => Self::ResponseOrigin(Self::read_address(val)?),
1065
1066            #[cfg(any(feature = "rfc5780"))]
1067            OTHER_ADDRESS => Self::OtherAddress(Self::read_address(val)?),
1068
1069            #[cfg(any(feature = "rfc6679"))]
1070            ECN_CHECK => Self::EcnCheck {
1071                valid: val.get(3).map(|val| val & 128 != 0)?,
1072                val: val.get(3).map(|val| (val & 96) >> 5)?,
1073            },
1074
1075            #[cfg(any(feature = "rfc7635"))]
1076            THIRD_PARTY_AUTHORISATION => Self::ThirdPartyAuthorisation(Self::read_string(val)?),
1077
1078            #[cfg(any(feature = "rfc8016"))]
1079            MOBILITY_TICKET => Self::MobilityTicket(val),
1080
1081            typ => Self::Other { typ, val },
1082        })
1083    }
1084
1085    fn read_address(buf: &[u8]) -> Option<SocketAddr> {
1086        let addr_family = buf.carved()
1087            .map(u16::from_be_ref)?;
1088
1089        let port = buf.carve(2)
1090            .map(u16::from_be_ref)?;
1091
1092        if addr_family == 1 {
1093            let ip = buf.carve(4)?;
1094            return Some(SocketAddr::V4(*ip, port));
1095        }
1096
1097        if addr_family == 2 {
1098            let ip = buf.carve(4)?;
1099            return Some(SocketAddr::V6(*ip, port));
1100        }
1101
1102        return None;
1103    }
1104
1105    fn read_xor_address(buf: &[u8], tid: &[u8; 16]) -> Option<SocketAddr> {
1106        let addr_family = buf.carved()
1107            .map(u16::from_be_ref)?;
1108
1109        let port_mask = tid.carved()
1110            .map(u16::from_be_ref)?;
1111
1112        let port = buf.carve(2)
1113            .map(u16::from_be_ref)
1114            .map(|port| port ^ port_mask)?;
1115
1116        if addr_family == 1 {
1117            let cookie = tid.carved()
1118                .map(u32::from_be_ref)?;
1119
1120            let ip = buf.carve(4)
1121                .map(u32::from_be_ref)
1122                .map(|ip| ip ^ cookie)
1123                .map(u32::to_be_bytes)?;
1124
1125            Some(SocketAddr::V4(ip, port))
1126        } else if addr_family == 2 {
1127            let tid: u128 = tid.as_be();
1128
1129            let ip = buf.carve(4)
1130                .map(u128::from_be_ref)
1131                .map(|ip| ip ^ tid)
1132                .map(u128::to_be_bytes)?;
1133
1134            Some(SocketAddr::V6(ip, port))
1135        } else { None }
1136    }
1137
1138    fn read_string(buf: &[u8]) -> Option<&str> {
1139        core::str::from_utf8(buf).ok()
1140    }
1141
1142    fn read_fingerprint(buf: &[u8]) -> Option<u32> {
1143        buf.carved()
1144            .map(u32::from_be_ref)
1145            .map(|val| val ^ 0x5354554E)
1146    }
1147
1148    fn read_error_code(buf: &[u8]) -> Option<(ErrorCode, &str)> {
1149        let code = ErrorCode::from_ref(buf.carve(2)?);
1150        let desc = buf.get(4..).map(Self::read_string)??;
1151        Some((code, desc))
1152    }
1153
1154    fn read_change_request(buf: &[u8]) -> Option<(bool, bool)> {
1155        let change_ip = buf.get(3).map(|b| b & 0x40 != 0)?;
1156        let change_port = buf.get(3).map(|b| b & 0x20 != 0)?;
1157        Some((change_ip, change_port))
1158    }
1159
1160    fn read_access_token(buf: &[u8]) -> Option<(&[u8], &[u8], core::time::Duration, core::time::Duration)> {
1161        let mut cursor = 0usize;
1162
1163        let nonce_len = buf.carve(cursor)
1164            .map(u16::from_be_ref)? as usize;
1165
1166        cursor += 2;
1167
1168        let nonce = buf.get(cursor..cursor + nonce_len)?;
1169
1170        cursor += nonce_len;
1171
1172        let mac_len = buf.carve(cursor)
1173            .map(u16::from_be_ref)? as usize;
1174
1175        cursor += 2;
1176
1177        let mac = buf.get(cursor..cursor + mac_len)?;
1178
1179        cursor += mac_len;
1180
1181        let timestamp_bytes = buf.carve::<8>(cursor)?;
1182
1183        cursor += 8;
1184
1185        let timestamp_seconds = timestamp_bytes.carved()
1186            .map(u32::from_be_ref)
1187            .map(|val| (val as u64) << 16)? | timestamp_bytes.carve(4)
1188            .map(u16::from_be_ref)? as u64;
1189
1190        let timestamp_frac = timestamp_bytes.carve(6)
1191            .map(u16::from_be_ref)? as f64 / 64000_f64;
1192
1193        let timestamp = core::time::Duration::from_secs_f64(timestamp_seconds as f64 + timestamp_frac);
1194
1195        let lifetime_secs = buf.carve(cursor)
1196            .map(u32::from_be_ref)?;
1197
1198        let lifetime = core::time::Duration::from_secs(lifetime_secs as u64);
1199
1200        Some((nonce, mac, timestamp, lifetime))
1201    }
1202
1203    fn read_password_algorithm(buf: &[u8]) -> Option<PasswordAlgorithm> {
1204        PasswordAlgorithmIter { byte_iter: stun_bytes::ByteAttrIter::from(buf) }.next()
1205    }
1206
1207    fn read_address_error_code(buf: &'a [u8]) -> Option<(AddressFamily, ErrorCode, &'a str)> {
1208        let address_family = buf.get(0)
1209            .map(AddressFamily::from_ref)?;
1210
1211        let error_code = buf.carve(2)
1212            .map(ErrorCode::from_ref)?;
1213
1214        let desc = Self::read_string(buf.get(4..)?)?;
1215
1216        Some((address_family, error_code, desc))
1217    }
1218}
1219
1220impl<'a> Attr<'a> {
1221    fn into_buf(&self, typ_buf: &'a mut [u8; 2], len_buf: &'a mut [u8; 2], val_buf: &'a mut [u8], tid_buf: &'a [u8; 16]) -> Option<usize> {
1222        use crate::consts::attr_type::*;
1223
1224        match self {
1225            #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
1226            Self::MappedAddress(addr) => {
1227                typ_buf.set_be(MAPPED_ADDRESS);
1228                let size = Self::write_address(&addr, val_buf)?;
1229                len_buf.set_be(size as u16);
1230                Some(size)
1231            }
1232
1233            #[cfg(feature = "rfc3489")]
1234            Self::ResponseAddress(addr) => {
1235                typ_buf.set_be(RESPONSE_ADDRESS);
1236                let size = Self::write_address(&addr, val_buf)?;
1237                len_buf.set_be(size as u16);
1238                Some(size)
1239            }
1240
1241            #[cfg(any(feature = "rfc3489", feature = "rfc5780"))]
1242            Self::ChangeRequest { change_ip, change_port } => {
1243                typ_buf.set_be(CHANGE_REQUEST);
1244                let size = Self::write_change_request(*change_ip, *change_port, val_buf)?;
1245                len_buf.set_be(size as u16);
1246                Some(size)
1247            }
1248
1249            #[cfg(feature = "rfc3489")]
1250            Self::SourceAddress(addr) => {
1251                typ_buf.set_be(SOURCE_ADDRESS);
1252                let size = Self::write_address(&addr, val_buf)?;
1253                len_buf.set_be(size as u16);
1254                Some(size)
1255            }
1256
1257            #[cfg(feature = "rfc3489")]
1258            Self::ChangedAddress(addr) => {
1259                typ_buf.set_be(CHANGED_ADDRESS);
1260                let size = Self::write_address(&addr, val_buf)?;
1261                len_buf.set_be(size as u16);
1262                Some(size)
1263            }
1264
1265            #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
1266            Self::Username(uname) => {
1267                typ_buf.set_be(USERNAME);
1268                let size = Self::write_string(uname, val_buf)?;
1269                len_buf.set_be(size as u16);
1270                Some(size)
1271            }
1272
1273            #[cfg(feature = "rfc3489")]
1274            Self::Password(pwd) => {
1275                typ_buf.set_be(PASSWORD);
1276                let size = Self::write_string(pwd, val_buf)?;
1277                len_buf.set_be(size as u16);
1278                Some(size)
1279            }
1280
1281            #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
1282            Self::MessageIntegrity(digest) => {
1283                typ_buf.set_be(MESSAGE_INTEGRITY);
1284                val_buf.carved_mut()?.copy_from(digest);
1285                len_buf.set_be(20 as u16);
1286                Some(20)
1287            }
1288
1289            #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
1290            Self::ErrorCode { code, desc } => {
1291                typ_buf.set_be(ERROR_CODE);
1292                let size = Self::write_error_code(code, desc, val_buf)?;
1293                len_buf.set_be(size as u16);
1294                Some(size)
1295            }
1296
1297            #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
1298            Self::UnknownAttributes(iter) => {
1299                typ_buf.set_be(UNKNOWN_ATTRIBUTES);
1300                let count = iter.clone().count();
1301                let len_with_padding = (count * 2 + 3) & !3;
1302                if val_buf.len() < len_with_padding { return None; }
1303                let mut idx = 0;
1304                for attr in iter.clone() {
1305                    val_buf.carve_mut(idx)?.set_be(attr);
1306                    idx += 2;
1307                }
1308                if count % 2 != 0 { // the padding should be one of the attrs (RFC 3489), or zero (RFC5389+)
1309                    if cfg!(any(feature = "rfc5349", feature = "rfc8489")) {
1310                        val_buf.carve_mut(idx)?.set_be(0u16);
1311                    } else {
1312                        val_buf.carve_mut(idx)?.set_be(iter.clone().next().unwrap_or(0u16));
1313                    }
1314                }
1315                len_buf.set_be((count * 2) as u16);
1316                Some(count * 2)
1317            }
1318
1319            #[cfg(feature = "rfc3489")]
1320            Self::ReflectedFrom(addr) => {
1321                typ_buf.set_be(REFLECTED_FROM);
1322                let size = Self::write_address(&addr, val_buf)?;
1323                len_buf.set_be(size as u16);
1324                Some(size)
1325            }
1326
1327            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
1328            Self::ChannelNumber(num) => {
1329                typ_buf.set_be(CHANNEL_NUMBER);
1330                val_buf.carved_mut()?.set_be(*num);
1331                len_buf.set_be(2 as u16);
1332                Some(2)
1333            }
1334
1335            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
1336            Self::Lifetime(lifetime) => {
1337                typ_buf.set_be(LIFETIME);
1338                val_buf.carved_mut()?.copy_from(&(lifetime.as_secs() as u32).to_be_bytes());
1339                len_buf.set_be(4 as u16);
1340                Some(4)
1341            }
1342
1343            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
1344            Self::XorPeerAddress(addr) => {
1345                typ_buf.set_be(XOR_PEER_ADDRESS);
1346                let size = Self::write_xor_address(&addr, val_buf, tid_buf)?;
1347                len_buf.set_be(size as u16);
1348                Some(size)
1349            }
1350
1351            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
1352            Self::Data(data) => {
1353                typ_buf.set_be(DATA);
1354                val_buf.get_mut(0..data.len())?.copy_from_slice(data);
1355                len_buf.set_be(data.len() as u16);
1356                Some(data.len())
1357            }
1358
1359            #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
1360            Self::Realm(realm) => {
1361                typ_buf.set_be(REALM);
1362                let size = Self::write_string(realm, val_buf)?;
1363                len_buf.set_be(size as u16);
1364                Some(size)
1365            }
1366
1367            #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
1368            Self::Nonce(nonce) => {
1369                typ_buf.set_be(NONCE);
1370                let size = Self::write_string(nonce, val_buf)?;
1371                len_buf.set_be(size as u16);
1372                Some(size)
1373            }
1374
1375            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
1376            Self::XorRelayedAddress(addr) => {
1377                typ_buf.set_be(XOR_RELAYED_ADDRESS);
1378                let size = Self::write_xor_address(addr, val_buf, tid_buf)?;
1379                len_buf.set_be(size as u16);
1380                Some(size)
1381            }
1382
1383            #[cfg(any(feature = "rfc8656"))]
1384            Self::RequestedAddressFamily(fam) => {
1385                typ_buf.set_be(REQUESTED_ADDRESS_FAMILY);
1386                *val_buf.get_mut(0)? = fam.ref_into();
1387                len_buf.set_be(4 as u16);
1388                Some(4)
1389            }
1390
1391            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
1392            Self::EvenPort(even_port) => {
1393                typ_buf.set_be(EVEN_PORT);
1394                *val_buf.get_mut(0)? = *even_port as u8;
1395                len_buf.set_be(1 as u16);
1396                Some(1)
1397            }
1398
1399            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
1400            Self::RequestedTransport(proto) => {
1401                typ_buf.set_be(REQUESTED_TRANSPORT);
1402                *val_buf.get_mut(0)? = proto.ref_into();
1403                len_buf.set_be(4 as u16);
1404                Some(4)
1405            }
1406
1407            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
1408            Self::DontFragment => {
1409                typ_buf.set_be(DONT_FRAGMENT);
1410                len_buf.set_be(0 as u16);
1411                Some(0)
1412            }
1413
1414            #[cfg(any(feature = "rfc7635"))]
1415            Self::AccessToken { nonce, mac, timestamp, lifetime } => {
1416                typ_buf.set_be(ACCESS_TOKEN);
1417                let size = Self::write_access_token(nonce, mac, timestamp, lifetime, val_buf)?;
1418                len_buf.set_be(size as u16);
1419                Some(size)
1420            }
1421
1422            #[cfg(any(feature = "rfc8489"))]
1423            Self::MessageIntegritySha256(digest) => {
1424                typ_buf.set_be(MESSAGE_INTEGRITY_SHA256);
1425                val_buf.carved_mut()?.copy_from(digest);
1426                len_buf.set_be(32 as u16);
1427                Some(32)
1428            }
1429
1430            #[cfg(any(feature = "rfc8489"))]
1431            Self::PasswordAlgorithm(alg) => {
1432                typ_buf.set_be(PASSWORD_ALGORITHM);
1433                let size = Self::write_password_algorithm(alg, val_buf)?;
1434                len_buf.set_be(size as u16);
1435                Some(size)
1436            }
1437
1438            #[cfg(any(feature = "rfc8489"))]
1439            Self::Userhash(digest) => {
1440                typ_buf.set_be(USERHASH);
1441                val_buf.carved_mut()?.copy_from(digest);
1442                len_buf.set_be(32 as u16);
1443                Some(32)
1444            }
1445
1446            #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
1447            Self::XorMappedAddress(addr) => {
1448                typ_buf.set_be(XOR_MAPPED_ADDRESS);
1449                let size = Self::write_xor_address(&addr, val_buf, tid_buf)?;
1450                len_buf.set_be(size as u16);
1451                Some(size)
1452            }
1453
1454            #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
1455            Self::ReservationToken(token) => {
1456                typ_buf.set_be(RESERVATION_TOKEN);
1457                val_buf.carved_mut()?.set_be(*token);
1458                len_buf.set_be(8 as u16);
1459                Some(8)
1460            }
1461
1462            #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
1463            Self::Priority(priority) => {
1464                typ_buf.set_be(PRIORITY);
1465                val_buf.carved_mut()?.set_be(*priority);
1466                len_buf.set_be(4 as u16);
1467                Some(4)
1468            }
1469
1470            #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
1471            Self::UseCandidate => {
1472                typ_buf.set_be(USE_CANDIDATE);
1473                len_buf.set_be(0 as u16);
1474                Some(0)
1475            }
1476
1477            #[cfg(any(feature = "rfc5780"))]
1478            Self::Padding(pad) => {
1479                typ_buf.set_be(PADDING);
1480                val_buf.get_mut(0..pad.len())?.copy_from_slice(pad);
1481                len_buf.set_be(pad.len() as u16);
1482                Some(pad.len())
1483            }
1484
1485            #[cfg(any(feature = "rfc5780"))]
1486            Self::ResponsePort(port) => {
1487                typ_buf.set_be(RESPONSE_PORT);
1488                val_buf.carved_mut()?.set_be(*port);
1489                len_buf.set_be(4 as u16);
1490                Some(2)
1491            }
1492
1493            #[cfg(any(feature = "rfc6062"))]
1494            Self::ConnectionId(cid) => {
1495                typ_buf.set_be(CONNECTION_ID);
1496                val_buf.carved_mut()?.set_be(*cid);
1497                len_buf.set_be(4 as u16);
1498                Some(4)
1499            }
1500
1501            #[cfg(any(feature = "rfc8656"))]
1502            Self::AdditionalAddressFamily(fam) => {
1503                typ_buf.set_be(ADDITIONAL_ADDRESS_FAMILY);
1504                *val_buf.get_mut(0)? = fam.ref_into();
1505                len_buf.set_be(4 as u16);
1506                Some(4)
1507            }
1508
1509            #[cfg(any(feature = "rfc8656"))]
1510            Self::AddressErrorCode { family, code, desc } => {
1511                typ_buf.set_be(ADDRESS_ERROR_CODE);
1512                let size = Self::write_address_error_code(family, code, desc, val_buf)?;
1513                len_buf.set_be(size as u16);
1514                Some(size)
1515            }
1516
1517            #[cfg(any(feature = "rfc8489"))]
1518            Self::PasswordAlgorithms(iter) => {
1519                typ_buf.set_be(PASSWORD_ALGORITHMS);
1520                let mut val_size = 0;
1521                for alg in iter.clone() {
1522                    let size = Self::write_password_algorithm(&alg, val_buf.get_mut(val_size..)?)?;
1523                    val_size += size;
1524                }
1525                len_buf.set_be(val_size as u16);
1526                Some(val_size)
1527            }
1528
1529            #[cfg(any(feature = "rfc8489"))]
1530            Self::AlternateDomain(domain) => {
1531                typ_buf.set_be(ALTERNATE_DOMAIN);
1532                let size = Self::write_string(domain, val_buf)?;
1533                len_buf.set_be(size as u16);
1534                Some(size)
1535            }
1536
1537            #[cfg(any(feature = "rfc8656"))]
1538            Self::Icmp { typ, code, data } => {
1539                typ_buf.set_be(ICMP);
1540                *val_buf.get_mut(2)? = *typ;
1541                *val_buf.get_mut(3)? = *code;
1542                val_buf.carve_mut(4)?.set_be(*data);
1543                len_buf.set_be(8 as u16);
1544                Some(8)
1545            }
1546
1547            #[cfg(any(feature = "rfc3489"))]
1548            Self::OptXorMappedAddress(addr) => {
1549                typ_buf.set_be(OPT_XOR_MAPPED_ADDRESS);
1550                let size = Self::write_xor_address(addr, val_buf, tid_buf)?;
1551                len_buf.set_be(size as u16);
1552                Some(size)
1553            }
1554
1555            #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
1556            Self::Software(software) => {
1557                typ_buf.set_be(SOFTWARE);
1558                let size = Self::write_string(software, val_buf)?;
1559                len_buf.set_be(size as u16);
1560                Some(size)
1561            }
1562
1563            #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
1564            Self::AlternateServer(addr) => {
1565                typ_buf.set_be(ALTERNATE_SERVER);
1566                let size = Self::write_address(addr, val_buf)?;
1567                len_buf.set_be(size as u16);
1568                Some(size)
1569            }
1570
1571            #[cfg(any(feature = "rfc7982"))]
1572            Self::TransactionTransmitCounter { req, res } => {
1573                typ_buf.set_be(TRANSACTION_TRANSMIT_COUNTER);
1574                *val_buf.get_mut(2)? = *req;
1575                *val_buf.get_mut(3)? = *res;
1576                len_buf.set_be(4 as u16);
1577                Some(4)
1578            }
1579
1580            #[cfg(any(feature = "rfc5780"))]
1581            Self::CacheTimeout(timeout) => {
1582                typ_buf.set_be(CACHE_TIMEOUT);
1583                val_buf.carved_mut()?.set_be(timeout.as_secs() as u32);
1584                len_buf.set_be(4 as u16);
1585                Some(4)
1586            }
1587
1588            #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
1589            Self::Fingerprint(digest) => {
1590                typ_buf.set_be(FINGERPRINT);
1591                val_buf.carved_mut()?.set_be(*digest ^ 0x5354554E);
1592                len_buf.set_be(4 as u16);
1593                Some(4)
1594            }
1595
1596            #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
1597            Self::IceControlled(token) => {
1598                typ_buf.set_be(ICE_CONTROLLED);
1599                val_buf.carved_mut()?.set_be(*token);
1600                len_buf.set_be(8 as u16);
1601                Some(8)
1602            }
1603
1604            #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
1605            Self::IceControlling(token) => {
1606                typ_buf.set_be(ICE_CONTROLLING);
1607                val_buf.carved_mut()?.set_be(*token);
1608                len_buf.set_be(8 as u16);
1609                Some(8)
1610            }
1611
1612            #[cfg(any(feature = "rfc5780"))]
1613            Self::ResponseOrigin(addr) => {
1614                typ_buf.set_be(RESPONSE_ORIGIN);
1615                let size = Self::write_address(addr, val_buf)?;
1616                len_buf.set_be(size as u16);
1617                Some(size)
1618            }
1619
1620            #[cfg(any(feature = "rfc5780"))]
1621            Self::OtherAddress(addr) => {
1622                typ_buf.set_be(OTHER_ADDRESS);
1623                let size = Self::write_address(addr, val_buf)?;
1624                len_buf.set_be(size as u16);
1625                Some(size)
1626            }
1627
1628            #[cfg(any(feature = "rfc6679"))]
1629            Self::EcnCheck { valid, val } => {
1630                typ_buf.set_be(ECN_CHECK);
1631                let valid = (*valid as u8) << 7;
1632                let val = (val & 3) << 5;
1633                *val_buf.get_mut(3)? = val | valid;
1634                len_buf.set_be(4 as u16);
1635                Some(4)
1636            }
1637
1638            #[cfg(any(feature = "rfc7635"))]
1639            Self::ThirdPartyAuthorisation(token) => {
1640                typ_buf.set_be(THIRD_PARTY_AUTHORISATION);
1641                let size = Self::write_string(token, val_buf)?;
1642                len_buf.set_be(size as u16);
1643                Some(size)
1644            }
1645
1646            #[cfg(any(feature = "rfc8016"))]
1647            Self::MobilityTicket(data) => {
1648                typ_buf.set_be(MOBILITY_TICKET);
1649                val_buf.get_mut(0..data.len())?.copy_from_slice(data);
1650                len_buf.set_be(data.len() as u16);
1651                Some(data.len())
1652            }
1653
1654            Self::Other { typ, val } => {
1655                typ_buf.set_be(*typ);
1656                val_buf.get_mut(0..val.len())?.copy_from_slice(val);
1657                len_buf.set_be(val.len() as u16);
1658                Some(val.len())
1659            }
1660        }
1661    }
1662
1663    fn write_address(addr: &SocketAddr, buf: &mut [u8]) -> Option<usize> {
1664        let addr_family = buf.carved_mut()?;
1665        let addr_fam: u8 = addr.addr_family().into();
1666        addr_family.copy_from(&(addr_fam as u16).to_be_bytes());
1667
1668        let port = buf.carve_mut(2)?;
1669
1670        match addr {
1671            SocketAddr::V4(ip, port_val) => {
1672                port.set_be(*port_val);
1673                buf.carve_mut(4)?.copy_from(ip);
1674                Some(8)
1675            }
1676            SocketAddr::V6(ip, port_val) => {
1677                port.set_be(*port_val);
1678                buf.carve_mut(4)?.copy_from(ip);
1679                Some(20)
1680            }
1681        }
1682    }
1683
1684    fn write_xor_address(addr: &SocketAddr, buf: &mut [u8], tid: &[u8; 16]) -> Option<usize> {
1685        let port_mask = tid.carved()
1686            .map(u16::from_be_ref)?;
1687
1688        let xor_addr = match addr {
1689            SocketAddr::V4(ip, port) => {
1690                let port = port ^ port_mask;
1691
1692                let cookie = tid.carved()
1693                    .map(u32::from_be_ref)?;
1694
1695                let ip: u32 = ip.as_be();
1696                let ip = (ip ^ cookie).to_be_bytes();
1697
1698                SocketAddr::V4(ip, port)
1699            }
1700
1701            SocketAddr::V6(ip, port) => {
1702                let port = port ^ port_mask;
1703
1704                let tid: u128 = tid.as_be();
1705
1706                let ip: u128 = ip.as_be();
1707                let ip = (ip ^ tid).to_be_bytes();
1708
1709                SocketAddr::V6(ip, port)
1710            }
1711        };
1712
1713        Self::write_address(&xor_addr, buf)
1714    }
1715
1716    fn write_string(val: &str, buf: &mut [u8]) -> Option<usize> {
1717        let len = val.len();
1718        buf.get_mut(0..len)?.copy_from_slice(val.as_bytes());
1719        Some(len)
1720    }
1721
1722    fn write_error_code(code: &ErrorCode, desc: &str, buf: &mut [u8]) -> Option<usize> {
1723        let code_bytes: [u8; 2] = code.ref_into();
1724        buf.carve_mut(2)?.copy_from(&code_bytes);
1725        Self::write_string(desc, buf.get_mut(4..)?).map(|size| 4 + size) // '4' accounts for error code
1726    }
1727
1728    fn write_change_request(change_ip: bool, change_port: bool, buf: &mut [u8]) -> Option<usize> {
1729        let change_ip = if change_ip { 0x40 } else { 0x00 } as u8;
1730        let change_port = if change_port { 0x20 } else { 0x00 } as u8;
1731
1732        buf.get_mut(3).map(|b| *b = change_ip | change_port);
1733        Some(4)
1734    }
1735
1736    fn write_access_token(nonce: &[u8], mac: &[u8], timestamp: &core::time::Duration, lifetime: &core::time::Duration, buf: &mut [u8]) -> Option<usize> {
1737        let mut cursor = 0usize;
1738
1739        let nonce_len = nonce.len();
1740
1741        buf.carve_mut(cursor)?.copy_from(&(nonce_len as u16).to_be_bytes());
1742
1743        cursor += 2;
1744
1745        buf.get_mut(cursor..cursor + nonce_len)?.copy_from_slice(nonce);
1746
1747        cursor += nonce_len;
1748
1749        let mac_len = mac.len();
1750
1751        buf.carve_mut(cursor)?.copy_from(&(mac_len as u16).to_be_bytes());
1752
1753        cursor += 2;
1754
1755        buf.get_mut(cursor..cursor + mac_len)?.copy_from_slice(mac);
1756
1757        cursor += mac_len;
1758
1759        let timestamp_unix = timestamp.as_secs() << 16;
1760        let timestamp_unix = timestamp_unix | (((timestamp.as_secs_f64() - timestamp.as_secs() as f64) * 64000_f64) as u16) as u64;
1761
1762        buf.carve_mut(cursor)?.copy_from(&timestamp_unix.to_be_bytes());
1763
1764        cursor += 8;
1765
1766        buf.carve_mut(cursor)?.copy_from(&(lifetime.as_secs() as u32).to_be_bytes());
1767
1768        cursor += 4;
1769
1770        Some(cursor)
1771    }
1772
1773    fn write_password_algorithm(val: &PasswordAlgorithm, buf: &mut [u8]) -> Option<usize> {
1774        let (typ, params) = val.into_nums();
1775
1776        buf.carved_mut()?.copy_from(&typ.to_be_bytes());
1777
1778        let len = params.len() as u16;
1779        buf.carve_mut(2)?.copy_from(&len.to_be_bytes());
1780
1781        buf.get_mut(4..4 + len as usize)?.copy_from_slice(params);
1782
1783        Some(4 + len as usize)
1784    }
1785
1786    fn write_address_error_code(fam: &AddressFamily, code: &ErrorCode, desc: &str, buf: &mut [u8]) -> Option<usize> {
1787        *buf.get_mut(0)? = fam.ref_into();
1788
1789        Self::write_error_code(code, desc, buf)
1790    }
1791}
1792
1793#[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
1794#[derive(Copy, Clone)]
1795pub struct UnknownAttrIter<'a> {
1796    buf: &'a [u8],
1797    is_buf_be: bool,
1798}
1799
1800#[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
1801impl<'a> From<&'a [u8]> for UnknownAttrIter<'a> {
1802    fn from(buf: &'a [u8]) -> Self {
1803        Self {
1804            buf,
1805            is_buf_be: true,
1806        }
1807    }
1808}
1809
1810#[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
1811impl<'a> From<&'a [u16]> for UnknownAttrIter<'a> {
1812    fn from(buf: &'a [u16]) -> Self {
1813        let buf = unsafe {
1814            let ptr = core::mem::transmute(buf.as_ptr());
1815            let size = buf.len() * core::mem::size_of::<u16>() / core::mem::size_of::<u8>();
1816            core::slice::from_raw_parts(ptr, size)
1817        };
1818        Self {
1819            buf,
1820            is_buf_be: false,
1821        }
1822    }
1823}
1824
1825#[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
1826#[cfg(feature = "fmt")]
1827impl<'a> core::fmt::Debug for UnknownAttrIter<'a> {
1828    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1829        f.write_str("[\n")?;
1830        for (idx, attr) in self.clone().enumerate() {
1831            f.write_fmt(format_args!("  ({}) {}\n", idx, attr))?;
1832        }
1833        f.write_str("]")?;
1834        Ok(())
1835    }
1836}
1837
1838#[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
1839impl<'a> Iterator for UnknownAttrIter<'a> {
1840    type Item = u16;
1841
1842    fn next(&mut self) -> Option<Self::Item> {
1843        let attr = self.buf.carved()?;
1844        self.buf = self.buf.get(2..)?;
1845
1846        if self.is_buf_be {
1847            Some(attr.as_be())
1848        } else {
1849            Some(attr.as_le())
1850        }
1851    }
1852}
1853
1854#[cfg_attr(feature = "fmt", derive(core::fmt::Debug))]
1855#[cfg(any(feature = "rfc8489"))]
1856#[derive(Copy, Clone)]
1857pub enum PasswordAlgorithm<'a> {
1858    Md5,
1859    Sha256,
1860    Other { typ: u16, params: &'a [u8] },
1861}
1862
1863#[cfg(any(feature = "rfc8489"))]
1864impl<'a> PasswordAlgorithm<'a> {
1865    fn from_nums(typ: u16, params: &'a [u8]) -> Self {
1866        use crate::consts::password_alg::*;
1867
1868        match typ {
1869            MD5 => PasswordAlgorithm::Md5,
1870            SHA256 => PasswordAlgorithm::Sha256,
1871            typ => PasswordAlgorithm::Other { typ, params },
1872        }
1873    }
1874
1875    fn into_nums(&self) -> (u16, &'a [u8]) {
1876        use crate::consts::password_alg::*;
1877
1878        match self {
1879            Self::Md5 => (MD5, &[]),
1880            Self::Sha256 => (SHA256, &[]),
1881            Self::Other { typ, params } => (*typ, *params),
1882        }
1883    }
1884}
1885
1886#[cfg(any(feature = "rfc8489"))]
1887#[derive(Copy, Clone)]
1888pub struct PasswordAlgorithmIter<'a> {
1889    byte_iter: stun_bytes::ByteAttrIter<'a>,
1890}
1891
1892#[cfg(any(feature = "rfc8489"))]
1893impl<'a> From<&'a [u8]> for PasswordAlgorithmIter<'a> {
1894    fn from(buf: &'a [u8]) -> Self {
1895        Self {
1896            byte_iter: stun_bytes::ByteAttrIter::from(buf)
1897        }
1898    }
1899}
1900
1901#[cfg(any(feature = "rfc8489"))]
1902#[cfg(feature = "fmt")]
1903impl<'a> core::fmt::Debug for PasswordAlgorithmIter<'a> {
1904    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1905        let iter = self.clone();
1906        f.write_str("[\n")?;
1907        for (idx, alg) in iter.enumerate() {
1908            f.write_fmt(format_args!("  ({}) {:?}\n", idx, alg))?;
1909        }
1910        f.write_str("]")?;
1911        Ok(())
1912    }
1913}
1914
1915#[cfg(any(feature = "rfc8489"))]
1916impl<'a> Iterator for PasswordAlgorithmIter<'a> {
1917    type Item = PasswordAlgorithm<'a>;
1918
1919    fn next(&mut self) -> Option<Self::Item> {
1920        let attr = self.byte_iter.next()?;
1921        let typ = attr.typ().map(u16::from_be_ref)?;
1922        let len = attr.len().map(u16::from_be_ref)?;
1923        let params = attr.val()?.get(0..len as usize)?;
1924        Some(PasswordAlgorithm::from_nums(typ, params))
1925    }
1926}
1927
1928#[cfg(any(feature = "rfc8489"))]
1929pub struct PasswordAlgorithmsBuilder<'a> {
1930    buf: &'a mut [u8],
1931    idx: usize,
1932}
1933
1934#[cfg(any(feature = "rfc8489"))]
1935impl<'a> From<&'a mut [u8]> for PasswordAlgorithmsBuilder<'a> {
1936    fn from(buf: &'a mut [u8]) -> Self {
1937        Self {
1938            buf,
1939            idx: 0,
1940        }
1941    }
1942}
1943
1944#[cfg(any(feature = "rfc8489"))]
1945impl<'a> PasswordAlgorithmsBuilder<'a> {
1946    pub fn add_alg(&mut self, alg: &PasswordAlgorithm) -> Option<()> {
1947        use crate::consts::password_alg::*;
1948
1949        let buf = self.buf.get_mut(self.idx..)?;
1950        let (typ_buf, buf) = buf.splice_mut()?;
1951        let (len_buf, val_buf) = buf.splice_mut()?;
1952
1953        match alg {
1954            PasswordAlgorithm::Md5 => {
1955                typ_buf.set_be(MD5);
1956                len_buf.set_be(0u16);
1957                self.idx += 4;
1958                Some(())
1959            }
1960            PasswordAlgorithm::Sha256 => {
1961                typ_buf.set_be(SHA256);
1962                len_buf.set_be(0u16);
1963                self.idx += 4;
1964                Some(())
1965            }
1966            PasswordAlgorithm::Other { typ, params } => {
1967                if val_buf.len() < (params.len() + 3) & !3 { return None; }
1968
1969                val_buf.get_mut(..params.len())?.copy_from_slice(params);
1970                typ_buf.set_be(*typ);
1971                len_buf.set_be(params.len() as u16);
1972
1973                self.idx += 4 + (params.len() + 3) & !3;
1974                Some(())
1975            }
1976        }
1977    }
1978
1979    pub fn to_buf(self) -> &'a [u8] {
1980        return self.buf.get(0..self.idx).unwrap_or(&[]);
1981    }
1982}
1983
1984pub struct AttrIter<'a> {
1985    byte_iter: stun_bytes::ByteAttrIter<'a>,
1986    tid: &'a [u8; 16],
1987}
1988
1989impl<'a> Iterator for AttrIter<'a> {
1990    type Item = Attr<'a>;
1991
1992    fn next(&mut self) -> Option<Self::Item> {
1993        let byte_attr = self.byte_iter.next()?;
1994        Attr::from_buf(byte_attr.typ()?, byte_attr.len()?, byte_attr.val()?, self.tid)
1995    }
1996}
1997
1998#[cfg(feature = "fmt")]
1999impl<'a> core::fmt::Debug for AttrIter<'a> {
2000    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2001        let iter = AttrIter { byte_iter: self.byte_iter.clone(), tid: self.tid };
2002        f.write_str("[\n")?;
2003        for (idx, e) in iter.enumerate() {
2004            f.write_fmt(format_args!("  ({}) {:?}\n", idx, e))?;
2005        }
2006        f.write_str("]")?;
2007        Ok(())
2008    }
2009}
2010
2011#[cfg(test)]
2012mod head {
2013    use super::*;
2014
2015    const MSG: [u8; 28] = [
2016        0x00, 0x01,                     // type: Binding Request
2017        0x00, 0x08,                     // length: 8 (header does not count)
2018        0x21, 0x12, 0xA4, 0x42,         // magic cookie
2019        0x00, 0x00, 0x00, 0x00,
2020        0x00, 0x00, 0x00, 0x00,
2021        0x00, 0x00, 0x00, 0x01,         // transaction id (16 bytes total incl. magic cookie)
2022        0x00, 0x03,                     // type: ChangeRequest
2023        0x00, 0x04,                     // length: 4 (only value bytes count)
2024        0x00, 0x00, 0x00, 0x40 | 0x20,  // change both ip and port
2025    ];
2026
2027    #[test]
2028    fn read() {
2029        let msg = Msg::from(MSG.as_slice());
2030
2031        if let MsgType::BindingRequest = msg.typ().unwrap() {} else { assert!(false); }
2032
2033        assert_eq!(0x2112A442, msg.cookie().unwrap());
2034
2035        assert_eq!(1, msg.tid().unwrap());
2036
2037        assert_eq!(1, msg.attrs_iter().count());
2038
2039        let attr = msg.attrs_iter().next().unwrap();
2040
2041        if let Attr::ChangeRequest { change_ip, change_port } = attr {
2042            assert_eq!(true, change_ip);
2043            assert_eq!(true, change_port);
2044        } else {
2045            assert!(false);
2046        }
2047    }
2048
2049    #[cfg(any(feature = "rfc3489", feature = "rfc5349", feature = "rfc8489"))]
2050    #[test]
2051    fn binding_request() {
2052        let buf = [
2053            0x00, 0x01,
2054        ];
2055
2056        let msg = Msg::from(buf.as_slice());
2057        if let Some(MsgType::BindingRequest) = msg.typ() {} else { assert!(false); }
2058    }
2059
2060    #[cfg(any(feature = "rfc3489", feature = "rfc5349", feature = "rfc8489"))]
2061    #[test]
2062    fn binding_response() {
2063        let buf = [
2064            0x01, 0x01,
2065        ];
2066
2067        let msg = Msg::from(buf.as_slice());
2068        if let Some(MsgType::BindingResponse) = msg.typ() {} else { assert!(false); }
2069    }
2070
2071    #[cfg(any(feature = "rfc5349", feature = "rfc8489"))]
2072    #[test]
2073    fn binding_indication() {
2074        let buf = [
2075            0x00, 0x11,
2076        ];
2077
2078        let msg = Msg::from(buf.as_slice());
2079        if let Some(MsgType::BindingIndication) = msg.typ() {} else { assert!(false); }
2080    }
2081
2082    #[cfg(any(feature = "rfc3489", feature = "rfc5349", feature = "rfc8489"))]
2083    #[test]
2084    fn binding_error_response() {
2085        let buf = [
2086            0x01, 0x11,
2087        ];
2088
2089        let msg = Msg::from(buf.as_slice());
2090        if let Some(MsgType::BindingErrorResponse) = msg.typ() {} else { assert!(false); }
2091    }
2092
2093    #[cfg(feature = "rfc3489")]
2094    #[test]
2095    fn shared_secret_request() {
2096        let buf = [
2097            0x00, 0x02,
2098        ];
2099
2100        let msg = Msg::from(buf.as_slice());
2101        if let Some(MsgType::SharedSecretRequest) = msg.typ() {} else { assert!(false); }
2102    }
2103
2104    #[cfg(feature = "rfc3489")]
2105    #[test]
2106    fn shared_secret_response() {
2107        let buf = [
2108            0x01, 0x02,
2109        ];
2110
2111        let msg = Msg::from(buf.as_slice());
2112        if let Some(MsgType::SharedSecretResponse) = msg.typ() {} else { assert!(false); }
2113    }
2114
2115    #[cfg(feature = "rfc3489")]
2116    #[test]
2117    fn shared_secret_error_response() {
2118        let buf = [
2119            0x01, 0x12,
2120        ];
2121
2122        let msg = Msg::from(buf.as_slice());
2123        if let Some(MsgType::SharedSecretErrorResponse) = msg.typ() {} else { assert!(false); }
2124    }
2125
2126    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2127    #[test]
2128    fn allocate_request() {
2129        let buf = [
2130            0x00, 0x03,
2131        ];
2132
2133        let msg = Msg::from(buf.as_slice());
2134        if let Some(MsgType::AllocateRequest) = msg.typ() {} else { assert!(false); }
2135    }
2136
2137    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2138    #[test]
2139    fn allocate_response() {
2140        let buf = [
2141            0x01, 0x03,
2142        ];
2143
2144        let msg = Msg::from(buf.as_slice());
2145        if let Some(MsgType::AllocateResponse) = msg.typ() {} else { assert!(false); }
2146    }
2147
2148    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2149    #[test]
2150    fn allocate_error_response() {
2151        let buf = [
2152            0x01, 0x13,
2153        ];
2154
2155        let msg = Msg::from(buf.as_slice());
2156        if let Some(MsgType::AllocateErrorResponse) = msg.typ() {} else { assert!(false); }
2157    }
2158
2159    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2160    #[test]
2161    fn refresh_request() {
2162        let buf = [
2163            0x00, 0x04,
2164        ];
2165
2166        let msg = Msg::from(buf.as_slice());
2167        if let Some(MsgType::RefreshRequest) = msg.typ() {} else { assert!(false); }
2168    }
2169
2170    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2171    #[test]
2172    fn refresh_response() {
2173        let buf = [
2174            0x01, 0x04,
2175        ];
2176
2177        let msg = Msg::from(buf.as_slice());
2178        if let Some(MsgType::RefreshResponse) = msg.typ() {} else { assert!(false); }
2179    }
2180
2181    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2182    #[test]
2183    fn refresh_error_response() {
2184        let buf = [
2185            0x01, 0x14,
2186        ];
2187
2188        let msg = Msg::from(buf.as_slice());
2189        if let Some(MsgType::RefreshErrorResponse) = msg.typ() {} else { assert!(false); }
2190    }
2191
2192    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2193    #[test]
2194    fn send_indication() {
2195        let buf = [
2196            0x00, 0x16,
2197        ];
2198
2199        let msg = Msg::from(buf.as_slice());
2200        if let Some(MsgType::SendIndication) = msg.typ() {} else { assert!(false); }
2201    }
2202
2203    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2204    #[test]
2205    fn data_indication() {
2206        let buf = [
2207            0x00, 0x17,
2208        ];
2209
2210        let msg = Msg::from(buf.as_slice());
2211        if let Some(MsgType::DataIndication) = msg.typ() {} else { assert!(false); }
2212    }
2213
2214    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2215    #[test]
2216    fn create_permission_request() {
2217        let buf = [
2218            0x00, 0x08,
2219        ];
2220
2221        let msg = Msg::from(buf.as_slice());
2222        if let Some(MsgType::CreatePermissionRequest) = msg.typ() {} else { assert!(false); }
2223    }
2224
2225    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2226    #[test]
2227    fn create_permission_response() {
2228        let buf = [
2229            0x01, 0x08,
2230        ];
2231
2232        let msg = Msg::from(buf.as_slice());
2233        if let Some(MsgType::CreatePermissionResponse) = msg.typ() {} else { assert!(false); }
2234    }
2235
2236    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2237    #[test]
2238    fn create_permission_error_response() {
2239        let buf = [
2240            0x01, 0x18,
2241        ];
2242
2243        let msg = Msg::from(buf.as_slice());
2244        if let Some(MsgType::CreatePermissionErrorResponse) = msg.typ() {} else { assert!(false); }
2245    }
2246
2247    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2248    #[test]
2249    fn channel_bind_request() {
2250        let buf = [
2251            0x00, 0x09,
2252        ];
2253
2254        let msg = Msg::from(buf.as_slice());
2255        if let Some(MsgType::ChannelBindRequest) = msg.typ() {} else { assert!(false); }
2256    }
2257
2258    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2259    #[test]
2260    fn channel_bind_response() {
2261        let buf = [
2262            0x01, 0x09,
2263        ];
2264
2265        let msg = Msg::from(buf.as_slice());
2266        if let Some(MsgType::ChannelBindResponse) = msg.typ() {} else { assert!(false); }
2267    }
2268
2269    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2270    #[test]
2271    fn channel_bind_error_response() {
2272        let buf = [
2273            0x01, 0x19,
2274        ];
2275
2276        let msg = Msg::from(buf.as_slice());
2277        if let Some(MsgType::ChannelBindErrorResponse) = msg.typ() {} else { assert!(false); }
2278    }
2279
2280    #[cfg(any(feature = "rfc6062"))]
2281    #[test]
2282    fn connect_request() {
2283        let buf = [
2284            0x00, 0x0A,
2285        ];
2286
2287        let msg = Msg::from(buf.as_slice());
2288        if let Some(MsgType::ConnectRequest) = msg.typ() {} else { assert!(false); }
2289    }
2290
2291    #[cfg(any(feature = "rfc6062"))]
2292    #[test]
2293    fn connect_response() {
2294        let buf = [
2295            0x01, 0x0A,
2296        ];
2297
2298        let msg = Msg::from(buf.as_slice());
2299        if let Some(MsgType::ConnectResponse) = msg.typ() {} else { assert!(false); }
2300    }
2301
2302    #[cfg(any(feature = "rfc6062"))]
2303    #[test]
2304    fn connect_error_response() {
2305        let buf = [
2306            0x01, 0x1A,
2307        ];
2308
2309        let msg = Msg::from(buf.as_slice());
2310        if let Some(MsgType::ConnectErrorResponse) = msg.typ() {} else { assert!(false); }
2311    }
2312
2313    #[cfg(any(feature = "rfc6062"))]
2314    #[test]
2315    fn connection_bind_request() {
2316        let buf = [
2317            0x00, 0x0B,
2318        ];
2319
2320        let msg = Msg::from(buf.as_slice());
2321        if let Some(MsgType::ConnectionBindRequest) = msg.typ() {} else { assert!(false); }
2322    }
2323
2324    #[cfg(any(feature = "rfc6062"))]
2325    #[test]
2326    fn connection_bind_response() {
2327        let buf = [
2328            0x01, 0x0B,
2329        ];
2330
2331        let msg = Msg::from(buf.as_slice());
2332        if let Some(MsgType::ConnectionBindResponse) = msg.typ() {} else { assert!(false); }
2333    }
2334
2335    #[cfg(any(feature = "rfc6062"))]
2336    #[test]
2337    fn connection_bind_error_response() {
2338        let buf = [
2339            0x01, 0x1B,
2340        ];
2341
2342        let msg = Msg::from(buf.as_slice());
2343        if let Some(MsgType::ConnectionBindErrorResponse) = msg.typ() {} else { assert!(false); }
2344    }
2345
2346    #[cfg(any(feature = "rfc6062"))]
2347    #[test]
2348    fn connection_attempt_indication() {
2349        let buf = [
2350            0x0, 0x1C,
2351        ];
2352
2353        let msg = Msg::from(buf.as_slice());
2354        if let Some(MsgType::ConnectionAttemptIndication) = msg.typ() {} else { assert!(false); }
2355    }
2356}
2357
2358#[cfg(test)]
2359mod attr {
2360    use super::*;
2361
2362    const TID: [u8; 16] = [1u8; 16];
2363
2364    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
2365    const MAPPED_ADDRESS_IP4: [u8; 12] = [
2366        0x00, 0x01,             // type: Mapped Address
2367        0x00, 0x08,             // len: 8
2368        0x00, 0x01,             // family: IPv4
2369        0x01, 0x02,             // port: 0x0102
2370        0x0A, 0x0B, 0x0C, 0x0D, // ip: 10.11.12.13
2371    ];
2372
2373    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
2374    const MAPPED_ADDRESS_IP6: [u8; 24] = [
2375        0x00, 0x01,             // type: Mapped Address
2376        0x00, 0x14,             // len: 20
2377        0x00, 0x02,             // family: IPv6
2378        0x01, 0x02,             // port: 0x0102
2379        0x00, 0x01, 0x02, 0x03,
2380        0x04, 0x05, 0x06, 0x07,
2381        0x08, 0x09, 0x0A, 0x0B,
2382        0x0C, 0x0D, 0x0E, 0x0F, // ip: 0123:4567:89AB:CDEF
2383    ];
2384
2385    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
2386    #[test]
2387    fn mapped_address_read() {
2388        let attr = AttrIter {
2389            byte_iter: stun_bytes::ByteAttrIter::from_arr(&MAPPED_ADDRESS_IP4),
2390            tid: &TID,
2391        }.next();
2392
2393        if let Some(Attr::MappedAddress(SocketAddr::V4(ip, port))) = attr {
2394            assert_eq!([10, 11, 12, 13], ip);
2395            assert_eq!(0x0102, port);
2396        } else { assert!(false); }
2397
2398        let attr = AttrIter {
2399            byte_iter: stun_bytes::ByteAttrIter::from_arr(&MAPPED_ADDRESS_IP6),
2400            tid: &TID,
2401        }.next();
2402
2403        if let Some(Attr::MappedAddress(SocketAddr::V6(ip, port))) = attr {
2404            assert_eq!([
2405                           0x00, 0x01, 0x02, 0x03,
2406                           0x04, 0x05, 0x06, 0x07,
2407                           0x08, 0x09, 0x0A, 0x0B,
2408                           0x0C, 0x0D, 0x0E, 0x0F,
2409                       ], ip);
2410            assert_eq!(0x0102, port);
2411        } else { assert!(false); }
2412    }
2413
2414    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
2415    #[test]
2416    fn mapped_address_write() {
2417        let mut buf = [0u8; 12];
2418        let (typ, len, val) = split_into_tlv(&mut buf);
2419
2420        Attr::MappedAddress(SocketAddr::V4([10, 11, 12, 13], 0x0102))
2421            .into_buf(typ, len, val, &TID);
2422
2423        assert_eq!(&MAPPED_ADDRESS_IP4, &buf);
2424
2425        let mut buf = [0u8; 24];
2426        let (typ, len, val) = split_into_tlv(&mut buf);
2427
2428        Attr::MappedAddress(SocketAddr::V6([
2429                                               0x00, 0x01, 0x02, 0x03,
2430                                               0x04, 0x05, 0x06, 0x07,
2431                                               0x08, 0x09, 0x0A, 0x0B,
2432                                               0x0C, 0x0D, 0x0E, 0x0F,
2433                                           ], 0x0102)).into_buf(typ, len, val, &TID);
2434
2435        assert_eq!(&MAPPED_ADDRESS_IP6, &buf);
2436    }
2437
2438    #[cfg(feature = "rfc3489")]
2439    const RESPONSE_ADDRESS_IP4: [u8; 12] = [
2440        0x00, 0x02,             // type: Response Address
2441        0x00, 0x08,             // len: 8
2442        0x00, 0x01,             // family: IPv4
2443        0x01, 0x02,             // port: 0x0102
2444        0x0A, 0x0B, 0x0C, 0x0D, // ip: 10.11.12.13
2445    ];
2446
2447    #[cfg(feature = "rfc3489")]
2448    const RESPONSE_ADDRESS_IP6: [u8; 24] = [
2449        0x00, 0x02,             // type: Response Address
2450        0x00, 0x14,             // len: 20
2451        0x00, 0x02,             // family: IPv6
2452        0x01, 0x02,             // port: 0x0102
2453        0x00, 0x01, 0x02, 0x03,
2454        0x04, 0x05, 0x06, 0x07,
2455        0x08, 0x09, 0x0A, 0x0B,
2456        0x0C, 0x0D, 0x0E, 0x0F, // ip: 0123:4567:89AB:CDEF
2457    ];
2458
2459    #[cfg(feature = "rfc3489")]
2460    #[test]
2461    fn response_address_read() {
2462        let attr = AttrIter {
2463            byte_iter: stun_bytes::ByteAttrIter::from_arr(&RESPONSE_ADDRESS_IP4),
2464            tid: &TID,
2465        }.next();
2466
2467        if let Some(Attr::ResponseAddress(SocketAddr::V4(ip, port))) = attr {
2468            assert_eq!([10, 11, 12, 13], ip);
2469            assert_eq!(0x0102, port);
2470        } else { assert!(false); }
2471
2472        let attr = AttrIter {
2473            byte_iter: stun_bytes::ByteAttrIter::from_arr(&RESPONSE_ADDRESS_IP6),
2474            tid: &TID,
2475        }.next();
2476
2477        if let Some(Attr::ResponseAddress(SocketAddr::V6(ip, port))) = attr {
2478            assert_eq!([
2479                           0x00, 0x01, 0x02, 0x03,
2480                           0x04, 0x05, 0x06, 0x07,
2481                           0x08, 0x09, 0x0A, 0x0B,
2482                           0x0C, 0x0D, 0x0E, 0x0F,
2483                       ], ip);
2484            assert_eq!(0x0102, port);
2485        } else { assert!(false); }
2486    }
2487
2488    #[cfg(feature = "rfc3489")]
2489    #[test]
2490    fn response_address_write() {
2491        let mut buf = [0u8; 12];
2492        let (typ, len, val) = split_into_tlv(&mut buf);
2493
2494        Attr::ResponseAddress(SocketAddr::V4([10, 11, 12, 13], 0x0102))
2495            .into_buf(typ, len, val, &TID);
2496
2497        assert_eq!(&RESPONSE_ADDRESS_IP4, &buf);
2498
2499        let mut buf = [0u8; 24];
2500        let (typ, len, val) = split_into_tlv(&mut buf);
2501
2502        Attr::ResponseAddress(SocketAddr::V6([
2503                                                 0x00, 0x01, 0x02, 0x03,
2504                                                 0x04, 0x05, 0x06, 0x07,
2505                                                 0x08, 0x09, 0x0A, 0x0B,
2506                                                 0x0C, 0x0D, 0x0E, 0x0F,
2507                                             ], 0x0102)).into_buf(typ, len, val, &TID);
2508
2509        assert_eq!(&RESPONSE_ADDRESS_IP6, &buf);
2510    }
2511
2512    #[cfg(any(feature = "rfc3489", feature = "rfc5780"))]
2513    const CHANGE_REQUEST_IP: [u8; 8] = [
2514        0x00, 0x03,              // type: ChangeRequest
2515        0x00, 0x04,              // length: 4 (only value bytes count)
2516        0x00, 0x00, 0x00, 0x40,  // change ip
2517    ];
2518
2519    #[cfg(any(feature = "rfc3489", feature = "rfc5780"))]
2520    const CHANGE_REQUEST_PORT: [u8; 8] = [
2521        0x00, 0x03,              // type: ChangeRequest
2522        0x00, 0x04,              // length: 4 (only value bytes count)
2523        0x00, 0x00, 0x00, 0x20,  // change port
2524    ];
2525
2526    #[cfg(any(feature = "rfc3489", feature = "rfc5780"))]
2527    #[test]
2528    fn change_request_read() {
2529        let attr = AttrIter {
2530            byte_iter: stun_bytes::ByteAttrIter::from_arr(&CHANGE_REQUEST_IP),
2531            tid: &TID,
2532        }.next();
2533
2534        if let Some(Attr::ChangeRequest { change_ip: true, change_port: false }) = attr {} else { assert!(false); }
2535
2536        let attr = AttrIter {
2537            byte_iter: stun_bytes::ByteAttrIter::from_arr(&CHANGE_REQUEST_PORT),
2538            tid: &TID,
2539        }.next();
2540
2541        if let Some(Attr::ChangeRequest { change_ip: false, change_port: true }) = attr {} else { assert!(false); }
2542    }
2543
2544    #[cfg(any(feature = "rfc3489", feature = "rfc5780"))]
2545    #[test]
2546    fn change_request_write() {
2547        let mut buf = [0u8; 8];
2548        let (typ, len, val) = split_into_tlv(&mut buf);
2549
2550        Attr::ChangeRequest { change_ip: true, change_port: false }
2551            .into_buf(typ, len, val, &TID);
2552
2553        assert_eq!(&CHANGE_REQUEST_IP, &buf);
2554
2555        let mut buf = [0u8; 8];
2556        let (typ, len, val) = split_into_tlv(&mut buf);
2557
2558        Attr::ChangeRequest { change_ip: false, change_port: true }
2559            .into_buf(typ, len, val, &TID);
2560
2561        assert_eq!(&CHANGE_REQUEST_PORT, &buf);
2562    }
2563
2564    #[cfg(feature = "rfc3489")]
2565    const SOURCE_ADDRESS_IP4: [u8; 12] = [
2566        0x00, 0x04,             // type: Source Address
2567        0x00, 0x08,             // len: 8
2568        0x00, 0x01,             // family: IPv4
2569        0x01, 0x02,             // port: 0x0102
2570        0x0A, 0x0B, 0x0C, 0x0D, // ip: 10.11.12.13
2571    ];
2572
2573    #[cfg(feature = "rfc3489")]
2574    const SOURCE_ADDRESS_IP6: [u8; 24] = [
2575        0x00, 0x04,             // type: Source Address
2576        0x00, 0x14,             // len: 20
2577        0x00, 0x02,             // family: IPv6
2578        0x01, 0x02,             // port: 0x0102
2579        0x00, 0x01, 0x02, 0x03,
2580        0x04, 0x05, 0x06, 0x07,
2581        0x08, 0x09, 0x0A, 0x0B,
2582        0x0C, 0x0D, 0x0E, 0x0F, // ip: 0123:4567:89AB:CDEF
2583    ];
2584
2585    #[cfg(feature = "rfc3489")]
2586    #[test]
2587    fn source_address_read() {
2588        let attr = AttrIter {
2589            byte_iter: stun_bytes::ByteAttrIter::from_arr(&SOURCE_ADDRESS_IP4),
2590            tid: &TID,
2591        }.next();
2592
2593        if let Some(Attr::SourceAddress(SocketAddr::V4(ip, port))) = attr {
2594            assert_eq!([10, 11, 12, 13], ip);
2595            assert_eq!(0x0102, port);
2596        } else { assert!(false); }
2597
2598        let attr = AttrIter {
2599            byte_iter: stun_bytes::ByteAttrIter::from_arr(&SOURCE_ADDRESS_IP6),
2600            tid: &TID,
2601        }.next();
2602
2603        if let Some(Attr::SourceAddress(SocketAddr::V6(ip, port))) = attr {
2604            assert_eq!([
2605                           0x00, 0x01, 0x02, 0x03,
2606                           0x04, 0x05, 0x06, 0x07,
2607                           0x08, 0x09, 0x0A, 0x0B,
2608                           0x0C, 0x0D, 0x0E, 0x0F,
2609                       ], ip);
2610            assert_eq!(0x0102, port);
2611        } else { assert!(false); }
2612    }
2613
2614    #[cfg(feature = "rfc3489")]
2615    #[test]
2616    fn source_address_write() {
2617        let mut buf = [0u8; 12];
2618        let (typ, len, val) = split_into_tlv(&mut buf);
2619
2620        Attr::SourceAddress(SocketAddr::V4([10, 11, 12, 13], 0x0102))
2621            .into_buf(typ, len, val, &TID);
2622
2623        assert_eq!(&SOURCE_ADDRESS_IP4, &buf);
2624
2625        let mut buf = [0u8; 24];
2626        let (typ, len, val) = split_into_tlv(&mut buf);
2627
2628        Attr::SourceAddress(SocketAddr::V6([
2629                                               0x00, 0x01, 0x02, 0x03,
2630                                               0x04, 0x05, 0x06, 0x07,
2631                                               0x08, 0x09, 0x0A, 0x0B,
2632                                               0x0C, 0x0D, 0x0E, 0x0F,
2633                                           ], 0x0102)).into_buf(typ, len, val, &TID);
2634
2635        assert_eq!(&SOURCE_ADDRESS_IP6, &buf);
2636    }
2637
2638    #[cfg(feature = "rfc3489")]
2639    const CHANGED_ADDRESS_IP4: [u8; 12] = [
2640        0x00, 0x05,             // type: Changed Address
2641        0x00, 0x08,             // len: 8
2642        0x00, 0x01,             // family: IPv4
2643        0x01, 0x02,             // port: 0x0102
2644        0x0A, 0x0B, 0x0C, 0x0D, // ip: 10.11.12.13
2645    ];
2646
2647    #[cfg(feature = "rfc3489")]
2648    const CHANGED_ADDRESS_IP6: [u8; 24] = [
2649        0x00, 0x05,             // type: Changed Address
2650        0x00, 0x14,             // len: 20
2651        0x00, 0x02,             // family: IPv6
2652        0x01, 0x02,             // port: 0x0102
2653        0x00, 0x01, 0x02, 0x03,
2654        0x04, 0x05, 0x06, 0x07,
2655        0x08, 0x09, 0x0A, 0x0B,
2656        0x0C, 0x0D, 0x0E, 0x0F, // ip: 0123:4567:89AB:CDEF
2657    ];
2658
2659    #[cfg(feature = "rfc3489")]
2660    #[test]
2661    fn changed_address_read() {
2662        let attr = AttrIter {
2663            byte_iter: stun_bytes::ByteAttrIter::from_arr(&CHANGED_ADDRESS_IP4),
2664            tid: &TID,
2665        }.next();
2666
2667        if let Some(Attr::ChangedAddress(SocketAddr::V4(ip, port))) = attr {
2668            assert_eq!([10, 11, 12, 13], ip);
2669            assert_eq!(0x0102, port);
2670        } else { assert!(false); }
2671
2672        let attr = AttrIter {
2673            byte_iter: stun_bytes::ByteAttrIter::from_arr(&CHANGED_ADDRESS_IP6),
2674            tid: &TID,
2675        }.next();
2676
2677        if let Some(Attr::ChangedAddress(SocketAddr::V6(ip, port))) = attr {
2678            assert_eq!([
2679                           0x00, 0x01, 0x02, 0x03,
2680                           0x04, 0x05, 0x06, 0x07,
2681                           0x08, 0x09, 0x0A, 0x0B,
2682                           0x0C, 0x0D, 0x0E, 0x0F,
2683                       ], ip);
2684            assert_eq!(0x0102, port);
2685        } else { assert!(false); }
2686    }
2687
2688    #[cfg(feature = "rfc3489")]
2689    #[test]
2690    fn changed_address_write() {
2691        let mut buf = [0u8; 12];
2692        let (typ, len, val) = split_into_tlv(&mut buf);
2693
2694        Attr::ChangedAddress(SocketAddr::V4([10, 11, 12, 13], 0x0102))
2695            .into_buf(typ, len, val, &TID);
2696
2697        assert_eq!(&CHANGED_ADDRESS_IP4, &buf);
2698
2699        let mut buf = [0u8; 24];
2700        let (typ, len, val) = split_into_tlv(&mut buf);
2701
2702        Attr::ChangedAddress(SocketAddr::V6([
2703                                                0x00, 0x01, 0x02, 0x03,
2704                                                0x04, 0x05, 0x06, 0x07,
2705                                                0x08, 0x09, 0x0A, 0x0B,
2706                                                0x0C, 0x0D, 0x0E, 0x0F,
2707                                            ], 0x0102)).into_buf(typ, len, val, &TID);
2708
2709        assert_eq!(&CHANGED_ADDRESS_IP6, &buf);
2710    }
2711
2712    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
2713    const USERNAME: [u8; 12] = [
2714        0x00, 0x06,                         // type: Username
2715        0x00, 0x06,                         // len: 6
2716        0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, // 'string'
2717        0x00, 0x00,                         // padding
2718    ];
2719
2720    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
2721    #[test]
2722    fn username_read() {
2723        let attr = AttrIter {
2724            byte_iter: stun_bytes::ByteAttrIter::from_arr(&USERNAME),
2725            tid: &TID,
2726        }.next();
2727
2728        if let Some(Attr::Username("string")) = attr {} else { assert!(false); }
2729    }
2730
2731    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
2732    #[test]
2733    fn username_write() {
2734        let mut buf = [0u8; 12];
2735        let (typ, len, val) = split_into_tlv(&mut buf);
2736
2737        Attr::Username("string").into_buf(typ, len, val, &TID);
2738
2739        assert_eq!(&USERNAME, &buf);
2740    }
2741
2742    #[cfg(feature = "rfc3489")]
2743    const PASSWORD: [u8; 12] = [
2744        0x00, 0x07,                         // type: Username
2745        0x00, 0x06,                         // len: 6
2746        0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, // 'string'
2747        0x00, 0x00,                         // padding
2748    ];
2749
2750    #[cfg(feature = "rfc3489")]
2751    #[test]
2752    fn password_read() {
2753        let attr = AttrIter {
2754            byte_iter: stun_bytes::ByteAttrIter::from_arr(&PASSWORD),
2755            tid: &TID,
2756        }.next();
2757
2758        if let Some(Attr::Password("string")) = attr {} else { assert!(false); }
2759    }
2760
2761    #[cfg(feature = "rfc3489")]
2762    #[test]
2763    fn password_write() {
2764        let mut buf = [0u8; 12];
2765        let (typ, len, val) = split_into_tlv(&mut buf);
2766
2767        Attr::Password("string").into_buf(typ, len, val, &TID);
2768
2769        assert_eq!(&PASSWORD, &buf);
2770    }
2771
2772    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
2773    const MESSAGE_INTEGRITY: [u8; 24] = [
2774        0x00, 0x08,             // type: Message Integrity
2775        0x00, 0x14,             // len: 20
2776        0x00, 0x01, 0x02, 0x03,
2777        0x04, 0x05, 0x06, 0x07,
2778        0x08, 0x09, 0x0A, 0x0B,
2779        0x0C, 0x0D, 0x0E, 0x0F,
2780        0x10, 0x11, 0x12, 0x13, // value
2781    ];
2782
2783    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
2784    #[test]
2785    fn message_integrity_read() {
2786        let attr = AttrIter {
2787            byte_iter: stun_bytes::ByteAttrIter::from_arr(&MESSAGE_INTEGRITY),
2788            tid: &TID,
2789        }.next();
2790
2791        if let Some(Attr::MessageIntegrity(val)) = attr {
2792            assert_eq!(&[0x00, 0x01, 0x02, 0x03,
2793                0x04, 0x05, 0x06, 0x07,
2794                0x08, 0x09, 0x0A, 0x0B,
2795                0x0C, 0x0D, 0x0E, 0x0F,
2796                0x10, 0x11, 0x12, 0x13, ], val.as_slice());
2797        } else { assert!(false); }
2798    }
2799
2800    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
2801    #[test]
2802    fn message_integrity_write() {
2803        let mut buf = [0u8; 24];
2804        let (typ, len, val) = split_into_tlv(&mut buf);
2805
2806        Attr::MessageIntegrity(&[0x00, 0x01, 0x02, 0x03,
2807            0x04, 0x05, 0x06, 0x07,
2808            0x08, 0x09, 0x0A, 0x0B,
2809            0x0C, 0x0D, 0x0E, 0x0F,
2810            0x10, 0x11, 0x12, 0x13, ]).into_buf(typ, len, val, &TID);
2811
2812        assert_eq!(&MESSAGE_INTEGRITY, &buf);
2813    }
2814
2815    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
2816    const ERROR_CODE: [u8; 16] = [
2817        0x00, 0x09,                         // type: Error Code
2818        0x00, 0x0A,                         // len: 10
2819        0x00, 0x00, 0x06 << 5, 0x10,        // code: 616
2820        0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, // desc: 'string'
2821        0x00, 0x00,                         // padding
2822    ];
2823
2824    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
2825    #[test]
2826    fn error_code_read() {
2827        let attr = AttrIter {
2828            byte_iter: stun_bytes::ByteAttrIter::from_arr(&ERROR_CODE),
2829            tid: &TID,
2830        }.next();
2831
2832        if let Some(Attr::ErrorCode { code: ErrorCode::Other(616), desc: "string" }) = attr {} else { assert!(false); }
2833    }
2834
2835    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
2836    #[test]
2837    fn error_code_write() {
2838        let mut buf = [0u8; 16];
2839        let (typ, len, val) = split_into_tlv(&mut buf);
2840
2841        Attr::ErrorCode { code: ErrorCode::Other(616), desc: "string" }
2842            .into_buf(typ, len, val, &TID);
2843
2844        assert_eq!(&ERROR_CODE, &buf);
2845    }
2846
2847    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
2848    const UNKNOWN_ATTRIBUTES: [u8; 8] = [
2849        0x00, 0x0A, // type: Unknown Attributes
2850        0x00, 0x02, // len: 2
2851        0x01, 0x02, // unknown attr: 0x0102
2852        0x00, 0x00, // padding
2853    ];
2854
2855    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
2856    #[test]
2857    fn unknown_attrs_read() {
2858        let attr = AttrIter {
2859            byte_iter: stun_bytes::ByteAttrIter::from_arr(&UNKNOWN_ATTRIBUTES),
2860            tid: &TID,
2861        }.next();
2862
2863        if let Some(Attr::UnknownAttributes(mut iter)) = attr {
2864            if let Some(0x0102) = iter.next() {} else { assert!(false); }
2865            assert!(iter.next().is_none());
2866        } else { assert!(false); }
2867    }
2868
2869    #[cfg(any(feature = "rfc3489", feature = "rfc5389", feature = "rfc8489"))]
2870    #[test]
2871    fn unknown_attrs_write() {
2872        let mut buf = [0u8; 8];
2873        let (typ, len, val) = split_into_tlv(&mut buf);
2874
2875        let unknown_attrs = [0x0102_u16];
2876
2877        Attr::UnknownAttributes(unknown_attrs.as_slice().into())
2878            .into_buf(typ, len, val, &TID);
2879
2880        assert_eq!(&UNKNOWN_ATTRIBUTES, &buf);
2881    }
2882
2883    #[cfg(feature = "rfc3489")]
2884    const REFLECTED_FROM_IP4: [u8; 12] = [
2885        0x00, 0x0B,             // type: Reflected From
2886        0x00, 0x08,             // len: 8
2887        0x00, 0x01,             // family: IPv4
2888        0x01, 0x02,             // port: 0x0102
2889        0x0A, 0x0B, 0x0C, 0x0D, // ip: 10.11.12.13
2890    ];
2891
2892    #[cfg(feature = "rfc3489")]
2893    const REFLECTED_FROM_IP6: [u8; 24] = [
2894        0x00, 0x0B,             // type: Reflected From
2895        0x00, 0x14,             // len: 20
2896        0x00, 0x02,             // family: IPv6
2897        0x01, 0x02,             // port: 0x0102
2898        0x00, 0x01, 0x02, 0x03,
2899        0x04, 0x05, 0x06, 0x07,
2900        0x08, 0x09, 0x0A, 0x0B,
2901        0x0C, 0x0D, 0x0E, 0x0F, // ip: 0123:4567:89AB:CDEF
2902    ];
2903
2904    #[cfg(feature = "rfc3489")]
2905    #[test]
2906    fn reflected_from_read() {
2907        let attr = AttrIter {
2908            byte_iter: stun_bytes::ByteAttrIter::from_arr(&REFLECTED_FROM_IP4),
2909            tid: &TID,
2910        }.next();
2911
2912        if let Some(Attr::ReflectedFrom(SocketAddr::V4(ip, port))) = attr {
2913            assert_eq!([10, 11, 12, 13], ip);
2914            assert_eq!(0x0102, port);
2915        } else { assert!(false); }
2916
2917        let attr = AttrIter {
2918            byte_iter: stun_bytes::ByteAttrIter::from_arr(&REFLECTED_FROM_IP6),
2919            tid: &TID,
2920        }.next();
2921
2922        if let Some(Attr::ReflectedFrom(SocketAddr::V6(ip, port))) = attr {
2923            assert_eq!([
2924                           0x00, 0x01, 0x02, 0x03,
2925                           0x04, 0x05, 0x06, 0x07,
2926                           0x08, 0x09, 0x0A, 0x0B,
2927                           0x0C, 0x0D, 0x0E, 0x0F,
2928                       ], ip);
2929            assert_eq!(0x0102, port);
2930        } else { assert!(false); }
2931    }
2932
2933    #[cfg(feature = "rfc3489")]
2934    #[test]
2935    fn reflected_from_write() {
2936        let mut buf = [0u8; 12];
2937        let (typ, len, val) = split_into_tlv(&mut buf);
2938
2939        Attr::ReflectedFrom(SocketAddr::V4([10, 11, 12, 13], 0x0102))
2940            .into_buf(typ, len, val, &TID);
2941
2942        assert_eq!(&REFLECTED_FROM_IP4, &buf);
2943
2944        let mut buf = [0u8; 24];
2945        let (typ, len, val) = split_into_tlv(&mut buf);
2946
2947        Attr::ReflectedFrom(SocketAddr::V6([
2948                                               0x00, 0x01, 0x02, 0x03,
2949                                               0x04, 0x05, 0x06, 0x07,
2950                                               0x08, 0x09, 0x0A, 0x0B,
2951                                               0x0C, 0x0D, 0x0E, 0x0F,
2952                                           ], 0x0102)).into_buf(typ, len, val, &TID);
2953
2954        assert_eq!(&REFLECTED_FROM_IP6, &buf);
2955    }
2956
2957    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2958    const CHANNEL_NUMBER: [u8; 8] = [
2959        0x00, 0x0C, // type: Channel Number
2960        0x00, 0x02, // len: 2
2961        0x01, 0x02, // channel num: 0x0102
2962        0x00, 0x00, // padding
2963    ];
2964
2965    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2966    #[test]
2967    fn channel_number_read() {
2968        let attr = AttrIter {
2969            byte_iter: stun_bytes::ByteAttrIter::from_arr(&CHANNEL_NUMBER),
2970            tid: &TID,
2971        }.next();
2972
2973        if let Some(Attr::ChannelNumber(0x0102)) = attr {} else { assert!(false); }
2974    }
2975
2976    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2977    #[test]
2978    fn channel_number_write() {
2979        let mut buf = [0u8; 8];
2980
2981        let (typ, len, val) = split_into_tlv(&mut buf);
2982        Attr::ChannelNumber(0x0102)
2983            .into_buf(typ, len, val, &TID);
2984
2985        assert_eq!(&CHANNEL_NUMBER, &buf);
2986    }
2987
2988    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2989    const LIFETIME: [u8; 8] = [
2990        0x00, 0x0D,             // type: Lifetime
2991        0x00, 0x04,             // len: 2
2992        0x01, 0x02, 0x03, 0x04  // secs: 0x01020304
2993    ];
2994
2995    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
2996    #[test]
2997    fn lifetime_read() {
2998        let attr = AttrIter {
2999            byte_iter: stun_bytes::ByteAttrIter::from_arr(&LIFETIME),
3000            tid: &TID,
3001        }.next();
3002
3003        if let Some(Attr::Lifetime(lifetime)) = attr {
3004            assert_eq!(0x01020304, lifetime.as_secs());
3005        } else { assert!(false); }
3006    }
3007
3008    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3009    #[test]
3010    fn lifetime_write() {
3011        let mut buf = [0u8; 8];
3012
3013        let (typ, len, val) = split_into_tlv(&mut buf);
3014        Attr::Lifetime(core::time::Duration::from_secs(0x01020304))
3015            .into_buf(typ, len, val, &TID);
3016
3017        assert_eq!(&LIFETIME, &buf);
3018    }
3019
3020    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3021    const XOR_PEER_ADDRESS_IP4: [u8; 12] = [
3022        0x00, 0x12,                                                 // type: Xor Peer Address
3023        0x00, 0x08,                                                 // len: 8
3024        0x00, 0x01,                                                 // family: IPv4
3025        0x01 ^ TID[0], 0x02 ^ TID[1],                               // port: 0x0102
3026        0x0A ^ TID[0], 0x0B ^ TID[1], 0x0C ^ TID[2], 0x0D ^ TID[3], // ip: 10.11.12.13
3027    ];
3028
3029    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3030    const XOR_PEER_ADDRESS_IP6: [u8; 24] = [
3031        0x00, 0x12,                                                     // type: Xor Peer Address
3032        0x00, 0x14,                                                     // len: 20
3033        0x00, 0x02,                                                     // family: IPv6
3034        0x01 ^ TID[0], 0x02 ^ TID[1],                                   // port: 0x0102
3035        0x00 ^ TID[0], 0x01 ^ TID[1], 0x02 ^ TID[2], 0x03 ^ TID[3],
3036        0x04 ^ TID[4], 0x05 ^ TID[5], 0x06 ^ TID[6], 0x07 ^ TID[7],
3037        0x08 ^ TID[8], 0x09 ^ TID[9], 0x0A ^ TID[10], 0x0B ^ TID[11],
3038        0x0C ^ TID[12], 0x0D ^ TID[13], 0x0E ^ TID[14], 0x0F ^ TID[15], // ip: 0123:4567:89AB:CDEF
3039    ];
3040
3041    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3042    #[test]
3043    fn xor_peer_address_read() {
3044        let attr = AttrIter {
3045            byte_iter: stun_bytes::ByteAttrIter::from_arr(&XOR_PEER_ADDRESS_IP4),
3046            tid: &TID,
3047        }.next();
3048
3049        if let Some(Attr::XorPeerAddress(SocketAddr::V4([10, 11, 12, 13], 0x0102))) = attr {} else { assert!(false); }
3050
3051        let attr = AttrIter {
3052            byte_iter: stun_bytes::ByteAttrIter::from_arr(&XOR_PEER_ADDRESS_IP6),
3053            tid: &TID,
3054        }.next();
3055
3056        if let Some(Attr::XorPeerAddress(SocketAddr::V6(ip, port))) = attr {
3057            assert_eq!([
3058                           0x00, 0x01, 0x02, 0x03,
3059                           0x04, 0x05, 0x06, 0x07,
3060                           0x08, 0x09, 0x0A, 0x0B,
3061                           0x0C, 0x0D, 0x0E, 0x0F,
3062                       ], ip);
3063            assert_eq!(0x0102, port);
3064        } else { assert!(false); }
3065    }
3066
3067    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3068    #[test]
3069    fn xor_peer_address_write() {
3070        let mut buf = [0u8; 12];
3071
3072        let (typ, len, val) = split_into_tlv(&mut buf);
3073        Attr::XorPeerAddress(SocketAddr::V4([10, 11, 12, 13], 0x0102))
3074            .into_buf(typ, len, val, &TID);
3075
3076        assert_eq!(&XOR_PEER_ADDRESS_IP4, &buf);
3077
3078        let mut buf = [0u8; 24];
3079
3080        let (typ, len, val) = split_into_tlv(&mut buf);
3081        Attr::XorPeerAddress(SocketAddr::V6([
3082                                                0x00, 0x01, 0x02, 0x03,
3083                                                0x04, 0x05, 0x06, 0x07,
3084                                                0x08, 0x09, 0x0A, 0x0B,
3085                                                0x0C, 0x0D, 0x0E, 0x0F,
3086                                            ], 0x0102))
3087            .into_buf(typ, len, val, &TID);
3088
3089        assert_eq!(&XOR_PEER_ADDRESS_IP6, &buf);
3090    }
3091
3092    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3093    const DATA: [u8; 8] = [
3094        0x00, 0x13,             // type: Data
3095        0x00, 0x04,             // len: 8
3096        0x01, 0x02, 0x03, 0x04, // data
3097    ];
3098
3099    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3100    #[test]
3101    fn data_read() {
3102        let attr = AttrIter {
3103            byte_iter: stun_bytes::ByteAttrIter::from_arr(&DATA),
3104            tid: &TID,
3105        }.next();
3106
3107        if let Some(Attr::Data(&[1, 2, 3, 4])) = attr {} else { assert!(false); }
3108    }
3109
3110    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3111    #[test]
3112    fn data_write() {
3113        let mut buf = [0u8; 8];
3114        let (typ, len, val) = split_into_tlv(&mut buf);
3115
3116        Attr::Data(&[1, 2, 3, 4]).into_buf(typ, len, val, &TID);
3117
3118        assert_eq!(&DATA, &buf);
3119    }
3120
3121    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
3122    const REALM: [u8; 12] = [
3123        0x00, 0x14,                         // type: Realm
3124        0x00, 0x06,                         // len: 6
3125        0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, // 'string'
3126        0x00, 0x00,                         // padding
3127    ];
3128
3129    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
3130    #[test]
3131    fn realm_read() {
3132        let attr = AttrIter {
3133            byte_iter: stun_bytes::ByteAttrIter::from_arr(&REALM),
3134            tid: &TID,
3135        }.next();
3136
3137        if let Some(Attr::Realm("string")) = attr {} else { assert!(false); }
3138    }
3139
3140    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
3141    #[test]
3142    fn realm_write() {
3143        let mut buf = [0u8; REALM.len()];
3144        let (typ, len, val) = split_into_tlv(&mut buf);
3145
3146        Attr::Realm("string").into_buf(typ, len, val, &TID);
3147
3148        assert_eq!(&REALM, &buf);
3149    }
3150
3151    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
3152    const NONCE: [u8; 12] = [
3153        0x00, 0x15,                         // type: Nonce
3154        0x00, 0x06,                         // len: 6
3155        0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, // 'string'
3156        0x00, 0x00,                         // padding
3157    ];
3158
3159    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
3160    #[test]
3161    fn nonce_read() {
3162        let attr = AttrIter {
3163            byte_iter: stun_bytes::ByteAttrIter::from_arr(&NONCE),
3164            tid: &TID,
3165        }.next();
3166
3167        if let Some(Attr::Nonce("string")) = attr {} else { assert!(false); }
3168    }
3169
3170    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
3171    #[test]
3172    fn nonce_write() {
3173        let mut buf = [0u8; 12];
3174        let (typ, len, val) = split_into_tlv(&mut buf);
3175
3176        Attr::Nonce("string").into_buf(typ, len, val, &TID);
3177
3178        assert_eq!(&NONCE, &buf);
3179    }
3180
3181    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3182    const XOR_RELAYED_ADDRESS_IP4: [u8; 12] = [
3183        0x00, 0x16,                                                 // type: Xor Relayed Address
3184        0x00, 0x08,                                                 // len: 8
3185        0x00, 0x01,                                                 // family: IPv4
3186        0x01 ^ TID[0], 0x02 ^ TID[1],                               // port: 0x0102
3187        0x0A ^ TID[0], 0x0B ^ TID[1], 0x0C ^ TID[2], 0x0D ^ TID[3], // ip: 10.11.12.13
3188    ];
3189
3190    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3191    const XOR_RELAYED_ADDRESS_IP6: [u8; 24] = [
3192        0x00, 0x16,                                                     // type: Xor Relayed Address
3193        0x00, 0x14,                                                     // len: 20
3194        0x00, 0x02,                                                     // family: IPv6
3195        0x01 ^ TID[0], 0x02 ^ TID[1],                                   // port: 0x0102
3196        0x00 ^ TID[0], 0x01 ^ TID[1], 0x02 ^ TID[2], 0x03 ^ TID[3],
3197        0x04 ^ TID[4], 0x05 ^ TID[5], 0x06 ^ TID[6], 0x07 ^ TID[7],
3198        0x08 ^ TID[8], 0x09 ^ TID[9], 0x0A ^ TID[10], 0x0B ^ TID[11],
3199        0x0C ^ TID[12], 0x0D ^ TID[13], 0x0E ^ TID[14], 0x0F ^ TID[15], // ip: 0123:4567:89AB:CDEF
3200    ];
3201
3202    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3203    #[test]
3204    fn xor_relayed_address_read() {
3205        let attr = AttrIter {
3206            byte_iter: stun_bytes::ByteAttrIter::from_arr(&XOR_RELAYED_ADDRESS_IP4),
3207            tid: &TID,
3208        }.next();
3209
3210        if let Some(Attr::XorRelayedAddress(SocketAddr::V4(ip, port))) = attr {
3211            assert_eq!([10, 11, 12, 13], ip);
3212            assert_eq!(0x0102, port);
3213        } else { assert!(false); }
3214
3215        let attr = AttrIter {
3216            byte_iter: stun_bytes::ByteAttrIter::from_arr(&XOR_RELAYED_ADDRESS_IP6),
3217            tid: &TID,
3218        }.next();
3219
3220        if let Some(Attr::XorRelayedAddress(SocketAddr::V6(ip, port))) = attr {
3221            assert_eq!([
3222                           0x00, 0x01, 0x02, 0x03,
3223                           0x04, 0x05, 0x06, 0x07,
3224                           0x08, 0x09, 0x0A, 0x0B,
3225                           0x0C, 0x0D, 0x0E, 0x0F,
3226                       ], ip);
3227            assert_eq!(0x0102, port);
3228        } else { assert!(false); }
3229    }
3230
3231    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3232    #[test]
3233    fn xor_relayed_address_write() {
3234        let mut buf = [0u8; 12];
3235
3236        let (typ, len, val) = split_into_tlv(&mut buf);
3237        Attr::XorRelayedAddress(SocketAddr::V4([10, 11, 12, 13], 0x0102))
3238            .into_buf(typ, len, val, &TID);
3239
3240        assert_eq!(&XOR_RELAYED_ADDRESS_IP4, &buf);
3241
3242        let mut buf = [0u8; 24];
3243
3244        let (typ, len, val) = split_into_tlv(&mut buf);
3245        Attr::XorRelayedAddress(SocketAddr::V6([
3246                                                   0x00, 0x01, 0x02, 0x03,
3247                                                   0x04, 0x05, 0x06, 0x07,
3248                                                   0x08, 0x09, 0x0A, 0x0B,
3249                                                   0x0C, 0x0D, 0x0E, 0x0F,
3250                                               ], 0x0102))
3251            .into_buf(typ, len, val, &TID);
3252
3253        assert_eq!(&XOR_RELAYED_ADDRESS_IP6, &buf);
3254    }
3255
3256    #[cfg(any(feature = "rfc8656"))]
3257    const REQUESTED_ADDRESS_FAMILY_IP4: [u8; 8] = [
3258        0x00, 0x17,             // type: Requested Address Family
3259        0x00, 0x04,             // len: 4
3260        0x01, 0x00, 0x00, 0x00, // family: IPv4
3261    ];
3262
3263    #[cfg(any(feature = "rfc8656"))]
3264    const REQUESTED_ADDRESS_FAMILY_IP6: [u8; 8] = [
3265        0x00, 0x17,             // type: Requested Address Family
3266        0x00, 0x04,             // len: 4
3267        0x02, 0x00, 0x00, 0x00, // family: IPv6
3268    ];
3269
3270    #[cfg(any(feature = "rfc8656"))]
3271    const REQUESTED_ADDRESS_FAMILY_OTHER: [u8; 8] = [
3272        0x00, 0x17,             // type: Requested Address Family
3273        0x00, 0x04,             // len: 4
3274        0x04, 0x00, 0x00, 0x00, // family: Other(4)
3275    ];
3276
3277    #[cfg(any(feature = "rfc8656"))]
3278    #[test]
3279    fn requested_address_family_read() {
3280        let attr = AttrIter {
3281            byte_iter: stun_bytes::ByteAttrIter::from_arr(&REQUESTED_ADDRESS_FAMILY_IP4),
3282            tid: &TID,
3283        }.next();
3284
3285        if let Some(Attr::RequestedAddressFamily(AddressFamily::IPv4)) = attr {} else { assert!(false); }
3286
3287        let attr = AttrIter {
3288            byte_iter: stun_bytes::ByteAttrIter::from_arr(&REQUESTED_ADDRESS_FAMILY_IP6),
3289            tid: &TID,
3290        }.next();
3291
3292        if let Some(Attr::RequestedAddressFamily(AddressFamily::IPv6)) = attr {} else { assert!(false); }
3293
3294        let attr = AttrIter {
3295            byte_iter: stun_bytes::ByteAttrIter::from_arr(&REQUESTED_ADDRESS_FAMILY_OTHER),
3296            tid: &TID,
3297        }.next();
3298
3299        if let Some(Attr::RequestedAddressFamily(AddressFamily::Other(4))) = attr {} else { assert!(false); }
3300    }
3301
3302    #[cfg(any(feature = "rfc8656"))]
3303    #[test]
3304    fn requested_address_family_write() {
3305        let mut buf = [0u8; 8];
3306        let (typ, len, val) = split_into_tlv(&mut buf);
3307
3308        Attr::RequestedAddressFamily(AddressFamily::IPv4).into_buf(typ, len, val, &TID);
3309
3310        assert_eq!(&REQUESTED_ADDRESS_FAMILY_IP4, &buf);
3311
3312        let mut buf = [0u8; 8];
3313        let (typ, len, val) = split_into_tlv(&mut buf);
3314
3315        Attr::RequestedAddressFamily(AddressFamily::IPv6).into_buf(typ, len, val, &TID);
3316
3317        assert_eq!(&REQUESTED_ADDRESS_FAMILY_IP6, &buf);
3318
3319        let mut buf = [0u8; 8];
3320        let (typ, len, val) = split_into_tlv(&mut buf);
3321
3322        Attr::RequestedAddressFamily(AddressFamily::Other(4)).into_buf(typ, len, val, &TID);
3323
3324        assert_eq!(&REQUESTED_ADDRESS_FAMILY_OTHER, &buf);
3325    }
3326
3327    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3328    const EVEN_PORT_ODD: [u8; 8] = [
3329        0x00, 0x18,       // type: Even Port
3330        0x00, 0x01,       // len: 1
3331        0x00,             // val: false
3332        0x00, 0x00, 0x00, // padding
3333    ];
3334
3335    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3336    const EVEN_PORT_EVEN: [u8; 8] = [
3337        0x00, 0x18,       // type: Even Port
3338        0x00, 0x01,       // len: 1
3339        0x01,             // val: true
3340        0x00, 0x00, 0x00, // padding
3341    ];
3342
3343    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3344    #[test]
3345    fn even_port_read() {
3346        let attr = AttrIter {
3347            byte_iter: stun_bytes::ByteAttrIter::from_arr(&EVEN_PORT_ODD),
3348            tid: &TID,
3349        }.next();
3350
3351        if let Some(Attr::EvenPort(false)) = attr {} else { assert!(false); }
3352
3353        let attr = AttrIter {
3354            byte_iter: stun_bytes::ByteAttrIter::from_arr(&EVEN_PORT_EVEN),
3355            tid: &TID,
3356        }.next();
3357
3358        if let Some(Attr::EvenPort(true)) = attr {} else { assert!(false); }
3359    }
3360
3361    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3362    #[test]
3363    fn even_port_write() {
3364        let mut buf = [0u8; 8];
3365        let (typ, len, val) = split_into_tlv(&mut buf);
3366
3367        Attr::EvenPort(false).into_buf(typ, len, val, &TID);
3368
3369        assert_eq!(&EVEN_PORT_ODD, &buf);
3370
3371        let mut buf = [0u8; 8];
3372        let (typ, len, val) = split_into_tlv(&mut buf);
3373
3374        Attr::EvenPort(true).into_buf(typ, len, val, &TID);
3375
3376        assert_eq!(&EVEN_PORT_EVEN, &buf);
3377    }
3378
3379    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3380    const REQUEST_TRANSPORT_UDP: [u8; 8] = [
3381        0x00, 0x19,             // type: Even Port
3382        0x00, 0x04,             // len: 4
3383        0x11, 0x00, 0x00, 0x00, // val: UDP
3384    ];
3385
3386    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3387    const REQUEST_TRANSPORT_OTHER: [u8; 8] = [
3388        0x00, 0x19,             // type: Even Port
3389        0x00, 0x04,             // len: 4
3390        0x01, 0x00, 0x00, 0x00, // val: Other(1)
3391    ];
3392
3393    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3394    #[test]
3395    fn requested_transport_read() {
3396        let attr = AttrIter {
3397            byte_iter: stun_bytes::ByteAttrIter::from_arr(&REQUEST_TRANSPORT_UDP),
3398            tid: &TID,
3399        }.next();
3400
3401        if let Some(Attr::RequestedTransport(TransportProtocol::UDP)) = attr {} else { assert!(false); }
3402
3403        let attr = AttrIter {
3404            byte_iter: stun_bytes::ByteAttrIter::from_arr(&REQUEST_TRANSPORT_OTHER),
3405            tid: &TID,
3406        }.next();
3407
3408        if let Some(Attr::RequestedTransport(TransportProtocol::Other(1))) = attr {} else { assert!(false); }
3409    }
3410
3411    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3412    #[test]
3413    fn requested_transport_write() {
3414        let mut buf = [0u8; 8];
3415        let (typ, len, val) = split_into_tlv(&mut buf);
3416
3417        Attr::RequestedTransport(TransportProtocol::UDP).into_buf(typ, len, val, &TID);
3418
3419        assert_eq!(&REQUEST_TRANSPORT_UDP, &buf);
3420
3421        let mut buf = [0u8; 8];
3422        let (typ, len, val) = split_into_tlv(&mut buf);
3423
3424        Attr::RequestedTransport(TransportProtocol::Other(1)).into_buf(typ, len, val, &TID);
3425
3426        assert_eq!(&REQUEST_TRANSPORT_OTHER, &buf);
3427    }
3428
3429    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3430    const DONT_FRAGMENT: [u8; 4] = [
3431        0x00, 0x1A, // type: Dont Fragment
3432        0x00, 0x00, // len: 0
3433    ];
3434
3435    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3436    #[test]
3437    fn dont_fragment_read() {
3438        let attr = AttrIter {
3439            byte_iter: stun_bytes::ByteAttrIter::from_arr(&DONT_FRAGMENT),
3440            tid: &TID,
3441        }.next();
3442
3443        if let Some(Attr::DontFragment) = attr {} else { assert!(false); }
3444    }
3445
3446    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3447    #[test]
3448    fn dont_fragment_write() {
3449        let mut buf = [0u8; 4];
3450        let (typ, len, val) = split_into_tlv(&mut buf);
3451
3452        Attr::DontFragment.into_buf(typ, len, val, &TID);
3453
3454        assert_eq!(&DONT_FRAGMENT, &buf);
3455    }
3456
3457    #[cfg(any(feature = "rfc7635"))]
3458    const ACCESS_TOKEN: [u8; 28] = [
3459        0x00, 0x1B,             // type: Access Token
3460        0x00, 0x18,             // len: X
3461        0x00, 0x04,             // nonce len: 4
3462        0x01, 0x02, 0x03, 0x04, // nonce
3463        0x00, 0x04,             // mac len: 4
3464        0x04, 0x03, 0x02, 0x01, // mac
3465        0x00, 0x00, 0x00, 0x00,
3466        0x00, 0x01, 0x00, 0x01, // timestamp: 1 + 1/64000 secs
3467        0x00, 0x00, 0x00, 0x01, // lifetime: 1 secs
3468    ];
3469
3470    #[cfg(any(feature = "rfc7635"))]
3471    #[test]
3472    fn access_token_read() {
3473        let attr = AttrIter {
3474            byte_iter: stun_bytes::ByteAttrIter::from_arr(&ACCESS_TOKEN),
3475            tid: &TID,
3476        }.next();
3477
3478        if let Some(Attr::AccessToken {
3479                        nonce: &[0x01, 0x02, 0x03, 0x04],
3480                        mac: &[0x04, 0x03, 0x02, 0x01],
3481                        timestamp,
3482                        lifetime,
3483                    }) = attr {
3484            assert_eq!(1.0 + 1.0 / 64000.0, timestamp.as_secs_f64());
3485            assert_eq!(1, lifetime.as_secs());
3486        } else { assert!(false); }
3487    }
3488
3489    #[cfg(any(feature = "rfc7635"))]
3490    #[test]
3491    fn access_token_write() {
3492        let mut buf = [0u8; 28];
3493        let (typ, len, val) = split_into_tlv(&mut buf);
3494
3495        Attr::AccessToken {
3496            nonce: &[0x01, 0x02, 0x03, 0x04],
3497            mac: &[0x04, 0x03, 0x02, 0x01],
3498            timestamp: core::time::Duration::from_secs_f64(1.0 + 1.0 / 64000.0),
3499            lifetime: core::time::Duration::from_secs(1),
3500        }.into_buf(typ, len, val, &TID);
3501
3502        assert_eq!(&ACCESS_TOKEN, &buf);
3503    }
3504
3505    #[cfg(any(feature = "rfc8489"))]
3506    const MESSAGE_INTEGRITY_SHA256: [u8; 36] = [
3507        0x00, 0x1C,             // type: Message Integrity SHA256
3508        0x00, 0x20,             // len: 32
3509        0x00, 0x01, 0x02, 0x03,
3510        0x04, 0x05, 0x06, 0x07,
3511        0x08, 0x09, 0x0A, 0x0B,
3512        0x0C, 0x0D, 0x0E, 0x0F,
3513        0x10, 0x11, 0x12, 0x13,
3514        0x14, 0x15, 0x16, 0x17,
3515        0x18, 0x19, 0x1A, 0x1B,
3516        0x1C, 0x1D, 0x1E, 0x1F, // digest
3517    ];
3518
3519    #[cfg(any(feature = "rfc8489"))]
3520    #[test]
3521    fn message_integrity_sha256_read() {
3522        let attr = AttrIter {
3523            byte_iter: stun_bytes::ByteAttrIter::from_arr(&MESSAGE_INTEGRITY_SHA256),
3524            tid: &TID,
3525        }.next();
3526
3527        if let Some(Attr::MessageIntegritySha256(&[
3528        0x00, 0x01, 0x02, 0x03,
3529        0x04, 0x05, 0x06, 0x07,
3530        0x08, 0x09, 0x0A, 0x0B,
3531        0x0C, 0x0D, 0x0E, 0x0F,
3532        0x10, 0x11, 0x12, 0x13,
3533        0x14, 0x15, 0x16, 0x17,
3534        0x18, 0x19, 0x1A, 0x1B,
3535        0x1C, 0x1D, 0x1E, 0x1F,
3536        ])) = attr {} else { assert!(false); }
3537    }
3538
3539    #[cfg(any(feature = "rfc8489"))]
3540    #[test]
3541    fn message_integrity_sha256_write() {
3542        let mut buf = [0u8; 36];
3543        let (typ, len, val) = split_into_tlv(&mut buf);
3544
3545        Attr::MessageIntegritySha256(&[
3546            0x00, 0x01, 0x02, 0x03,
3547            0x04, 0x05, 0x06, 0x07,
3548            0x08, 0x09, 0x0A, 0x0B,
3549            0x0C, 0x0D, 0x0E, 0x0F,
3550            0x10, 0x11, 0x12, 0x13,
3551            0x14, 0x15, 0x16, 0x17,
3552            0x18, 0x19, 0x1A, 0x1B,
3553            0x1C, 0x1D, 0x1E, 0x1F,
3554        ]).into_buf(typ, len, val, &TID);
3555
3556        assert_eq!(&MESSAGE_INTEGRITY_SHA256, &buf);
3557    }
3558
3559    #[cfg(any(feature = "rfc8489"))]
3560    const PASSWORD_ALGORITHM_MD5: [u8; 8] = [
3561        0x00, 0x1D, // type: Password Algorithm
3562        0x00, 0x04, // len: 4
3563        0x00, 0x01, // typ: MD5
3564        0x00, 0x00, // param len: 0
3565    ];
3566
3567    #[cfg(any(feature = "rfc8489"))]
3568    const PASSWORD_ALGORITHM_SHA256: [u8; 8] = [
3569        0x00, 0x1D, // type: Password Algorithm
3570        0x00, 0x04, // len: 4
3571        0x00, 0x02, // typ: SHA256
3572        0x00, 0x00, // param len: 0
3573    ];
3574
3575    #[cfg(any(feature = "rfc8489"))]
3576    const PASSWORD_ALGORITHM_OTHER: [u8; 12] = [
3577        0x00, 0x1D,             // type: Password Algorithm
3578        0x00, 0x08,             // len: 8
3579        0x00, 0x04,             // typ: Other(4)
3580        0x00, 0x04,             // param len: 4
3581        0x01, 0x02, 0x03, 0x04, // params
3582    ];
3583
3584    #[cfg(any(feature = "rfc8489"))]
3585    #[test]
3586    fn password_algorithm_read() {
3587        let attr = AttrIter {
3588            byte_iter: stun_bytes::ByteAttrIter::from_arr(&PASSWORD_ALGORITHM_MD5),
3589            tid: &TID,
3590        }.next();
3591
3592        if let Some(Attr::PasswordAlgorithm(PasswordAlgorithm::Md5)) = attr {} else { assert!(false); }
3593
3594        let attr = AttrIter {
3595            byte_iter: stun_bytes::ByteAttrIter::from_arr(&PASSWORD_ALGORITHM_SHA256),
3596            tid: &TID,
3597        }.next();
3598
3599        if let Some(Attr::PasswordAlgorithm(PasswordAlgorithm::Sha256)) = attr {} else { assert!(false); }
3600
3601        let attr = AttrIter {
3602            byte_iter: stun_bytes::ByteAttrIter::from_arr(&PASSWORD_ALGORITHM_OTHER),
3603            tid: &TID,
3604        }.next();
3605
3606        if let Some(Attr::PasswordAlgorithm(PasswordAlgorithm::Other {
3607                                                typ: 4,
3608                                                params: &[0x01, 0x02, 0x03, 0x04]
3609                                            }
3610                    )) = attr {} else { assert!(false); }
3611    }
3612
3613    #[cfg(any(feature = "rfc8489"))]
3614    #[test]
3615    fn password_algorithm_write() {
3616        let mut buf = [0u8; 8];
3617        let (typ, len, val) = split_into_tlv(&mut buf);
3618
3619        Attr::PasswordAlgorithm(PasswordAlgorithm::Md5).into_buf(typ, len, val, &TID);
3620
3621        assert_eq!(&PASSWORD_ALGORITHM_MD5, &buf);
3622
3623        let mut buf = [0u8; 8];
3624        let (typ, len, val) = split_into_tlv(&mut buf);
3625
3626        Attr::PasswordAlgorithm(PasswordAlgorithm::Sha256).into_buf(typ, len, val, &TID);
3627
3628        assert_eq!(&PASSWORD_ALGORITHM_SHA256, &buf);
3629
3630        let mut buf = [0u8; 12];
3631        let (typ, len, val) = split_into_tlv(&mut buf);
3632
3633        Attr::PasswordAlgorithm(PasswordAlgorithm::Other { typ: 4, params: &[0x01, 0x02, 0x03, 0x04] })
3634            .into_buf(typ, len, val, &TID);
3635
3636        assert_eq!(&PASSWORD_ALGORITHM_OTHER, &buf);
3637    }
3638
3639    #[cfg(any(feature = "rfc8489"))]
3640    const USERHASH: [u8; 36] = [
3641        0x00, 0x1E,             // type: Userhash
3642        0x00, 0x20,             // len: 32
3643        0x00, 0x01, 0x02, 0x03,
3644        0x04, 0x05, 0x06, 0x07,
3645        0x08, 0x09, 0x0A, 0x0B,
3646        0x0C, 0x0D, 0x0E, 0x0F,
3647        0x10, 0x11, 0x12, 0x13,
3648        0x14, 0x15, 0x16, 0x17,
3649        0x18, 0x19, 0x1A, 0x1B,
3650        0x1C, 0x1D, 0x1E, 0x1F, // digest
3651    ];
3652
3653    #[cfg(any(feature = "rfc8489"))]
3654    #[test]
3655    fn userhash_read() {
3656        let attr = AttrIter {
3657            byte_iter: stun_bytes::ByteAttrIter::from_arr(&USERHASH),
3658            tid: &TID,
3659        }.next();
3660
3661        if let Some(Attr::Userhash(&[
3662        0x00, 0x01, 0x02, 0x03,
3663        0x04, 0x05, 0x06, 0x07,
3664        0x08, 0x09, 0x0A, 0x0B,
3665        0x0C, 0x0D, 0x0E, 0x0F,
3666        0x10, 0x11, 0x12, 0x13,
3667        0x14, 0x15, 0x16, 0x17,
3668        0x18, 0x19, 0x1A, 0x1B,
3669        0x1C, 0x1D, 0x1E, 0x1F,
3670        ])) = attr {} else { assert!(false); }
3671    }
3672
3673    #[cfg(any(feature = "rfc8489"))]
3674    #[test]
3675    fn userhash_write() {
3676        let mut buf = [0u8; 36];
3677        let (typ, len, val) = split_into_tlv(&mut buf);
3678
3679        Attr::Userhash(&[
3680            0x00, 0x01, 0x02, 0x03,
3681            0x04, 0x05, 0x06, 0x07,
3682            0x08, 0x09, 0x0A, 0x0B,
3683            0x0C, 0x0D, 0x0E, 0x0F,
3684            0x10, 0x11, 0x12, 0x13,
3685            0x14, 0x15, 0x16, 0x17,
3686            0x18, 0x19, 0x1A, 0x1B,
3687            0x1C, 0x1D, 0x1E, 0x1F,
3688        ]).into_buf(typ, len, val, &TID);
3689
3690        assert_eq!(&USERHASH, &buf);
3691    }
3692
3693    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
3694    const XOR_MAPPED_ADDRESS_IP4: [u8; 12] = [
3695        0x00, 0x20,                                                 // type: Xor Mapped Address
3696        0x00, 0x08,                                                 // len: 8
3697        0x00, 0x01,                                                 // family: IPv4
3698        0x01 ^ TID[0], 0x02 ^ TID[1],                               // port: 0x0102
3699        0x0A ^ TID[0], 0x0B ^ TID[1], 0x0C ^ TID[2], 0x0D ^ TID[3], // ip: 10.11.12.13
3700    ];
3701
3702    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
3703    const XOR_MAPPED_ADDRESS_IP6: [u8; 24] = [
3704        0x00, 0x20,                                                     // type: Xor Mapped Address
3705        0x00, 0x14,                                                     // len: 20
3706        0x00, 0x02,                                                     // family: IPv6
3707        0x01 ^ TID[0], 0x02 ^ TID[1],                                   // port: 0x0102
3708        0x00 ^ TID[0], 0x01 ^ TID[1], 0x02 ^ TID[2], 0x03 ^ TID[3],
3709        0x04 ^ TID[4], 0x05 ^ TID[5], 0x06 ^ TID[6], 0x07 ^ TID[7],
3710        0x08 ^ TID[8], 0x09 ^ TID[9], 0x0A ^ TID[10], 0x0B ^ TID[11],
3711        0x0C ^ TID[12], 0x0D ^ TID[13], 0x0E ^ TID[14], 0x0F ^ TID[15], // ip: 0123:4567:89AB:CDEF
3712    ];
3713
3714    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
3715    #[test]
3716    fn xor_mapped_address_read() {
3717        let attr = AttrIter {
3718            byte_iter: stun_bytes::ByteAttrIter::from_arr(&XOR_MAPPED_ADDRESS_IP4),
3719            tid: &TID,
3720        }.next();
3721
3722        if let Some(Attr::XorMappedAddress(SocketAddr::V4(ip, port))) = attr {
3723            assert_eq!([10, 11, 12, 13], ip);
3724            assert_eq!(0x0102, port);
3725        } else { assert!(false); }
3726
3727        let attr = AttrIter {
3728            byte_iter: stun_bytes::ByteAttrIter::from_arr(&XOR_MAPPED_ADDRESS_IP6),
3729            tid: &TID,
3730        }.next();
3731
3732        if let Some(Attr::XorMappedAddress(SocketAddr::V6(ip, port))) = attr {
3733            assert_eq!([
3734                           0x00, 0x01, 0x02, 0x03,
3735                           0x04, 0x05, 0x06, 0x07,
3736                           0x08, 0x09, 0x0A, 0x0B,
3737                           0x0C, 0x0D, 0x0E, 0x0F,
3738                       ], ip);
3739            assert_eq!(0x0102, port);
3740        } else { assert!(false); }
3741    }
3742
3743    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
3744    #[test]
3745    fn xor_mapped_address_write() {
3746        let mut buf = [0u8; 12];
3747
3748        let (typ, len, val) = split_into_tlv(&mut buf);
3749        Attr::XorMappedAddress(SocketAddr::V4([10, 11, 12, 13], 0x0102))
3750            .into_buf(typ, len, val, &TID);
3751
3752        assert_eq!(&XOR_MAPPED_ADDRESS_IP4, &buf);
3753
3754        let mut buf = [0u8; 24];
3755
3756        let (typ, len, val) = split_into_tlv(&mut buf);
3757        Attr::XorMappedAddress(SocketAddr::V6([
3758                                                  0x00, 0x01, 0x02, 0x03,
3759                                                  0x04, 0x05, 0x06, 0x07,
3760                                                  0x08, 0x09, 0x0A, 0x0B,
3761                                                  0x0C, 0x0D, 0x0E, 0x0F,
3762                                              ], 0x0102))
3763            .into_buf(typ, len, val, &TID);
3764
3765        assert_eq!(&XOR_MAPPED_ADDRESS_IP6, &buf);
3766    }
3767
3768    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3769    const RESERVATION_TOKEN: [u8; 12] = [
3770        0x00, 0x22,             // type: Reservation Token
3771        0x00, 0x08,             // len: 8
3772        0x01, 0x02, 0x03, 0x04,
3773        0x05, 0x06, 0x07, 0x08, // token
3774    ];
3775
3776    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3777    #[test]
3778    fn reservation_token_read() {
3779        let attr = AttrIter {
3780            byte_iter: stun_bytes::ByteAttrIter::from_arr(&RESERVATION_TOKEN),
3781            tid: &TID,
3782        }.next();
3783
3784        if let Some(Attr::ReservationToken(0x0102030405060708)) = attr {} else { assert!(false); }
3785    }
3786
3787    #[cfg(any(feature = "rfc5766", feature = "rfc8656"))]
3788    #[test]
3789    fn reservation_token_write() {
3790        let mut buf = [0u8; 12];
3791        let (typ, len, val) = split_into_tlv(&mut buf);
3792
3793        Attr::ReservationToken(0x0102030405060708).into_buf(typ, len, val, &TID);
3794
3795        assert_eq!(&RESERVATION_TOKEN, &buf);
3796    }
3797
3798    #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
3799    const PRIORITY: [u8; 8] = [
3800        0x00, 0x24,             // type: Priority
3801        0x00, 0x04,             // len: 4
3802        0x01, 0x02, 0x03, 0x04, // priority
3803    ];
3804
3805    #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
3806    #[test]
3807    fn priority_read() {
3808        let attr = AttrIter {
3809            byte_iter: stun_bytes::ByteAttrIter::from_arr(&PRIORITY),
3810            tid: &TID,
3811        }.next();
3812
3813        if let Some(Attr::Priority(0x01020304)) = attr {} else { assert!(false); }
3814    }
3815
3816    #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
3817    #[test]
3818    fn priority_write() {
3819        let mut buf = [0u8; 8];
3820        let (typ, len, val) = split_into_tlv(&mut buf);
3821
3822        Attr::Priority(0x01020304).into_buf(typ, len, val, &TID);
3823
3824        assert_eq!(&PRIORITY, &buf);
3825    }
3826
3827    #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
3828    const USE_CANDIDATE: [u8; 4] = [
3829        0x00, 0x25, // type: Use Candidate
3830        0x00, 0x00, // len: 0
3831    ];
3832
3833    #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
3834    #[test]
3835    fn use_candidate_read() {
3836        let attr = AttrIter {
3837            byte_iter: stun_bytes::ByteAttrIter::from_arr(&USE_CANDIDATE),
3838            tid: &TID,
3839        }.next();
3840
3841        if let Some(Attr::UseCandidate) = attr {} else { assert!(false); }
3842    }
3843
3844    #[cfg(any(feature = "rfc5780"))]
3845    #[test]
3846    fn use_candidate_write() {
3847        let mut buf = [0u8; 4];
3848        let (typ, len, val) = split_into_tlv(&mut buf);
3849
3850        Attr::UseCandidate.into_buf(typ, len, val, &TID);
3851
3852        assert_eq!(&USE_CANDIDATE, &buf);
3853    }
3854
3855    #[cfg(any(feature = "rfc5780"))]
3856    const PADDING: [u8; 8] = [
3857        0x00, 0x26,             // type: Padding
3858        0x00, 0x04,             // len: 4
3859        0x00, 0x00, 0x00, 0x00, // padding
3860    ];
3861
3862    #[cfg(any(feature = "rfc5780"))]
3863    #[test]
3864    fn padding_read() {
3865        let attr = AttrIter {
3866            byte_iter: stun_bytes::ByteAttrIter::from_arr(&PADDING),
3867            tid: &TID,
3868        }.next();
3869
3870        if let Some(Attr::Padding(&[0, 0, 0, 0])) = attr {} else { assert!(false); }
3871    }
3872
3873    #[cfg(any(feature = "rfc5780"))]
3874    #[test]
3875    fn padding_write() {
3876        let mut buf = [0u8; 8];
3877        let (typ, len, val) = split_into_tlv(&mut buf);
3878
3879        Attr::Padding(&[0, 0, 0, 0]).into_buf(typ, len, val, &TID);
3880
3881        assert_eq!(&PADDING, &buf);
3882    }
3883
3884    #[cfg(any(feature = "rfc5780"))]
3885    const RESPONSE_PORT: [u8; 8] = [
3886        0x00, 0x27, // type: Response Port
3887        0x00, 0x04, // len: 2
3888        0x01, 0x02, // port: 0x0102
3889        0x00, 0x00, // padding
3890    ];
3891
3892    #[cfg(any(feature = "rfc5780"))]
3893    #[test]
3894    fn response_port_read() {
3895        let attr = AttrIter {
3896            byte_iter: stun_bytes::ByteAttrIter::from_arr(&RESPONSE_PORT),
3897            tid: &TID,
3898        }.next();
3899
3900        if let Some(Attr::ResponsePort(0x0102)) = attr {} else { assert!(false); }
3901    }
3902
3903    #[cfg(any(feature = "rfc5780"))]
3904    #[test]
3905    fn response_port_write() {
3906        let mut buf = [0u8; 8];
3907        let (typ, len, val) = split_into_tlv(&mut buf);
3908
3909        Attr::ResponsePort(0x0102).into_buf(typ, len, val, &TID);
3910
3911        assert_eq!(&RESPONSE_PORT, &buf);
3912    }
3913
3914    #[cfg(any(feature = "rfc6062"))]
3915    const CONNECTION_ID: [u8; 8] = [
3916        0x00, 0x2A,             // type: Connection Id
3917        0x00, 0x04,             // len: 4
3918        0x01, 0x02, 0x03, 0x04, // id: 0x01020304
3919    ];
3920
3921    #[cfg(any(feature = "rfc6062"))]
3922    #[test]
3923    fn connection_id_read() {
3924        let attr = AttrIter {
3925            byte_iter: stun_bytes::ByteAttrIter::from_arr(&CONNECTION_ID),
3926            tid: &TID,
3927        }.next();
3928
3929        if let Some(Attr::ConnectionId(0x01020304)) = attr {} else { assert!(false); }
3930    }
3931
3932    #[cfg(any(feature = "rfc6062"))]
3933    #[test]
3934    fn connection_id_write() {
3935        let mut buf = [0u8; 8];
3936        let (typ, len, val) = split_into_tlv(&mut buf);
3937
3938        Attr::ConnectionId(0x01020304).into_buf(typ, len, val, &TID);
3939
3940        assert_eq!(&CONNECTION_ID, &buf);
3941    }
3942
3943    #[cfg(any(feature = "rfc8656"))]
3944    const ADDITIONAL_ADDRESS_FAMILY_IP4: [u8; 8] = [
3945        0x80, 0x00,             // type: Additional Address Family
3946        0x00, 0x04,             // len: 4
3947        0x01, 0x00, 0x00, 0x00, // family: IPv4
3948    ];
3949
3950    #[cfg(any(feature = "rfc8656"))]
3951    const ADDITIONAL_ADDRESS_FAMILY_IP6: [u8; 8] = [
3952        0x80, 0x00,             // type: Additional Address Family
3953        0x00, 0x04,             // len: 4
3954        0x02, 0x00, 0x00, 0x00, // family: IPv6
3955    ];
3956
3957    #[cfg(any(feature = "rfc8656"))]
3958    const ADDITIONAL_ADDRESS_FAMILY_OTHER: [u8; 8] = [
3959        0x80, 0x00,             // type: Additional Address Family
3960        0x00, 0x04,             // len: 4
3961        0x04, 0x00, 0x00, 0x00, // family: Other(4)
3962    ];
3963
3964    #[cfg(any(feature = "rfc8656"))]
3965    #[test]
3966    fn additional_address_family_read() {
3967        let attr = AttrIter {
3968            byte_iter: stun_bytes::ByteAttrIter::from_arr(&ADDITIONAL_ADDRESS_FAMILY_IP4),
3969            tid: &TID,
3970        }.next();
3971
3972        if let Some(Attr::AdditionalAddressFamily(AddressFamily::IPv4)) = attr {} else { assert!(false); }
3973
3974        let attr = AttrIter {
3975            byte_iter: stun_bytes::ByteAttrIter::from_arr(&ADDITIONAL_ADDRESS_FAMILY_IP6),
3976            tid: &TID,
3977        }.next();
3978
3979        if let Some(Attr::AdditionalAddressFamily(AddressFamily::IPv6)) = attr {} else { assert!(false); }
3980
3981        let attr = AttrIter {
3982            byte_iter: stun_bytes::ByteAttrIter::from_arr(&ADDITIONAL_ADDRESS_FAMILY_OTHER),
3983            tid: &TID,
3984        }.next();
3985
3986        if let Some(Attr::AdditionalAddressFamily(AddressFamily::Other(4))) = attr {} else { assert!(false); }
3987    }
3988
3989    #[cfg(any(feature = "rfc8656"))]
3990    #[test]
3991    fn additional_address_family_write() {
3992        let mut buf = [0u8; 8];
3993
3994        let (typ, len, val) = split_into_tlv(&mut buf);
3995        Attr::AdditionalAddressFamily(AddressFamily::IPv4)
3996            .into_buf(typ, len, val, &TID);
3997
3998        assert_eq!(&ADDITIONAL_ADDRESS_FAMILY_IP4, &buf);
3999
4000        let (typ, len, val) = split_into_tlv(&mut buf);
4001        Attr::AdditionalAddressFamily(AddressFamily::IPv6)
4002            .into_buf(typ, len, val, &TID);
4003
4004        assert_eq!(&ADDITIONAL_ADDRESS_FAMILY_IP6, &buf);
4005
4006        let (typ, len, val) = split_into_tlv(&mut buf);
4007        Attr::AdditionalAddressFamily(AddressFamily::Other(4))
4008            .into_buf(typ, len, val, &TID);
4009
4010        assert_eq!(&ADDITIONAL_ADDRESS_FAMILY_OTHER, &buf);
4011    }
4012
4013    const ADDRESS_ERROR_CODE: [u8; 16] = [
4014        0x80, 0x01,                         // type: Address Error Code
4015        0x00, 0x0A,                         // len: 10
4016        0x01, 0x00,                         // family: IPv4
4017        0x06 << 5, 0x10,                    // code: 616
4018        0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, // desc: 'string'
4019        0x00, 0x00,                         // padding
4020    ];
4021
4022    #[cfg(any(feature = "rfc8656"))]
4023    #[test]
4024    fn address_error_code_read() {
4025        let attr = AttrIter {
4026            byte_iter: stun_bytes::ByteAttrIter::from_arr(&ADDRESS_ERROR_CODE),
4027            tid: &TID,
4028        }.next();
4029
4030        if let Some(Attr::AddressErrorCode {
4031                        family: AddressFamily::IPv4,
4032                        code: ErrorCode::Other(616),
4033                        desc: "string"
4034                    }) = attr {} else { assert!(false); }
4035    }
4036
4037    #[cfg(any(feature = "rfc8656"))]
4038    #[test]
4039    fn address_error_code_write() {
4040        let mut buf = [0u8; 16];
4041        let (typ, len, val) = split_into_tlv(&mut buf);
4042
4043        Attr::AddressErrorCode {
4044            family: AddressFamily::IPv4,
4045            code: ErrorCode::Other(616),
4046            desc: "string",
4047        }.into_buf(typ, len, val, &TID);
4048
4049        assert_eq!(&ADDRESS_ERROR_CODE, &buf);
4050    }
4051
4052    #[cfg(any(feature = "rfc8489"))]
4053    const PASSWORD_ALGORITHMS: [u8; 20] = [
4054        0x80, 0x02,             // type: Password Algorithms
4055        0x00, 0x10,             // len: 16
4056        0x00, 0x01,             // typ: MD5
4057        0x00, 0x00,             // param len: 0
4058        0x00, 0x02,             // typ: SHA256
4059        0x00, 0x00,             // param len: 0
4060        0x00, 0x04,             // typ: Other(4)
4061        0x00, 0x04,             // param len: 4
4062        0x01, 0x02, 0x03, 0x04  // params
4063    ];
4064
4065    #[cfg(any(feature = "rfc8489"))]
4066    #[test]
4067    fn password_algorithms_read() {
4068        let attr = AttrIter {
4069            byte_iter: stun_bytes::ByteAttrIter::from_arr(&PASSWORD_ALGORITHMS),
4070            tid: &TID,
4071        }.next();
4072
4073        if let Some(Attr::PasswordAlgorithms(mut iter)) = attr {
4074            if let Some(PasswordAlgorithm::Md5) = iter.next() {} else { assert!(false); }
4075            if let Some(PasswordAlgorithm::Sha256) = iter.next() {} else { assert!(false); }
4076            if let Some(PasswordAlgorithm::Other { typ: 4, params: &[1, 2, 3, 4] }) = iter.next() {} else { assert!(false); }
4077            assert!(iter.next().is_none());
4078        } else { assert!(false); }
4079    }
4080
4081    #[cfg(any(feature = "rfc8489"))]
4082    #[test]
4083    fn password_algorithms_write() {
4084        let mut buf = [0u8; 16];
4085        let mut builder = PasswordAlgorithmsBuilder::from_arr_mut(&mut buf);
4086        builder.add_alg(&PasswordAlgorithm::Md5).unwrap();
4087        builder.add_alg(&PasswordAlgorithm::Sha256).unwrap();
4088        builder.add_alg(&PasswordAlgorithm::Other { typ: 4, params: &[1, 2, 3, 4] }).unwrap();
4089
4090        let mut buf = [0u8; 20];
4091        let (typ, len, val) = split_into_tlv(&mut buf);
4092
4093        Attr::PasswordAlgorithms(builder.to_buf().into())
4094            .into_buf(typ, len, val, &TID);
4095
4096        assert_eq!(&PASSWORD_ALGORITHMS, &buf);
4097    }
4098
4099    #[cfg(any(feature = "rfc8489"))]
4100    const ALTERNATE_DOMAIN: [u8; 12] = [
4101        0x80, 0x03,                         // type: Alternate Domain
4102        0x00, 0x06,                         // len: 6
4103        0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, // val: 'string'
4104        0x00, 0x00,                         // padding
4105    ];
4106
4107    #[cfg(any(feature = "rfc8489"))]
4108    #[test]
4109    fn alternate_domain_read() {
4110        let attr = AttrIter {
4111            byte_iter: stun_bytes::ByteAttrIter::from_arr(&ALTERNATE_DOMAIN),
4112            tid: &TID,
4113        }.next();
4114
4115        if let Some(Attr::AlternateDomain("string")) = attr {} else { assert!(false); }
4116    }
4117
4118    #[cfg(any(feature = "rfc8489"))]
4119    #[test]
4120    fn alternate_domain_write() {
4121        let mut buf = [0u8; 12];
4122        let (typ, len, val) = split_into_tlv(&mut buf);
4123
4124        Attr::AlternateDomain("string")
4125            .into_buf(typ, len, val, &TID);
4126
4127        assert_eq!(&ALTERNATE_DOMAIN, &buf);
4128    }
4129
4130    #[cfg(any(feature = "rfc8656"))]
4131    const ICMP: [u8; 12] = [
4132        0x80, 0x04,             // type: Icmp
4133        0x00, 0x08,             // len: 8
4134        0x00, 0x00,             // RFFU
4135        0x01,                   // typ
4136        0x02,                   // code
4137        0x01, 0x02, 0x03, 0x04, // data
4138    ];
4139
4140    #[cfg(any(feature = "rfc8656"))]
4141    #[test]
4142    fn icmp_read() {
4143        let attr = AttrIter {
4144            byte_iter: stun_bytes::ByteAttrIter::from_arr(&ICMP),
4145            tid: &TID,
4146        }.next();
4147
4148        if let Some(Attr::Icmp { typ: 1, code: 2, data: 0x01020304 }) = attr {} else { assert!(false); }
4149    }
4150
4151    #[cfg(any(feature = "rfc8656"))]
4152    #[test]
4153    fn icmp_write() {
4154        let mut buf = [0u8; 12];
4155        let (typ, len, val) = split_into_tlv(&mut buf);
4156
4157        Attr::Icmp { typ: 1, code: 2, data: 0x01020304 }
4158            .into_buf(typ, len, val, &TID);
4159
4160        assert_eq!(&ICMP, &buf);
4161    }
4162
4163    #[cfg(any(feature = "rfc3489"))]
4164    const OPT_XOR_MAPPED_ADDRESS_IP4: [u8; 12] = [
4165        0x80, 0x20,                                                 // type: Opt Xor Mapped Address
4166        0x00, 0x08,                                                 // len: 8
4167        0x00, 0x01,                                                 // family: IPv4
4168        0x01 ^ TID[0], 0x02 ^ TID[1],                               // port: 0x0102
4169        0x0A ^ TID[0], 0x0B ^ TID[1], 0x0C ^ TID[2], 0x0D ^ TID[3], // ip: 10.11.12.13
4170    ];
4171
4172    #[cfg(any(feature = "rfc3489"))]
4173    const OPT_XOR_MAPPED_ADDRESS_IP6: [u8; 24] = [
4174        0x80, 0x20,                                                     // type: Opt Xor Mapped Address
4175        0x00, 0x14,                                                     // len: 20
4176        0x00, 0x02,                                                     // family: IPv6
4177        0x01 ^ TID[0], 0x02 ^ TID[1],                                   // port: 0x0102
4178        0x00 ^ TID[0], 0x01 ^ TID[1], 0x02 ^ TID[2], 0x03 ^ TID[3],
4179        0x04 ^ TID[4], 0x05 ^ TID[5], 0x06 ^ TID[6], 0x07 ^ TID[7],
4180        0x08 ^ TID[8], 0x09 ^ TID[9], 0x0A ^ TID[10], 0x0B ^ TID[11],
4181        0x0C ^ TID[12], 0x0D ^ TID[13], 0x0E ^ TID[14], 0x0F ^ TID[15], // ip: 0123:4567:89AB:CDEF
4182    ];
4183
4184    #[cfg(any(feature = "rfc3489"))]
4185    #[test]
4186    fn opt_xor_mapped_address() {
4187        let attr = AttrIter {
4188            byte_iter: stun_bytes::ByteAttrIter::from_arr(&OPT_XOR_MAPPED_ADDRESS_IP4),
4189            tid: &TID,
4190        }.next();
4191
4192        if let Some(Attr::OptXorMappedAddress(SocketAddr::V4([10, 11, 12, 13], 0x0102))) = attr {} else { assert!(false); }
4193
4194        let attr = AttrIter {
4195            byte_iter: stun_bytes::ByteAttrIter::from_arr(&OPT_XOR_MAPPED_ADDRESS_IP6),
4196            tid: &TID,
4197        }.next();
4198
4199        if let Some(Attr::OptXorMappedAddress(SocketAddr::V6(ip, port))) = attr {
4200            assert_eq!([
4201                           0x00, 0x01, 0x02, 0x03,
4202                           0x04, 0x05, 0x06, 0x07,
4203                           0x08, 0x09, 0x0A, 0x0B,
4204                           0x0C, 0x0D, 0x0E, 0x0F,
4205                       ], ip);
4206            assert_eq!(0x0102, port);
4207        } else { assert!(false); }
4208    }
4209
4210    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
4211    const SOFTWARE: [u8; 12] = [
4212        0x80, 0x22,                         // type: Software
4213        0x00, 0x06,                         // len: 6
4214        0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, // val: 'string'
4215        0x00, 0x00,                         // padding
4216    ];
4217
4218    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
4219    #[test]
4220    fn software_read() {
4221        let attr = AttrIter {
4222            byte_iter: stun_bytes::ByteAttrIter::from_arr(&SOFTWARE),
4223            tid: &TID,
4224        }.next();
4225
4226        if let Some(Attr::Software("string")) = attr {} else { assert!(false); }
4227    }
4228
4229    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
4230    #[test]
4231    fn software_write() {
4232        let mut buf = [0u8; 12];
4233        let (typ, len, val) = split_into_tlv(&mut buf);
4234
4235        Attr::Software("string")
4236            .into_buf(typ, len, val, &TID);
4237
4238        assert_eq!(&SOFTWARE, &buf);
4239    }
4240
4241    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
4242    const ALTERNATE_SERVER_IP4: [u8; 12] = [
4243        0x80, 0x23,             // type: Alternate Server
4244        0x00, 0x08,             // len: 8
4245        0x00, 0x01,             // family: IPv4
4246        0x01, 0x02,             // port: 0x0102
4247        0x0A, 0x0B, 0x0C, 0x0D, // ip: 10.11.12.13
4248    ];
4249
4250    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
4251    const ALTERNATE_SERVER_IP6: [u8; 24] = [
4252        0x80, 0x23,             // type: Alternate Server
4253        0x00, 0x14,             // len: 20
4254        0x00, 0x02,             // family: IPv6
4255        0x01, 0x02,             // port: 0x0102
4256        0x00, 0x01, 0x02, 0x03,
4257        0x04, 0x05, 0x06, 0x07,
4258        0x08, 0x09, 0x0A, 0x0B,
4259        0x0C, 0x0D, 0x0E, 0x0F, // ip: 0123:4567:89AB:CDEF
4260    ];
4261
4262    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
4263    #[test]
4264    fn alternate_server_read() {
4265        let attr = AttrIter {
4266            byte_iter: stun_bytes::ByteAttrIter::from_arr(&ALTERNATE_SERVER_IP4),
4267            tid: &TID,
4268        }.next();
4269
4270        if let Some(Attr::AlternateServer(SocketAddr::V4(ip, port))) = attr {
4271            assert_eq!([10, 11, 12, 13], ip);
4272            assert_eq!(0x0102, port);
4273        } else { assert!(false); }
4274
4275        let attr = AttrIter {
4276            byte_iter: stun_bytes::ByteAttrIter::from_arr(&ALTERNATE_SERVER_IP6),
4277            tid: &TID,
4278        }.next();
4279
4280        if let Some(Attr::AlternateServer(SocketAddr::V6(ip, port))) = attr {
4281            assert_eq!([
4282                           0x00, 0x01, 0x02, 0x03,
4283                           0x04, 0x05, 0x06, 0x07,
4284                           0x08, 0x09, 0x0A, 0x0B,
4285                           0x0C, 0x0D, 0x0E, 0x0F,
4286                       ], ip);
4287            assert_eq!(0x0102, port);
4288        } else { assert!(false); }
4289    }
4290
4291    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
4292    #[test]
4293    fn alternate_server_write() {
4294        let mut buf = [0u8; 12];
4295        let (typ, len, val) = split_into_tlv(&mut buf);
4296
4297        Attr::AlternateServer(SocketAddr::V4([10, 11, 12, 13], 0x0102))
4298            .into_buf(typ, len, val, &TID);
4299
4300        assert_eq!(&ALTERNATE_SERVER_IP4, &buf);
4301
4302        let mut buf = [0u8; 24];
4303        let (typ, len, val) = split_into_tlv(&mut buf);
4304
4305        Attr::AlternateServer(SocketAddr::V6([
4306                                                 0x00, 0x01, 0x02, 0x03,
4307                                                 0x04, 0x05, 0x06, 0x07,
4308                                                 0x08, 0x09, 0x0A, 0x0B,
4309                                                 0x0C, 0x0D, 0x0E, 0x0F,
4310                                             ], 0x0102)).into_buf(typ, len, val, &TID);
4311
4312        assert_eq!(&ALTERNATE_SERVER_IP6, &buf);
4313    }
4314
4315    #[cfg(any(feature = "rfc7982"))]
4316    const TRANSACTION_TRANSMIT_COUNTER: [u8; 8] = [
4317        0x80, 0x25, // type: Transaction Transmit Counter
4318        0x00, 0x04, // len: 4
4319        0x00, 0x00, // RFFU
4320        0x01,       // req: 1
4321        0x02,       // res: 2
4322    ];
4323
4324    #[cfg(any(feature = "rfc7982"))]
4325    #[test]
4326    fn transaction_transmit_counter_read() {
4327        let attr = AttrIter {
4328            byte_iter: stun_bytes::ByteAttrIter::from_arr(&TRANSACTION_TRANSMIT_COUNTER),
4329            tid: &TID,
4330        }.next();
4331
4332        if let Some(Attr::TransactionTransmitCounter { req: 1, res: 2 }) = attr {} else { assert!(false); }
4333    }
4334
4335    #[cfg(any(feature = "rfc7982"))]
4336    #[test]
4337    fn transaction_transmit_counter_write() {
4338        let mut buf = [0u8; 8];
4339        let (typ, len, val) = split_into_tlv(&mut buf);
4340
4341        Attr::TransactionTransmitCounter { req: 1, res: 2 }
4342            .into_buf(typ, len, val, &TID);
4343
4344        assert_eq!(&TRANSACTION_TRANSMIT_COUNTER, &buf);
4345    }
4346
4347    #[cfg(any(feature = "rfc5780"))]
4348    const CACHE_TIMEOUT: [u8; 8] = [
4349        0x80, 0x27,             // type: Cache Timeout
4350        0x00, 0x04,             // len: 4
4351        0x01, 0x02, 0x03, 0x04, // timemout: 0x01020304
4352    ];
4353
4354    #[cfg(any(feature = "rfc5780"))]
4355    #[test]
4356    fn cache_timeout_read() {
4357        let attr = AttrIter {
4358            byte_iter: stun_bytes::ByteAttrIter::from_arr(&CACHE_TIMEOUT),
4359            tid: &TID,
4360        }.next();
4361
4362        if let Some(Attr::CacheTimeout(timeout)) = attr {
4363            assert_eq!(0x01020304, timeout.as_secs());
4364        } else { assert!(false); }
4365    }
4366
4367    #[cfg(any(feature = "rfc5780"))]
4368    #[test]
4369    fn cache_timeout_write() {
4370        let mut buf = [0u8; 8];
4371        let (typ, len, val) = split_into_tlv(&mut buf);
4372
4373        Attr::CacheTimeout(core::time::Duration::from_secs(0x01020304))
4374            .into_buf(typ, len, val, &TID);
4375
4376        assert_eq!(&CACHE_TIMEOUT, &buf);
4377    }
4378
4379    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
4380    const FINGERPRINT: [u8; 8] = [
4381        0x80, 0x28, // type: Fingerprint
4382        0x00, 0x04, // len: 4
4383        0x01 ^ 0x53,
4384        0x02 ^ 0x54,
4385        0x03 ^ 0x55,
4386        0x04 ^ 0x4E, // val: 0x01020304
4387    ];
4388
4389    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
4390    #[test]
4391    fn fingerprint_read() {
4392        let attr = AttrIter {
4393            byte_iter: stun_bytes::ByteAttrIter::from_arr(&FINGERPRINT),
4394            tid: &TID,
4395        }.next();
4396
4397        if let Some(Attr::Fingerprint(0x01020304)) = attr {} else { assert!(false); }
4398    }
4399
4400    #[cfg(any(feature = "rfc5389", feature = "rfc8489"))]
4401    #[test]
4402    fn fingerprint_write() {
4403        let mut buf = [0u8; 8];
4404        let (typ, len, val) = split_into_tlv(&mut buf);
4405
4406        Attr::Fingerprint(0x01020304)
4407            .into_buf(typ, len, val, &TID);
4408
4409        assert_eq!(&FINGERPRINT, &buf);
4410    }
4411
4412    #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
4413    const ICE_CONTROLLED: [u8; 12] = [
4414        0x80, 0x29,             // type: Ice Controlled
4415        0x00, 0x08,             // len: 8
4416        0x01, 0x02, 0x03, 0x04,
4417        0x05, 0x06, 0x07, 0x08, // val
4418    ];
4419
4420    #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
4421    #[test]
4422    fn ice_controlled_read() {
4423        let attr = AttrIter {
4424            byte_iter: stun_bytes::ByteAttrIter::from_arr(&ICE_CONTROLLED),
4425            tid: &TID,
4426        }.next();
4427
4428        if let Some(Attr::IceControlled(0x0102030405060708)) = attr {} else { assert!(false); }
4429    }
4430
4431    #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
4432    #[test]
4433    fn ice_controlled_write() {
4434        let mut buf = [0u8; 12];
4435        let (typ, len, val) = split_into_tlv(&mut buf);
4436
4437        Attr::IceControlled(0x0102030405060708)
4438            .into_buf(typ, len, val, &TID);
4439
4440        assert_eq!(&ICE_CONTROLLED, &buf);
4441    }
4442
4443    #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
4444    const ICE_CONTROLLING: [u8; 12] = [
4445        0x80, 0x2A,             // type: Ice Controlling
4446        0x00, 0x08,             // len: 8
4447        0x01, 0x02, 0x03, 0x04,
4448        0x05, 0x06, 0x07, 0x08, // val
4449    ];
4450
4451    #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
4452    #[test]
4453    fn ice_controlling_read() {
4454        let attr = AttrIter {
4455            byte_iter: stun_bytes::ByteAttrIter::from_arr(&ICE_CONTROLLING),
4456            tid: &TID,
4457        }.next();
4458
4459        if let Some(Attr::IceControlling(0x0102030405060708)) = attr {} else { assert!(false); }
4460    }
4461
4462    #[cfg(any(feature = "rfc5425", feature = "rfc8445"))]
4463    #[test]
4464    fn ice_controlling_write() {
4465        let mut buf = [0u8; 12];
4466        let (typ, len, val) = split_into_tlv(&mut buf);
4467
4468        Attr::IceControlling(0x0102030405060708)
4469            .into_buf(typ, len, val, &TID);
4470
4471        assert_eq!(&ICE_CONTROLLING, &buf);
4472    }
4473
4474    #[cfg(any(feature = "rfc5780"))]
4475    const RESPONSE_ORIGIN_IP4: [u8; 12] = [
4476        0x80, 0x2B,             // type: Response Origin
4477        0x00, 0x08,             // len: 8
4478        0x00, 0x01,             // family: IPv4
4479        0x01, 0x02,             // port: 0x0102
4480        0x0A, 0x0B, 0x0C, 0x0D, // ip: 10.11.12.13
4481    ];
4482
4483    #[cfg(any(feature = "rfc5780"))]
4484    const RESPONSE_ORIGIN_IP6: [u8; 24] = [
4485        0x80, 0x2B,             // type: Response Origin
4486        0x00, 0x14,             // len: 20
4487        0x00, 0x02,             // family: IPv6
4488        0x01, 0x02,             // port: 0x0102
4489        0x00, 0x01, 0x02, 0x03,
4490        0x04, 0x05, 0x06, 0x07,
4491        0x08, 0x09, 0x0A, 0x0B,
4492        0x0C, 0x0D, 0x0E, 0x0F, // ip: 0123:4567:89AB:CDEF
4493    ];
4494
4495    #[cfg(any(feature = "rfc5780"))]
4496    #[test]
4497    fn response_origin_read() {
4498        let attr = AttrIter {
4499            byte_iter: stun_bytes::ByteAttrIter::from_arr(&RESPONSE_ORIGIN_IP4),
4500            tid: &TID,
4501        }.next();
4502
4503        if let Some(Attr::ResponseOrigin(SocketAddr::V4(ip, port))) = attr {
4504            assert_eq!([10, 11, 12, 13], ip);
4505            assert_eq!(0x0102, port);
4506        } else { assert!(false); }
4507
4508        let attr = AttrIter {
4509            byte_iter: stun_bytes::ByteAttrIter::from_arr(&RESPONSE_ORIGIN_IP6),
4510            tid: &TID,
4511        }.next();
4512
4513        if let Some(Attr::ResponseOrigin(SocketAddr::V6(ip, port))) = attr {
4514            assert_eq!([
4515                           0x00, 0x01, 0x02, 0x03,
4516                           0x04, 0x05, 0x06, 0x07,
4517                           0x08, 0x09, 0x0A, 0x0B,
4518                           0x0C, 0x0D, 0x0E, 0x0F,
4519                       ], ip);
4520            assert_eq!(0x0102, port);
4521        } else { assert!(false); }
4522    }
4523
4524    #[cfg(any(feature = "rfc5780"))]
4525    #[test]
4526    fn response_origin_write() {
4527        let mut buf = [0u8; 12];
4528        let (typ, len, val) = split_into_tlv(&mut buf);
4529
4530        Attr::ResponseOrigin(SocketAddr::V4([10, 11, 12, 13], 0x0102))
4531            .into_buf(typ, len, val, &TID);
4532
4533        assert_eq!(&RESPONSE_ORIGIN_IP4, &buf);
4534
4535        let mut buf = [0u8; 24];
4536        let (typ, len, val) = split_into_tlv(&mut buf);
4537
4538        Attr::ResponseOrigin(SocketAddr::V6([
4539                                                0x00, 0x01, 0x02, 0x03,
4540                                                0x04, 0x05, 0x06, 0x07,
4541                                                0x08, 0x09, 0x0A, 0x0B,
4542                                                0x0C, 0x0D, 0x0E, 0x0F,
4543                                            ], 0x0102)).into_buf(typ, len, val, &TID);
4544
4545        assert_eq!(&RESPONSE_ORIGIN_IP6, &buf);
4546    }
4547
4548    #[cfg(any(feature = "rfc5780"))]
4549    const OTHER_ADDRESS_IP4: [u8; 12] = [
4550        0x80, 0x2C,             // type: Other Address
4551        0x00, 0x08,             // len: 8
4552        0x00, 0x01,             // family: IPv4
4553        0x01, 0x02,             // port: 0x0102
4554        0x0A, 0x0B, 0x0C, 0x0D, // ip: 10.11.12.13
4555    ];
4556
4557    #[cfg(any(feature = "rfc5780"))]
4558    const OTHER_ADDRESS_IP6: [u8; 24] = [
4559        0x80, 0x2C,             // type: Other Address
4560        0x00, 0x14,             // len: 20
4561        0x00, 0x02,             // family: IPv6
4562        0x01, 0x02,             // port: 0x0102
4563        0x00, 0x01, 0x02, 0x03,
4564        0x04, 0x05, 0x06, 0x07,
4565        0x08, 0x09, 0x0A, 0x0B,
4566        0x0C, 0x0D, 0x0E, 0x0F, // ip: 0123:4567:89AB:CDEF
4567    ];
4568
4569    #[cfg(any(feature = "rfc5780"))]
4570    #[test]
4571    fn other_address_read() {
4572        let attr = AttrIter {
4573            byte_iter: stun_bytes::ByteAttrIter::from_arr(&OTHER_ADDRESS_IP4),
4574            tid: &TID,
4575        }.next();
4576
4577        if let Some(Attr::OtherAddress(SocketAddr::V4(ip, port))) = attr {
4578            assert_eq!([10, 11, 12, 13], ip);
4579            assert_eq!(0x0102, port);
4580        } else { assert!(false); }
4581
4582        let attr = AttrIter {
4583            byte_iter: stun_bytes::ByteAttrIter::from_arr(&OTHER_ADDRESS_IP6),
4584            tid: &TID,
4585        }.next();
4586
4587        if let Some(Attr::OtherAddress(SocketAddr::V6(ip, port))) = attr {
4588            assert_eq!([
4589                           0x00, 0x01, 0x02, 0x03,
4590                           0x04, 0x05, 0x06, 0x07,
4591                           0x08, 0x09, 0x0A, 0x0B,
4592                           0x0C, 0x0D, 0x0E, 0x0F,
4593                       ], ip);
4594            assert_eq!(0x0102, port);
4595        } else { assert!(false); }
4596    }
4597
4598    #[cfg(any(feature = "rfc5780"))]
4599    #[test]
4600    fn other_address_write() {
4601        let mut buf = [0u8; 12];
4602        let (typ, len, val) = split_into_tlv(&mut buf);
4603
4604        Attr::OtherAddress(SocketAddr::V4([10, 11, 12, 13], 0x0102))
4605            .into_buf(typ, len, val, &TID);
4606
4607        assert_eq!(&OTHER_ADDRESS_IP4, &buf);
4608
4609        let mut buf = [0u8; 24];
4610        let (typ, len, val) = split_into_tlv(&mut buf);
4611
4612        Attr::OtherAddress(SocketAddr::V6([
4613                                              0x00, 0x01, 0x02, 0x03,
4614                                              0x04, 0x05, 0x06, 0x07,
4615                                              0x08, 0x09, 0x0A, 0x0B,
4616                                              0x0C, 0x0D, 0x0E, 0x0F,
4617                                          ], 0x0102)).into_buf(typ, len, val, &TID);
4618
4619        assert_eq!(&OTHER_ADDRESS_IP6, &buf);
4620    }
4621
4622    #[cfg(any(feature = "rfc6679"))]
4623    const ECN_CHECK: [u8; 8] = [
4624        0x80, 0x2D,                             // type: Ecn Check
4625        0x00, 0x04,                             // len: 4
4626        0x00, 0x00,                             // RFFU
4627        0x00, 0x01 << 7 | 0x01 << 6 | 0x01 << 5 // valid: true , val: 3
4628    ];
4629
4630    #[cfg(any(feature = "rfc6679"))]
4631    #[test]
4632    fn ecn_check_read() {
4633        let attr = AttrIter {
4634            byte_iter: stun_bytes::ByteAttrIter::from_arr(&ECN_CHECK),
4635            tid: &TID,
4636        }.next();
4637
4638        if let Some(Attr::EcnCheck { valid: true, val: 3 }) = attr {} else { assert!(false); }
4639    }
4640
4641    #[cfg(any(feature = "rfc6679"))]
4642    #[test]
4643    fn ecn_check_write() {
4644        let mut buf = [0u8; 8];
4645        let (typ, len, val) = split_into_tlv(&mut buf);
4646
4647        Attr::EcnCheck { valid: true, val: 3 }.into_buf(typ, len, val, &TID);
4648
4649        assert_eq!(&ECN_CHECK, &buf);
4650    }
4651
4652    #[cfg(any(feature = "rfc7635"))]
4653    const THIRD_PARTY_AUTHORISATION: [u8; 12] = [
4654        0x80, 0x2E,                         // type: Third Party Authorisation
4655        0x00, 0x06,                         // len: 6
4656        0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, // val: 'string'
4657        0x00, 0x00,                         // padding
4658    ];
4659
4660    #[cfg(any(feature = "rfc7635"))]
4661    #[test]
4662    fn third_party_authorisation_read() {
4663        let attr = AttrIter {
4664            byte_iter: stun_bytes::ByteAttrIter::from_arr(&THIRD_PARTY_AUTHORISATION),
4665            tid: &TID,
4666        }.next();
4667
4668        if let Some(Attr::ThirdPartyAuthorisation("string")) = attr {} else { assert!(false); }
4669    }
4670
4671    #[cfg(any(feature = "rfc7635"))]
4672    #[test]
4673    fn third_party_authorisation_write() {
4674        let mut buf = [0u8; 12];
4675        let (typ, len, val) = split_into_tlv(&mut buf);
4676
4677        Attr::ThirdPartyAuthorisation("string").into_buf(typ, len, val, &TID);
4678
4679        assert_eq!(&THIRD_PARTY_AUTHORISATION, &buf);
4680    }
4681
4682    #[cfg(any(feature = "rfc8016"))]
4683    const MOBILITY_TICKET: [u8; 8] = [
4684        0x80, 0x30,             // type: Mobility Ticket
4685        0x00, 0x04,             // len: 4
4686        0x01, 0x02, 0x03, 0x04, // val
4687    ];
4688
4689    #[cfg(any(feature = "rfc8016"))]
4690    #[test]
4691    fn mobility_ticket_read() {
4692        let attr = AttrIter {
4693            byte_iter: stun_bytes::ByteAttrIter::from_arr(&MOBILITY_TICKET),
4694            tid: &TID,
4695        }.next();
4696
4697        if let Some(Attr::MobilityTicket(&[1, 2, 3, 4])) = attr {} else { assert!(false); }
4698    }
4699
4700    #[cfg(any(feature = "rfc8016"))]
4701    #[test]
4702    fn mobility_ticket_write() {
4703        let mut buf = [0u8; 8];
4704        let (typ, len, val) = split_into_tlv(&mut buf);
4705
4706        Attr::MobilityTicket(&[1, 2, 3, 4]).into_buf(typ, len, val, &TID);
4707
4708        assert_eq!(&MOBILITY_TICKET, &buf);
4709    }
4710
4711    fn split_into_tlv<const N: usize>(buf: &mut [u8; N]) -> (&mut [u8; 2], &mut [u8; 2], &mut [u8]) {
4712        let (typ, buf) = buf.splice_mut().unwrap();
4713        let (len, buf) = buf.splice_mut().unwrap();
4714        (typ, len, buf)
4715    }
4716}
4717
4718#[cfg(test)]
4719mod msg {
4720    use super::*;
4721
4722    const MSG: [u8; 28] = [
4723        0x00, 0x01,                     // type: Binding Request
4724        0x00, 0x08,                     // length: 8 (header does not count)
4725        0x21, 0x12, 0xA4, 0x42,         // magic cookie
4726        0x00, 0x00, 0x00, 0x00,
4727        0x00, 0x00, 0x00, 0x00,
4728        0x00, 0x00, 0x00, 0x01,         // transaction id (16 bytes total incl. magic cookie)
4729        0x00, 0x03,                     // type: ChangeRequest
4730        0x00, 0x04,                     // length: 4 (only value bytes count)
4731        0x00, 0x00, 0x00, 0x40 | 0x20,  // change both ip and port
4732    ];
4733
4734    #[test]
4735    fn read() {
4736        let msg = Msg::from(MSG.as_slice());
4737        if let Some(MsgType::BindingRequest) = msg.typ() {} else { assert!(false) };
4738
4739        assert_eq!(0x2112A442, msg.cookie().unwrap());
4740
4741        assert_eq!(1, msg.tid().unwrap());
4742
4743        let mut iter = msg.attrs_iter();
4744
4745        if let Some(Attr::ChangeRequest { change_ip: true, change_port: true }) = iter.next() {} else { assert!(false); }
4746
4747        assert!(iter.next().is_none());
4748    }
4749
4750    #[test]
4751    fn write() {
4752        let mut buf = [0u8; MSG.len()];
4753        let mut msg = MsgBuilder::from(buf.as_mut_slice());
4754
4755        msg.typ(MsgType::BindingRequest).unwrap();
4756        msg.tid(1).unwrap();
4757        msg.add_attr(Attr::ChangeRequest { change_ip: true, change_port: true }).unwrap();
4758
4759        assert_eq!(&MSG, msg.as_bytes());
4760    }
4761}