1use super::{
2 ComposeSvcParamValue, LongSvcParam, PushError, ParseSvcParamValue,
3 SvcParamsBuilder, SvcParams, SvcParamValue, UnknownSvcParam,
4};
5use crate::base::iana::SvcParamKey;
6use crate::base::net::{Ipv4Addr, Ipv6Addr};
7use crate::base::wire::{Compose, Parse, ParseError};
8use crate::utils::base64;
9use octseq::builder::{
10 EmptyBuilder, FreezeBuilder, FromBuilder, OctetsBuilder, ShortBuf
11};
12use octseq::octets::{Octets, OctetsFrom};
13use octseq::parse::Parser;
14use octseq::str::Str;
15use core::{fmt, hash, str};
16use core::fmt::Write as _;
17use core::str::FromStr;
18
19macro_rules! values_enum {
22 (
23 $( $type:ident $( < $( $type_arg:ident ),* > )?, )+
24 ) => {
25 #[derive(Debug, Clone)]
30 pub enum AllValues<Octs> {
31 $(
32 $type($type $( < $( $type_arg ),* > )? ),
33 )+
34 Unknown(UnknownSvcParam<Octs>),
35 }
36
37 impl<Octs: AsRef<[u8]>> AllValues<Octs> {
38 pub(super) fn parse_any<'a, Src>(
47 key: SvcParamKey,
48 parser: &mut Parser<'a, Src>,
49 ) -> Self
50 where Src: Octets<Range<'a> = Octs> + ?Sized {
51 let pos = parser.pos();
52 let res = match key {
53 $(
54 SvcParamKey::$type => {
55 $type::parse(
56 parser
57 ).map(Self::$type)
58 }
59 )+
60 _ => {
61 UnknownSvcParam::parse(
62 key, parser
63 ).map(Self::Unknown)
64 }
65 };
66 if let Ok(res) = res {
67 return res
68 }
69 parser.seek(pos).expect("invalid SvcParams");
70 let octets = parser.parse_octets(
71 parser.remaining()
72 ).expect("invalid SvcParams");
73
74 Self::Unknown(unsafe {
75 UnknownSvcParam::new_unchecked(key, octets)
76 })
77 }
78 }
79
80 $(
83 impl<Octs> From<$type $( < $( $type_arg ),* > )*>
84 for AllValues<Octs> {
85 fn from(p: $type $( < $( $type_arg ),* > )*) -> Self {
86 Self::$type(p)
87 }
88 }
89 )+
90
91 impl<Octs> From<UnknownSvcParam<Octs>> for AllValues<Octs> {
92 fn from(p: UnknownSvcParam<Octs>) -> Self {
93 Self::Unknown(p)
94 }
95 }
96
97 impl<Octs> SvcParamValue for AllValues<Octs> {
100 fn key(&self) -> SvcParamKey {
101 match self {
102 $(
103 Self::$type(v) => v.key(),
104 )+
105 Self::Unknown(v) => v.key(),
106 }
107 }
108 }
109
110 impl<'a, Octs> ParseSvcParamValue<'a, Octs>
111 for AllValues<Octs::Range<'a>>
112 where Octs: Octets + ?Sized {
113 fn parse_value(
114 key: SvcParamKey,
115 parser: &mut Parser<'a, Octs>,
116 ) -> Result<Option<Self>, ParseError> {
117 match key {
118 $(
119 SvcParamKey::$type => {
120 $type::parse(
121 parser
122 ).map(|res| Some(Self::$type(res)))
123 }
124 )+
125 _ => {
126 UnknownSvcParam::parse_value(
127 key, parser
128 ).map(|res| res.map(Self::Unknown))
129 }
130 }
131 }
132 }
133
134 impl<Octs: AsRef<[u8]>> ComposeSvcParamValue for AllValues<Octs> {
135 fn compose_len(&self) -> u16 {
136 match self {
137 $(
138 Self::$type(v) => v.compose_len(),
139 )*
140 Self::Unknown(v) => v.compose_len(),
141 }
142 }
143
144 fn compose_value<Target: OctetsBuilder + ?Sized>(
145 &self, target: &mut Target,
146 ) -> Result<(), Target::AppendError> {
147 match self {
148 $(
149 Self::$type(v) => v.compose_value(target),
150 )*
151 Self::Unknown(v) => v.compose_value(target),
152 }
153 }
154 }
155
156 impl<Octs, OtherOcts> PartialEq<AllValues<OtherOcts>>
159 for AllValues<Octs>
160 where
161 Octs: AsRef<[u8]>,
162 OtherOcts: AsRef<[u8]>,
163 {
164 fn eq(&self, other: &AllValues<OtherOcts>) -> bool {
165 match (self, other) {
166 $(
167 (AllValues::$type(left), AllValues::$type(right)) => {
168 left.eq(right)
169 }
170 )*
171 (AllValues::Unknown(left), AllValues::Unknown(right)) => {
172 left.eq(right)
173 }
174 _ => false
175 }
176 }
177 }
178
179 impl<Octs: AsRef<[u8]>> Eq for AllValues<Octs> { }
180
181 impl<Octs: AsRef<[u8]>> hash::Hash for AllValues<Octs> {
184 fn hash<H: hash::Hasher>(&self, state: &mut H) {
185 match self {
186 $(
187 Self::$type(value) => value.hash(state),
188 )*
189 Self::Unknown(value) => value.hash(state)
190 }
191 }
192 }
193
194 impl<Octs: Octets> fmt::Display for AllValues<Octs> {
197 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
198 match self {
199 $(
200 Self::$type(v) => v.fmt(f),
201 )*
202 Self::Unknown(v) => v.fmt(f),
203 }
204 }
205 }
206 }
207}
208
209values_enum! {
210 Mandatory<Octs>,
211 Alpn<Octs>,
212 NoDefaultAlpn,
213 Port,
214 Ech<Octs>,
215 Ipv4Hint<Octs>,
216 Ipv6Hint<Octs>,
217 DohPath<Octs>,
218}
219
220macro_rules! octets_wrapper {
226 ( $(#[$attr:meta])* $name:ident ) => {
227 $(#[$attr])*
228 #[derive(Debug, Clone)]
229 pub struct $name<Octs: ?Sized>(Octs);
230
231 impl<Octs> $name<Octs> {
232 pub unsafe fn from_octets_unchecked(octets: Octs) -> Self {
239 $name(octets)
240 }
241 }
242
243 impl $name<[u8]> {
244 #[must_use]
251 pub unsafe fn from_slice_unchecked(slice: &[u8]) -> &Self {
252 &*(slice as *const [u8] as *const Self)
253 }
254 }
255
256 impl<Octs: ?Sized> $name<Octs> {
257 pub fn as_octets(&self) -> &Octs {
259 &self.0
260 }
261
262 pub fn as_slice(&self) -> &[u8]
264 where Octs: AsRef<[u8]> {
265 self.0.as_ref()
266 }
267 }
268
269 impl<O, OO> OctetsFrom<$name<O>> for $name<OO>
272 where
273 OO: OctetsFrom<O>,
274 {
275 type Error = OO::Error;
276
277 fn try_octets_from(
278 source: $name<O>,
279 ) -> Result<Self, Self::Error> {
280 Ok(unsafe {
281 $name::from_octets_unchecked(
282 OO::try_octets_from(source.0)?
283 )
284 })
285 }
286 }
287
288 impl<Octs> AsRef<Octs> for $name<Octs> {
291 fn as_ref(&self) -> &Octs {
292 self.as_octets()
293 }
294 }
295
296 impl<Octs: AsRef<[u8]> + ?Sized> AsRef<[u8]> for $name<Octs> {
297 fn as_ref(&self) -> &[u8] {
298 self.as_slice()
299 }
300 }
301
302 impl<Octs, OtherOcts> PartialEq<$name<OtherOcts>> for $name<Octs>
305 where
306 Octs: AsRef<[u8]>,
307 OtherOcts: AsRef<[u8]>,
308 {
309 fn eq(&self, other: &$name<OtherOcts>) -> bool {
310 self.as_slice().eq(other.as_slice())
311 }
312 }
313
314 impl<Octs: AsRef<[u8]>> Eq for $name<Octs> { }
315
316 impl<Octs: AsRef<[u8]>> hash::Hash for $name<Octs> {
319 fn hash<H: hash::Hasher>(&self, state: &mut H) {
320 self.as_slice().hash(state)
321 }
322 }
323
324 impl<Octs: ?Sized> SvcParamValue for $name<Octs> {
327 fn key(&self) -> SvcParamKey {
328 SvcParamKey::$name
329 }
330 }
331
332 impl<'a, Octs> ParseSvcParamValue<'a, Octs> for $name<Octs::Range<'a>>
333 where Octs: Octets + ?Sized {
334 fn parse_value(
335 key: SvcParamKey,
336 parser: &mut Parser<'a, Octs>,
337 ) -> Result<Option<Self>, ParseError> {
338 if key == SvcParamKey::$name {
339 Self::parse(parser).map(Some)
340 }
341 else {
342 Ok(None)
343 }
344 }
345 }
346
347 impl<Octs: AsRef<[u8]> + ?Sized> ComposeSvcParamValue for $name<Octs> {
348 fn compose_len(&self) -> u16 {
349 u16::try_from(self.as_slice().len()).expect("long value")
350 }
351
352 fn compose_value<Target: OctetsBuilder + ?Sized>(
353 &self, target: &mut Target,
354 ) -> Result<(), Target::AppendError> {
355 target.append_slice(self.as_slice())
356 }
357 }
358 };
359
360 ($(#[$attr:meta])* $name:ident, $iter:ident) => {
361 octets_wrapper!( $(#[$attr])* $name );
362
363 impl<Octs: AsRef<[u8]> + ?Sized> $name<Octs> {
364 pub fn iter(&self) -> $iter<'_, Octs> {
366 $iter {
367 parser: Parser::from_ref(&self.0),
368 }
369 }
370 }
371
372 pub struct $iter<'a, Octs: ?Sized> {
374 parser: Parser<'a, Octs>,
375 }
376 };
377}
378
379octets_wrapper!(
382 Mandatory,
396 MandatoryIter
397);
398
399impl<Octs: AsRef<[u8]>> Mandatory<Octs> {
400 pub fn from_octets(octets: Octs) -> Result<Self, ParseError> {
406 Mandatory::check_slice(octets.as_ref())?;
407 Ok(unsafe { Self::from_octets_unchecked(octets) })
408 }
409}
410
411impl Mandatory<[u8]> {
412 pub fn from_slice(slice: &[u8]) -> Result<&Self, ParseError> {
418 Self::check_slice(slice)?;
419 Ok(unsafe { Self::from_slice_unchecked(slice) })
420 }
421
422 fn check_slice(slice: &[u8]) -> Result<(), ParseError> {
424 LongSvcParam::check_len(slice.len())?;
425 if slice.len() % usize::from(SvcParamKey::COMPOSE_LEN) != 0 {
426 return Err(ParseError::form_error("invalid mandatory parameter"))
427 }
428 Ok(())
429 }
430}
431
432impl<Octs: AsRef<[u8]>> Mandatory<Octs> {
433 pub fn from_keys(
441 keys: impl Iterator<Item = SvcParamKey>
442 ) -> Result<Self, BuildValueError>
443 where
444 Octs: FromBuilder,
445 <Octs as FromBuilder>::Builder: EmptyBuilder
446 {
447 let mut octets = EmptyBuilder::empty();
448 for item in keys {
449 item.compose(&mut octets)?;
450 }
451 let octets = Octs::from_builder(octets);
452 if LongSvcParam::check_len(octets.as_ref().len()).is_err() {
453 return Err(BuildValueError::LongSvcParam)
454 }
455 Ok(unsafe { Self::from_octets_unchecked(octets) })
456 }
457}
458
459impl<Octs: AsRef<[u8]>> Mandatory<Octs> {
460 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
462 parser: &mut Parser<'a, Src>,
463 ) -> Result<Self, ParseError> {
464 Self::from_octets(parser.parse_octets(parser.remaining())?)
465 }
466}
467
468impl<'a, Octs: Octets + ?Sized> Iterator for MandatoryIter<'a, Octs> {
471 type Item = SvcParamKey;
472
473 fn next(&mut self) -> Option<Self::Item> {
474 if self.parser.remaining() == 0 {
475 return None;
476 }
477 Some(
478 SvcParamKey::parse(
479 &mut self.parser
480 ).expect("invalid mandatory parameter")
481 )
482 }
483}
484
485impl<Octs: Octets + ?Sized> fmt::Display for Mandatory<Octs> {
488 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
489 for (i, v) in self.iter().enumerate() {
490 if i == 0 {
491 write!(f, "mandatory={}", v)?;
492 } else {
493 write!(f, ",{}", v)?;
494 }
495 }
496 Ok(())
497 }
498}
499
500impl<Octs: Octets + ?Sized> SvcParams<Octs> {
503 pub fn mandatory(&self) -> Option<Mandatory<Octs::Range<'_>>> {
505 self.first()
506 }
507}
508
509impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
510 pub fn mandatory(
516 &mut self, keys: impl AsRef<[SvcParamKey]>,
517 ) -> Result<(), PushValueError> {
518 self.push_raw(
519 SvcParamKey::Mandatory,
520 u16::try_from(
521 keys.as_ref().len() * usize::from(SvcParamKey::COMPOSE_LEN)
522 ).map_err(|_| PushValueError::LongSvcParam)?,
523 |octs| {
524 keys.as_ref().iter().try_for_each(|item| item.compose(octs))
525 },
526 ).map_err(Into::into)
527 }
528}
529
530
531octets_wrapper!(
534 Alpn,
551 AlpnIter
552);
553
554impl<Octs: AsRef<[u8]>> Alpn<Octs> {
555 pub fn from_octets(octets: Octs) -> Result<Self, ParseError> {
561 Alpn::check_slice(octets.as_ref())?;
562 Ok(unsafe { Self::from_octets_unchecked(octets) })
563 }
564}
565
566impl Alpn<[u8]> {
567 pub fn from_slice(slice: &[u8]) -> Result<&Self, ParseError> {
573 Self::check_slice(slice)?;
574 Ok(unsafe { Self::from_slice_unchecked(slice) })
575 }
576
577 fn check_slice(slice: &[u8]) -> Result<(), ParseError> {
582 LongSvcParam::check_len(slice.len())?;
583 let mut parser = Parser::from_ref(slice);
584 while parser.remaining() > 0 {
585 let len = usize::from(u8::parse(&mut parser)?);
586 parser.advance(len)?;
587 }
588 Ok(())
589 }
590}
591
592impl<Octs: AsRef<[u8]>> Alpn<Octs> {
593 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
595 parser: &mut Parser<'a, Src>,
596 ) -> Result<Self, ParseError> {
597 Self::from_octets(parser.parse_octets(parser.remaining())?)
598 }
599}
600
601impl<'a, Octs: Octets + ?Sized> Iterator for AlpnIter<'a, Octs> {
604 type Item = Octs::Range<'a>;
605
606 fn next(&mut self) -> Option<Self::Item> {
607 if self.parser.remaining() == 0 {
608 return None
609 }
610 let len = usize::from(
611 u8::parse(&mut self.parser).expect("invalid alpn parameter")
612 );
613 Some(self.parser.parse_octets(len).expect("invalid alpn parameter"))
614 }
615}
616
617impl<Octs: Octets + ?Sized> fmt::Display for Alpn<Octs> {
620 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
621 for (i, v) in self.iter().enumerate() {
622 if i == 0 {
623 f.write_str("alpn=")?;
624 } else {
625 f.write_str(",")?;
626 }
627 for ch in v.as_ref() {
628 f.write_char(*ch as char)?;
629 }
630 }
631 Ok(())
632 }
633}
634
635impl<Octs: Octets + ?Sized> SvcParams<Octs> {
638 pub fn alpn(&self) -> Option<Alpn<Octs::Range<'_>>> {
640 self.first()
641 }
642}
643
644impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
645 pub fn alpn(
655 &mut self, protocols: &[&[u8]],
656 ) -> Result<(), PushAlpnError> {
657 let mut len = 0u16;
659 for proto in protocols.iter() {
660 let proto_len = u8::try_from(
661 proto.len()
662 ).map_err(|_| PushAlpnError::InvalidProtocol)?;
663 len = len.checked_add(
664 u16::from(proto_len) + u8::COMPOSE_LEN
665 ).ok_or(PushAlpnError::LongSvcParam)?;
666 }
667 self.push_raw(
668 SvcParamKey::Alpn,
669 len,
670 |octs| {
671 protocols.iter().try_for_each(|proto| {
672 u8::try_from(
673 proto.len()
674 ).expect("long protocol").compose(octs)?;
675 octs.append_slice(proto)
676 })
677 }
678 ).map_err(Into::into)
679 }
680}
681
682#[derive(Clone, Debug)]
686pub struct AlpnBuilder<Target> {
687 target: Target,
689}
690
691impl<Target> AlpnBuilder<Target> {
692 #[must_use]
694 pub fn empty() -> Self
695 where
696 Target: EmptyBuilder,
697 {
698 AlpnBuilder { target: Target::empty() }
699 }
700
701 pub fn push(
706 &mut self, protocol: impl AsRef<[u8]>
707 ) -> Result<(), BuildAlpnError>
708 where Target: OctetsBuilder + AsRef<[u8]> {
709 let protocol = protocol.as_ref();
710 if protocol.is_empty() {
711 return Err(BuildAlpnError::InvalidProtocol)
712 }
713 let len = u8::try_from(
714 protocol.len()
715 ).map_err(|_| BuildAlpnError::InvalidProtocol)?;
716 LongSvcParam::check_len(
717 self.target.as_ref().len().checked_add(
718 protocol.len() + 1
719 ).expect("long Alpn value")
720 ).map_err(|_| BuildAlpnError::LongSvcParam)?;
721 len.compose(&mut self.target).map(Into::into)?;
722 self.target.append_slice(
723 protocol
724 ).map_err(|_| BuildAlpnError::ShortBuf)
725 }
726
727 pub fn freeze(self) -> Alpn<Target::Octets>
729 where
730 Target: FreezeBuilder
731 {
732 unsafe { Alpn::from_octets_unchecked(self.target.freeze()) }
733 }
734}
735
736#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
747pub struct NoDefaultAlpn;
748
749impl NoDefaultAlpn {
750 pub fn parse<Src: Octets + ?Sized>(
752 _parser: &mut Parser<Src>,
753 ) -> Result<Self, ParseError> {
754 Ok(Self)
755 }
756}
757
758impl SvcParamValue for NoDefaultAlpn {
761 fn key(&self) -> SvcParamKey {
762 SvcParamKey::NoDefaultAlpn
763 }
764}
765
766impl<'a, Octs: Octets + ?Sized> ParseSvcParamValue<'a, Octs> for NoDefaultAlpn {
767 fn parse_value(
768 key: SvcParamKey,
769 parser: &mut Parser<'a, Octs>,
770 ) -> Result<Option<Self>, ParseError> {
771 if key == SvcParamKey::NoDefaultAlpn {
772 Self::parse(parser).map(Some)
773 }
774 else {
775 Ok(None)
776 }
777 }
778}
779
780impl ComposeSvcParamValue for NoDefaultAlpn {
781 fn compose_len(&self) -> u16 {
782 0
783 }
784
785 fn compose_value<Target: OctetsBuilder + ?Sized>(
786 &self, _target: &mut Target,
787 ) -> Result<(), Target::AppendError> {
788 Ok(())
789 }
790}
791
792impl fmt::Display for NoDefaultAlpn {
795 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
796 f.write_str("nodefaultalpn")
797 }
798}
799
800impl<Octs: Octets + ?Sized> SvcParams<Octs> {
803 pub fn no_default_alpn(&self) -> bool {
805 self.first::<NoDefaultAlpn>().is_some()
806 }
807}
808
809impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
810 pub fn no_default_alpn(&mut self) -> Result<(), PushError> {
812 self.push(&NoDefaultAlpn)
813 }
814}
815
816#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
822pub struct Port(u16);
823
824impl Port {
825 #[must_use]
827 pub fn new(port: u16) -> Self {
828 Port(port)
829 }
830
831 pub fn parse<Src: Octets + ?Sized>(
833 parser: &mut Parser<Src>,
834 ) -> Result<Self, ParseError> {
835 u16::parse(parser).map(Port::new)
836 }
837
838 #[must_use]
840 pub fn port(self) -> u16 {
841 self.0
842 }
843}
844
845impl SvcParamValue for Port {
848 fn key(&self) -> SvcParamKey {
849 SvcParamKey::Port
850 }
851}
852
853impl<'a, Octs: Octets + ?Sized> ParseSvcParamValue<'a, Octs> for Port {
854 fn parse_value(
855 key: SvcParamKey,
856 parser: &mut Parser<'a, Octs>,
857 ) -> Result<Option<Self>, ParseError> {
858 if key == SvcParamKey::Port {
859 Self::parse(parser).map(Some)
860 }
861 else {
862 Ok(None)
863 }
864 }
865}
866
867impl ComposeSvcParamValue for Port {
868 fn compose_len(&self) -> u16 {
869 u16::COMPOSE_LEN
870 }
871
872 fn compose_value<Target: OctetsBuilder + ?Sized>(
873 &self, target: &mut Target,
874 ) -> Result<(), Target::AppendError> {
875 self.0.compose(target)
876 }
877}
878
879impl fmt::Display for Port {
882 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
883 write!(f, "port={}", self.0)
884 }
885}
886
887impl<Octs: Octets + ?Sized> SvcParams<Octs> {
890 pub fn port(&self) -> Option<Port> {
892 self.first()
893 }
894}
895
896impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
897 pub fn port(&mut self, port: u16) -> Result<(), PushError> {
899 self.push(&Port::new(port))
900 }
901}
902
903octets_wrapper!(
906 Ech
915);
916
917impl<Octs: AsRef<[u8]>> Ech<Octs> {
918 pub fn from_octets(octets: Octs) -> Result<Self, LongSvcParam> {
923 Ech::check_slice(octets.as_ref())?;
924 Ok(unsafe { Self::from_octets_unchecked(octets) })
925 }
926}
927
928impl Ech<[u8]> {
929 pub fn from_slice(slice: &[u8]) -> Result<&Self, LongSvcParam> {
934 Self::check_slice(slice)?;
935 Ok(unsafe { Self::from_slice_unchecked(slice) })
936 }
937
938 fn check_slice(slice: &[u8]) -> Result<(), LongSvcParam> {
942 LongSvcParam::check_len(slice.len())?;
943 Ok(())
944 }
945}
946
947impl<Octs: AsRef<[u8]>> Ech<Octs> {
948 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
950 parser: &mut Parser<'a, Src>,
951 ) -> Result<Self, ParseError> {
952 Self::from_octets(
953 parser.parse_octets(parser.remaining())?
954 ).map_err(Into::into)
955 }
956}
957
958impl<Octs: AsRef<[u8]> + ?Sized> fmt::Display for Ech<Octs> {
961 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
962 if self.as_slice().is_empty() {
963 f.write_str("ech")
964 }
965 else {
966 f.write_str("ech=")?;
967 base64::display(self.as_slice(), f)
968 }
969 }
970}
971
972impl<Octs: Octets + ?Sized> SvcParams<Octs> {
975 pub fn ech(&self) -> Option<Ech<Octs::Range<'_>>> {
977 self.first()
978 }
979}
980
981impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
982 pub fn ech<Source: AsRef<[u8]> + ?Sized>(
984 &mut self, ech: &Source
985 ) -> Result<(), PushValueError> {
986 self.push(Ech::from_slice(ech.as_ref())?).map_err(Into::into)
987 }
988}
989
990octets_wrapper!(
993 Ipv4Hint,
1006 Ipv4HintIter
1007);
1008
1009impl<Octs: AsRef<[u8]>> Ipv4Hint<Octs> {
1010 pub fn from_octets(octets: Octs) -> Result<Self, ParseError> {
1015 Ipv4Hint::check_slice(octets.as_ref())?;
1016 Ok(unsafe { Self::from_octets_unchecked(octets) })
1017 }
1018
1019 pub fn from_addrs(
1025 addrs: impl IntoIterator<Item = Ipv4Addr>
1026 ) -> Result<Self, BuildValueError>
1027 where
1028 Octs: FromBuilder,
1029 <Octs as FromBuilder>::Builder: EmptyBuilder
1030 {
1031 let mut octets = EmptyBuilder::empty();
1032 for item in addrs {
1033 item.compose(&mut octets)?;
1034 }
1035 let octets = Octs::from_builder(octets);
1036 if LongSvcParam::check_len(octets.as_ref().len()).is_err() {
1037 return Err(BuildValueError::LongSvcParam)
1038 }
1039 Ok(unsafe { Self::from_octets_unchecked(octets) })
1040 }
1041}
1042
1043impl Ipv4Hint<[u8]> {
1044 pub fn from_slice(slice: &[u8]) -> Result<&Self, ParseError> {
1049 Self::check_slice(slice)?;
1050 Ok(unsafe { Self::from_slice_unchecked(slice) })
1051 }
1052
1053 fn check_slice(slice: &[u8]) -> Result<(), ParseError> {
1058 LongSvcParam::check_len(slice.len())?;
1059 if slice.len() % usize::from(Ipv4Addr::COMPOSE_LEN) != 0 {
1060 return Err(ParseError::form_error("invalid ipv4hint parameter"))
1061 }
1062 Ok(())
1063 }
1064}
1065
1066impl<Octs: AsRef<[u8]>> Ipv4Hint<Octs> {
1067 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
1069 parser: &mut Parser<'a, Src>,
1070 ) -> Result<Self, ParseError> {
1071 Self::from_octets(parser.parse_octets(parser.remaining())?)
1072 }
1073}
1074
1075impl<'a, Octs: Octets + ?Sized> Iterator for Ipv4HintIter<'a, Octs> {
1076 type Item = Ipv4Addr;
1077
1078 fn next(&mut self) -> Option<Self::Item> {
1079 if self.parser.remaining() == 0 {
1080 return None;
1081 }
1082 Some(
1083 Ipv4Addr::parse(
1084 &mut self.parser
1085 ).expect("invalid ipv4hint parameter")
1086 )
1087 }
1088}
1089
1090impl<Octs: Octets + ?Sized> fmt::Display for Ipv4Hint<Octs> {
1091 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1092 for (i, v) in self.iter().enumerate() {
1093 if i == 0 {
1094 write!(f, "ipv4hint={}", v)?;
1095 } else {
1096 write!(f, ",{}", v)?;
1097 }
1098 }
1099 Ok(())
1100 }
1101}
1102
1103impl<Octs: Octets + ?Sized> SvcParams<Octs> {
1106 pub fn ipv4hint(&self) -> Option<Ipv4Hint<Octs::Range<'_>>> {
1108 self.first()
1109 }
1110}
1111
1112impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
1113 pub fn ipv4hint(
1119 &mut self, addrs: impl AsRef<[Ipv4Addr]>,
1120 ) -> Result<(), PushValueError> {
1121 self.push_raw(
1122 SvcParamKey::Ipv4Hint,
1123 u16::try_from(
1124 addrs.as_ref().len() * usize::from(Ipv4Addr::COMPOSE_LEN)
1125 ).map_err(|_| PushValueError::LongSvcParam)?,
1126 |octs| {
1127 addrs.as_ref().iter().try_for_each(|item| item.compose(octs))
1128 },
1129 ).map_err(Into::into)
1130 }
1131}
1132
1133octets_wrapper!(
1136 Ipv6Hint,
1149 Ipv6HintIter
1150);
1151
1152impl<Octs: AsRef<[u8]>> Ipv6Hint<Octs> {
1153 pub fn from_octets(octets: Octs) -> Result<Self, ParseError> {
1158 Ipv6Hint::check_slice(octets.as_ref())?;
1159 Ok(unsafe { Self::from_octets_unchecked(octets) })
1160 }
1161
1162 pub fn from_addrs(
1168 addrs: impl IntoIterator<Item = Ipv6Addr>
1169 ) -> Result<Self, BuildValueError>
1170 where
1171 Octs: FromBuilder,
1172 <Octs as FromBuilder>::Builder: EmptyBuilder
1173 {
1174 let mut octets = EmptyBuilder::empty();
1175 for item in addrs {
1176 item.compose(&mut octets)?;
1177 }
1178 let octets = Octs::from_builder(octets);
1179 if LongSvcParam::check_len(octets.as_ref().len()).is_err() {
1180 return Err(BuildValueError::LongSvcParam)
1181 }
1182 Ok(unsafe { Self::from_octets_unchecked(octets) })
1183 }
1184}
1185
1186impl Ipv6Hint<[u8]> {
1187 pub fn from_slice(slice: &[u8]) -> Result<&Self, ParseError> {
1192 Self::check_slice(slice)?;
1193 Ok(unsafe { Self::from_slice_unchecked(slice) })
1194 }
1195
1196 fn check_slice(slice: &[u8]) -> Result<(), ParseError> {
1201 LongSvcParam::check_len(slice.len())?;
1202 if slice.len() % usize::from(Ipv6Addr::COMPOSE_LEN) != 0 {
1203 return Err(ParseError::form_error("invalid ipv6hint parameter"))
1204 }
1205 Ok(())
1206 }
1207}
1208
1209impl<Octs: AsRef<[u8]>> Ipv6Hint<Octs> {
1210 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
1212 parser: &mut Parser<'a, Src>,
1213 ) -> Result<Self, ParseError> {
1214 Self::from_octets(parser.parse_octets(parser.remaining())?)
1215 }
1216}
1217
1218impl<'a, Octs: Octets + ?Sized> Iterator for Ipv6HintIter<'a, Octs> {
1221 type Item = Ipv6Addr;
1222
1223 fn next(&mut self) -> Option<Self::Item> {
1224 if self.parser.remaining() == 0 {
1225 return None;
1226 }
1227 Some(
1228 Ipv6Addr::parse(
1229 &mut self.parser
1230 ).expect("invalid ipv6hint parameter")
1231 )
1232 }
1233}
1234
1235impl<Octs: Octets + ?Sized> fmt::Display for Ipv6Hint<Octs> {
1238 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1239 for (i, v) in self.iter().enumerate() {
1240 if i == 0 {
1241 write!(f, "ipv6hint={}", v)?;
1242 } else {
1243 write!(f, ",{}", v)?;
1244 }
1245 }
1246 Ok(())
1247 }
1248}
1249
1250impl<Octs: Octets + ?Sized> SvcParams<Octs> {
1253 pub fn ipv6hint(&self) -> Option<Ipv6Hint<Octs::Range<'_>>> {
1255 self.first()
1256 }
1257}
1258
1259impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
1260 pub fn ipv6hint(
1266 &mut self, addrs: impl AsRef<[Ipv6Addr]>,
1267 ) -> Result<(), PushValueError> {
1268 self.push_raw(
1269 SvcParamKey::Ipv6Hint,
1270 u16::try_from(
1271 addrs.as_ref().len() * usize::from(Ipv6Addr::COMPOSE_LEN)
1272 ).map_err(|_| PushValueError::LongSvcParam)?,
1273 |octs| {
1274 addrs.as_ref().iter().try_for_each(|item| item.compose(octs))
1275 },
1276 ).map_err(Into::into)
1277 }
1278}
1279
1280octets_wrapper!(
1283 DohPath
1294);
1295
1296impl<Octs: AsRef<[u8]>> DohPath<Octs> {
1297 pub fn from_octets(octets: Octs) -> Result<Self, LongSvcParam> {
1301 DohPath::check_slice(octets.as_ref())?;
1302 Ok(unsafe { Self::from_octets_unchecked(octets) })
1303 }
1304}
1305
1306impl DohPath<[u8]> {
1307 pub fn from_slice(slice: &[u8]) -> Result<&Self, LongSvcParam> {
1311 Self::check_slice(slice)?;
1312 Ok(unsafe { Self::from_slice_unchecked(slice) })
1313 }
1314
1315 fn check_slice(slice: &[u8]) -> Result<(), LongSvcParam> {
1319 LongSvcParam::check_len(slice.len())?;
1320 Ok(())
1321 }
1322}
1323
1324impl<Octs: AsRef<[u8]>> DohPath<Octs> {
1325 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
1327 parser: &mut Parser<'a, Src>,
1328 ) -> Result<Self, ParseError> {
1329 Self::from_octets(
1330 parser.parse_octets(parser.remaining())?
1331 ).map_err(Into::into)
1332 }
1333}
1334
1335impl<Octs: AsRef<[u8]>> TryFrom<Str<Octs>> for DohPath<Octs> {
1338 type Error = LongSvcParam;
1339
1340 fn try_from(src: Str<Octs>) -> Result<Self, Self::Error> {
1341 Self::from_octets(src.into_octets())
1342 }
1343}
1344
1345impl<Octs> FromStr for DohPath<Octs>
1346where
1347 Octs: FromBuilder,
1348 <Octs as FromBuilder>::Builder:
1349 EmptyBuilder
1350 + FreezeBuilder<Octets = Octs>
1351{
1352 type Err = BuildValueError;
1353
1354 fn from_str(s: &str) -> Result<Self, Self::Err> {
1355 DohPath::check_slice(s.as_bytes())?;
1356 let mut res: <Octs as FromBuilder>::Builder = EmptyBuilder::empty();
1357 res.append_slice(s.as_bytes()).map_err(Into::into)?;
1358 Ok(unsafe { Self::from_octets_unchecked(res.freeze()) })
1359 }
1360}
1361
1362impl<Octs: AsRef<[u8]> + ?Sized> fmt::Display for DohPath<Octs> {
1365 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1366 if self.as_slice().is_empty() {
1367 f.write_str("dohpath")
1368 }
1369 else {
1370 f.write_str("dohpath=")?;
1371 let mut s = self.as_slice();
1372
1373 while !s.is_empty() {
1375 match str::from_utf8(s) {
1376 Ok(s) => return f.write_str(s),
1377 Err(err) => {
1378 let end = err.valid_up_to();
1379 if end > 0 {
1380 f.write_str(unsafe {
1381 str::from_utf8_unchecked(&s[..end])
1382 })?;
1383 }
1384 f.write_str("\u{FFFD}")?;
1385 match err.error_len() {
1386 Some(len) => {
1387 s = &s[end + len..];
1388 }
1389 None => break,
1390 }
1391 }
1392 }
1393 }
1394 Ok(())
1395 }
1396 }
1397}
1398
1399impl<Octs: Octets + ?Sized> SvcParams<Octs> {
1402 pub fn dohpath(&self) -> Option<DohPath<Octs::Range<'_>>> {
1404 self.first()
1405 }
1406}
1407
1408impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
1409 pub fn dohpath(
1415 &mut self, template: &str
1416 ) -> Result<(), PushValueError> {
1417 self.push_raw(
1418 SvcParamKey::DohPath,
1419 u16::try_from(
1420 template.len()
1421 ).map_err(|_| PushValueError::LongSvcParam)?,
1422 |octs| {
1423 octs.append_slice(template.as_bytes())
1424 },
1425 ).map_err(Into::into)
1426 }
1427}
1428
1429#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1435pub enum BuildValueError {
1436 LongSvcParam,
1438
1439 ShortBuf,
1441}
1442
1443impl From<LongSvcParam> for BuildValueError {
1444 fn from(_: LongSvcParam) -> Self {
1445 Self::LongSvcParam
1446 }
1447}
1448
1449impl<T: Into<ShortBuf>> From<T> for BuildValueError {
1450 fn from(_: T) -> Self {
1451 Self::ShortBuf
1452 }
1453}
1454
1455impl fmt::Display for BuildValueError {
1458 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1459 match self {
1460 Self::LongSvcParam => f.write_str("long SVCB value"),
1461 Self::ShortBuf => ShortBuf.fmt(f)
1462 }
1463 }
1464}
1465
1466#[cfg(feature = "std")]
1467impl std::error::Error for BuildValueError {}
1468
1469#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1473pub enum PushValueError {
1474 DuplicateKey,
1476
1477 LongSvcParam,
1479
1480 ShortBuf,
1482}
1483
1484impl From<LongSvcParam> for PushValueError {
1485 fn from(_: LongSvcParam) -> Self {
1486 Self::LongSvcParam
1487 }
1488}
1489
1490impl From<PushError> for PushValueError {
1491 fn from(src: PushError) -> Self {
1492 match src {
1493 PushError::DuplicateKey => Self::DuplicateKey,
1494 PushError::ShortBuf => Self::ShortBuf,
1495 }
1496 }
1497}
1498
1499impl From<BuildValueError> for PushValueError {
1500 fn from(src: BuildValueError) -> Self {
1501 match src {
1502 BuildValueError::LongSvcParam => Self::LongSvcParam,
1503 BuildValueError::ShortBuf => Self::ShortBuf,
1504 }
1505 }
1506}
1507
1508impl<T: Into<ShortBuf>> From<T> for PushValueError {
1509 fn from(_: T) -> Self {
1510 Self::ShortBuf
1511 }
1512}
1513
1514impl fmt::Display for PushValueError {
1517 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1518 match self {
1519 Self::DuplicateKey => f.write_str("duplicate key"),
1520 Self::LongSvcParam => f.write_str("long SVCB value"),
1521 Self::ShortBuf => ShortBuf.fmt(f)
1522 }
1523 }
1524}
1525
1526#[cfg(feature = "std")]
1527impl std::error::Error for PushValueError {}
1528
1529#[derive(Clone, Copy, Debug)]
1533pub enum BuildAlpnError {
1534 InvalidProtocol,
1538
1539 LongSvcParam,
1541
1542 ShortBuf,
1544}
1545
1546impl<T: Into<ShortBuf>> From<T> for BuildAlpnError {
1547 fn from(_: T) -> Self {
1548 Self::ShortBuf
1549 }
1550}
1551
1552impl fmt::Display for BuildAlpnError {
1555 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1556 match self {
1557 Self::InvalidProtocol => f.write_str("invalid ALPN protocol"),
1558 Self::LongSvcParam => f.write_str("long SVCB value"),
1559 Self::ShortBuf => ShortBuf.fmt(f)
1560 }
1561 }
1562}
1563
1564#[cfg(feature = "std")]
1565impl std::error::Error for BuildAlpnError {}
1566
1567#[derive(Clone, Copy, Debug)]
1571pub enum PushAlpnError {
1572 DuplicateKey,
1574
1575 InvalidProtocol,
1579
1580 LongSvcParam,
1582
1583 ShortBuf,
1585}
1586
1587impl From<PushError> for PushAlpnError {
1588 fn from(src: PushError) -> Self {
1589 match src {
1590 PushError::DuplicateKey => Self::DuplicateKey,
1591 PushError::ShortBuf => Self::ShortBuf,
1592 }
1593 }
1594}
1595
1596impl From<BuildValueError> for PushAlpnError {
1597 fn from(src: BuildValueError) -> Self {
1598 match src {
1599 BuildValueError::LongSvcParam => Self::LongSvcParam,
1600 BuildValueError::ShortBuf => Self::ShortBuf,
1601 }
1602 }
1603}
1604
1605impl<T: Into<ShortBuf>> From<T> for PushAlpnError {
1606 fn from(_: T) -> Self {
1607 Self::ShortBuf
1608 }
1609}
1610
1611impl fmt::Display for PushAlpnError {
1614 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1615 match self {
1616 Self::DuplicateKey => f.write_str("duplicate key"),
1617 Self::InvalidProtocol => f.write_str("invalid ALPN protocol"),
1618 Self::LongSvcParam => f.write_str("long SVCB value"),
1619 Self::ShortBuf => ShortBuf.fmt(f)
1620 }
1621 }
1622}
1623
1624#[cfg(feature = "std")]
1625impl std::error::Error for PushAlpnError {}
1626
1627#[cfg(test)]
1630mod test {
1631 use super::*;
1632
1633 #[test]
1634 fn test_vectors_alpn_escape() {
1635 let mut parser = Parser::from_ref(b"\
1636 \x08\
1637 \x66\x5c\x6f\x6f\x2c\x62\x61\x72\
1638 \x02\
1639 \x68\x32\
1640 ".as_ref());
1641 let alpn = Alpn::parse(&mut parser).unwrap();
1642 assert_eq!(parser.remaining(), 0);
1643 assert!(
1644 alpn.iter().eq(
1645 [
1646 br"f\oo,bar".as_ref(),
1647 b"h2".as_ref(),
1648 ]
1649 )
1650 );
1651 }
1652
1653}
1654