Expand description
§cdns-rs
v 1.2.0

An implementation of client side DNS query library which also is able to look for host name in /etc/hosts.
Also it is able to /etc/resolv.conf and uses options from this file to configure itself. So it acts like libc’s gethostbyname(3) or gethostbyaddr(3). The configuration can be overriden.
This library supports both async and sync code. At the moment async part is not available because:
- it is based on the sync realization because async code is based on sync code and sync code is unstable at the moment
- it requires proper porting from sync, because sync uses
poll(2)to achieve the parallel name resolution
§Supports
- Sending and receiving responses via TCP/UDP
- Reacting on the message truncated event by trying TCP
- Parsing /etc/hosts (all options)
- Partial parsing /etc/resolve.conf (all options)
- Async and Sync code (separate implementations)
- Sequential and pipelined requests.
- DNS-over-TLS
- IDN international domain names (experimental)
§ToDo
- DNS-over-HTTPS
- Parse /etc/nsswitch.conf
- DNSSEC
- OPT_NO_CHECK_NAMES
- resolv.conf (search, domain, sortlist)
§Extension
To use the DNS-over-TLS, the record to system’s resolv.conf can be added:
nameserver 1.1.1.1#@853#cloudflare-dns.comAll after the # is considered as extension if there is no space between IP address and ‘#’.
§Features
enable_IDN_support - (enabled by default) allows to resolve IDN
use_sync - enabled a sync code base
use_sync_tls - enables a TLS support (HTTPS is not yet functional)
no_error_output - does not output any errors to stderr
One of the following:
use_async- enables an async code baseuse_async_tokio- enablesan async tokio code base
One of the following:
use_async_tls- enables a general TLS support (own implementation out of crate)use_async_tokio_tls- enables a tokio based TLS
Usage:
- see ./examples/
Simple Example:
use std::{net::{IpAddr, SocketAddr}, sync::Arc, time::Instant};
use cdns_rs::{cfg_resolv_parser::{OptionFlags, ResolveConfEntry}, common::bind_all, sync::{request, ResolveConfig}};
fn main()
{
let now = Instant::now();
let cfg =
"nameserver 8.8.8.8 \n\
options use-vc";
// -- or --
let resolver_ip: IpAddr = "8.8.8.8".parse().unwrap();
let mut resolve = ResolveConfig::default();
resolve.nameservers.push(Arc::new(ResolveConfEntry::new(SocketAddr::new(resolver_ip, 53), None, bind_all(resolver_ip)).unwrap()));
resolve.option_flags = OptionFlags::OPT_USE_VC;
let cust_parsed = Arc::new(ResolveConfig::custom_config(cfg).unwrap());
let cust_manual = Arc::new(resolve);
assert_eq!(cust_parsed, cust_manual);
// a, aaaa
let res_a = request::resolve_fqdn("protonmail.com", Some(cust_parsed)).unwrap();
let elapsed = now.elapsed();
println!("Elapsed: {:.2?}", elapsed);
println!("A/AAAA:");
for a in res_a
{
println!("\t{}", a);
}
return;
}ToSockAddr
use std::net::UdpSocket;
use cdns_rs::sync::query::QDnsSockerAddr;
// run in shell `nc -u -l 44444` a "test" should be received
fn main()
{
let udp = UdpSocket::bind("127.0.0.1:33333").unwrap();
udp.connect(QDnsSockerAddr::resolve("localhost:44444").unwrap()).unwrap();
udp.send("test".as_bytes()).unwrap();
return;
}§Custom resolv.conf use TCP:
use std::{net::{IpAddr, SocketAddr}, sync::Arc, time::Instant};
use cdns_rs::{cfg_resolv_parser::{OptionFlags, ResolveConfEntry}, common::bind_all, sync::{request, ResolveConfig}};
fn main()
{
let now = Instant::now();
let cfg =
"nameserver 8.8.8.8 \n\
options use-vc";
// -- or --
let resolver_ip: IpAddr = "8.8.8.8".parse().unwrap();
let mut resolve = ResolveConfig::default();
resolve.nameservers.push(Arc::new(ResolveConfEntry::new(SocketAddr::new(resolver_ip, 53), None, bind_all(resolver_ip)).unwrap()));
resolve.option_flags = OptionFlags::OPT_USE_VC;
let cust_parsed = Arc::new(ResolveConfig::custom_config(cfg).unwrap());
let cust_manual = Arc::new(resolve);
assert_eq!(cust_parsed, cust_manual);
// a, aaaa
let res_a = request::resolve_fqdn("protonmail.com", Some(cust_parsed)).unwrap();
let elapsed = now.elapsed();
println!("Elapsed: {:.2?}", elapsed);
println!("A/AAAA:");
for a in res_a
{
println!("\t{}", a);
}
return;
}§Custom resolv.conf use TLS:
use std::{sync::Arc, time::Instant};
use cdns_rs::sync::{request, ResolveConfig};
fn main()
{
let now = Instant::now();
let cfg = "nameserver 1.1.1.1#@853#cloudflare-dns.com \n\
options use-vc single-request";
let cust = Arc::new(ResolveConfig::custom_config(cfg).unwrap());
// a, aaaa
let res_a = request::resolve_fqdn("google.com", Some(cust.clone())).unwrap();
let elapsed = now.elapsed();
println!("Elapsed: {:.2?}", elapsed);
println!("A/AAAA:");
for a in res_a
{
println!("\t{}", a);
}
return;
}
§Async (tokio) feature = “use_async_tokio”
use std::sync::Arc;
use cdns_rs::a_sync::{request, CachesController, IoInterf, QDns, QType, QuerySetup, ResolveConfig, SocketBase};
use tokio::time::Instant;
#[tokio::main]
async fn main()
{
let cache = Arc::new(CachesController::new().await.unwrap());
let cfg = "nameserver 1.1.1.1";
let cust = Arc::new(ResolveConfig::async_custom_config(cfg).await.unwrap());
let now = Instant::now();
// a, aaaa
let res_a = request::resolve_fqdn::<_, SocketBase, SocketBase, IoInterf>("protonmail.com", Some(cust.clone()), cache.clone()).await.unwrap();
// mx
let res_mx = request::resolve_mx::<_, SocketBase, SocketBase, IoInterf>("protonmail.com", Some(cust.clone()), cache.clone()).await.unwrap();
let mut dns_req =
QDns::<SocketBase, SocketBase, IoInterf>::make_empty(Some(cust.clone()), QuerySetup::default(), cache.clone())
.await
.unwrap();
dns_req.add_request(QType::SOA, "protonmail.com");
// sending request and receiving results
let res = dns_req.query().await;
let elapsed = now.elapsed();
println!("Elapsed: {:.2?}", elapsed);
println!("A/AAAA:");
for a in res_a
{
println!("\t{}", a);
}
println!("MX:");
for mx in res_mx
{
println!("\t{}", mx);
}
println!("SOA:");
let soa_res = res.get_result();
if soa_res.is_err() == true
{
println!("error: {}", soa_res.err().unwrap());
}
else
{
let soa = soa_res.unwrap();
if soa.is_empty() == true
{
println!("\tNo SOA found!")
}
else
{
for s in soa
{
for i in s.resp
{
println!("\t{}", i)
}
}
}
}
}Re-exports§
pub use common::QType;pub use common::DnsResponsePayload;pub use common::DnsRdata;pub use query::QDnsQueryResult;pub use query::QDnsQuery;pub use query::QuerySetup;pub use query::QDnsQueryRec;pub use cfg_host_parser::HostConfig;pub use cfg_resolv_parser::ResolveConfig;pub use error::*;
Modules§
- a_sync
- An
asynccode. - cfg_
host_ parser - A common
hostsfile parser. - cfg_
resolv_ parser - A common
resolv.conffile parser. - common
- A common functions (shared).
- error
- Error handling.
- external
- An external code under the separate license.
- query
- A public items for query.
- sync
- A
synccode.
Macros§
Traits§
- Socket
TapCommon - A common items for bot sync and async. Shhould be implemented by each instance.