domain/rdata/svcb/
params.rs

1//! Handling of service binding parameters.
2//!
3//! This is a private module. It’s public types are re-exported by the
4//! parent.
5use super::value::AllValues;
6use crate::base::iana::SvcParamKey;
7use crate::base::scan::Symbol;
8use crate::base::wire::{Compose, Parse, ParseError};
9use octseq::builder::{EmptyBuilder, FromBuilder, OctetsBuilder, ShortBuf};
10use octseq::octets::{Octets, OctetsFrom, OctetsInto};
11use octseq::parse::{Parser, ShortInput};
12use core::{cmp, fmt, hash};
13use core::cmp::Ordering;
14use core::marker::PhantomData;
15
16//------------ SvcParams -----------------------------------------------------
17
18/// A sequence of service binding parameters.
19///
20/// These parameters provide information helpful when trying to connect to an
21/// endpoint offering a service. They consist of a sequence of parameter
22/// values. Each value has a type and some data specific to that type. The
23/// type is provided through a `u16` key with values assigned via an IANA
24/// registry. The key and registry are available through
25/// [`SvcParamKey`][crate::base::iana::SvcParamKey]. Each key is only allowed
26/// to appear at most once in the parameter sequence. Values need to be
27/// ordered by their key’s integer value.
28///
29/// A value of the `SvcParams` type contains a sequence of values in their
30/// wire-format encoded form. It guarantees that this content is correctly
31/// encoded. It does not guarantee that the content of the individual
32/// parameter value is correct. It also does not guarantee any size limit
33/// to the octets sequence.
34///
35/// You can create a value of this type through parsing or manually via
36/// [`from_octets`][Self::from_octets] or [`from_slice`][Self::from_slice].
37/// You can also build a new value from scratch via the [`SvcParamsBuilder`].
38/// The [`from_values`][Self::from_values] function provides a shortcut that
39/// crates the builder, passes it to a closure, and returns the finished
40/// parameter sequence.
41///
42/// Access to the values of the parameter sequence happens through a mechanism
43/// similar to record data: Various types exist that implement either a
44/// specific value type or a group of types. These types need to implement the
45/// [`SvcParamValue`] and [`ParseSvcParamValue`] traits to be used to access
46/// values. They can be used as a type parameter to the [`iter`][Self::iter]
47/// method to acquire an iterator over all the values that they understand.
48/// Since every concrete value can only be present once, the
49/// [`first`][Self::first] method can be used together with a value type
50/// implementing that concrete value to get the value if present. As a
51/// convenience, methods exist for every currently defined value type which
52/// return a value of that type if present.
53///
54/// The type [`UnknownSvcParam`] can be used to represent any value type with
55/// the value as a octets sequence. The [`AllValues`] enum provides typed
56/// access to all known value types.
57///
58/// # Wire Format
59///
60/// The wire format of a parameter sequence consists of a sequence of
61/// values. Each value is encoded as a 16 bit parameter key – represented
62/// by [`SvcParamKey`][crate::base::iana::SvcParamKey] in this crate –,
63/// followed by an unsigned 16 bit length value, followed by this many
64/// octets. Since the sequence is the last element in the record data, it
65/// is limited by the length of the record data only.
66#[derive(Clone, Default)]
67#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
68pub struct SvcParams<Octs: ?Sized> {
69    #[cfg_attr(
70        feature = "serde",
71        serde(
72            serialize_with =
73                "octseq::serde::SerializeOctets::serialize_octets",
74            deserialize_with =
75                "octseq::serde::DeserializeOctets::deserialize_octets",
76            bound(
77                serialize = "Octs: octseq::serde::SerializeOctets",
78                deserialize =
79                    "Octs: octseq::serde::DeserializeOctets<'de> + Sized",
80            )
81        )
82    )]
83    octets: Octs,
84}
85
86impl<Octs> SvcParams<Octs> {
87    /// Creates a parameter sequence from an octets sequence.
88    ///
89    /// The method checks that `octets` contains a parameter sequence that is
90    /// correctly encoded in wire format. It does not check that the
91    /// individual values are correctly encoded. It also does not check for
92    /// any length limit.
93    pub fn from_octets(octets: Octs) -> Result<Self, SvcParamsError>
94    where Octs: AsRef<[u8]> {
95        SvcParams::check_slice(octets.as_ref())?;
96        Ok(unsafe { Self::from_octets_unchecked(octets) })
97    }
98
99    /// Creates a new value from an octets sequence without checking.
100    ///
101    /// # Safety
102    ///
103    /// The caller has to ensure that `octets` contains a properly formatted
104    /// parameter sequence.
105    pub unsafe fn from_octets_unchecked(octets: Octs) -> Self {
106        SvcParams { octets }
107    }
108}
109
110impl SvcParams<[u8]> {
111    /// Creates a parameter sequence from an octets slice.
112    ///
113    /// The method checks that `slice` contains a parameter sequence that is
114    /// correctly encoded in wire format. It does not check that the
115    /// individual values are correctly encoded. It also does not check for
116    /// any length limit.
117    pub fn from_slice(slice: &[u8]) -> Result<&Self, SvcParamsError> {
118        SvcParams::check_slice(slice)?;
119        Ok(unsafe { Self::from_slice_unchecked(slice) })
120    }
121
122    /// Creates a new value from a slice without checking.
123    ///
124    /// # Safety
125    ///
126    /// The caller has to ensure that `slice` contains a properly formatted
127    /// parameter sequence.
128    #[must_use]
129    pub unsafe fn from_slice_unchecked(slice: &[u8]) -> &Self {
130        &*(slice as *const [u8] as *const Self)
131    }
132
133    /// Checks that a slice contains a correctly encoded parameters sequence.
134    fn check_slice(slice: &[u8]) -> Result<(), SvcParamsError> {
135        let mut parser = Parser::from_ref(slice);
136        let mut last_key = None;
137        while parser.remaining() > 0 {
138            let key = u16::parse(&mut parser)?;
139            if let Some(last_key) = last_key {
140                if key <= last_key {
141                    Err(ParseError::form_error("unordered SVCB params"))?;
142                }
143            }
144            last_key = Some(key);
145            let len = u16::parse(&mut parser)?;
146            parser.advance(len.into())?;
147        }
148        Ok(())
149    }
150}
151
152impl<Octs> SvcParams<Octs> {
153    /// Creates a parameter sequence by constructing it from values.
154    ///
155    /// The method expects a closure that receives an [`SvcParamsBuilder`]
156    /// which it should push all the required values to. Once it returns,
157    /// this builder is frozen into an `SvcParams` value and returned.
158    pub fn from_values<F>(op: F) -> Result<Self, PushError>
159    where
160        Octs: FromBuilder,
161        <Octs  as FromBuilder>::Builder:
162            AsRef<[u8]> + OctetsBuilder + EmptyBuilder,
163        F: FnOnce(
164            &mut SvcParamsBuilder<<Octs  as FromBuilder>::Builder>
165        ) -> Result<(), PushError>,
166    {
167        let mut res = SvcParamsBuilder::empty();
168        op(&mut res)?;
169        res.freeze().map_err(Into::into)
170    }
171}
172
173impl<Octs: AsRef<[u8]>> SvcParams<Octs> {
174    /// Parses a parameter sequence from its wire format.
175    pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized + 'a>(
176        parser: &mut Parser<'a, Src>
177    ) -> Result<Self, ParseError> {
178        Self::from_octets(
179            parser.parse_octets(parser.remaining())?
180        ).map_err(Into::into)
181    }
182}
183
184impl<Octs: ?Sized> SvcParams<Octs> {
185    /// Returns a reference to the underlying octets sequence.
186    pub fn as_octets(&self) -> &Octs {
187        &self.octets
188    }
189}
190
191impl<Octs: AsRef<[u8]> + ?Sized> SvcParams<Octs> {
192    /// Returns a slice of the underlying octets sequence.
193    pub fn as_slice(&self) -> &[u8] {
194        self.octets.as_ref()
195    }
196
197    /// Returns a parameter sequence atop a slice of this value’s octets.
198    pub fn for_slice(&self) -> &SvcParams<[u8]> {
199        unsafe { SvcParams::from_slice_unchecked(self.octets.as_ref()) }
200    }
201
202    /// Returns the length of the parameter sequence in octets.
203    pub fn len(&self) -> usize {
204        self.octets.as_ref().len()
205    }
206
207    /// Returns whether the parameters sequences is empty.
208    pub fn is_empty(&self) -> bool {
209        self.octets.as_ref().is_empty()
210    }
211
212    /// Returns the first value of type `Value`.
213    ///
214    /// This method is intended to be used with value types implementing a
215    /// specific type. Since only one instance is allowed to be present,
216    /// this method also returns `None` if the first value fails parsing,
217    /// assuming that the value is unusable and should be ignored.
218    ///
219    /// This may not be the correct behaviour in all cases. Please use
220    /// `self.iter::<Value>().next()` to get an optional parsing result.
221    pub fn first<'s, Value>(&'s self) -> Option<Value>
222    where
223        Octs: Octets,
224        Value: ParseSvcParamValue<'s, Octs>,
225    {
226        self.iter::<Value>().next().and_then(Result::ok)
227    }
228
229    /// Returns an iterator over all values accepted by `Value`.
230    pub fn iter<Value>(&self) -> ValueIter<Octs, Value> {
231        ValueIter::new(self.as_octets())
232    }
233
234    /// Returns an iterator over all values.
235    pub fn iter_all(&self) -> ValueIter<Octs, AllValues<Octs>>
236    where Octs: Sized {
237        self.iter()
238    }
239
240    /// Returns an iterator over all values in their raw form.
241    pub fn iter_raw(
242        &self
243    ) -> impl Iterator<Item = UnknownSvcParam<Octs::Range<'_>>>
244    where Octs: Octets + Sized {
245        self.iter().map(|item| item.expect("parsing cannot have failed"))
246    }
247
248    /// Composes the wire-format of the parameter sequence.
249    pub fn compose<Target: OctetsBuilder + ?Sized>(
250        &self, target: &mut Target
251    ) -> Result<(), Target::AppendError> {
252        target.append_slice(self.octets.as_ref())
253    }
254}
255
256//--- OctetsFrom
257
258impl<SrcOcts, Octs> OctetsFrom<SvcParams<SrcOcts>> for SvcParams<Octs>
259where Octs: OctetsFrom<SrcOcts> {
260    type Error = Octs::Error;
261
262    fn try_octets_from(
263        src: SvcParams<SrcOcts>
264    ) -> Result<Self, Self::Error> {
265        Ok(unsafe {
266            SvcParams::from_octets_unchecked(src.octets.try_octets_into()?)
267        })
268    }
269}
270
271//--- PartialEq and Eq
272
273impl<Octs, OtherOcts> PartialEq<SvcParams<OtherOcts>> for SvcParams<Octs>
274where
275    Octs: AsRef<[u8]> + ?Sized,
276    OtherOcts: AsRef<[u8]> + ?Sized,
277{
278    fn eq(&self, other: &SvcParams<OtherOcts>) -> bool {
279        self.as_slice().eq(other.as_slice())
280    }
281}
282
283impl<Octs: AsRef<[u8]> + ?Sized> Eq for SvcParams<Octs> { }
284
285//--- Hash
286
287impl<Octs: AsRef<[u8]> + ?Sized> hash::Hash for SvcParams<Octs> {
288    fn hash<H: hash::Hasher>(&self, state: &mut H) {
289        self.as_slice().hash(state)
290    }
291}
292
293//--- PartialOrd and Ord
294
295impl<Octs, OtherOcts> PartialOrd<SvcParams<OtherOcts>> for SvcParams<Octs>
296where
297    Octs: AsRef<[u8]> + ?Sized,
298    OtherOcts: AsRef<[u8]> + ?Sized,
299{
300    fn partial_cmp(
301        &self, other: &SvcParams<OtherOcts>
302    ) -> Option<cmp::Ordering> {
303        self.as_slice().partial_cmp(other.as_slice())
304    }
305}
306
307impl<Octs: AsRef<[u8]> + ?Sized> Ord for SvcParams<Octs> {
308    fn cmp(&self, other: &Self) -> cmp::Ordering {
309        self.as_slice().cmp(other.as_slice())
310    }
311}
312
313//--- Display and Debug
314
315impl<Octs: Octets + ?Sized> fmt::Display for SvcParams<Octs> {
316    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
317        let mut parser = Parser::from_ref(self.as_slice());
318        let mut first = true;
319        while parser.remaining() > 0 {
320            let key = SvcParamKey::parse(
321                &mut parser
322            ).expect("invalid SvcbParam");
323            let len = usize::from(
324                u16::parse(&mut parser).expect("invalid SvcParam")
325            );
326            let mut parser = parser.parse_parser(
327                len
328            ).expect("invalid SvcParam");
329            if first {
330                first = false;
331            }
332            else {
333                f.write_str(" ")?;
334            }
335            write!(
336                f, "{}", super::value::AllValues::parse_any(key, &mut parser)
337            )?;
338        };
339        Ok(())
340    }
341}
342
343impl<Octs: Octets + ?Sized> fmt::Debug for SvcParams<Octs> {
344    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
345        f.debug_tuple("SvcParams").field(
346            &format_args!("{}", self)
347        ).finish()
348    }
349}
350
351
352//------------ ValueIter -----------------------------------------------------
353
354/// An iterator over the values in a parameter sequence.
355///
356/// The iterator skips over those values that `Value` does not accept. It
357/// returns the result of trying to parse the value into `Value`.
358#[derive(Clone, Debug)]
359pub struct ValueIter<'a, Octs: ?Sized, Value> {
360    parser: Parser<'a, Octs>,
361    marker: PhantomData<Value>,
362}
363
364impl<'a, Octs: AsRef<[u8]> + ?Sized, Value> ValueIter<'a, Octs, Value> {
365    fn new(octets: &'a Octs) -> Self {
366        ValueIter {
367            parser: Parser::from_ref(octets),
368            marker: PhantomData,
369        }
370    }
371
372    fn next_step(&mut self) -> Result<Option<Value>, ParseError>
373    where
374        Octs: Octets,
375        Value: ParseSvcParamValue<'a, Octs>,
376    {
377        let key = SvcParamKey::parse(&mut self.parser)?;
378        let len = usize::from(u16::parse(&mut self.parser)?);
379        let mut parser = self.parser.parse_parser(len)?;
380        let res = Value::parse_value(key, &mut parser)?;
381        if res.is_some() && parser.remaining() > 0 {
382            return Err(ParseError::form_error(
383                "trailing data in SVCB parameter",
384            ));
385        }
386        Ok(res)
387    }
388}
389
390impl<'a, Octs, Value> Iterator for ValueIter<'a, Octs, Value>
391where
392    Octs: Octets + ?Sized,
393    Value: ParseSvcParamValue<'a, Octs>,
394{
395    type Item = Result<Value, ParseError>;
396
397    fn next(&mut self) -> Option<Self::Item> {
398        while self.parser.remaining() > 0 {
399            match self.next_step() {
400                Ok(Some(res)) => return Some(Ok(res)),
401                Ok(None) => { }
402                Err(err) => {
403                    // Advance to end so we’ll return None from now on.
404                    self.parser.advance_to_end();
405                    return Some(Err(err));
406                }
407            }
408        }
409        None
410    }
411}
412
413//------------ SvcParamValue, ParseSvcParamValue, ComposeSvcParamValue -------
414
415/// A type representing a service binding parameter value.
416pub trait SvcParamValue {
417    /// Returns the parameter key of the value.
418    fn key(&self) -> SvcParamKey;
419}
420
421/// A service binding parameter value that can be parse from wire format.
422pub trait ParseSvcParamValue<'a, Octs: ?Sized>: SvcParamValue + Sized {
423    /// Parse a parameter value from wire format.
424    ///
425    /// The method should return `Ok(None)` if the type cannot parse values
426    /// with `key`. It should return an error if parsing fails.
427    fn parse_value(
428        key: SvcParamKey, parser: &mut Parser<'a, Octs>,
429    ) -> Result<Option<Self>, ParseError>;
430}
431
432/// A service binding parameter value that can be composed into wire format.
433///
434/// All value types need to be able to calculate the length of their
435/// wire format. This length needs to fit into a `u16`. It is the
436/// responsibility of the value type to ensure that it will not grow too
437/// large.
438pub trait ComposeSvcParamValue: SvcParamValue {
439    /// Returns the length of the composed value.
440    fn compose_len(&self) -> u16;
441
442    /// Appends the wire format of the value to the end of `target`.
443    fn compose_value<Target: OctetsBuilder + ?Sized>(
444        &self, target: &mut Target,
445    ) -> Result<(), Target::AppendError>;
446}
447
448//------------ UnknownSvcParam -----------------------------------------------
449
450/// A service binding parameter value in its raw form.
451///
452/// This type can be used for any value type. It keeps the value’s data in
453/// its raw wire format.
454#[derive(Clone, Debug)]
455pub struct UnknownSvcParam<Octs> {
456    /// The key of the value.
457    key: SvcParamKey,
458
459    /// The octets of the value.
460    value: Octs,
461}
462
463impl<Octs> UnknownSvcParam<Octs> {
464    /// Creates a new parameter value from the given key and data.
465    ///
466    /// The function returns an error if `value` is longer than 65,535 octets.
467    pub fn new(key: SvcParamKey, value: Octs) -> Result<Self, LongSvcParam>
468    where Octs: AsRef<[u8]> {
469        LongSvcParam::check_len(value.as_ref().len())?;
470        Ok(unsafe { Self::new_unchecked(key, value) })
471    }
472
473    /// Creates a new SVCB parameter value without checking.
474    ///
475    /// # Safety
476    ///
477    /// The caller needs to make sure that `value` is not longer than
478    /// 65,535 octets.
479    pub unsafe fn new_unchecked(key: SvcParamKey, value: Octs) -> Self {
480        Self { key, value }
481    }
482}
483
484impl<Octs: AsRef<[u8]>> UnknownSvcParam<Octs> {
485    /// Parses a parameter value’s data from its wire format.
486    pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
487        key: SvcParamKey,
488        parser: &mut Parser<'a, Src>,
489    ) -> Result<Self, ParseError> {
490        Self::new(
491            key, parser.parse_octets(parser.remaining())?
492        ).map_err(Into::into)
493    }
494
495    /// Parses a full parameter from the wire format.
496    ///
497    /// This function parses the key, length, and data of the parameter.
498    pub fn parse_param<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
499        parser: &mut Parser<'a, Src>,
500    ) -> Result<Self, ParseError> {
501        let key = SvcParamKey::parse(parser)?;
502        let len = usize::from(u16::parse(parser)?);
503        let value = parser.parse_octets(len)?;
504        Ok(unsafe { Self::new_unchecked(key, value) })
505    }
506
507    /// Appends the wire format of the full parameter to the target.
508    ///
509    /// This includes the key and length of the parameter.
510    pub fn compose_param<Target: OctetsBuilder + ?Sized>(
511        &self, target: &mut Target
512    ) -> Result<(), Target::AppendError> {
513        self.key.compose(target)?;
514        self.compose_len().compose(target)?;
515        self.compose_value(target)
516    }
517}
518
519impl<Octs> UnknownSvcParam<Octs> {
520    /// Returns the key of the value.
521    pub fn key(&self) -> SvcParamKey {
522        self.key
523    }
524
525    /// Returns a reference to the value octets.
526    pub fn value(&self) -> &Octs {
527        &self.value
528    }
529 
530    /// Returns a slice of the value.
531    pub fn as_slice(&self) -> &[u8]
532    where Octs: AsRef<[u8]> {
533        self.value.as_ref()
534    }
535 
536    /// Returns a mutable slice of the value.
537    pub fn as_slice_mut(&mut self) -> &mut [u8]
538    where Octs: AsMut<[u8]> {
539        self.value.as_mut()
540    }
541}
542
543//--- AsRef and AsMut
544
545impl<Octs> AsRef<Octs> for UnknownSvcParam<Octs> {
546    fn as_ref(&self) -> &Octs {
547        self.value()
548    }
549}
550
551impl<Octs: AsRef<[u8]>> AsRef<[u8]> for UnknownSvcParam<Octs> {
552    fn as_ref(&self) -> &[u8] {
553        self.as_slice()
554    }
555}
556
557impl<Octs: AsMut<[u8]>> AsMut<[u8]> for UnknownSvcParam<Octs> {
558    fn as_mut(&mut self) -> &mut [u8] {
559        self.as_slice_mut()
560    }
561}
562
563//--- PartialEq and Eq
564
565impl<Octs, OtherOcts> PartialEq<UnknownSvcParam<OtherOcts>>
566for UnknownSvcParam<Octs>
567where
568    Octs: AsRef<[u8]>,
569    OtherOcts: AsRef<[u8]>,
570{
571    fn eq(&self, other: &UnknownSvcParam<OtherOcts>) -> bool {
572        self.as_slice().eq(other.as_slice())
573    }
574}
575
576impl<Octs: AsRef<[u8]>> Eq for UnknownSvcParam<Octs> { }
577
578//--- Hash
579
580impl<Octs: AsRef<[u8]>> hash::Hash for UnknownSvcParam<Octs> {
581    fn hash<H: hash::Hasher>(&self, state: &mut H) {
582        self.as_slice().hash(state)
583    }
584}
585
586//--- SvcParamValue et al.
587
588impl<Octs> SvcParamValue for UnknownSvcParam<Octs> {
589    fn key(&self) -> SvcParamKey {
590        self.key
591    }
592}
593
594impl<'a, Octs: Octets + ?Sized> ParseSvcParamValue<'a, Octs>
595for UnknownSvcParam<Octs::Range<'a>> {
596    fn parse_value(
597        key: SvcParamKey,
598        parser: &mut Parser<'a, Octs>,
599    ) -> Result<Option<Self>, ParseError> {
600        Self::new(
601            key, parser.parse_octets(parser.remaining())?
602        ).map(Some).map_err(Into::into)
603    }
604}
605
606impl<Octs: AsRef<[u8]>> ComposeSvcParamValue for UnknownSvcParam<Octs> {
607    fn compose_len(&self) -> u16 {
608        u16::try_from(self.as_slice().len()).expect("long value")
609    }
610
611    fn compose_value<Target: OctetsBuilder + ?Sized>(
612        &self, target: &mut Target,
613    ) -> Result<(), Target::AppendError> {
614        target.append_slice(self.as_slice())
615    }
616}
617
618//--- Display and Debug
619
620impl<Octs: AsRef<[u8]>> fmt::Display for UnknownSvcParam<Octs> {
621    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
622        write!(f, "{}", self.key)?;
623        let slice = self.value.as_ref();
624        if !slice.is_empty() {
625            f.write_str("=")?;
626            for &ch in slice {
627                Symbol::from_octet(ch).fmt(f)?;
628            }
629        }
630        Ok(())
631    }
632}
633
634
635//------------ SvcParamsBuilder ----------------------------------------------
636
637/// A builder for a service parameter sequence.
638///
639/// This type wraps an octets builder and allows appending parameter values.
640/// You can create a new empty builder using the [`empty`][Self::empty]
641/// function or copy an existing value through
642/// [`from_params`][Self::from_params].
643///
644/// You can add additional values using the [`push`][Self::push] method.
645/// There are also dedicated methods for all known value types. The builder
646/// will make sure that each parameter key can only appear once. Thus,
647/// pushing values may fail if a value is already present.
648///
649/// The builder also takes care of sorting the values into their correct
650/// order. So you can push them in any order.
651///
652/// It only sorts the items when producing a frozen value via the
653/// [`freeze`][Self::freeze] method.
654#[derive(Clone, Debug)]
655pub struct SvcParamsBuilder<Octs> {
656    /// The octets builder.
657    octets: Octs,
658}
659
660impl<Octs> SvcParamsBuilder<Octs> {
661    /// Creates an empty parameter builder.
662    #[must_use]
663    pub fn empty() -> Self
664    where Octs: EmptyBuilder {
665        Self { octets: Octs::empty() }
666    }
667
668    /// Creates a parameter builder from an existing parameter sequence.
669    ///
670    /// The function creates a new empty builder and copies over the content
671    /// of `params`. It can fail if the octets builder is not capable of
672    /// providing enough space to hold the content of `params`.
673    pub fn from_params<Src: Octets + ?Sized>(
674        params: &SvcParams<Src>
675    ) -> Result<Self, ShortBuf>
676    where Octs: AsRef<[u8]> + OctetsBuilder + EmptyBuilder {
677        let mut octets = Octs::empty();
678        for item in params.iter::<UnknownSvcParam<_>>() {
679            let item = item.expect("invalid SvcParams");
680            let start = u32::try_from(
681                octets.as_ref().len()
682            ).map_err(|_| ShortBuf)?.checked_add(
683                u32::from(u32::COMPOSE_LEN)
684            ).ok_or(ShortBuf)?;
685            octets.append_slice(
686                start.to_ne_bytes().as_ref()
687            ).map_err(Into::into)?;
688            item.compose_param(&mut octets).map_err(Into::into)?;
689        }
690        octets.append_slice(
691            u32::MAX.to_be_bytes().as_ref()
692        ).map_err(Into::into)?;
693        Ok(Self { octets })
694    }
695
696    /// Adds a new value to the builder.
697    ///
698    /// The method will return an error if a value with this key is already
699    /// present or if there isn’t enough space left in the builder’s buffer.
700    pub fn push<Value: ComposeSvcParamValue + ?Sized>(
701        &mut self, value: &Value
702    ) -> Result<(), PushError>
703    where Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]> {
704        self.push_raw(
705            value.key(), value.compose_len(), |octs| value.compose_value(octs)
706        )
707    }
708
709    pub(super) fn push_raw(
710        &mut self,
711        key: SvcParamKey,
712        value_len: u16,
713        value: impl FnOnce(&mut Octs) -> Result<(), Octs::AppendError>
714    ) -> Result<(), PushError>
715    where Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]> {
716        // If octets is emtpy, we can just append ourselves and be done.
717        if self.octets.as_ref().is_empty() {
718            self.octets.append_slice(
719                &u32::from(u32::COMPOSE_LEN).to_ne_bytes()
720            )?;
721            key.compose(&mut self.octets)?;
722            value_len.compose(&mut self.octets)?;
723            (value)(&mut self.octets)?;
724            u32::MAX.compose(&mut self.octets)?;
725            return Ok(())
726        }
727
728        // Where will this value start? This also serves as a check whether
729        // we have become too long.
730        let start = u32::try_from(self.octets.as_ref().len()).map_err(|_|
731            PushError::ShortBuf
732        )?;
733
734        // Go over the values and find the predecessor and successor.
735        let mut pre = None;
736        let mut next = None;
737        let mut parser = Parser::from_ref(self.octets.as_ref());
738
739        // Skip the first pointer.
740        parser.advance(u32::COMPOSE_LEN.into()).unwrap();
741
742        while parser.remaining() > 0 {
743            let tmp_start = u32::try_from(parser.pos()).unwrap();
744            let tmp = UnknownSvcParam::parse_param(&mut parser).unwrap();
745            let tmp_end = u32::try_from(parser.pos()).unwrap();
746            let tmp_key = tmp.key();
747            match tmp_key.cmp(&key) {
748                Ordering::Equal => return Err(PushError::DuplicateKey),
749                Ordering::Less => {
750                    match pre {
751                        Some((key, _)) => {
752                            if tmp_key > key {
753                                pre = Some((tmp_key, tmp_end));
754                            }
755                        }
756                        None => {
757                            pre = Some((tmp_key, tmp_end))
758                        }
759                    }
760                }
761                Ordering::Greater => {
762                    match next {
763                        Some((key, _)) => {
764                            if tmp_key < key {
765                                next = Some((tmp_key, tmp_start));
766                            }
767                         }
768                        None => {
769                            next = Some((tmp_key, tmp_start))
770                        }
771                    }
772                }
773            }
774            parser.advance(u32::COMPOSE_LEN.into()).unwrap();
775        }
776
777        // Append the value.
778        key.compose(&mut self.octets)?;
779        value_len.compose(&mut self.octets)?;
780        (value)(&mut self.octets)?;
781
782        // Append the pointer to the next value. MAX means none.
783        self.octets.append_slice(
784            &next.map(|(_, pos)| pos).unwrap_or(u32::MAX).to_ne_bytes()
785        )?;
786
787        // Replace the predecessor’s point with our start. If there is no
788        // predecessor, we are the first item.
789        let pos = pre.map(|(_, pos)| {
790            // The u32 here was made from a usize so converting it back has to
791            // work.
792            usize::try_from(pos).unwrap()
793        }).unwrap_or(0);
794        self.octets.as_mut()[
795            pos..pos + usize::from(u32::COMPOSE_LEN)
796        ].copy_from_slice(
797            &start.to_ne_bytes()
798        );
799
800        Ok(())
801    }
802
803    /// Freezes the builder to a parameter sequence.
804    ///
805    /// Because the values may need to be resorted, this method actually
806    /// produces a new octets sequence. This is why it doesn’t consume the
807    /// builder and may fail if the target octet’s builder can’t provide
808    /// enough space.
809    pub fn freeze<Target>(
810        &self
811    ) -> Result<
812        SvcParams<Target>,
813        <<Target as FromBuilder>::Builder as OctetsBuilder>::AppendError
814    >
815    where
816        Octs: AsRef<[u8]>,
817        Target: FromBuilder,
818        <Target as FromBuilder>::Builder: OctetsBuilder + EmptyBuilder
819    {
820        let mut target = <Target as FromBuilder>::Builder::empty();
821        if !self.octets.as_ref().is_empty() {
822            let mut parser = Parser::from_ref(self.octets.as_ref());
823            loop {
824                let pos = u32::from_ne_bytes(
825                    Parse::parse(&mut parser).unwrap()
826                );
827                if pos == u32::MAX {
828                    break;
829                }
830                let pos = usize::try_from(pos).unwrap();
831                parser.seek(pos).unwrap();
832                let param = UnknownSvcParam::parse_param(&mut parser).unwrap();
833                param.compose_param(&mut target)?;
834            }
835        }
836        Ok(unsafe {
837            SvcParams::from_octets_unchecked(
838                Target::from_builder(target)
839            )
840        })
841    }
842}
843
844//============ Error Types ===================================================
845
846//------------ SvcParamsError -----------------------------------------------
847
848/// An octets sequence was not a valid service bindings parameter sequence.
849pub struct SvcParamsError(ParseError);
850
851impl From<ShortInput> for SvcParamsError {
852    fn from(err: ShortInput) -> Self {
853        ParseError::from(err).into()
854    }
855}
856    
857impl From<ParseError> for SvcParamsError {
858    fn from(err: ParseError) -> Self {
859        SvcParamsError(err)
860    }
861}
862
863impl From<SvcParamsError> for ParseError {
864    fn from(err: SvcParamsError) -> Self {
865        err.0
866    }
867}
868
869//------------ LongSvcParam --------------------------------------------------
870
871/// The octets sequence to be used for record data is too long.
872#[derive(Clone, Copy, Debug)]
873pub struct LongSvcParam(());
874
875impl LongSvcParam {
876    #[must_use]
877    pub fn as_str(self) -> &'static str {
878        "service parameter too long"
879    }
880
881    pub fn check_len(len: usize) -> Result<(), Self> {
882        if len > usize::from(u16::MAX) {
883            Err(LongSvcParam(()))
884        } else {
885            Ok(())
886        }
887    }
888}
889
890impl From<LongSvcParam> for ParseError {
891    fn from(src: LongSvcParam) -> Self {
892        ParseError::form_error(src.as_str())
893    }
894}
895
896impl fmt::Display for LongSvcParam {
897    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
898        f.write_str(self.as_str())
899    }
900}
901
902#[cfg(feature = "std")]
903impl std::error::Error for LongSvcParam {}
904
905
906//------------ PushError -----------------------------------------------------
907
908/// An error happened when pushing values to a parameters builder.
909#[derive(Clone, Copy, Debug)]
910#[non_exhaustive]
911pub enum PushError {
912    /// A value with this key is already present.
913    DuplicateKey,
914
915    /// The octets builder does not have enough space to append the value.
916    ShortBuf,
917}
918
919impl<T: Into<ShortBuf>> From<T> for PushError {
920    fn from(_: T) -> Self {
921        PushError::ShortBuf
922    }
923}
924
925impl fmt::Display for PushError {
926    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
927        match self {
928            PushError::DuplicateKey => f.write_str("duplicate key"),
929            PushError::ShortBuf => ShortBuf.fmt(f)
930        }
931    }
932}
933
934#[cfg(feature = "std")]
935impl std::error::Error for PushError {}
936
937
938//============ Tests =========================================================
939
940#[cfg(test)]
941mod test {
942    use super::*;
943    use super::super::value;
944    use octseq::array::Array;
945
946    type Octets512 = Array<512>;
947    type Params512 = SvcParams<Array<512>>;
948    type Builder512 = SvcParamsBuilder<Array<512>>;
949
950    fn octets512(slice: impl AsRef<[u8]>) -> Octets512 {
951        Octets512::try_from(slice.as_ref()).unwrap()
952    }
953
954
955    //--- Test vectors from the draft.
956    //
957    // We’re only testing the parameter portion here.
958
959    macro_rules! parse_compose {
960        ( $rdata:expr, [ $( $value:expr )* ] ) => {
961            // parse test
962            let mut parser = Parser::from_ref($rdata.as_ref());
963            let params = SvcParams::parse(&mut parser).unwrap();
964
965            let mut param_iter = params.iter_all();
966            $(
967                assert_eq!(
968                    param_iter.next().unwrap().unwrap(),
969                    AllValues::<Octets512>::from($value)
970                );
971            )*
972            assert_eq!(None, param_iter.next());
973
974            // compose test
975            let built = Params512::from_values(|_builder| {
976                $(
977                    _builder.push(&$value).unwrap();
978                )*
979                Ok(())
980            }).unwrap();
981            let mut buf = Octets512::new();
982            built.compose(&mut buf).unwrap();
983            assert_eq!($rdata.as_ref(), buf.as_ref());
984        }
985    }
986
987    #[test]
988    fn test_vectors_alias() {
989        parse_compose!(b"", []);
990    }
991
992    #[test]
993    fn test_vectors_port_only() {
994        parse_compose!(
995            b"\x00\x03\
996              \x00\x02\
997              \x00\x35",
998            [ value::Port::new(53) ]
999        );
1000    }
1001
1002    #[test]
1003    fn test_vectors_unknown_param() {
1004        parse_compose!(
1005            b"\x02\x9b\
1006              \x00\x05\
1007              \x68\x65\x6c\x6c\x6f",
1008            [
1009                UnknownSvcParam::new(
1010                    0x029b.into(),
1011                    octets512(b"hello")
1012                ).unwrap()
1013            ]
1014        );
1015    }
1016
1017    #[test]
1018    fn test_vectors_unknown_param_quote() {
1019        parse_compose!(
1020            b"\x02\x9b\
1021              \x00\x09\
1022              \x68\x65\x6c\x6c\x6f\xd2\x71\x6f\x6f",
1023            [
1024                UnknownSvcParam::new(
1025                    0x029b.into(),
1026                    octets512(b"\x68\x65\x6c\x6c\x6f\xd2\x71\x6f\x6f"),
1027                ).unwrap()
1028            ]
1029        );
1030    }
1031
1032    #[test]
1033    fn test_vectors_ipv6hint() {
1034        use crate::base::net::Ipv6Addr;
1035        use core::str::FromStr;
1036
1037        parse_compose!(
1038            b"\x00\x06\
1039              \x00\x20\
1040              \x20\x01\x0d\xb8\x00\x00\x00\x00\
1041              \x00\x00\x00\x00\x00\x00\x00\x01\
1042              \x20\x01\x0d\xb8\x00\x00\x00\x00\
1043              \x00\x00\x00\x00\x00\x53\x00\x01",
1044            [
1045                value::Ipv6Hint::<Octets512>::from_addrs([
1046                    Ipv6Addr::from_str("2001:db8::1").unwrap(),
1047                    Ipv6Addr::from_str("2001:db8::53:1").unwrap(),
1048                ]).unwrap()
1049            ]
1050        );
1051    }
1052
1053    #[test]
1054    fn test_vectors_ipv6hint_v4mapped() {
1055        use crate::base::net::Ipv6Addr;
1056        use core::str::FromStr;
1057
1058        parse_compose!(
1059            b"\x00\x06\
1060              \x00\x10\
1061              \x00\x00\x00\x00\x00\x00\x00\x00\
1062              \x00\x00\xff\xff\xc6\x33\x64\x64",
1063            [
1064                value::Ipv6Hint::<Octets512>::from_addrs([
1065                    Ipv6Addr::from_str("::ffff:198.51.100.100").unwrap(),
1066                ]).unwrap()
1067            ]
1068        );
1069    }
1070
1071    // test vector key_sorting: see builder tests below
1072    // test vector alpn_escape: see super::value::test
1073
1074    #[cfg(feature = "std")]
1075    #[test]
1076    fn test_representation() {
1077        use crate::base::iana::svcb::SVC_PARAM_KEY_PRIVATE_RANGE_BEGIN;
1078
1079        let mandatory = value::Mandatory::<Octets512>::from_keys(
1080            [
1081                SvcParamKey::Alpn,
1082                SvcParamKey::Ipv4Hint,
1083                SVC_PARAM_KEY_PRIVATE_RANGE_BEGIN.into()
1084            ].into_iter()
1085        ).unwrap();
1086        assert_eq!(
1087            "mandatory=alpn,ipv4hint,key65280",
1088            format!("{}", mandatory)
1089        );
1090
1091        let mut alpn_builder = value::AlpnBuilder::<Octets512>::empty();
1092        alpn_builder.push("h2").unwrap();
1093        alpn_builder.push("h3-19").unwrap();
1094        assert_eq!(
1095            "alpn=h2,h3-19",
1096            format!("{}", alpn_builder.freeze())
1097        );
1098
1099        assert_eq!("nodefaultalpn", format!("{}", value::NoDefaultAlpn));
1100
1101        assert_eq!(
1102            "ech",
1103            format!(
1104                "{}",
1105                value::Ech::from_octets(Octets512::new()).unwrap()
1106            )
1107        );
1108
1109        assert_eq!(
1110            "ipv4hint=192.0.2.1,192.0.2.2",
1111            format!(
1112                "{}",
1113                value::Ipv4Hint::<Octets512>::from_addrs(
1114                    [
1115                        [192, 0, 2, 1].into(), [192, 0, 2, 2].into()
1116                    ]
1117                ).unwrap()
1118            )
1119        );
1120    }
1121
1122
1123    //--- Builder
1124
1125    #[test]
1126    fn empty_builder() {
1127        assert_eq!(
1128            Builder512::empty().freeze::<Octets512>().unwrap().as_slice(),
1129            b""
1130        );
1131    }
1132
1133    #[test]
1134    fn one_value() {
1135        let mut builder = Builder512::empty();
1136        builder.push(&value::Port::new(53)).unwrap();
1137        assert_eq!(
1138            builder.freeze::<Octets512>().unwrap().as_slice(),
1139            b"\x00\x03\x00\x02\x00\x35"
1140        );
1141    }
1142
1143    #[test]
1144    fn three_values_in_order() {
1145        let mut builder = Builder512::empty();
1146        builder.push(
1147            &UnknownSvcParam::new(1.into(), b"223").unwrap()
1148        ).unwrap();
1149        builder.push(
1150            &UnknownSvcParam::new(2.into(), b"224").unwrap()
1151        ).unwrap();
1152        builder.push(
1153            &UnknownSvcParam::new(8.into(), b"225").unwrap()
1154        ).unwrap();
1155        assert_eq!(
1156            builder.freeze::<Octets512>().unwrap().as_slice(),
1157            b"\x00\x01\x00\x03223\
1158              \x00\x02\x00\x03224\
1159              \x00\x08\x00\x03225"
1160        );
1161    }
1162
1163    #[test]
1164    fn three_values_out_of_order() {
1165        let mut builder = Builder512::empty();
1166        builder.push(
1167            &UnknownSvcParam::new(1.into(), b"223").unwrap()
1168        ).unwrap();
1169        builder.push(
1170            &UnknownSvcParam::new(8.into(), b"225").unwrap()
1171        ).unwrap();
1172        builder.push(
1173            &UnknownSvcParam::new(2.into(), b"224").unwrap()
1174        ).unwrap();
1175        assert_eq!(
1176            builder.freeze::<Octets512>().unwrap().as_slice(),
1177            b"\x00\x01\x00\x03223\
1178              \x00\x02\x00\x03224\
1179              \x00\x08\x00\x03225"
1180        );
1181    }
1182
1183    #[test]
1184    fn three_values_with_collision() {
1185        let mut builder = Builder512::empty();
1186        builder.push(
1187            &UnknownSvcParam::new(1.into(), b"223").unwrap()
1188        ).unwrap();
1189        builder.push(
1190            &UnknownSvcParam::new(8.into(), b"225").unwrap()
1191        ).unwrap();
1192        assert!(
1193            builder.push(
1194                &UnknownSvcParam::new(8.into(), b"224").unwrap()
1195            ).is_err()
1196        );
1197    }
1198}
1199