Skip to content

Commit

Permalink
Reuse more hickory_proto types
Browse files Browse the repository at this point in the history
  • Loading branch information
jcgruenhage committed Oct 22, 2024
1 parent f89b40a commit 1a25fbc
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 164 deletions.
81 changes: 5 additions & 76 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ use core::fmt;
use std::{
borrow::Cow,
fmt::{Display, Formatter},
net::{Ipv4Addr, Ipv6Addr},
str::FromStr,
time::Duration,
};

use hickory_client::proto::rr::dnssec::{KeyPair, Private};
use hickory_proto::rr::RData;
use providers::{
cloudflare::{CloudflareConfig, CloudflareProvider},
rfc2136::{DnsAddress, Rfc2136Config, Rfc2136Provider},
Expand All @@ -29,6 +28,8 @@ use thiserror::Error;
pub mod http;
pub mod providers;

pub use hickory_proto::rr::dnssec::{rdata::tsig::TsigAlgorithm, Algorithm};

#[derive(Debug, Error)]
pub enum Error {
Protocol(String),
Expand All @@ -41,58 +42,6 @@ pub enum Error {
NotFound,
}

/// A DNS record type.
pub enum DnsRecord {
A {
content: Ipv4Addr,
},
AAAA {
content: Ipv6Addr,
},
CNAME {
content: String,
},
NS {
content: String,
},
MX {
content: String,
priority: u16,
},
TXT {
content: String,
},
SRV {
content: String,
priority: u16,
weight: u16,
port: u16,
},
}

/// A TSIG algorithm.
pub enum TsigAlgorithm {
HmacMd5,
Gss,
HmacSha1,
HmacSha224,
HmacSha256,
HmacSha256_128,
HmacSha384,
HmacSha384_192,
HmacSha512,
HmacSha512_256,
}

/// A DNSSEC algorithm.
pub enum Algorithm {
RSASHA256,
RSASHA512,
ECDSAP256SHA256,
ECDSAP384SHA384,
ED25519,
}

pub type Result<T> = std::result::Result<T, Error>;

#[derive(Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -174,7 +123,7 @@ impl DnsUpdater {
pub async fn create(
&self,
name: impl IntoFqdn<'_>,
record: DnsRecord,
record: RData,
ttl: u32,
origin: impl IntoFqdn<'_>,
) -> crate::Result<()> {
Expand All @@ -188,7 +137,7 @@ impl DnsUpdater {
pub async fn update(
&self,
name: impl IntoFqdn<'_>,
record: DnsRecord,
record: RData,
ttl: u32,
origin: impl IntoFqdn<'_>,
) -> crate::Result<()> {
Expand Down Expand Up @@ -257,26 +206,6 @@ impl<'x> IntoFqdn<'x> for String {
}
}

impl FromStr for TsigAlgorithm {
type Err = ();

fn from_str(s: &str) -> std::prelude::v1::Result<Self, Self::Err> {
match s {
"hmac-md5" => Ok(TsigAlgorithm::HmacMd5),
"gss" => Ok(TsigAlgorithm::Gss),
"hmac-sha1" => Ok(TsigAlgorithm::HmacSha1),
"hmac-sha224" => Ok(TsigAlgorithm::HmacSha224),
"hmac-sha256" => Ok(TsigAlgorithm::HmacSha256),
"hmac-sha256-128" => Ok(TsigAlgorithm::HmacSha256_128),
"hmac-sha384" => Ok(TsigAlgorithm::HmacSha384),
"hmac-sha384-192" => Ok(TsigAlgorithm::HmacSha384_192),
"hmac-sha512" => Ok(TsigAlgorithm::HmacSha512),
"hmac-sha512-256" => Ok(TsigAlgorithm::HmacSha512_256),
_ => Err(()),
}
}
}

impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Expand Down
63 changes: 46 additions & 17 deletions src/providers/cloudflare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ use std::{
time::Duration,
};

use hickory_proto::rr::RData;
use serde::{Deserialize, Serialize};
use serde_json::Value;

use crate::{http::HttpClientBuilder, DnsRecord, Error, IntoFqdn};
use crate::{http::HttpClientBuilder, Error, IntoFqdn};

#[derive(Clone, Serialize, Deserialize)]
pub struct CloudflareConfig {
Expand Down Expand Up @@ -162,7 +163,7 @@ impl CloudflareProvider {
pub(crate) async fn create(
&self,
name: impl IntoFqdn<'_>,
record: DnsRecord,
rdata: RData,
ttl: u32,
origin: impl IntoFqdn<'_>,
) -> crate::Result<()> {
Expand All @@ -173,10 +174,14 @@ impl CloudflareProvider {
))
.with_body(CreateDnsRecordParams {
ttl: ttl.into(),
priority: record.priority(),
priority: match &rdata {
RData::MX(mx) => Some(mx.preference()),
RData::SRV(srv) => Some(srv.priority()),
_ => None,
},
proxied: false.into(),
name: name.into_name().as_ref(),
content: record.into(),
content: rdata.try_into()?,
})?
.send::<ApiResult<Value>>()
.await
Expand All @@ -187,7 +192,7 @@ impl CloudflareProvider {
pub(crate) async fn update(
&self,
name: impl IntoFqdn<'_>,
record: DnsRecord,
rdata: RData,
ttl: u32,
origin: impl IntoFqdn<'_>,
) -> crate::Result<()> {
Expand All @@ -202,7 +207,7 @@ impl CloudflareProvider {
ttl: ttl.into(),
proxied: None,
name: name.as_ref(),
content: record.into(),
content: rdata.try_into()?,
})?
.send::<ApiResult<Value>>()
.await
Expand Down Expand Up @@ -252,16 +257,40 @@ impl Query {
}
}

impl From<DnsRecord> for DnsContent {
fn from(record: DnsRecord) -> Self {
match record {
DnsRecord::A { content } => DnsContent::A { content },
DnsRecord::AAAA { content } => DnsContent::AAAA { content },
DnsRecord::CNAME { content } => DnsContent::CNAME { content },
DnsRecord::NS { content } => DnsContent::NS { content },
DnsRecord::MX { content, priority } => DnsContent::MX { content, priority },
DnsRecord::TXT { content } => DnsContent::TXT { content },
DnsRecord::SRV { content, .. } => DnsContent::SRV { content },
}
impl TryFrom<RData> for DnsContent {
type Error = crate::Error;

fn try_from(rdata: RData) -> crate::Result<Self> {
Ok(match rdata {
RData::A(a) => DnsContent::A { content: a.0 },
RData::AAAA(aaaa) => DnsContent::AAAA { content: aaaa.0 },
RData::CNAME(cname) => DnsContent::CNAME {
content: cname.0.to_utf8(),
},
RData::MX(mx) => DnsContent::MX {
content: mx.exchange().to_utf8(),
priority: mx.preference(),
},
RData::NS(ns) => DnsContent::NS {
content: ns.0.to_utf8(),
},
RData::SRV(srv) => DnsContent::SRV {
content: format!(
"{} {} {} {}",
srv.priority(),
srv.weight(),
srv.port(),
srv.target()
),
},
RData::TXT(txt) => DnsContent::TXT {
content: format!("{txt}"),
},
rdata => {
return Err(crate::Error::Serialize(format!(
"Failed to turn record {rdata} into cloudflare DnsContent",
)))
}
})
}
}
12 changes: 0 additions & 12 deletions src/providers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,5 @@
* except according to those terms.
*/

use crate::DnsRecord;

pub mod cloudflare;
pub mod rfc2136;

impl DnsRecord {
pub fn priority(&self) -> Option<u16> {
match self {
DnsRecord::MX { priority, .. } => Some(*priority),
DnsRecord::SRV { priority, .. } => Some(*priority),
_ => None,
}
}
}
62 changes: 3 additions & 59 deletions src/providers/rfc2136.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,14 @@ use hickory_client::udp::UdpClientConnection;
use hickory_proto::op::ResponseCode;
use hickory_proto::rr::dnssec::rdata::tsig::TsigAlgorithm;
use hickory_proto::rr::dnssec::rdata::KEY;
use hickory_proto::rr::rdata::{A, AAAA, CNAME, MX, NS, SRV, TXT};
use hickory_proto::rr::{DNSClass, Name, RData, Record};
use hickory_proto::runtime::TokioRuntimeProvider;

use serde::{Deserialize, Serialize};
use serde_with::base64::Base64;
use serde_with::serde_as;

use crate::{DnsRecord, Error, IntoFqdn};
use crate::{Error, IntoFqdn};

#[derive(Clone, Serialize, Deserialize)]
pub struct Rfc2136Config {
Expand Down Expand Up @@ -161,11 +160,10 @@ impl Rfc2136Provider {
pub(crate) async fn create(
&self,
name: impl IntoFqdn<'_>,
record: DnsRecord,
rdata: RData,
ttl: u32,
origin: impl IntoFqdn<'_>,
) -> crate::Result<()> {
let rdata = convert_record(record)?;
let record = Record::from_rdata(
Name::from_str_relaxed(name.into_name().as_ref())?,
ttl,
Expand All @@ -186,11 +184,10 @@ impl Rfc2136Provider {
pub(crate) async fn update(
&self,
name: impl IntoFqdn<'_>,
record: DnsRecord,
rdata: RData,
ttl: u32,
origin: impl IntoFqdn<'_>,
) -> crate::Result<()> {
let rdata = convert_record(record)?;
let record = Record::from_rdata(
Name::from_str_relaxed(name.into_name().as_ref())?,
ttl,
Expand Down Expand Up @@ -233,30 +230,6 @@ impl Rfc2136Provider {
}
}

fn convert_record(record: DnsRecord) -> crate::Result<RData> {
Ok(match record {
DnsRecord::A { content } => RData::A(A::from(content)),
DnsRecord::AAAA { content } => RData::AAAA(AAAA::from(content)),
DnsRecord::CNAME { content } => RData::CNAME(CNAME(Name::from_str_relaxed(content)?)),
DnsRecord::NS { content } => RData::NS(NS(Name::from_str_relaxed(content)?)),
DnsRecord::MX { content, priority } => {
RData::MX(MX::new(priority, Name::from_str_relaxed(content)?))
}
DnsRecord::TXT { content } => RData::TXT(TXT::new(vec![content])),
DnsRecord::SRV {
content,
priority,
weight,
port,
} => RData::SRV(SRV::new(
priority,
weight,
port,
Name::from_str_relaxed(content)?,
)),
})
}

impl TryFrom<&str> for DnsAddress {
type Error = ();

Expand Down Expand Up @@ -310,35 +283,6 @@ impl TryFrom<String> for DnsAddress {
}
}

impl From<crate::TsigAlgorithm> for TsigAlgorithm {
fn from(alg: crate::TsigAlgorithm) -> Self {
match alg {
crate::TsigAlgorithm::HmacMd5 => TsigAlgorithm::HmacMd5,
crate::TsigAlgorithm::Gss => TsigAlgorithm::Gss,
crate::TsigAlgorithm::HmacSha1 => TsigAlgorithm::HmacSha1,
crate::TsigAlgorithm::HmacSha224 => TsigAlgorithm::HmacSha224,
crate::TsigAlgorithm::HmacSha256 => TsigAlgorithm::HmacSha256,
crate::TsigAlgorithm::HmacSha256_128 => TsigAlgorithm::HmacSha256_128,
crate::TsigAlgorithm::HmacSha384 => TsigAlgorithm::HmacSha384,
crate::TsigAlgorithm::HmacSha384_192 => TsigAlgorithm::HmacSha384_192,
crate::TsigAlgorithm::HmacSha512 => TsigAlgorithm::HmacSha512,
crate::TsigAlgorithm::HmacSha512_256 => TsigAlgorithm::HmacSha512_256,
}
}
}

impl From<crate::Algorithm> for Algorithm {
fn from(alg: crate::Algorithm) -> Self {
match alg {
crate::Algorithm::RSASHA256 => Algorithm::RSASHA256,
crate::Algorithm::RSASHA512 => Algorithm::RSASHA512,
crate::Algorithm::ECDSAP256SHA256 => Algorithm::ECDSAP256SHA256,
crate::Algorithm::ECDSAP384SHA384 => Algorithm::ECDSAP384SHA384,
crate::Algorithm::ED25519 => Algorithm::ED25519,
}
}
}

impl From<ProtoError> for Error {
fn from(e: ProtoError) -> Self {
Error::Protocol(e.to_string())
Expand Down

0 comments on commit 1a25fbc

Please sign in to comment.