1use alloc::boxed::Box;
10use core::net::SocketAddr;
11
12use crate::AddressFamily;
13use stun_types::{
14 attribute::*,
15 message::{StunParseError, TransactionId},
16};
17
18#[derive(Debug, Clone)]
25pub struct XorPeerAddress {
26 addr: XorSocketAddr,
28}
29
30impl AttributeStaticType for XorPeerAddress {
31 const TYPE: AttributeType = AttributeType::new(0x0012);
32}
33
34impl Attribute for XorPeerAddress {
35 fn get_type(&self) -> AttributeType {
36 Self::TYPE
37 }
38
39 fn length(&self) -> u16 {
40 self.addr.length()
41 }
42}
43
44impl AttributeWrite for XorPeerAddress {
45 fn to_raw(&self) -> RawAttribute<'_> {
46 self.addr.to_raw(self.get_type())
47 }
48 fn write_into_unchecked(&self, dest: &mut [u8]) {
49 self.write_header_unchecked(dest);
50 self.addr.write_into_unchecked(&mut dest[4..]);
51 }
52}
53
54impl AttributeFromRaw<'_> for XorPeerAddress {
55 fn from_raw_ref(raw: &RawAttribute) -> Result<Self, StunParseError>
56 where
57 Self: Sized,
58 {
59 Self::try_from(raw)
60 }
61}
62
63impl TryFrom<&RawAttribute<'_>> for XorPeerAddress {
64 type Error = StunParseError;
65 fn try_from(raw: &RawAttribute) -> Result<Self, Self::Error> {
66 raw.check_type_and_len(Self::TYPE, 4..=20)?;
67 Ok(Self {
68 addr: XorSocketAddr::from_raw(raw)?,
69 })
70 }
71}
72
73impl XorPeerAddress {
74 pub fn new(addr: SocketAddr, transaction: TransactionId) -> Self {
86 Self {
87 addr: XorSocketAddr::new(addr, transaction),
88 }
89 }
90
91 pub fn addr(&self, transaction: TransactionId) -> SocketAddr {
103 self.addr.addr(transaction)
104 }
105}
106
107impl core::fmt::Display for XorPeerAddress {
108 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
109 write!(f, "{}: {}", self.get_type(), self.addr)
110 }
111}
112
113#[derive(Debug, Clone)]
119pub struct XorRelayedAddress {
120 addr: XorSocketAddr,
121}
122
123impl AttributeStaticType for XorRelayedAddress {
124 const TYPE: AttributeType = AttributeType::new(0x0016);
125}
126
127impl Attribute for XorRelayedAddress {
128 fn get_type(&self) -> AttributeType {
129 Self::TYPE
130 }
131
132 fn length(&self) -> u16 {
133 self.addr.length()
134 }
135}
136
137impl AttributeWrite for XorRelayedAddress {
138 fn to_raw(&self) -> RawAttribute<'_> {
139 self.addr.to_raw(self.get_type())
140 }
141 fn write_into_unchecked(&self, dest: &mut [u8]) {
142 self.write_header_unchecked(dest);
143 self.addr.write_into_unchecked(&mut dest[4..]);
144 }
145}
146
147impl AttributeFromRaw<'_> for XorRelayedAddress {
148 fn from_raw_ref(raw: &RawAttribute) -> Result<Self, StunParseError>
149 where
150 Self: Sized,
151 {
152 Self::try_from(raw)
153 }
154}
155
156impl TryFrom<&RawAttribute<'_>> for XorRelayedAddress {
157 type Error = StunParseError;
158 fn try_from(raw: &RawAttribute) -> Result<Self, Self::Error> {
159 if raw.get_type() != Self::TYPE {
160 return Err(StunParseError::WrongAttributeImplementation);
161 }
162 Ok(Self {
163 addr: XorSocketAddr::from_raw(raw)?,
164 })
165 }
166}
167
168impl XorRelayedAddress {
169 pub fn new(addr: SocketAddr, transaction: TransactionId) -> Self {
181 Self {
182 addr: XorSocketAddr::new(addr, transaction),
183 }
184 }
185
186 pub fn addr(&self, transaction: TransactionId) -> SocketAddr {
198 self.addr.addr(transaction)
199 }
200}
201
202impl core::fmt::Display for XorRelayedAddress {
203 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
204 write!(f, "{}: {}", self.get_type(), self.addr)
205 }
206}
207
208#[derive(Debug, Clone)]
214pub struct RequestedAddressFamily {
215 family: AddressFamily,
216}
217
218impl AttributeStaticType for RequestedAddressFamily {
219 const TYPE: AttributeType = AttributeType::new(0x0017);
220}
221
222impl Attribute for RequestedAddressFamily {
223 fn get_type(&self) -> AttributeType {
224 Self::TYPE
225 }
226
227 fn length(&self) -> u16 {
228 4
229 }
230}
231
232impl AttributeWrite for RequestedAddressFamily {
233 fn to_raw(&self) -> RawAttribute<'_> {
234 let mut data = [0; 4];
235 data[0] = match self.family {
236 AddressFamily::IPV4 => 1,
237 AddressFamily::IPV6 => 2,
238 };
239 RawAttribute::new(self.get_type(), &data).into_owned()
240 }
241 fn write_into_unchecked(&self, dest: &mut [u8]) {
242 self.write_header_unchecked(dest);
243 dest[4] = match self.family {
244 AddressFamily::IPV4 => 1,
245 AddressFamily::IPV6 => 2,
246 };
247 dest[5] = 0;
248 dest[6] = 0;
249 dest[7] = 0;
250 }
251}
252
253impl AttributeFromRaw<'_> for RequestedAddressFamily {
254 fn from_raw_ref(raw: &RawAttribute) -> Result<Self, StunParseError>
255 where
256 Self: Sized,
257 {
258 Self::try_from(raw)
259 }
260}
261
262impl TryFrom<&RawAttribute<'_>> for RequestedAddressFamily {
263 type Error = StunParseError;
264 fn try_from(raw: &RawAttribute) -> Result<Self, Self::Error> {
265 if raw.get_type() != Self::TYPE {
266 return Err(StunParseError::WrongAttributeImplementation);
267 }
268 raw.check_type_and_len(Self::TYPE, 4..=4)?;
269 let family = match raw.value[0] {
270 1 => AddressFamily::IPV4,
271 2 => AddressFamily::IPV6,
272 _ => return Err(StunParseError::InvalidAttributeData),
273 };
274 Ok(Self { family })
275 }
276}
277
278impl RequestedAddressFamily {
279 pub fn new(family: AddressFamily) -> Self {
290 Self { family }
291 }
292
293 pub fn family(&self) -> AddressFamily {
304 self.family
305 }
306}
307
308impl core::fmt::Display for RequestedAddressFamily {
309 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
310 write!(f, "{}: {}", self.get_type(), self.family)
311 }
312}
313
314#[derive(Debug, Clone)]
320pub struct AdditionalAddressFamily {
321 family: AddressFamily,
322}
323
324impl AttributeStaticType for AdditionalAddressFamily {
325 const TYPE: AttributeType = AttributeType::new(0x8000);
326}
327
328impl Attribute for AdditionalAddressFamily {
329 fn get_type(&self) -> AttributeType {
330 Self::TYPE
331 }
332
333 fn length(&self) -> u16 {
334 4
335 }
336}
337
338impl AttributeWrite for AdditionalAddressFamily {
339 fn to_raw(&self) -> RawAttribute<'_> {
340 let mut data = [0; 4];
341 data[0] = match self.family {
342 AddressFamily::IPV4 => 1,
343 AddressFamily::IPV6 => 2,
344 };
345 RawAttribute::new(self.get_type(), &data).into_owned()
346 }
347 fn write_into_unchecked(&self, dest: &mut [u8]) {
348 self.write_header_unchecked(dest);
349 dest[4] = match self.family {
350 AddressFamily::IPV4 => 1,
351 AddressFamily::IPV6 => 2,
352 };
353 dest[5] = 0;
354 dest[6] = 0;
355 dest[7] = 0;
356 }
357}
358
359impl AttributeFromRaw<'_> for AdditionalAddressFamily {
360 fn from_raw_ref(raw: &RawAttribute) -> Result<Self, StunParseError>
361 where
362 Self: Sized,
363 {
364 Self::try_from(raw)
365 }
366}
367
368impl TryFrom<&RawAttribute<'_>> for AdditionalAddressFamily {
369 type Error = StunParseError;
370 fn try_from(raw: &RawAttribute) -> Result<Self, Self::Error> {
371 if raw.get_type() != Self::TYPE {
372 return Err(StunParseError::WrongAttributeImplementation);
373 }
374 raw.check_type_and_len(Self::TYPE, 4..=4)?;
375 let family = match raw.value[0] {
376 2 => AddressFamily::IPV6,
378 _ => return Err(StunParseError::InvalidAttributeData),
379 };
380 Ok(Self { family })
381 }
382}
383
384impl AdditionalAddressFamily {
385 pub fn new(family: AddressFamily) -> Self {
398 if family == AddressFamily::IPV4 {
399 panic!("IPv4 is not supported in AdditionalAddressFamily");
400 }
401 Self { family }
402 }
403
404 pub fn family(&self) -> AddressFamily {
415 self.family
416 }
417}
418
419impl core::fmt::Display for AdditionalAddressFamily {
420 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
421 write!(f, "{}: {}", self.get_type(), self.family)
422 }
423}
424
425#[derive(Debug, Clone)]
431pub struct AddressErrorCode {
432 family: AddressFamily,
433 error: ErrorCode,
434}
435
436impl AttributeStaticType for AddressErrorCode {
437 const TYPE: AttributeType = AttributeType::new(0x8001);
438}
439
440impl Attribute for AddressErrorCode {
441 fn get_type(&self) -> AttributeType {
442 Self::TYPE
443 }
444
445 fn length(&self) -> u16 {
446 self.error.length()
447 }
448}
449
450impl AttributeWrite for AddressErrorCode {
451 fn to_raw(&self) -> RawAttribute<'_> {
452 let raw = self.error.to_raw();
453 let mut data = raw.to_bytes();
454 data[4] = match self.family {
455 AddressFamily::IPV4 => 1,
456 AddressFamily::IPV6 => 2,
457 };
458 RawAttribute::new_owned(
459 self.get_type(),
460 Box::from(&data[4..4 + raw.length() as usize]),
461 )
462 }
463 fn write_into_unchecked(&self, dest: &mut [u8]) {
464 self.error.write_into_unchecked(dest);
465 self.write_header_unchecked(dest);
466 dest[4] = match self.family {
467 AddressFamily::IPV4 => 1,
468 AddressFamily::IPV6 => 2,
469 };
470 }
471}
472
473impl AttributeFromRaw<'_> for AddressErrorCode {
474 fn from_raw_ref(raw: &RawAttribute) -> Result<Self, StunParseError>
475 where
476 Self: Sized,
477 {
478 Self::try_from(raw)
479 }
480}
481
482impl TryFrom<&RawAttribute<'_>> for AddressErrorCode {
483 type Error = StunParseError;
484 fn try_from(raw: &RawAttribute) -> Result<Self, Self::Error> {
485 if raw.get_type() != Self::TYPE {
486 return Err(StunParseError::WrongAttributeImplementation);
487 }
488 let tmp_raw = RawAttribute::new(ErrorCode::TYPE, &raw.value);
489 let error = ErrorCode::from_raw_ref(&tmp_raw)?;
490 let family = match raw.value[0] {
491 1 => AddressFamily::IPV4,
492 2 => AddressFamily::IPV6,
493 _ => return Err(StunParseError::InvalidAttributeData),
494 };
495 Ok(Self { family, error })
496 }
497}
498
499impl AddressErrorCode {
500 pub fn new(family: AddressFamily, error: ErrorCode) -> Self {
513 Self { family, error }
514 }
515
516 pub fn family(&self) -> AddressFamily {
529 self.family
530 }
531
532 pub fn error(&self) -> &ErrorCode {
546 &self.error
547 }
548}
549
550impl core::fmt::Display for AddressErrorCode {
551 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
552 write!(f, "{}: {} {}", self.get_type(), self.family, self.error)
553 }
554}
555
556#[cfg(test)]
557mod tests {
558 use super::*;
559 use alloc::vec::Vec;
560 use byteorder::{BigEndian, ByteOrder};
561 use std::println;
562
563 #[test]
564 fn xor_peer_address() {
565 let _log = crate::tests::test_init_log();
566 let transaction_id = 0x9876_5432_1098_7654_3210_9876.into();
567 let addrs = &[
568 "192.168.0.1:40000".parse().unwrap(),
569 "[fd12:3456:789a:1::1]:41000".parse().unwrap(),
570 ];
571 for addr in addrs {
572 let mapped = XorPeerAddress::new(*addr, transaction_id);
573 assert_eq!(mapped.get_type(), XorPeerAddress::TYPE);
574 assert_eq!(mapped.addr(transaction_id), *addr);
575 let raw: RawAttribute = mapped.to_raw();
576 println!("{}", raw);
577 assert_eq!(raw.get_type(), XorPeerAddress::TYPE);
578 let mapped2 = XorPeerAddress::try_from(&raw).unwrap();
579 assert_eq!(mapped2.get_type(), XorPeerAddress::TYPE);
580 assert_eq!(mapped2.addr(transaction_id), *addr);
581 let mut data: Vec<_> = raw.clone().into();
583 let len = data.len();
584 BigEndian::write_u16(&mut data[2..4], len as u16 - 4 - 1);
585 assert!(matches!(
586 XorPeerAddress::try_from(
587 &RawAttribute::from_bytes(data[..len - 1].as_ref()).unwrap()
588 ),
589 Err(StunParseError::Truncated {
590 expected: _,
591 actual: _,
592 })
593 ));
594 let mut data: Vec<_> = raw.into();
596 BigEndian::write_u16(&mut data[0..2], 0);
597 assert!(matches!(
598 XorPeerAddress::try_from(&RawAttribute::from_bytes(data.as_ref()).unwrap()),
599 Err(StunParseError::WrongAttributeImplementation)
600 ));
601 }
602 }
603
604 #[test]
605 fn xor_relayed_address() {
606 let _log = crate::tests::test_init_log();
607 let transaction_id = 0x9876_5432_1098_7654_3210_9876.into();
608 let addrs = &[
609 "192.168.0.1:40000".parse().unwrap(),
610 "[fd12:3456:789a:1::1]:41000".parse().unwrap(),
611 ];
612 for addr in addrs {
613 let mapped = XorRelayedAddress::new(*addr, transaction_id);
614 assert_eq!(mapped.get_type(), XorRelayedAddress::TYPE);
615 assert_eq!(mapped.addr(transaction_id), *addr);
616 let raw: RawAttribute = mapped.to_raw();
617 println!("{}", raw);
618 assert_eq!(raw.get_type(), XorRelayedAddress::TYPE);
619 let mapped2 = XorRelayedAddress::try_from(&raw).unwrap();
620 assert_eq!(mapped2.get_type(), XorRelayedAddress::TYPE);
621 assert_eq!(mapped2.addr(transaction_id), *addr);
622 let mut data: Vec<_> = raw.clone().into();
624 let len = data.len();
625 BigEndian::write_u16(&mut data[2..4], len as u16 - 4 - 1);
626 assert!(matches!(
627 XorRelayedAddress::try_from(
628 &RawAttribute::from_bytes(data[..len - 1].as_ref()).unwrap()
629 ),
630 Err(StunParseError::Truncated {
631 expected: _,
632 actual: _,
633 })
634 ));
635 let mut data: Vec<_> = raw.into();
637 BigEndian::write_u16(&mut data[0..2], 0);
638 assert!(matches!(
639 XorRelayedAddress::try_from(&RawAttribute::from_bytes(data.as_ref()).unwrap()),
640 Err(StunParseError::WrongAttributeImplementation)
641 ));
642 }
643 }
644
645 #[test]
646 fn requested_address_family() {
647 let _log = crate::tests::test_init_log();
648 for family in [AddressFamily::IPV4, AddressFamily::IPV6] {
649 let mapped = RequestedAddressFamily::new(family);
650 assert_eq!(mapped.get_type(), RequestedAddressFamily::TYPE);
651 assert_eq!(mapped.family(), family);
652 let raw: RawAttribute = mapped.to_raw();
653 println!("{}", raw);
654 assert_eq!(raw.get_type(), RequestedAddressFamily::TYPE);
655 let mapped2 = RequestedAddressFamily::try_from(&raw).unwrap();
656 assert_eq!(mapped2.get_type(), RequestedAddressFamily::TYPE);
657 assert_eq!(mapped2.family(), family);
658 }
659 let mapped = RequestedAddressFamily::new(AddressFamily::IPV4);
660 let raw: RawAttribute = mapped.to_raw();
661 let mut data: Vec<_> = raw.clone().into();
663 let len = data.len();
664 BigEndian::write_u16(&mut data[2..4], len as u16 - 4 - 1);
665 assert!(matches!(
666 RequestedAddressFamily::try_from(
667 &RawAttribute::from_bytes(data[..len - 1].as_ref()).unwrap()
668 ),
669 Err(StunParseError::Truncated {
670 expected: _,
671 actual: _,
672 })
673 ));
674 let mut data: Vec<_> = raw.clone().into();
676 BigEndian::write_u16(&mut data[0..2], 0);
677 assert!(matches!(
678 RequestedAddressFamily::try_from(&RawAttribute::from_bytes(data.as_ref()).unwrap()),
679 Err(StunParseError::WrongAttributeImplementation)
680 ));
681 let mut data: Vec<_> = raw.clone().into();
683 data[4] = 3;
684 assert!(matches!(
685 RequestedAddressFamily::try_from(&RawAttribute::from_bytes(data.as_ref()).unwrap()),
686 Err(StunParseError::InvalidAttributeData)
687 ));
688 }
689
690 #[test]
691 fn additional_address_family() {
692 let _log = crate::tests::test_init_log();
693 let mapped = AdditionalAddressFamily::new(AddressFamily::IPV6);
694 assert_eq!(mapped.get_type(), AdditionalAddressFamily::TYPE);
695 assert_eq!(mapped.family(), AddressFamily::IPV6);
696 let raw: RawAttribute = mapped.to_raw();
697 println!("{}", raw);
698 assert_eq!(raw.get_type(), AdditionalAddressFamily::TYPE);
699 let mapped2 = AdditionalAddressFamily::try_from(&raw).unwrap();
700 assert_eq!(mapped2.get_type(), AdditionalAddressFamily::TYPE);
701 assert_eq!(mapped2.family(), AddressFamily::IPV6);
702 let mut data: Vec<_> = raw.clone().into();
704 let len = data.len();
705 BigEndian::write_u16(&mut data[2..4], len as u16 - 4 - 1);
706 println!(
707 "{:?}",
708 AdditionalAddressFamily::try_from(
709 &RawAttribute::from_bytes(data[..len - 1].as_ref()).unwrap()
710 )
711 );
712 assert!(matches!(
713 AdditionalAddressFamily::try_from(
714 &RawAttribute::from_bytes(data[..len - 1].as_ref()).unwrap()
715 ),
716 Err(StunParseError::Truncated {
717 expected: _,
718 actual: _,
719 })
720 ));
721 let mut data: Vec<_> = raw.clone().into();
723 BigEndian::write_u16(&mut data[0..2], 0);
724 assert!(matches!(
725 AdditionalAddressFamily::try_from(&RawAttribute::from_bytes(data.as_ref()).unwrap()),
726 Err(StunParseError::WrongAttributeImplementation)
727 ));
728 let mut data: Vec<_> = raw.clone().into();
730 data[4] = 1;
731 assert!(matches!(
732 AdditionalAddressFamily::try_from(&RawAttribute::from_bytes(data.as_ref()).unwrap()),
733 Err(StunParseError::InvalidAttributeData)
734 ));
735 }
736
737 #[test]
738 #[should_panic = "IPv4 is not supported"]
739 fn additional_address_family_ipv4_panic() {
740 let _log = crate::tests::test_init_log();
741 AdditionalAddressFamily::new(AddressFamily::IPV4);
742 }
743
744 #[test]
745 fn address_error_code() {
746 let _log = crate::tests::test_init_log();
747 let error = ErrorCode::builder(ErrorCode::INSUFFICIENT_CAPACITY)
748 .build()
749 .unwrap();
750 for family in [AddressFamily::IPV4, AddressFamily::IPV6] {
751 let mapped = AddressErrorCode::new(family, error.clone());
752 assert_eq!(mapped.get_type(), AddressErrorCode::TYPE);
753 assert_eq!(mapped.family(), family);
754 assert_eq!(mapped.error(), &error);
755 let raw: RawAttribute = mapped.to_raw();
756 println!("{}", raw);
757 assert_eq!(raw.get_type(), AddressErrorCode::TYPE);
758 let mapped2 = AddressErrorCode::try_from(&raw).unwrap();
759 assert_eq!(mapped2.get_type(), AddressErrorCode::TYPE);
760 assert_eq!(mapped2.family(), family);
761 assert_eq!(mapped2.error(), &error);
762 }
763 let mapped = AddressErrorCode::new(AddressFamily::IPV6, error);
764 let raw: RawAttribute = mapped.to_raw();
765 let mut data: Vec<_> = raw.clone().into();
767 BigEndian::write_u16(&mut data[0..2], 0);
768 assert!(matches!(
769 AddressErrorCode::try_from(&RawAttribute::from_bytes(data.as_ref()).unwrap()),
770 Err(StunParseError::WrongAttributeImplementation)
771 ));
772 let mut data: Vec<_> = raw.clone().into();
774 data[4] = 3;
775 assert!(matches!(
776 AddressErrorCode::try_from(&RawAttribute::from_bytes(data.as_ref()).unwrap()),
777 Err(StunParseError::InvalidAttributeData)
778 ));
779 }
780}