1use super::{
2 ComposeSvcParamValue, LongSvcParam, ParseSvcParamValue, PushError,
3 SvcParamValue, SvcParams, SvcParamsBuilder, 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 core::fmt::Write as _;
10use core::str::FromStr;
11use core::{fmt, hash, mem, str};
12use octseq::builder::{
13 EmptyBuilder, FreezeBuilder, FromBuilder, OctetsBuilder, ShortBuf,
14};
15use octseq::octets::{Octets, OctetsFrom};
16use octseq::parse::Parser;
17use octseq::str::Str;
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 $type::KEY => {
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 $type::KEY => {
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 => $key:ident) => {
227 $(#[$attr])*
228 #[derive(Debug, Clone)]
229 #[repr(transparent)]
230 pub struct $name<Octs: ?Sized>(Octs);
231
232 impl $name<()> {
233 const KEY: SvcParamKey = SvcParamKey::$key;
235 }
236
237 impl<Octs> $name<Octs> {
238 pub unsafe fn from_octets_unchecked(octets: Octs) -> Self {
245 $name(octets)
246 }
247 }
248
249 impl $name<[u8]> {
250 #[must_use]
257 pub unsafe fn from_slice_unchecked(slice: &[u8]) -> &Self {
258 mem::transmute(slice)
260 }
261 }
262
263 impl<Octs: ?Sized> $name<Octs> {
264 pub fn as_octets(&self) -> &Octs {
266 &self.0
267 }
268
269 pub fn as_slice(&self) -> &[u8]
271 where Octs: AsRef<[u8]> {
272 self.0.as_ref()
273 }
274 }
275
276 impl<O, OO> OctetsFrom<$name<O>> for $name<OO>
279 where
280 OO: OctetsFrom<O>,
281 {
282 type Error = OO::Error;
283
284 fn try_octets_from(
285 source: $name<O>,
286 ) -> Result<Self, Self::Error> {
287 Ok(unsafe {
288 $name::from_octets_unchecked(
289 OO::try_octets_from(source.0)?
290 )
291 })
292 }
293 }
294
295 impl<Octs> AsRef<Octs> for $name<Octs> {
298 fn as_ref(&self) -> &Octs {
299 self.as_octets()
300 }
301 }
302
303 impl<Octs: AsRef<[u8]> + ?Sized> AsRef<[u8]> for $name<Octs> {
304 fn as_ref(&self) -> &[u8] {
305 self.as_slice()
306 }
307 }
308
309 impl<Octs, OtherOcts> PartialEq<$name<OtherOcts>> for $name<Octs>
312 where
313 Octs: AsRef<[u8]>,
314 OtherOcts: AsRef<[u8]>,
315 {
316 fn eq(&self, other: &$name<OtherOcts>) -> bool {
317 self.as_slice().eq(other.as_slice())
318 }
319 }
320
321 impl<Octs: AsRef<[u8]>> Eq for $name<Octs> { }
322
323 impl<Octs: AsRef<[u8]>> hash::Hash for $name<Octs> {
326 fn hash<H: hash::Hasher>(&self, state: &mut H) {
327 self.as_slice().hash(state)
328 }
329 }
330
331 impl<Octs: ?Sized> SvcParamValue for $name<Octs> {
334 fn key(&self) -> SvcParamKey {
335 $name::KEY
336 }
337 }
338
339 impl<'a, Octs> ParseSvcParamValue<'a, Octs> for $name<Octs::Range<'a>>
340 where Octs: Octets + ?Sized {
341 fn parse_value(
342 key: SvcParamKey,
343 parser: &mut Parser<'a, Octs>,
344 ) -> Result<Option<Self>, ParseError> {
345 if key == $name::KEY {
346 Self::parse(parser).map(Some)
347 }
348 else {
349 Ok(None)
350 }
351 }
352 }
353
354 impl<Octs: AsRef<[u8]> + ?Sized> ComposeSvcParamValue for $name<Octs> {
355 fn compose_len(&self) -> u16 {
356 u16::try_from(self.as_slice().len()).expect("long value")
357 }
358
359 fn compose_value<Target: OctetsBuilder + ?Sized>(
360 &self, target: &mut Target,
361 ) -> Result<(), Target::AppendError> {
362 target.append_slice(self.as_slice())
363 }
364 }
365 };
366
367 ($(#[$attr:meta])* $name:ident => $key:ident, $iter:ident) => {
368 octets_wrapper!( $(#[$attr])* $name => $key);
369
370 impl<Octs: AsRef<[u8]> + ?Sized> $name<Octs> {
371 pub fn iter(&self) -> $iter<'_, Octs> {
373 $iter {
374 parser: Parser::from_ref(&self.0),
375 }
376 }
377 }
378
379 pub struct $iter<'a, Octs: ?Sized> {
381 parser: Parser<'a, Octs>,
382 }
383 };
384}
385
386octets_wrapper!(
389 Mandatory => MANDATORY,
403 MandatoryIter
404);
405
406impl<Octs: AsRef<[u8]>> Mandatory<Octs> {
407 pub fn from_octets(octets: Octs) -> Result<Self, ParseError> {
413 Mandatory::check_slice(octets.as_ref())?;
414 Ok(unsafe { Self::from_octets_unchecked(octets) })
415 }
416}
417
418impl Mandatory<[u8]> {
419 pub fn from_slice(slice: &[u8]) -> Result<&Self, ParseError> {
425 Self::check_slice(slice)?;
426 Ok(unsafe { Self::from_slice_unchecked(slice) })
427 }
428
429 fn check_slice(slice: &[u8]) -> Result<(), ParseError> {
431 LongSvcParam::check_len(slice.len())?;
432 if slice.len() % usize::from(SvcParamKey::COMPOSE_LEN) != 0 {
433 return Err(ParseError::form_error(
434 "invalid mandatory parameter",
435 ));
436 }
437 Ok(())
438 }
439}
440
441impl<Octs: AsRef<[u8]>> Mandatory<Octs> {
442 pub fn from_keys(
450 keys: impl Iterator<Item = SvcParamKey>,
451 ) -> Result<Self, BuildValueError>
452 where
453 Octs: FromBuilder,
454 <Octs as FromBuilder>::Builder: EmptyBuilder,
455 {
456 let mut octets = EmptyBuilder::empty();
457 for item in keys {
458 item.compose(&mut octets)?;
459 }
460 let octets = Octs::from_builder(octets);
461 if LongSvcParam::check_len(octets.as_ref().len()).is_err() {
462 return Err(BuildValueError::LongSvcParam);
463 }
464 Ok(unsafe { Self::from_octets_unchecked(octets) })
465 }
466}
467
468impl<Octs: AsRef<[u8]>> Mandatory<Octs> {
469 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
471 parser: &mut Parser<'a, Src>,
472 ) -> Result<Self, ParseError> {
473 Self::from_octets(parser.parse_octets(parser.remaining())?)
474 }
475}
476
477impl<Octs: Octets + ?Sized> Iterator for MandatoryIter<'_, Octs> {
480 type Item = SvcParamKey;
481
482 fn next(&mut self) -> Option<Self::Item> {
483 if self.parser.remaining() == 0 {
484 return None;
485 }
486 Some(
487 SvcParamKey::parse(&mut self.parser)
488 .expect("invalid mandatory parameter"),
489 )
490 }
491}
492
493impl<Octs: Octets + ?Sized> fmt::Display for Mandatory<Octs> {
496 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
497 for (i, v) in self.iter().enumerate() {
498 if i == 0 {
499 write!(f, "mandatory={}", v)?;
500 } else {
501 write!(f, ",{}", v)?;
502 }
503 }
504 Ok(())
505 }
506}
507
508impl<Octs: Octets + ?Sized> SvcParams<Octs> {
511 pub fn mandatory(&self) -> Option<Mandatory<Octs::Range<'_>>> {
513 self.first()
514 }
515}
516
517impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
518 pub fn mandatory(
524 &mut self,
525 keys: impl AsRef<[SvcParamKey]>,
526 ) -> Result<(), PushValueError> {
527 self.push_raw(
528 Mandatory::KEY,
529 u16::try_from(
530 keys.as_ref().len() * usize::from(SvcParamKey::COMPOSE_LEN),
531 )
532 .map_err(|_| PushValueError::LongSvcParam)?,
533 |octs| {
534 keys.as_ref().iter().try_for_each(|item| item.compose(octs))
535 },
536 )
537 .map_err(Into::into)
538 }
539}
540
541octets_wrapper!(
544 Alpn => ALPN,
561 AlpnIter
562);
563
564impl<Octs: AsRef<[u8]>> Alpn<Octs> {
565 pub fn from_octets(octets: Octs) -> Result<Self, ParseError> {
571 Alpn::check_slice(octets.as_ref())?;
572 Ok(unsafe { Self::from_octets_unchecked(octets) })
573 }
574}
575
576impl Alpn<[u8]> {
577 pub fn from_slice(slice: &[u8]) -> Result<&Self, ParseError> {
583 Self::check_slice(slice)?;
584 Ok(unsafe { Self::from_slice_unchecked(slice) })
585 }
586
587 fn check_slice(slice: &[u8]) -> Result<(), ParseError> {
592 LongSvcParam::check_len(slice.len())?;
593 let mut parser = Parser::from_ref(slice);
594 while parser.remaining() > 0 {
595 let len = usize::from(u8::parse(&mut parser)?);
596 parser.advance(len)?;
597 }
598 Ok(())
599 }
600}
601
602impl<Octs: AsRef<[u8]>> Alpn<Octs> {
603 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
605 parser: &mut Parser<'a, Src>,
606 ) -> Result<Self, ParseError> {
607 Self::from_octets(parser.parse_octets(parser.remaining())?)
608 }
609}
610
611impl<'a, Octs: Octets + ?Sized> Iterator for AlpnIter<'a, Octs> {
614 type Item = Octs::Range<'a>;
615
616 fn next(&mut self) -> Option<Self::Item> {
617 if self.parser.remaining() == 0 {
618 return None;
619 }
620 let len = usize::from(
621 u8::parse(&mut self.parser).expect("invalid alpn parameter"),
622 );
623 Some(
624 self.parser
625 .parse_octets(len)
626 .expect("invalid alpn parameter"),
627 )
628 }
629}
630
631impl<Octs: Octets + ?Sized> fmt::Display for Alpn<Octs> {
634 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
635 for (i, v) in self.iter().enumerate() {
636 if i == 0 {
637 f.write_str("alpn=")?;
638 } else {
639 f.write_str(",")?;
640 }
641 for ch in v.as_ref() {
642 f.write_char(*ch as char)?;
643 }
644 }
645 Ok(())
646 }
647}
648
649impl<Octs: Octets + ?Sized> SvcParams<Octs> {
652 pub fn alpn(&self) -> Option<Alpn<Octs::Range<'_>>> {
654 self.first()
655 }
656}
657
658impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
659 pub fn alpn(&mut self, protocols: &[&[u8]]) -> Result<(), PushAlpnError> {
669 let mut len = 0u16;
671 for proto in protocols.iter() {
672 let proto_len = u8::try_from(proto.len())
673 .map_err(|_| PushAlpnError::InvalidProtocol)?;
674 len = len
675 .checked_add(u16::from(proto_len) + u8::COMPOSE_LEN)
676 .ok_or(PushAlpnError::LongSvcParam)?;
677 }
678 self.push_raw(Alpn::KEY, len, |octs| {
679 protocols.iter().try_for_each(|proto| {
680 u8::try_from(proto.len())
681 .expect("long protocol")
682 .compose(octs)?;
683 octs.append_slice(proto)
684 })
685 })
686 .map_err(Into::into)
687 }
688}
689
690#[derive(Clone, Debug)]
694pub struct AlpnBuilder<Target> {
695 target: Target,
697}
698
699impl<Target> AlpnBuilder<Target> {
700 #[must_use]
702 pub fn empty() -> Self
703 where
704 Target: EmptyBuilder,
705 {
706 AlpnBuilder {
707 target: Target::empty(),
708 }
709 }
710
711 pub fn push(
716 &mut self,
717 protocol: impl AsRef<[u8]>,
718 ) -> Result<(), BuildAlpnError>
719 where
720 Target: OctetsBuilder + AsRef<[u8]>,
721 {
722 let protocol = protocol.as_ref();
723 if protocol.is_empty() {
724 return Err(BuildAlpnError::InvalidProtocol);
725 }
726 let len = u8::try_from(protocol.len())
727 .map_err(|_| BuildAlpnError::InvalidProtocol)?;
728 LongSvcParam::check_len(
729 self.target
730 .as_ref()
731 .len()
732 .checked_add(protocol.len() + 1)
733 .expect("long Alpn value"),
734 )
735 .map_err(|_| BuildAlpnError::LongSvcParam)?;
736 len.compose(&mut self.target)?;
737 self.target
738 .append_slice(protocol)
739 .map_err(|_| BuildAlpnError::ShortBuf)
740 }
741
742 pub fn freeze(self) -> Alpn<Target::Octets>
744 where
745 Target: FreezeBuilder,
746 {
747 unsafe { Alpn::from_octets_unchecked(self.target.freeze()) }
748 }
749}
750
751#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
762pub struct NoDefaultAlpn;
763
764impl NoDefaultAlpn {
765 const KEY: SvcParamKey = SvcParamKey::NO_DEFAULT_ALPN;
767}
768
769impl NoDefaultAlpn {
770 pub fn parse<Src: Octets + ?Sized>(
772 _parser: &mut Parser<'_, Src>,
773 ) -> Result<Self, ParseError> {
774 Ok(Self)
775 }
776}
777
778impl SvcParamValue for NoDefaultAlpn {
781 fn key(&self) -> SvcParamKey {
782 Self::KEY
783 }
784}
785
786impl<'a, Octs: Octets + ?Sized> ParseSvcParamValue<'a, Octs>
787 for NoDefaultAlpn
788{
789 fn parse_value(
790 key: SvcParamKey,
791 parser: &mut Parser<'a, Octs>,
792 ) -> Result<Option<Self>, ParseError> {
793 if key == Self::KEY {
794 Self::parse(parser).map(Some)
795 } else {
796 Ok(None)
797 }
798 }
799}
800
801impl ComposeSvcParamValue for NoDefaultAlpn {
802 fn compose_len(&self) -> u16 {
803 0
804 }
805
806 fn compose_value<Target: OctetsBuilder + ?Sized>(
807 &self,
808 _target: &mut Target,
809 ) -> Result<(), Target::AppendError> {
810 Ok(())
811 }
812}
813
814impl fmt::Display for NoDefaultAlpn {
817 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
818 f.write_str("nodefaultalpn")
819 }
820}
821
822impl<Octs: Octets + ?Sized> SvcParams<Octs> {
825 pub fn no_default_alpn(&self) -> bool {
827 self.first::<NoDefaultAlpn>().is_some()
828 }
829}
830
831impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
832 pub fn no_default_alpn(&mut self) -> Result<(), PushError> {
834 self.push(&NoDefaultAlpn)
835 }
836}
837
838#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
844pub struct Port(u16);
845
846impl Port {
847 const KEY: SvcParamKey = SvcParamKey::PORT;
849}
850
851impl Port {
852 #[must_use]
854 pub fn new(port: u16) -> Self {
855 Port(port)
856 }
857
858 pub fn parse<Src: Octets + ?Sized>(
860 parser: &mut Parser<'_, Src>,
861 ) -> Result<Self, ParseError> {
862 u16::parse(parser).map(Port::new)
863 }
864
865 #[must_use]
867 pub fn port(self) -> u16 {
868 self.0
869 }
870}
871
872impl SvcParamValue for Port {
875 fn key(&self) -> SvcParamKey {
876 Self::KEY
877 }
878}
879
880impl<'a, Octs: Octets + ?Sized> ParseSvcParamValue<'a, Octs> for Port {
881 fn parse_value(
882 key: SvcParamKey,
883 parser: &mut Parser<'a, Octs>,
884 ) -> Result<Option<Self>, ParseError> {
885 if key == Self::KEY {
886 Self::parse(parser).map(Some)
887 } else {
888 Ok(None)
889 }
890 }
891}
892
893impl ComposeSvcParamValue for Port {
894 fn compose_len(&self) -> u16 {
895 u16::COMPOSE_LEN
896 }
897
898 fn compose_value<Target: OctetsBuilder + ?Sized>(
899 &self,
900 target: &mut Target,
901 ) -> Result<(), Target::AppendError> {
902 self.0.compose(target)
903 }
904}
905
906impl fmt::Display for Port {
909 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
910 write!(f, "port={}", self.0)
911 }
912}
913
914impl<Octs: Octets + ?Sized> SvcParams<Octs> {
917 pub fn port(&self) -> Option<Port> {
919 self.first()
920 }
921}
922
923impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
924 pub fn port(&mut self, port: u16) -> Result<(), PushError> {
926 self.push(&Port::new(port))
927 }
928}
929
930octets_wrapper!(
933 Ech => ECH
942);
943
944impl<Octs: AsRef<[u8]>> Ech<Octs> {
945 pub fn from_octets(octets: Octs) -> Result<Self, LongSvcParam> {
950 Ech::check_slice(octets.as_ref())?;
951 Ok(unsafe { Self::from_octets_unchecked(octets) })
952 }
953}
954
955impl Ech<[u8]> {
956 pub fn from_slice(slice: &[u8]) -> Result<&Self, LongSvcParam> {
961 Self::check_slice(slice)?;
962 Ok(unsafe { Self::from_slice_unchecked(slice) })
963 }
964
965 fn check_slice(slice: &[u8]) -> Result<(), LongSvcParam> {
969 LongSvcParam::check_len(slice.len())?;
970 Ok(())
971 }
972}
973
974impl<Octs: AsRef<[u8]>> Ech<Octs> {
975 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
977 parser: &mut Parser<'a, Src>,
978 ) -> Result<Self, ParseError> {
979 Self::from_octets(parser.parse_octets(parser.remaining())?)
980 .map_err(Into::into)
981 }
982}
983
984impl<Octs: AsRef<[u8]> + ?Sized> fmt::Display for Ech<Octs> {
987 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
988 if self.as_slice().is_empty() {
989 f.write_str("ech")
990 } else {
991 f.write_str("ech=")?;
992 base64::display(self.as_slice(), f)
993 }
994 }
995}
996
997impl<Octs: Octets + ?Sized> SvcParams<Octs> {
1000 pub fn ech(&self) -> Option<Ech<Octs::Range<'_>>> {
1002 self.first()
1003 }
1004}
1005
1006impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
1007 pub fn ech<Source: AsRef<[u8]> + ?Sized>(
1009 &mut self,
1010 ech: &Source,
1011 ) -> Result<(), PushValueError> {
1012 self.push(Ech::from_slice(ech.as_ref())?)
1013 .map_err(Into::into)
1014 }
1015}
1016
1017octets_wrapper!(
1020 Ipv4Hint => IPV4HINT,
1033 Ipv4HintIter
1034);
1035
1036impl<Octs: AsRef<[u8]>> Ipv4Hint<Octs> {
1037 pub fn from_octets(octets: Octs) -> Result<Self, ParseError> {
1042 Ipv4Hint::check_slice(octets.as_ref())?;
1043 Ok(unsafe { Self::from_octets_unchecked(octets) })
1044 }
1045
1046 pub fn from_addrs(
1052 addrs: impl IntoIterator<Item = Ipv4Addr>,
1053 ) -> Result<Self, BuildValueError>
1054 where
1055 Octs: FromBuilder,
1056 <Octs as FromBuilder>::Builder: EmptyBuilder,
1057 {
1058 let mut octets = EmptyBuilder::empty();
1059 for item in addrs {
1060 item.compose(&mut octets)?;
1061 }
1062 let octets = Octs::from_builder(octets);
1063 if LongSvcParam::check_len(octets.as_ref().len()).is_err() {
1064 return Err(BuildValueError::LongSvcParam);
1065 }
1066 Ok(unsafe { Self::from_octets_unchecked(octets) })
1067 }
1068}
1069
1070impl Ipv4Hint<[u8]> {
1071 pub fn from_slice(slice: &[u8]) -> Result<&Self, ParseError> {
1076 Self::check_slice(slice)?;
1077 Ok(unsafe { Self::from_slice_unchecked(slice) })
1078 }
1079
1080 fn check_slice(slice: &[u8]) -> Result<(), ParseError> {
1085 LongSvcParam::check_len(slice.len())?;
1086 if slice.len() % usize::from(Ipv4Addr::COMPOSE_LEN) != 0 {
1087 return Err(ParseError::form_error("invalid ipv4hint parameter"));
1088 }
1089 Ok(())
1090 }
1091}
1092
1093impl<Octs: AsRef<[u8]>> Ipv4Hint<Octs> {
1094 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
1096 parser: &mut Parser<'a, Src>,
1097 ) -> Result<Self, ParseError> {
1098 Self::from_octets(parser.parse_octets(parser.remaining())?)
1099 }
1100}
1101
1102impl<Octs: Octets + ?Sized> Iterator for Ipv4HintIter<'_, Octs> {
1103 type Item = Ipv4Addr;
1104
1105 fn next(&mut self) -> Option<Self::Item> {
1106 if self.parser.remaining() == 0 {
1107 return None;
1108 }
1109 Some(
1110 Ipv4Addr::parse(&mut self.parser)
1111 .expect("invalid ipv4hint parameter"),
1112 )
1113 }
1114}
1115
1116impl<Octs: Octets + ?Sized> fmt::Display for Ipv4Hint<Octs> {
1117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1118 for (i, v) in self.iter().enumerate() {
1119 if i == 0 {
1120 write!(f, "ipv4hint={}", v)?;
1121 } else {
1122 write!(f, ",{}", v)?;
1123 }
1124 }
1125 Ok(())
1126 }
1127}
1128
1129impl<Octs: Octets + ?Sized> SvcParams<Octs> {
1132 pub fn ipv4hint(&self) -> Option<Ipv4Hint<Octs::Range<'_>>> {
1134 self.first()
1135 }
1136}
1137
1138impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
1139 pub fn ipv4hint(
1145 &mut self,
1146 addrs: impl AsRef<[Ipv4Addr]>,
1147 ) -> Result<(), PushValueError> {
1148 self.push_raw(
1149 Ipv4Hint::KEY,
1150 u16::try_from(
1151 addrs.as_ref().len() * usize::from(Ipv4Addr::COMPOSE_LEN),
1152 )
1153 .map_err(|_| PushValueError::LongSvcParam)?,
1154 |octs| {
1155 addrs
1156 .as_ref()
1157 .iter()
1158 .try_for_each(|item| item.compose(octs))
1159 },
1160 )
1161 .map_err(Into::into)
1162 }
1163}
1164
1165octets_wrapper!(
1168 Ipv6Hint => IPV6HINT,
1181 Ipv6HintIter
1182);
1183
1184impl<Octs: AsRef<[u8]>> Ipv6Hint<Octs> {
1185 pub fn from_octets(octets: Octs) -> Result<Self, ParseError> {
1190 Ipv6Hint::check_slice(octets.as_ref())?;
1191 Ok(unsafe { Self::from_octets_unchecked(octets) })
1192 }
1193
1194 pub fn from_addrs(
1200 addrs: impl IntoIterator<Item = Ipv6Addr>,
1201 ) -> Result<Self, BuildValueError>
1202 where
1203 Octs: FromBuilder,
1204 <Octs as FromBuilder>::Builder: EmptyBuilder,
1205 {
1206 let mut octets = EmptyBuilder::empty();
1207 for item in addrs {
1208 item.compose(&mut octets)?;
1209 }
1210 let octets = Octs::from_builder(octets);
1211 if LongSvcParam::check_len(octets.as_ref().len()).is_err() {
1212 return Err(BuildValueError::LongSvcParam);
1213 }
1214 Ok(unsafe { Self::from_octets_unchecked(octets) })
1215 }
1216}
1217
1218impl Ipv6Hint<[u8]> {
1219 pub fn from_slice(slice: &[u8]) -> Result<&Self, ParseError> {
1224 Self::check_slice(slice)?;
1225 Ok(unsafe { Self::from_slice_unchecked(slice) })
1226 }
1227
1228 fn check_slice(slice: &[u8]) -> Result<(), ParseError> {
1233 LongSvcParam::check_len(slice.len())?;
1234 if slice.len() % usize::from(Ipv6Addr::COMPOSE_LEN) != 0 {
1235 return Err(ParseError::form_error("invalid ipv6hint parameter"));
1236 }
1237 Ok(())
1238 }
1239}
1240
1241impl<Octs: AsRef<[u8]>> Ipv6Hint<Octs> {
1242 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
1244 parser: &mut Parser<'a, Src>,
1245 ) -> Result<Self, ParseError> {
1246 Self::from_octets(parser.parse_octets(parser.remaining())?)
1247 }
1248}
1249
1250impl<Octs: Octets + ?Sized> Iterator for Ipv6HintIter<'_, Octs> {
1253 type Item = Ipv6Addr;
1254
1255 fn next(&mut self) -> Option<Self::Item> {
1256 if self.parser.remaining() == 0 {
1257 return None;
1258 }
1259 Some(
1260 Ipv6Addr::parse(&mut self.parser)
1261 .expect("invalid ipv6hint parameter"),
1262 )
1263 }
1264}
1265
1266impl<Octs: Octets + ?Sized> fmt::Display for Ipv6Hint<Octs> {
1269 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1270 for (i, v) in self.iter().enumerate() {
1271 if i == 0 {
1272 write!(f, "ipv6hint={}", v)?;
1273 } else {
1274 write!(f, ",{}", v)?;
1275 }
1276 }
1277 Ok(())
1278 }
1279}
1280
1281impl<Octs: Octets + ?Sized> SvcParams<Octs> {
1284 pub fn ipv6hint(&self) -> Option<Ipv6Hint<Octs::Range<'_>>> {
1286 self.first()
1287 }
1288}
1289
1290impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
1291 pub fn ipv6hint(
1297 &mut self,
1298 addrs: impl AsRef<[Ipv6Addr]>,
1299 ) -> Result<(), PushValueError> {
1300 self.push_raw(
1301 Ipv6Hint::KEY,
1302 u16::try_from(
1303 addrs.as_ref().len() * usize::from(Ipv6Addr::COMPOSE_LEN),
1304 )
1305 .map_err(|_| PushValueError::LongSvcParam)?,
1306 |octs| {
1307 addrs
1308 .as_ref()
1309 .iter()
1310 .try_for_each(|item| item.compose(octs))
1311 },
1312 )
1313 .map_err(Into::into)
1314 }
1315}
1316
1317octets_wrapper!(
1320 DohPath => DOHPATH
1331);
1332
1333impl<Octs: AsRef<[u8]>> DohPath<Octs> {
1334 pub fn from_octets(octets: Octs) -> Result<Self, LongSvcParam> {
1338 DohPath::check_slice(octets.as_ref())?;
1339 Ok(unsafe { Self::from_octets_unchecked(octets) })
1340 }
1341}
1342
1343impl DohPath<[u8]> {
1344 pub fn from_slice(slice: &[u8]) -> Result<&Self, LongSvcParam> {
1348 Self::check_slice(slice)?;
1349 Ok(unsafe { Self::from_slice_unchecked(slice) })
1350 }
1351
1352 fn check_slice(slice: &[u8]) -> Result<(), LongSvcParam> {
1356 LongSvcParam::check_len(slice.len())?;
1357 Ok(())
1358 }
1359}
1360
1361impl<Octs: AsRef<[u8]>> DohPath<Octs> {
1362 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
1364 parser: &mut Parser<'a, Src>,
1365 ) -> Result<Self, ParseError> {
1366 Self::from_octets(parser.parse_octets(parser.remaining())?)
1367 .map_err(Into::into)
1368 }
1369}
1370
1371impl<Octs: AsRef<[u8]>> TryFrom<Str<Octs>> for DohPath<Octs> {
1374 type Error = LongSvcParam;
1375
1376 fn try_from(src: Str<Octs>) -> Result<Self, Self::Error> {
1377 Self::from_octets(src.into_octets())
1378 }
1379}
1380
1381impl<Octs> FromStr for DohPath<Octs>
1382where
1383 Octs: FromBuilder,
1384 <Octs as FromBuilder>::Builder:
1385 EmptyBuilder + FreezeBuilder<Octets = Octs>,
1386{
1387 type Err = BuildValueError;
1388
1389 fn from_str(s: &str) -> Result<Self, Self::Err> {
1390 DohPath::check_slice(s.as_bytes())?;
1391 let mut res: <Octs as FromBuilder>::Builder = EmptyBuilder::empty();
1392 res.append_slice(s.as_bytes()).map_err(Into::into)?;
1393 Ok(unsafe { Self::from_octets_unchecked(res.freeze()) })
1394 }
1395}
1396
1397impl<Octs: AsRef<[u8]> + ?Sized> fmt::Display for DohPath<Octs> {
1400 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1401 if self.as_slice().is_empty() {
1402 f.write_str("dohpath")
1403 } else {
1404 f.write_str("dohpath=")?;
1405 let mut s = self.as_slice();
1406
1407 while !s.is_empty() {
1409 match str::from_utf8(s) {
1410 Ok(s) => return f.write_str(s),
1411 Err(err) => {
1412 let end = err.valid_up_to();
1413 if end > 0 {
1414 f.write_str(unsafe {
1415 str::from_utf8_unchecked(&s[..end])
1416 })?;
1417 }
1418 f.write_str("\u{FFFD}")?;
1419 match err.error_len() {
1420 Some(len) => {
1421 s = &s[end + len..];
1422 }
1423 None => break,
1424 }
1425 }
1426 }
1427 }
1428 Ok(())
1429 }
1430 }
1431}
1432
1433impl<Octs: Octets + ?Sized> SvcParams<Octs> {
1436 pub fn dohpath(&self) -> Option<DohPath<Octs::Range<'_>>> {
1438 self.first()
1439 }
1440}
1441
1442impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
1443 pub fn dohpath(&mut self, template: &str) -> Result<(), PushValueError> {
1449 self.push_raw(
1450 DohPath::KEY,
1451 u16::try_from(template.len())
1452 .map_err(|_| PushValueError::LongSvcParam)?,
1453 |octs| octs.append_slice(template.as_bytes()),
1454 )
1455 .map_err(Into::into)
1456 }
1457}
1458
1459#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1465pub enum BuildValueError {
1466 LongSvcParam,
1468
1469 ShortBuf,
1471}
1472
1473impl From<LongSvcParam> for BuildValueError {
1474 fn from(_: LongSvcParam) -> Self {
1475 Self::LongSvcParam
1476 }
1477}
1478
1479impl<T: Into<ShortBuf>> From<T> for BuildValueError {
1480 fn from(_: T) -> Self {
1481 Self::ShortBuf
1482 }
1483}
1484
1485impl fmt::Display for BuildValueError {
1488 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1489 match self {
1490 Self::LongSvcParam => f.write_str("long SVCB value"),
1491 Self::ShortBuf => ShortBuf.fmt(f),
1492 }
1493 }
1494}
1495
1496#[cfg(feature = "std")]
1497impl std::error::Error for BuildValueError {}
1498
1499#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1503pub enum PushValueError {
1504 DuplicateKey,
1506
1507 LongSvcParam,
1509
1510 ShortBuf,
1512}
1513
1514impl From<LongSvcParam> for PushValueError {
1515 fn from(_: LongSvcParam) -> Self {
1516 Self::LongSvcParam
1517 }
1518}
1519
1520impl From<PushError> for PushValueError {
1521 fn from(src: PushError) -> Self {
1522 match src {
1523 PushError::DuplicateKey => Self::DuplicateKey,
1524 PushError::ShortBuf => Self::ShortBuf,
1525 }
1526 }
1527}
1528
1529impl From<BuildValueError> for PushValueError {
1530 fn from(src: BuildValueError) -> Self {
1531 match src {
1532 BuildValueError::LongSvcParam => Self::LongSvcParam,
1533 BuildValueError::ShortBuf => Self::ShortBuf,
1534 }
1535 }
1536}
1537
1538impl<T: Into<ShortBuf>> From<T> for PushValueError {
1539 fn from(_: T) -> Self {
1540 Self::ShortBuf
1541 }
1542}
1543
1544impl fmt::Display for PushValueError {
1547 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1548 match self {
1549 Self::DuplicateKey => f.write_str("duplicate key"),
1550 Self::LongSvcParam => f.write_str("long SVCB value"),
1551 Self::ShortBuf => ShortBuf.fmt(f),
1552 }
1553 }
1554}
1555
1556#[cfg(feature = "std")]
1557impl std::error::Error for PushValueError {}
1558
1559#[derive(Clone, Copy, Debug)]
1563pub enum BuildAlpnError {
1564 InvalidProtocol,
1568
1569 LongSvcParam,
1571
1572 ShortBuf,
1574}
1575
1576impl<T: Into<ShortBuf>> From<T> for BuildAlpnError {
1577 fn from(_: T) -> Self {
1578 Self::ShortBuf
1579 }
1580}
1581
1582impl fmt::Display for BuildAlpnError {
1585 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1586 match self {
1587 Self::InvalidProtocol => f.write_str("invalid ALPN protocol"),
1588 Self::LongSvcParam => f.write_str("long SVCB value"),
1589 Self::ShortBuf => ShortBuf.fmt(f),
1590 }
1591 }
1592}
1593
1594#[cfg(feature = "std")]
1595impl std::error::Error for BuildAlpnError {}
1596
1597#[derive(Clone, Copy, Debug)]
1601pub enum PushAlpnError {
1602 DuplicateKey,
1604
1605 InvalidProtocol,
1609
1610 LongSvcParam,
1612
1613 ShortBuf,
1615}
1616
1617impl From<PushError> for PushAlpnError {
1618 fn from(src: PushError) -> Self {
1619 match src {
1620 PushError::DuplicateKey => Self::DuplicateKey,
1621 PushError::ShortBuf => Self::ShortBuf,
1622 }
1623 }
1624}
1625
1626impl From<BuildValueError> for PushAlpnError {
1627 fn from(src: BuildValueError) -> Self {
1628 match src {
1629 BuildValueError::LongSvcParam => Self::LongSvcParam,
1630 BuildValueError::ShortBuf => Self::ShortBuf,
1631 }
1632 }
1633}
1634
1635impl<T: Into<ShortBuf>> From<T> for PushAlpnError {
1636 fn from(_: T) -> Self {
1637 Self::ShortBuf
1638 }
1639}
1640
1641impl fmt::Display for PushAlpnError {
1644 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1645 match self {
1646 Self::DuplicateKey => f.write_str("duplicate key"),
1647 Self::InvalidProtocol => f.write_str("invalid ALPN protocol"),
1648 Self::LongSvcParam => f.write_str("long SVCB value"),
1649 Self::ShortBuf => ShortBuf.fmt(f),
1650 }
1651 }
1652}
1653
1654#[cfg(feature = "std")]
1655impl std::error::Error for PushAlpnError {}
1656
1657#[cfg(test)]
1660mod test {
1661 use super::*;
1662
1663 #[test]
1664 fn test_vectors_alpn_escape() {
1665 let mut parser = Parser::from_ref(
1666 b"\
1667 \x08\
1668 \x66\x5c\x6f\x6f\x2c\x62\x61\x72\
1669 \x02\
1670 \x68\x32\
1671 "
1672 .as_ref(),
1673 );
1674 let alpn = Alpn::parse(&mut parser).unwrap();
1675 assert_eq!(parser.remaining(), 0);
1676 assert!(alpn.iter().eq([br"f\oo,bar".as_ref(), b"h2".as_ref(),]));
1677 }
1678}