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