pub trait Client {
    type Response: Stream<Item = Result<DnsResponse, ProtoError>> + 'static + Send + Unpin;
    type Handle: DnsHandle<Response = Self::Response, Error = ProtoError> + 'static + Send + Unpin;

    // Required method
    fn new_future(
        &self
    ) -> Pin<Box<dyn Future<Output = Result<(Self::Handle, Box<dyn Future<Output = Result<(), ProtoError>> + Send + Unpin + 'static>), ProtoError>> + Send + 'static>>;

    // Provided methods
    fn spawn_client(&self) -> ClientResult<(Self::Handle, Runtime)> { ... }
    fn send<R: Into<DnsRequest> + Unpin + Send + 'static>(
        &self,
        msg: R
    ) -> Vec<ClientResult<DnsResponse>> { ... }
    fn query(
        &self,
        name: &Name,
        query_class: DNSClass,
        query_type: RecordType
    ) -> ClientResult<DnsResponse> { ... }
    fn notify<R>(
        &mut self,
        name: Name,
        query_class: DNSClass,
        query_type: RecordType,
        rrset: Option<R>
    ) -> ClientResult<DnsResponse>
       where R: Into<RecordSet> { ... }
    fn create<R>(
        &self,
        rrset: R,
        zone_origin: Name
    ) -> ClientResult<DnsResponse>
       where R: Into<RecordSet> { ... }
    fn append<R>(
        &self,
        rrset: R,
        zone_origin: Name,
        must_exist: bool
    ) -> ClientResult<DnsResponse>
       where R: Into<RecordSet> { ... }
    fn compare_and_swap<CR, NR>(
        &self,
        current: CR,
        new: NR,
        zone_origin: Name
    ) -> ClientResult<DnsResponse>
       where CR: Into<RecordSet>,
             NR: Into<RecordSet> { ... }
    fn delete_by_rdata<R>(
        &self,
        record: R,
        zone_origin: Name
    ) -> ClientResult<DnsResponse>
       where R: Into<RecordSet> { ... }
    fn delete_rrset(
        &self,
        record: Record,
        zone_origin: Name
    ) -> ClientResult<DnsResponse> { ... }
    fn delete_all(
        &self,
        name_of_records: Name,
        zone_origin: Name,
        dns_class: DNSClass
    ) -> ClientResult<DnsResponse> { ... }
    fn zone_transfer(
        &self,
        name: &Name,
        last_soa: Option<SOA>
    ) -> ClientResult<BlockingStream<ClientStreamXfr<<Self as Client>::Response>>> { ... }
}
Expand description

Client trait which implements basic DNS Client operations.

As of 0.10.0, the Client is now a wrapper around the AsyncClient, which is a futures-rs and tokio-rs based implementation. This trait implements synchronous functions for ease of use.

There was a strong attempt to make it backwards compatible, but making it a drop in replacement for the old Client was not possible. This trait has two implementations, the SyncClient which is a standard DNS Client, and the SyncDnssecClient which is a wrapper on DnssecDnsHandle providing DNSSEC validation.

note When upgrading from previous usage, both SyncClient and SyncDnssecClient have an signer which can be optionally associated to the Client. This replaces the previous per-function parameter, and it will sign all update requests (this matches the AsyncClient API).

Required Associated Types§

source

type Response: Stream<Item = Result<DnsResponse, ProtoError>> + 'static + Send + Unpin

The result stream that will resolve into a DnsResponse

source

type Handle: DnsHandle<Response = Self::Response, Error = ProtoError> + 'static + Send + Unpin

The AsyncClient type used

Required Methods§

source

