1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
//! Domain names. //! //! This module contains various types for working with domain names. //! //! Domain names are a sequence of *labels.* For the most part, labels are //! in turn a sequence of up to 63 octets. While they are limited to ASCII //! by convention, all values are allowed. In their wire-format representation //! labels are prefixed with an octet containing the the number of octets //! in the label. The labels in a domain name are nominally arranged //! backwards. That is, the ‘most significant’ label is the last one. In an //! *absolute* domain name, this last label is an empty label, often called //! the *root label.* Only absolute names can appear inside DNS messages. //! //! There are two twists to this: One are binary labels which essentially //! encode a sequence of one-bit labels, are somewhat esoteric, and have been //! declared historic. The other is name compression. In order to save //! space in DNS messages (which were originally limited to 512 bytes for //! most cases), a name can end in a pointer to another name stored //! elsewhere in the message. This makes lazy message parsing somewhat //! difficult since you need to carry around a reference to the original //! message until actual parsing happens. //! //! This is why there are three types for domain names in this module. Two //! types represent uncompressed domain names encoded in their wire format //! atop a bytes sequence. The [`DNameSlice`] type is a slice of a domain //! name akin to a `[u8]`. It is an unsized type and will have to be used //! behind a pointer, typically a reference. The [`DNameBuf`] type acts as //! its owned companion. Similar to the relationship between `[u8]` and a //! `Vec<u8>` it derefs to a [`DNameSlice`] and provides facilities to //! manipulate domain names. Both types can contain either absolute or //! relative domain names. //! //! A compressed domain name can only occur in a parsed DNS message. //! Accordingly, its type is called [`ParsedDName`]. It internally holds a //! reference to the message it was parsed from. There’s only two things you //! can do with a parsed domain name: convert it into a regular domain name //! and iterate over its labels. Luckily, though, the latter is good enough //! for comparing them to other domain names. //! //! Creating data structures that can use both [`DNameSlice`] and [`DNameBuf`] //! can be achieved by being generic over `AsRef<DNameSlice>` as `AsRef` is //! implemented both for `&DNameSlice` and `DNameBuf`. In order to allow //! types that allow [`ParsedDName`] as well, there is an additional trait //! [`DName`]. Naturally, the functionality provided by it is limited to //! what [`ParsedDName`] can do: conversion into a regular domain name and //! iteration over labels. //! //! # TODO //! //! - Implement an optimization where there is an optional first byte with //! the unallocated label type 0b10 that indicates whether the name is //! absolute or relative (ie., 0x80 means absolute and 0x81 relative and //! everything else means this really is the first byte of the domain //! name). //! //! [`DName`]: trait.DName.html //! [`DNameSlice`]: struct.DNameSlice.html //! [`DNameBuf`]: struct.DNameBuf.html //! [`ParsedDName`]: struct.ParsedDName.html pub use self::builder::{DNameBuilder, DNameBuildInto}; pub use self::dname::DName; pub use self::iter::{NameLabels, NameLabelettes}; pub use self::label::{Label, LabelBuf, LabelContent, Labelette, LabelIter}; pub use self::parsed::ParsedDName; pub use self::plain::{DNameBuf, DNameSlice, FromStrError, PushError, StripSuffixError}; mod builder; mod dname; mod from_str; mod iter; mod label; mod parsed; mod plain;