mirror of
https://github.com/NLnetLabs/domain.git
synced 2026-09-13 05:17:45 +02:00
[new/rdata] Add Srv
This commit is contained in:
@@ -43,6 +43,7 @@
|
||||
//! - [`Mx`]
|
||||
//! - [`Txt`]
|
||||
//! - [`Rp`]
|
||||
//! - [`Srv`]
|
||||
//!
|
||||
//! Indirection types:
|
||||
//! - [`CName`]
|
||||
@@ -115,6 +116,9 @@ pub use edns::{EdnsOptionsIter, Opt};
|
||||
mod rp;
|
||||
pub use rp::Rp;
|
||||
|
||||
mod srv;
|
||||
pub use srv::Srv;
|
||||
|
||||
mod dnssec;
|
||||
pub use dnssec::{
|
||||
DNSKey, DNSKeyFlags, DigestType, Ds, NSec, NSec3, NSec3Flags,
|
||||
@@ -280,6 +284,9 @@ define_record_data! {
|
||||
/// Identification of the person/party responsible for this domain.
|
||||
Rp(Rp<N>) = RP,
|
||||
|
||||
/// The locations of services associated with this domain.
|
||||
Srv(&'a Srv) = SRV,
|
||||
|
||||
/// The IPv6 address of a host responsible for this domain.
|
||||
Aaaa(Aaaa) = AAAA,
|
||||
|
||||
@@ -331,6 +338,7 @@ impl<'a, N> RecordData<'a, N> {
|
||||
Self::Txt(r) => RecordData::Txt(r),
|
||||
Self::Rp(r) => RecordData::Rp(r.map_names(f)),
|
||||
Self::Aaaa(r) => RecordData::Aaaa(r),
|
||||
Self::Srv(r) => RecordData::Srv(r),
|
||||
Self::DName(r) => RecordData::DName(r),
|
||||
Self::Opt(r) => RecordData::Opt(r),
|
||||
Self::Ds(r) => RecordData::Ds(r),
|
||||
@@ -360,6 +368,7 @@ impl<'a, N> RecordData<'a, N> {
|
||||
Self::Txt(r) => RecordData::Txt(r),
|
||||
Self::Rp(r) => RecordData::Rp(r.map_names_by_ref(f)),
|
||||
Self::Aaaa(r) => RecordData::Aaaa(*r),
|
||||
Self::Srv(r) => RecordData::Srv(r),
|
||||
Self::DName(r) => RecordData::DName(r),
|
||||
Self::Opt(r) => RecordData::Opt(r),
|
||||
Self::Ds(r) => RecordData::Ds(r),
|
||||
@@ -395,6 +404,7 @@ impl<'a, N> RecordData<'a, N> {
|
||||
Self::Txt(r) => RecordData::Txt(copy_to_bump(*r, bump)),
|
||||
Self::Rp(r) => RecordData::Rp(r.clone()),
|
||||
Self::Aaaa(r) => RecordData::Aaaa(*r),
|
||||
Self::Srv(r) => RecordData::Srv(copy_to_bump(*r, bump)),
|
||||
Self::DName(r) => RecordData::DName(copy_to_bump(*r, bump)),
|
||||
Self::Opt(r) => RecordData::Opt(copy_to_bump(*r, bump)),
|
||||
Self::Ds(r) => RecordData::Ds(copy_to_bump(*r, bump)),
|
||||
@@ -450,6 +460,9 @@ impl<'a, N: SplitMessageBytes<'a>> ParseRecordData<'a> for RecordData<'a, N> {
|
||||
RType::AAAA => {
|
||||
Aaaa::parse_bytes(&contents[start..]).map(Self::Aaaa)
|
||||
}
|
||||
RType::SRV => {
|
||||
<&Srv>::parse_bytes(&contents[start..]).map(Self::Srv)
|
||||
}
|
||||
RType::DNAME => {
|
||||
<&DName>::parse_bytes(&contents[start..]).map(Self::DName)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
//! The SRV record data type.
|
||||
//!
|
||||
//! See [RFC 2782](https://datatracker.ietf.org/doc/html/rfc2782).
|
||||
|
||||
use core::cmp::Ordering;
|
||||
|
||||
use crate::new::base::build::{
|
||||
AsBytes, BuildBytes, BuildInMessage, NameCompressor,
|
||||
};
|
||||
use crate::new::base::name::{CanonicalName, Name};
|
||||
use crate::new::base::wire::*;
|
||||
use crate::new::base::{
|
||||
CanonicalRecordData, ParseRecordData, ParseRecordDataBytes, RType,
|
||||
};
|
||||
use crate::utils::dst::UnsizedCopy;
|
||||
|
||||
//----------- Srv ------------------------------------------------------------
|
||||
|
||||
/// The locations of services associated with this domain.
|
||||
//
|
||||
// TODO: Documentation.
|
||||
#[derive(
|
||||
Debug,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
Hash,
|
||||
AsBytes,
|
||||
BuildBytes,
|
||||
ParseBytesZC,
|
||||
SplitBytesZC,
|
||||
UnsizedCopy,
|
||||
)]
|
||||
#[repr(C)]
|
||||
pub struct Srv {
|
||||
/// The priority of this host.
|
||||
pub priority: U16,
|
||||
|
||||
/// The relative weight for selection of this host.
|
||||
pub weight: U16,
|
||||
|
||||
/// The port number on which the service is provided.
|
||||
pub port: U16,
|
||||
|
||||
/// The domain name of the target host.
|
||||
pub name: Name,
|
||||
}
|
||||
|
||||
//--- Canonical operations
|
||||
|
||||
impl CanonicalRecordData for Srv {
|
||||
fn build_canonical_bytes<'b>(
|
||||
&self,
|
||||
bytes: &'b mut [u8],
|
||||
) -> Result<&'b mut [u8], TruncationError> {
|
||||
let bytes = self.priority.build_bytes(bytes)?;
|
||||
let bytes = self.weight.build_bytes(bytes)?;
|
||||
let bytes = self.port.build_bytes(bytes)?;
|
||||
let bytes = self.name.build_lowercased_bytes(bytes)?;
|
||||
Ok(bytes)
|
||||
}
|
||||
|
||||
fn cmp_canonical(&self, other: &Self) -> Ordering {
|
||||
// `Srv` uses canonical comparisons by default.
|
||||
self.cmp(other)
|
||||
}
|
||||
}
|
||||
|
||||
//--- Building into DNS messages
|
||||
|
||||
impl BuildInMessage for Srv {
|
||||
fn build_in_message(
|
||||
&self,
|
||||
contents: &mut [u8],
|
||||
start: usize,
|
||||
_compressor: &mut NameCompressor,
|
||||
) -> Result<usize, TruncationError> {
|
||||
let bytes = self.as_bytes();
|
||||
let end = start + bytes.len();
|
||||
contents
|
||||
.get_mut(start..end)
|
||||
.ok_or(TruncationError)?
|
||||
.copy_from_slice(bytes);
|
||||
Ok(end)
|
||||
}
|
||||
}
|
||||
|
||||
//--- Cloning
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
impl Clone for alloc::boxed::Box<Srv> {
|
||||
fn clone(&self) -> Self {
|
||||
(*self).unsized_copy_into()
|
||||
}
|
||||
}
|
||||
|
||||
//--- Parsing record data
|
||||
|
||||
impl<'a> ParseRecordData<'a> for &'a Srv {}
|
||||
|
||||
impl<'a> ParseRecordDataBytes<'a> for &'a Srv {
|
||||
fn parse_record_data_bytes(
|
||||
bytes: &'a [u8],
|
||||
rtype: RType,
|
||||
) -> Result<Self, ParseError> {
|
||||
match rtype {
|
||||
RType::SRV => Self::parse_bytes(bytes),
|
||||
_ => Err(ParseError),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user