fn new_future( &self ) -> Pin<Box<dyn Future<Output = Result<(Self::Handle, Box<dyn Future<Output = Result<(), ProtoError>> + Send + Unpin + 'static>), ProtoError>> + Send + 'static>>

Return the inner Futures items

Consumes the connection and allows for future based operations afterward.

Provided Methods§

source

fn spawn_client(&self) -> ClientResult<(Self::Handle, Runtime)>

This will create a new AsyncClient and spawn it into a new Runtime

source

fn send<R: Into<DnsRequest> + Unpin + Send + 'static>( &self, msg: R ) -> Vec<ClientResult<DnsResponse>>

Sends an arbitrary DnsRequest to the client

source

fn query( &self, name: &Name, query_class: DNSClass, query_type: RecordType ) -> ClientResult<DnsResponse>

A classic DNS query, i.e. does not perform any DNSSEC operations

Note As of now, this will not recurse on PTR record responses, that is up to the caller.

Arguments
  • name - the label to lookup
  • query_class - most likely this should always be DNSClass::IN
  • query_type - record type to lookup
source

fn notify<R>( &mut self, name: Name, query_class: DNSClass, query_type: RecordType, rrset: Option<R> ) -> ClientResult<DnsResponse>
where R: Into<RecordSet>,

Sends a NOTIFY message to the remote system

Arguments
  • name - the label which is being notified
  • query_class - most likely this should always be DNSClass::IN
  • query_type - record type which has been updated
  • rrset - the new version of the record(s) being notified
source

fn create<R>(&self, rrset: R, zone_origin: Name) -> ClientResult<DnsResponse>
where R: Into<RecordSet>,

Sends a record to create on the server, this will fail if the record exists (atomicity depends on the server)

RFC 2136, DNS Update, April 1997

 2.4.3 - RRset Does Not Exist

  No RRs with a specified NAME and TYPE (in the zone and class denoted
  by the Zone Section) can exist.

  For this prerequisite, a requestor adds to the section a single RR
  whose NAME and TYPE are equal to that of the RRset whose nonexistence
  is required.  The RDLENGTH of this record is zero (0), and RDATA
  field is therefore empty.  CLASS must be specified as NONE in order
  to distinguish this condition from a valid RR whose RDLENGTH is
  naturally zero (0) (for example, the NULL RR).  TTL must be specified
  as zero (0).

2.5.1 - Add To An RRset

   RRs are added to the Update Section whose NAME, TYPE, TTL, RDLENGTH
   and RDATA are those being added, and CLASS is the same as the zone
   class.  Any duplicate RRs will be silently ignored by the Primary
   Zone Server.
Arguments
  • rrset - the record(s) to create
  • zone_origin - the zone name to update, i.e. SOA name

The update must go to a zone authority (i.e. the server used in the ClientConnection)

source

fn append<R>( &self, rrset: R, zone_origin: Name, must_exist: bool ) -> ClientResult<DnsResponse>
where R: Into<RecordSet>,

Appends a record to an existing rrset, optionally require the rrset to exist (atomicity depends on the server)

RFC 2136, DNS Update, April 1997

2.4.1 - RRset Exists (Value Independent)

  At least one RR with a specified NAME and TYPE (in the zone and class
  specified in the Zone Section) must exist.

  For this prerequisite, a requestor adds to the section a single RR
  whose NAME and TYPE are equal to that of the zone RRset whose
  existence is required.  RDLENGTH is zero and RDATA is therefore
  empty.  CLASS must be specified as ANY to differentiate this
  condition from that of an actual RR whose RDLENGTH is naturally zero
  (0) (e.g., NULL).  TTL is specified as zero (0).

2.5.1 - Add To An RRset

   RRs are added to the Update Section whose NAME, TYPE, TTL, RDLENGTH
   and RDATA are those being added, and CLASS is the same as the zone
   class.  Any duplicate RRs will be silently ignored by the Primary
   Zone Server.
Arguments
  • rrset - the record(s) to append to an RRSet
  • zone_origin - the zone name to update, i.e. SOA name
  • must_exist - if true, the request will fail if the record does not exist

The update must go to a zone authority (i.e. the server used in the ClientConnection). If the rrset does not exist and must_exist is false, then the RRSet will be created.

source

fn compare_and_swap<CR, NR>( &self, current: CR, new: NR, zone_origin: Name ) -> ClientResult<DnsResponse>
where CR: Into<RecordSet>, NR: Into<RecordSet>,

Compares and if it matches, swaps it for the new value (atomicity depends on the server)

 2.4.2 - RRset Exists (Value Dependent)

  A set of RRs with a specified NAME and TYPE exists and has the same
  members with the same RDATAs as the RRset specified here in this
  section.  While RRset ordering is undefined and therefore not
  significant to this comparison, the sets be identical in their
  extent.

  For this prerequisite, a requestor adds to the section an entire
  RRset whose preexistence is required.  NAME and TYPE are that of the
  RRset being denoted.  CLASS is that of the zone.  TTL must be
  specified as zero (0) and is ignored when comparing RRsets for
  identity.

 2.5.4 - Delete An RR From An RRset

  RRs to be deleted are added to the Update Section.  The NAME, TYPE,
  RDLENGTH and RDATA must match the RR being deleted.  TTL must be
  specified as zero (0) and will otherwise be ignored by the Primary
  Zone Server.  CLASS must be specified as NONE to distinguish this from an
  RR addition.  If no such RRs exist, then this Update RR will be
  silently ignored by the Primary Zone Server.

 2.5.1 - Add To An RRset

  RRs are added to the Update Section whose NAME, TYPE, TTL, RDLENGTH
  and RDATA are those being added, and CLASS is the same as the zone
  class.  Any duplicate RRs will be silently ignored by the Primary
  Zone Server.
Arguments
  • current - the current rrset which must exist for the swap to complete
  • new - the new rrset with which to replace the current rrset
  • zone_origin - the zone name to update, i.e. SOA name

The update must go to a zone authority (i.e. the server used in the ClientConnection).

source

fn delete_by_rdata<R>( &self, record: R, zone_origin: Name ) -> ClientResult<DnsResponse>
where R: Into<RecordSet>,

Deletes a record (by rdata) from an rrset, optionally require the rrset to exist.

RFC 2136, DNS Update, April 1997

2.4.1 - RRset Exists (Value Independent)

  At least one RR with a specified NAME and TYPE (in the zone and class
  specified in the Zone Section) must exist.

  For this prerequisite, a requestor adds to the section a single RR
  whose NAME and TYPE are equal to that of the zone RRset whose
  existence is required.  RDLENGTH is zero and RDATA is therefore
  empty.  CLASS must be specified as ANY to differentiate this
  condition from that of an actual RR whose RDLENGTH is naturally zero
  (0) (e.g., NULL).  TTL is specified as zero (0).

2.5.4 - Delete An RR From An RRset

  RRs to be deleted are added to the Update Section.  The NAME, TYPE,
  RDLENGTH and RDATA must match the RR being deleted.  TTL must be
  specified as zero (0) and will otherwise be ignored by the Primary
  Zone Server.  CLASS must be specified as NONE to distinguish this from an
  RR addition.  If no such RRs exist, then this Update RR will be
  silently ignored by the Primary Zone Server.
Arguments
  • rrset - the record(s) to delete from a RRSet, the name, type and rdata must match the record to delete
  • zone_origin - the zone name to update, i.e. SOA name

The update must go to a zone authority (i.e. the server used in the ClientConnection). If the rrset does not exist and must_exist is false, then the RRSet will be deleted.

source

fn delete_rrset( &self, record: Record, zone_origin: Name ) -> ClientResult<DnsResponse>

Deletes an entire rrset, optionally require the rrset to exist.

RFC 2136, DNS Update, April 1997

2.4.1 - RRset Exists (Value Independent)

  At least one RR with a specified NAME and TYPE (in the zone and class
  specified in the Zone Section) must exist.

  For this prerequisite, a requestor adds to the section a single RR
  whose NAME and TYPE are equal to that of the zone RRset whose
  existence is required.  RDLENGTH is zero and RDATA is therefore
  empty.  CLASS must be specified as ANY to differentiate this
  condition from that of an actual RR whose RDLENGTH is naturally zero
  (0) (e.g., NULL).  TTL is specified as zero (0).

2.5.2 - Delete An RRset

  One RR is added to the Update Section whose NAME and TYPE are those
  of the RRset to be deleted.  TTL must be specified as zero (0) and is
  otherwise not used by the Primary Zone Sever.  CLASS must be specified as
  ANY.  RDLENGTH must be zero (0) and RDATA must therefore be empty.
  If no such RRset exists, then this Update RR will be silently ignored
  by the Primary Zone Server.
Arguments
  • record - the record to delete from a RRSet, the name, and type must match the record set to delete
  • zone_origin - the zone name to update, i.e. SOA name

The update must go to a zone authority (i.e. the server used in the ClientConnection). If the rrset does not exist and must_exist is false, then the RRSet will be deleted.

source

fn delete_all( &self, name_of_records: Name, zone_origin: Name, dns_class: DNSClass ) -> ClientResult<DnsResponse>

Deletes all records at the specified name

RFC 2136, DNS Update, April 1997

2.5.3 - Delete All RRsets From A Name

  One RR is added to the Update Section whose NAME is that of the name
  to be cleansed of RRsets.  TYPE must be specified as ANY.  TTL must
  be specified as zero (0) and is otherwise not used by the Primary
  Zone Server.  CLASS must be specified as ANY.  RDLENGTH must be zero (0)
  and RDATA must therefore be empty.  If no such RRsets exist, then
  this Update RR will be silently ignored by the Primary Zone Server.
Arguments
  • name_of_records - the name of all the record sets to delete
  • zone_origin - the zone name to update, i.e. SOA name
  • dns_class - the class of the SOA

The update must go to a zone authority (i.e. the server used in the ClientConnection). This operation attempts to delete all resource record sets the specified name regardless of the record type.

source

fn zone_transfer( &self, name: &Name, last_soa: Option<SOA> ) -> ClientResult<BlockingStream<ClientStreamXfr<<Self as Client>::Response>>>

Download all records from a zone, or all records modified since given SOA was observed. The request will either be a AXFR Query (ask for full zone transfer) if a SOA was not provided, or a IXFR Query (incremental zone transfer) if a SOA was provided.

Arguments
  • zone_origin - the zone name to update, i.e. SOA name
  • last_soa - the last SOA known, if any. If provided, name must match zone_origin

Object Safety§

This trait is not object safe.

Implementors§