trust_dns_client/client/
client_connection.rs

1// Copyright (C) 2016 Benjamin Fry <benjaminfry@me.com>
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Trait for client connections
16use std::future::Future;
17use std::sync::Arc;
18
19use crate::op::{MessageFinalizer, MessageVerifier};
20#[cfg(feature = "dnssec")]
21#[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
22use crate::proto::rr::dnssec::tsig::TSigner;
23#[cfg(feature = "dnssec")]
24#[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
25use crate::proto::rr::dnssec::SigSigner;
26use crate::proto::{error::ProtoError, xfer::DnsRequestSender};
27
28use crate::proto::error::ProtoResult;
29use crate::proto::op::Message;
30use crate::proto::rr::Record;
31
32/// List of currently supported signers
33#[allow(missing_copy_implementations)]
34pub enum Signer {
35    /// A Sig0 based signer
36    #[cfg(feature = "dnssec")]
37    #[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
38    Sig0(Box<SigSigner>),
39    /// A TSIG based signer
40    #[cfg(feature = "dnssec")]
41    #[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
42    TSIG(TSigner),
43}
44
45#[cfg(feature = "dnssec")]
46#[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
47impl From<SigSigner> for Signer {
48    fn from(s: SigSigner) -> Self {
49        Self::Sig0(Box::new(s))
50    }
51}
52
53#[cfg(feature = "dnssec")]
54#[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
55impl From<TSigner> for Signer {
56    fn from(s: TSigner) -> Self {
57        Self::TSIG(s)
58    }
59}
60
61impl MessageFinalizer for Signer {
62    #[allow(unreachable_patterns, unused_variables)]
63    fn finalize_message(
64        &self,
65        message: &Message,
66        time: u32,
67    ) -> ProtoResult<(Vec<Record>, Option<MessageVerifier>)> {
68        match self {
69            #[cfg(feature = "dnssec")]
70            #[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
71            Self::Sig0(s0) => s0.finalize_message(message, time),
72            #[cfg(feature = "dnssec")]
73            #[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
74            Self::TSIG(tsig) => tsig.finalize_message(message, time),
75            _ => unreachable!("the feature `dnssec` is required for Message signing"),
76        }
77    }
78}
79
80/// Trait for client connections
81pub trait ClientConnection: 'static + Sized + Send + Sync + Unpin {
82    /// The associated DNS RequestSender type.
83    type Sender: DnsRequestSender;
84    /// A future that resolves to the RequestSender
85    type SenderFuture: Future<Output = Result<Self::Sender, ProtoError>> + 'static + Send + Unpin;
86
87    /// Construct a new stream for use in the Client
88    fn new_stream(&self, signer: Option<Arc<Signer>>) -> Self::SenderFuture;
89}