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, mem, 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 $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("invalid mandatory parameter"))
434 }
435 Ok(())
436 }
437}
438
439impl<Octs: AsRef<[u8]>> Mandatory<Octs> {
440 pub fn from_keys(
448 keys: impl Iterator<Item = SvcParamKey>
449 ) -> Result<Self, BuildValueError>
450 where
451 Octs: FromBuilder,
452 <Octs as FromBuilder>::Builder: EmptyBuilder
453 {
454 let mut octets = EmptyBuilder::empty();
455 for item in keys {
456 item.compose(&mut octets)?;
457 }
458 let octets = Octs::from_builder(octets);
459 if LongSvcParam::check_len(octets.as_ref().len()).is_err() {
460 return Err(BuildValueError::LongSvcParam)
461 }
462 Ok(unsafe { Self::from_octets_unchecked(octets) })
463 }
464}
465
466impl<Octs: AsRef<[u8]>> Mandatory<Octs> {
467 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
469 parser: &mut Parser<'a, Src>,
470 ) -> Result<Self, ParseError> {
471 Self::from_octets(parser.parse_octets(parser.remaining())?)
472 }
473}
474
475impl<Octs: Octets + ?Sized> Iterator for MandatoryIter<'_, Octs> {
478 type Item = SvcParamKey;
479
480 fn next(&mut self) -> Option<Self::Item> {
481 if self.parser.remaining() == 0 {
482 return None;
483 }
484 Some(
485 SvcParamKey::parse(
486 &mut self.parser
487 ).expect("invalid mandatory parameter")
488 )
489 }
490}
491
492impl<Octs: Octets + ?Sized> fmt::Display for Mandatory<Octs> {
495 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
496 for (i, v) in self.iter().enumerate() {
497 if i == 0 {
498 write!(f, "mandatory={}", v)?;
499 } else {
500 write!(f, ",{}", v)?;
501 }
502 }
503 Ok(())
504 }
505}
506
507impl<Octs: Octets + ?Sized> SvcParams<Octs> {
510 pub fn mandatory(&self) -> Option<Mandatory<Octs::Range<'_>>> {
512 self.first()
513 }
514}
515
516impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
517 pub fn mandatory(
523 &mut self, keys: impl AsRef<[SvcParamKey]>,
524 ) -> Result<(), PushValueError> {
525 self.push_raw(
526 Mandatory::KEY,
527 u16::try_from(
528 keys.as_ref().len() * usize::from(SvcParamKey::COMPOSE_LEN)
529 ).map_err(|_| PushValueError::LongSvcParam)?,
530 |octs| {
531 keys.as_ref().iter().try_for_each(|item| item.compose(octs))
532 },
533 ).map_err(Into::into)
534 }
535}
536
537
538octets_wrapper!(
541 Alpn => ALPN,
558 AlpnIter
559);
560
561impl<Octs: AsRef<[u8]>> Alpn<Octs> {
562 pub fn from_octets(octets: Octs) -> Result<Self, ParseError> {
568 Alpn::check_slice(octets.as_ref())?;
569 Ok(unsafe { Self::from_octets_unchecked(octets) })
570 }
571}
572
573impl Alpn<[u8]> {
574 pub fn from_slice(slice: &[u8]) -> Result<&Self, ParseError> {
580 Self::check_slice(slice)?;
581 Ok(unsafe { Self::from_slice_unchecked(slice) })
582 }
583
584 fn check_slice(slice: &[u8]) -> Result<(), ParseError> {
589 LongSvcParam::check_len(slice.len())?;
590 let mut parser = Parser::from_ref(slice);
591 while parser.remaining() > 0 {
592 let len = usize::from(u8::parse(&mut parser)?);
593 parser.advance(len)?;
594 }
595 Ok(())
596 }
597}
598
599impl<Octs: AsRef<[u8]>> Alpn<Octs> {
600 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
602 parser: &mut Parser<'a, Src>,
603 ) -> Result<Self, ParseError> {
604 Self::from_octets(parser.parse_octets(parser.remaining())?)
605 }
606}
607
608impl<'a, Octs: Octets + ?Sized> Iterator for AlpnIter<'a, Octs> {
611 type Item = Octs::Range<'a>;
612
613 fn next(&mut self) -> Option<Self::Item> {
614 if self.parser.remaining() == 0 {
615 return None
616 }
617 let len = usize::from(
618 u8::parse(&mut self.parser).expect("invalid alpn parameter")
619 );
620 Some(self.parser.parse_octets(len).expect("invalid alpn parameter"))
621 }
622}
623
624impl<Octs: Octets + ?Sized> fmt::Display for Alpn<Octs> {
627 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
628 for (i, v) in self.iter().enumerate() {
629 if i == 0 {
630 f.write_str("alpn=")?;
631 } else {
632 f.write_str(",")?;
633 }
634 for ch in v.as_ref() {
635 f.write_char(*ch as char)?;
636 }
637 }
638 Ok(())
639 }
640}
641
642impl<Octs: Octets + ?Sized> SvcParams<Octs> {
645 pub fn alpn(&self) -> Option<Alpn<Octs::Range<'_>>> {
647 self.first()
648 }
649}
650
651impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
652 pub fn alpn(
662 &mut self, protocols: &[&[u8]],
663 ) -> Result<(), PushAlpnError> {
664 let mut len = 0u16;
666 for proto in protocols.iter() {
667 let proto_len = u8::try_from(
668 proto.len()
669 ).map_err(|_| PushAlpnError::InvalidProtocol)?;
670 len = len.checked_add(
671 u16::from(proto_len) + u8::COMPOSE_LEN
672 ).ok_or(PushAlpnError::LongSvcParam)?;
673 }
674 self.push_raw(
675 Alpn::KEY,
676 len,
677 |octs| {
678 protocols.iter().try_for_each(|proto| {
679 u8::try_from(
680 proto.len()
681 ).expect("long protocol").compose(octs)?;
682 octs.append_slice(proto)
683 })
684 }
685 ).map_err(Into::into)
686 }
687}
688
689#[derive(Clone, Debug)]
693pub struct AlpnBuilder<Target> {
694 target: Target,
696}
697
698impl<Target> AlpnBuilder<Target> {
699 #[must_use]
701 pub fn empty() -> Self
702 where
703 Target: EmptyBuilder,
704 {
705 AlpnBuilder { target: Target::empty() }
706 }
707
708 pub fn push(
713 &mut self, protocol: impl AsRef<[u8]>
714 ) -> Result<(), BuildAlpnError>
715 where Target: OctetsBuilder + AsRef<[u8]> {
716 let protocol = protocol.as_ref();
717 if protocol.is_empty() {
718 return Err(BuildAlpnError::InvalidProtocol)
719 }
720 let len = u8::try_from(
721 protocol.len()
722 ).map_err(|_| BuildAlpnError::InvalidProtocol)?;
723 LongSvcParam::check_len(
724 self.target.as_ref().len().checked_add(
725 protocol.len() + 1
726 ).expect("long Alpn value")
727 ).map_err(|_| BuildAlpnError::LongSvcParam)?;
728 len.compose(&mut self.target)?;
729 self.target.append_slice(
730 protocol
731 ).map_err(|_| BuildAlpnError::ShortBuf)
732 }
733
734 pub fn freeze(self) -> Alpn<Target::Octets>
736 where
737 Target: FreezeBuilder
738 {
739 unsafe { Alpn::from_octets_unchecked(self.target.freeze()) }
740 }
741}
742
743#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
754pub struct NoDefaultAlpn;
755
756impl NoDefaultAlpn {
757 const KEY: SvcParamKey = SvcParamKey::NO_DEFAULT_ALPN;
759}
760
761impl NoDefaultAlpn {
762 pub fn parse<Src: Octets + ?Sized>(
764 _parser: &mut Parser<Src>,
765 ) -> Result<Self, ParseError> {
766 Ok(Self)
767 }
768}
769
770impl SvcParamValue for NoDefaultAlpn {
773 fn key(&self) -> SvcParamKey {
774 Self::KEY
775 }
776}
777
778impl<'a, Octs: Octets + ?Sized> ParseSvcParamValue<'a, Octs> for NoDefaultAlpn {
779 fn parse_value(
780 key: SvcParamKey,
781 parser: &mut Parser<'a, Octs>,
782 ) -> Result<Option<Self>, ParseError> {
783 if key == Self::KEY {
784 Self::parse(parser).map(Some)
785 }
786 else {
787 Ok(None)
788 }
789 }
790}
791
792impl ComposeSvcParamValue for NoDefaultAlpn {
793 fn compose_len(&self) -> u16 {
794 0
795 }
796
797 fn compose_value<Target: OctetsBuilder + ?Sized>(
798 &self, _target: &mut Target,
799 ) -> Result<(), Target::AppendError> {
800 Ok(())
801 }
802}
803
804impl fmt::Display for NoDefaultAlpn {
807 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
808 f.write_str("nodefaultalpn")
809 }
810}
811
812impl<Octs: Octets + ?Sized> SvcParams<Octs> {
815 pub fn no_default_alpn(&self) -> bool {
817 self.first::<NoDefaultAlpn>().is_some()
818 }
819}
820
821impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
822 pub fn no_default_alpn(&mut self) -> Result<(), PushError> {
824 self.push(&NoDefaultAlpn)
825 }
826}
827
828#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
834pub struct Port(u16);
835
836impl Port {
837 const KEY: SvcParamKey = SvcParamKey::PORT;
839}
840
841impl Port {
842 #[must_use]
844 pub fn new(port: u16) -> Self {
845 Port(port)
846 }
847
848 pub fn parse<Src: Octets + ?Sized>(
850 parser: &mut Parser<Src>,
851 ) -> Result<Self, ParseError> {
852 u16::parse(parser).map(Port::new)
853 }
854
855 #[must_use]
857 pub fn port(self) -> u16 {
858 self.0
859 }
860}
861
862impl SvcParamValue for Port {
865 fn key(&self) -> SvcParamKey {
866 Self::KEY
867 }
868}
869
870impl<'a, Octs: Octets + ?Sized> ParseSvcParamValue<'a, Octs> for Port {
871 fn parse_value(
872 key: SvcParamKey,
873 parser: &mut Parser<'a, Octs>,
874 ) -> Result<Option<Self>, ParseError> {
875 if key == Self::KEY {
876 Self::parse(parser).map(Some)
877 }
878 else {
879 Ok(None)
880 }
881 }
882}
883
884impl ComposeSvcParamValue for Port {
885 fn compose_len(&self) -> u16 {
886 u16::COMPOSE_LEN
887 }
888
889 fn compose_value<Target: OctetsBuilder + ?Sized>(
890 &self, target: &mut Target,
891 ) -> Result<(), Target::AppendError> {
892 self.0.compose(target)
893 }
894}
895
896impl fmt::Display for Port {
899 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
900 write!(f, "port={}", self.0)
901 }
902}
903
904impl<Octs: Octets + ?Sized> SvcParams<Octs> {
907 pub fn port(&self) -> Option<Port> {
909 self.first()
910 }
911}
912
913impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
914 pub fn port(&mut self, port: u16) -> Result<(), PushError> {
916 self.push(&Port::new(port))
917 }
918}
919
920octets_wrapper!(
923 Ech => ECH
932);
933
934impl<Octs: AsRef<[u8]>> Ech<Octs> {
935 pub fn from_octets(octets: Octs) -> Result<Self, LongSvcParam> {
940 Ech::check_slice(octets.as_ref())?;
941 Ok(unsafe { Self::from_octets_unchecked(octets) })
942 }
943}
944
945impl Ech<[u8]> {
946 pub fn from_slice(slice: &[u8]) -> Result<&Self, LongSvcParam> {
951 Self::check_slice(slice)?;
952 Ok(unsafe { Self::from_slice_unchecked(slice) })
953 }
954
955 fn check_slice(slice: &[u8]) -> Result<(), LongSvcParam> {
959 LongSvcParam::check_len(slice.len())?;
960 Ok(())
961 }
962}
963
964impl<Octs: AsRef<[u8]>> Ech<Octs> {
965 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
967 parser: &mut Parser<'a, Src>,
968 ) -> Result<Self, ParseError> {
969 Self::from_octets(
970 parser.parse_octets(parser.remaining())?
971 ).map_err(Into::into)
972 }
973}
974
975impl<Octs: AsRef<[u8]> + ?Sized> fmt::Display for Ech<Octs> {
978 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
979 if self.as_slice().is_empty() {
980 f.write_str("ech")
981 }
982 else {
983 f.write_str("ech=")?;
984 base64::display(self.as_slice(), f)
985 }
986 }
987}
988
989impl<Octs: Octets + ?Sized> SvcParams<Octs> {
992 pub fn ech(&self) -> Option<Ech<Octs::Range<'_>>> {
994 self.first()
995 }
996}
997
998impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
999 pub fn ech<Source: AsRef<[u8]> + ?Sized>(
1001 &mut self, ech: &Source
1002 ) -> Result<(), PushValueError> {
1003 self.push(Ech::from_slice(ech.as_ref())?).map_err(Into::into)
1004 }
1005}
1006
1007octets_wrapper!(
1010 Ipv4Hint => IPV4HINT,
1023 Ipv4HintIter
1024);
1025
1026impl<Octs: AsRef<[u8]>> Ipv4Hint<Octs> {
1027 pub fn from_octets(octets: Octs) -> Result<Self, ParseError> {
1032 Ipv4Hint::check_slice(octets.as_ref())?;
1033 Ok(unsafe { Self::from_octets_unchecked(octets) })
1034 }
1035
1036 pub fn from_addrs(
1042 addrs: impl IntoIterator<Item = Ipv4Addr>
1043 ) -> Result<Self, BuildValueError>
1044 where
1045 Octs: FromBuilder,
1046 <Octs as FromBuilder>::Builder: EmptyBuilder
1047 {
1048 let mut octets = EmptyBuilder::empty();
1049 for item in addrs {
1050 item.compose(&mut octets)?;
1051 }
1052 let octets = Octs::from_builder(octets);
1053 if LongSvcParam::check_len(octets.as_ref().len()).is_err() {
1054 return Err(BuildValueError::LongSvcParam)
1055 }
1056 Ok(unsafe { Self::from_octets_unchecked(octets) })
1057 }
1058}
1059
1060impl Ipv4Hint<[u8]> {
1061 pub fn from_slice(slice: &[u8]) -> Result<&Self, ParseError> {
1066 Self::check_slice(slice)?;
1067 Ok(unsafe { Self::from_slice_unchecked(slice) })
1068 }
1069
1070 fn check_slice(slice: &[u8]) -> Result<(), ParseError> {
1075 LongSvcParam::check_len(slice.len())?;
1076 if slice.len() % usize::from(Ipv4Addr::COMPOSE_LEN) != 0 {
1077 return Err(ParseError::form_error("invalid ipv4hint parameter"))
1078 }
1079 Ok(())
1080 }
1081}
1082
1083impl<Octs: AsRef<[u8]>> Ipv4Hint<Octs> {
1084 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
1086 parser: &mut Parser<'a, Src>,
1087 ) -> Result<Self, ParseError> {
1088 Self::from_octets(parser.parse_octets(parser.remaining())?)
1089 }
1090}
1091
1092impl<Octs: Octets + ?Sized> Iterator for Ipv4HintIter<'_, Octs> {
1093 type Item = Ipv4Addr;
1094
1095 fn next(&mut self) -> Option<Self::Item> {
1096 if self.parser.remaining() == 0 {
1097 return None;
1098 }
1099 Some(
1100 Ipv4Addr::parse(
1101 &mut self.parser
1102 ).expect("invalid ipv4hint parameter")
1103 )
1104 }
1105}
1106
1107impl<Octs: Octets + ?Sized> fmt::Display for Ipv4Hint<Octs> {
1108 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1109 for (i, v) in self.iter().enumerate() {
1110 if i == 0 {
1111 write!(f, "ipv4hint={}", v)?;
1112 } else {
1113 write!(f, ",{}", v)?;
1114 }
1115 }
1116 Ok(())
1117 }
1118}
1119
1120impl<Octs: Octets + ?Sized> SvcParams<Octs> {
1123 pub fn ipv4hint(&self) -> Option<Ipv4Hint<Octs::Range<'_>>> {
1125 self.first()
1126 }
1127}
1128
1129impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
1130 pub fn ipv4hint(
1136 &mut self, addrs: impl AsRef<[Ipv4Addr]>,
1137 ) -> Result<(), PushValueError> {
1138 self.push_raw(
1139 Ipv4Hint::KEY,
1140 u16::try_from(
1141 addrs.as_ref().len() * usize::from(Ipv4Addr::COMPOSE_LEN)
1142 ).map_err(|_| PushValueError::LongSvcParam)?,
1143 |octs| {
1144 addrs.as_ref().iter().try_for_each(|item| item.compose(octs))
1145 },
1146 ).map_err(Into::into)
1147 }
1148}
1149
1150octets_wrapper!(
1153 Ipv6Hint => IPV6HINT,
1166 Ipv6HintIter
1167);
1168
1169impl<Octs: AsRef<[u8]>> Ipv6Hint<Octs> {
1170 pub fn from_octets(octets: Octs) -> Result<Self, ParseError> {
1175 Ipv6Hint::check_slice(octets.as_ref())?;
1176 Ok(unsafe { Self::from_octets_unchecked(octets) })
1177 }
1178
1179 pub fn from_addrs(
1185 addrs: impl IntoIterator<Item = Ipv6Addr>
1186 ) -> Result<Self, BuildValueError>
1187 where
1188 Octs: FromBuilder,
1189 <Octs as FromBuilder>::Builder: EmptyBuilder
1190 {
1191 let mut octets = EmptyBuilder::empty();
1192 for item in addrs {
1193 item.compose(&mut octets)?;
1194 }
1195 let octets = Octs::from_builder(octets);
1196 if LongSvcParam::check_len(octets.as_ref().len()).is_err() {
1197 return Err(BuildValueError::LongSvcParam)
1198 }
1199 Ok(unsafe { Self::from_octets_unchecked(octets) })
1200 }
1201}
1202
1203impl Ipv6Hint<[u8]> {
1204 pub fn from_slice(slice: &[u8]) -> Result<&Self, ParseError> {
1209 Self::check_slice(slice)?;
1210 Ok(unsafe { Self::from_slice_unchecked(slice) })
1211 }
1212
1213 fn check_slice(slice: &[u8]) -> Result<(), ParseError> {
1218 LongSvcParam::check_len(slice.len())?;
1219 if slice.len() % usize::from(Ipv6Addr::COMPOSE_LEN) != 0 {
1220 return Err(ParseError::form_error("invalid ipv6hint parameter"))
1221 }
1222 Ok(())
1223 }
1224}
1225
1226impl<Octs: AsRef<[u8]>> Ipv6Hint<Octs> {
1227 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
1229 parser: &mut Parser<'a, Src>,
1230 ) -> Result<Self, ParseError> {
1231 Self::from_octets(parser.parse_octets(parser.remaining())?)
1232 }
1233}
1234
1235impl<Octs: Octets + ?Sized> Iterator for Ipv6HintIter<'_, Octs> {
1238 type Item = Ipv6Addr;
1239
1240 fn next(&mut self) -> Option<Self::Item> {
1241 if self.parser.remaining() == 0 {
1242 return None;
1243 }
1244 Some(
1245 Ipv6Addr::parse(
1246 &mut self.parser
1247 ).expect("invalid ipv6hint parameter")
1248 )
1249 }
1250}
1251
1252impl<Octs: Octets + ?Sized> fmt::Display for Ipv6Hint<Octs> {
1255 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1256 for (i, v) in self.iter().enumerate() {
1257 if i == 0 {
1258 write!(f, "ipv6hint={}", v)?;
1259 } else {
1260 write!(f, ",{}", v)?;
1261 }
1262 }
1263 Ok(())
1264 }
1265}
1266
1267impl<Octs: Octets + ?Sized> SvcParams<Octs> {
1270 pub fn ipv6hint(&self) -> Option<Ipv6Hint<Octs::Range<'_>>> {
1272 self.first()
1273 }
1274}
1275
1276impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
1277 pub fn ipv6hint(
1283 &mut self, addrs: impl AsRef<[Ipv6Addr]>,
1284 ) -> Result<(), PushValueError> {
1285 self.push_raw(
1286 Ipv6Hint::KEY,
1287 u16::try_from(
1288 addrs.as_ref().len() * usize::from(Ipv6Addr::COMPOSE_LEN)
1289 ).map_err(|_| PushValueError::LongSvcParam)?,
1290 |octs| {
1291 addrs.as_ref().iter().try_for_each(|item| item.compose(octs))
1292 },
1293 ).map_err(Into::into)
1294 }
1295}
1296
1297octets_wrapper!(
1300 DohPath => DOHPATH
1311);
1312
1313impl<Octs: AsRef<[u8]>> DohPath<Octs> {
1314 pub fn from_octets(octets: Octs) -> Result<Self, LongSvcParam> {
1318 DohPath::check_slice(octets.as_ref())?;
1319 Ok(unsafe { Self::from_octets_unchecked(octets) })
1320 }
1321}
1322
1323impl DohPath<[u8]> {
1324 pub fn from_slice(slice: &[u8]) -> Result<&Self, LongSvcParam> {
1328 Self::check_slice(slice)?;
1329 Ok(unsafe { Self::from_slice_unchecked(slice) })
1330 }
1331
1332 fn check_slice(slice: &[u8]) -> Result<(), LongSvcParam> {
1336 LongSvcParam::check_len(slice.len())?;
1337 Ok(())
1338 }
1339}
1340
1341impl<Octs: AsRef<[u8]>> DohPath<Octs> {
1342 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
1344 parser: &mut Parser<'a, Src>,
1345 ) -> Result<Self, ParseError> {
1346 Self::from_octets(
1347 parser.parse_octets(parser.remaining())?
1348 ).map_err(Into::into)
1349 }
1350}
1351
1352impl<Octs: AsRef<[u8]>> TryFrom<Str<Octs>> for DohPath<Octs> {
1355 type Error = LongSvcParam;
1356
1357 fn try_from(src: Str<Octs>) -> Result<Self, Self::Error> {
1358 Self::from_octets(src.into_octets())
1359 }
1360}
1361
1362impl<Octs> FromStr for DohPath<Octs>
1363where
1364 Octs: FromBuilder,
1365 <Octs as FromBuilder>::Builder:
1366 EmptyBuilder
1367 + FreezeBuilder<Octets = Octs>
1368{
1369 type Err = BuildValueError;
1370
1371 fn from_str(s: &str) -> Result<Self, Self::Err> {
1372 DohPath::check_slice(s.as_bytes())?;
1373 let mut res: <Octs as FromBuilder>::Builder = EmptyBuilder::empty();
1374 res.append_slice(s.as_bytes()).map_err(Into::into)?;
1375 Ok(unsafe { Self::from_octets_unchecked(res.freeze()) })
1376 }
1377}
1378
1379impl<Octs: AsRef<[u8]> + ?Sized> fmt::Display for DohPath<Octs> {
1382 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1383 if self.as_slice().is_empty() {
1384 f.write_str("dohpath")
1385 }
1386 else {
1387 f.write_str("dohpath=")?;
1388 let mut s = self.as_slice();
1389
1390 while !s.is_empty() {
1392 match str::from_utf8(s) {
1393 Ok(s) => return f.write_str(s),
1394 Err(err) => {
1395 let end = err.valid_up_to();
1396 if end > 0 {
1397 f.write_str(unsafe {
1398 str::from_utf8_unchecked(&s[..end])
1399 })?;
1400 }
1401 f.write_str("\u{FFFD}")?;
1402 match err.error_len() {
1403 Some(len) => {
1404 s = &s[end + len..];
1405 }
1406 None => break,
1407 }
1408 }
1409 }
1410 }
1411 Ok(())
1412 }
1413 }
1414}
1415
1416impl<Octs: Octets + ?Sized> SvcParams<Octs> {
1419 pub fn dohpath(&self) -> Option<DohPath<Octs::Range<'_>>> {
1421 self.first()
1422 }
1423}
1424
1425impl<Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>> SvcParamsBuilder<Octs> {
1426 pub fn dohpath(
1432 &mut self, template: &str
1433 ) -> Result<(), PushValueError> {
1434 self.push_raw(
1435 DohPath::KEY,
1436 u16::try_from(
1437 template.len()
1438 ).map_err(|_| PushValueError::LongSvcParam)?,
1439 |octs| {
1440 octs.append_slice(template.as_bytes())
1441 },
1442 ).map_err(Into::into)
1443 }
1444}
1445
1446#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1452pub enum BuildValueError {
1453 LongSvcParam,
1455
1456 ShortBuf,
1458}
1459
1460impl From<LongSvcParam> for BuildValueError {
1461 fn from(_: LongSvcParam) -> Self {
1462 Self::LongSvcParam
1463 }
1464}
1465
1466impl<T: Into<ShortBuf>> From<T> for BuildValueError {
1467 fn from(_: T) -> Self {
1468 Self::ShortBuf
1469 }
1470}
1471
1472impl fmt::Display for BuildValueError {
1475 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1476 match self {
1477 Self::LongSvcParam => f.write_str("long SVCB value"),
1478 Self::ShortBuf => ShortBuf.fmt(f)
1479 }
1480 }
1481}
1482
1483#[cfg(feature = "std")]
1484impl std::error::Error for BuildValueError {}
1485
1486#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1490pub enum PushValueError {
1491 DuplicateKey,
1493
1494 LongSvcParam,
1496
1497 ShortBuf,
1499}
1500
1501impl From<LongSvcParam> for PushValueError {
1502 fn from(_: LongSvcParam) -> Self {
1503 Self::LongSvcParam
1504 }
1505}
1506
1507impl From<PushError> for PushValueError {
1508 fn from(src: PushError) -> Self {
1509 match src {
1510 PushError::DuplicateKey => Self::DuplicateKey,
1511 PushError::ShortBuf => Self::ShortBuf,
1512 }
1513 }
1514}
1515
1516impl From<BuildValueError> for PushValueError {
1517 fn from(src: BuildValueError) -> Self {
1518 match src {
1519 BuildValueError::LongSvcParam => Self::LongSvcParam,
1520 BuildValueError::ShortBuf => Self::ShortBuf,
1521 }
1522 }
1523}
1524
1525impl<T: Into<ShortBuf>> From<T> for PushValueError {
1526 fn from(_: T) -> Self {
1527 Self::ShortBuf
1528 }
1529}
1530
1531impl fmt::Display for PushValueError {
1534 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1535 match self {
1536 Self::DuplicateKey => f.write_str("duplicate key"),
1537 Self::LongSvcParam => f.write_str("long SVCB value"),
1538 Self::ShortBuf => ShortBuf.fmt(f)
1539 }
1540 }
1541}
1542
1543#[cfg(feature = "std")]
1544impl std::error::Error for PushValueError {}
1545
1546#[derive(Clone, Copy, Debug)]
1550pub enum BuildAlpnError {
1551 InvalidProtocol,
1555
1556 LongSvcParam,
1558
1559 ShortBuf,
1561}
1562
1563impl<T: Into<ShortBuf>> From<T> for BuildAlpnError {
1564 fn from(_: T) -> Self {
1565 Self::ShortBuf
1566 }
1567}
1568
1569impl fmt::Display for BuildAlpnError {
1572 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1573 match self {
1574 Self::InvalidProtocol => f.write_str("invalid ALPN protocol"),
1575 Self::LongSvcParam => f.write_str("long SVCB value"),
1576 Self::ShortBuf => ShortBuf.fmt(f)
1577 }
1578 }
1579}
1580
1581#[cfg(feature = "std")]
1582impl std::error::Error for BuildAlpnError {}
1583
1584#[derive(Clone, Copy, Debug)]
1588pub enum PushAlpnError {
1589 DuplicateKey,
1591
1592 InvalidProtocol,
1596
1597 LongSvcParam,
1599
1600 ShortBuf,
1602}
1603
1604impl From<PushError> for PushAlpnError {
1605 fn from(src: PushError) -> Self {
1606 match src {
1607 PushError::DuplicateKey => Self::DuplicateKey,
1608 PushError::ShortBuf => Self::ShortBuf,
1609 }
1610 }
1611}
1612
1613impl From<BuildValueError> for PushAlpnError {
1614 fn from(src: BuildValueError) -> Self {
1615 match src {
1616 BuildValueError::LongSvcParam => Self::LongSvcParam,
1617 BuildValueError::ShortBuf => Self::ShortBuf,
1618 }
1619 }
1620}
1621
1622impl<T: Into<ShortBuf>> From<T> for PushAlpnError {
1623 fn from(_: T) -> Self {
1624 Self::ShortBuf
1625 }
1626}
1627
1628impl fmt::Display for PushAlpnError {
1631 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1632 match self {
1633 Self::DuplicateKey => f.write_str("duplicate key"),
1634 Self::InvalidProtocol => f.write_str("invalid ALPN protocol"),
1635 Self::LongSvcParam => f.write_str("long SVCB value"),
1636 Self::ShortBuf => ShortBuf.fmt(f)
1637 }
1638 }
1639}
1640
1641#[cfg(feature = "std")]
1642impl std::error::Error for PushAlpnError {}
1643
1644#[cfg(test)]
1647mod test {
1648 use super::*;
1649
1650 #[test]
1651 fn test_vectors_alpn_escape() {
1652 let mut parser = Parser::from_ref(b"\
1653 \x08\
1654 \x66\x5c\x6f\x6f\x2c\x62\x61\x72\
1655 \x02\
1656 \x68\x32\
1657 ".as_ref());
1658 let alpn = Alpn::parse(&mut parser).unwrap();
1659 assert_eq!(parser.remaining(), 0);
1660 assert!(
1661 alpn.iter().eq(
1662 [
1663 br"f\oo,bar".as_ref(),
1664 b"h2".as_ref(),
1665 ]
1666 )
1667 );
1668 }
1669
1670}
1671