Make Client and Resolver Send + Sync (#245)
* resolver is sendable * Client and SyncClient now Clone and Send * share cache across clones of sync Resolver * assert Client and SyncClient are send and sync * remove explicit ClientConnection and Client send+sync requirements * rusls send + sync * fix type of messagefinalizer * everything compiling * use rustls for client side validation of server * fix client when all features disabled * add type param for compatibility tests * fix references from subject_name to dns_name * cleanup unused errors * ignore integration-tests lib from coverage
This commit is contained in:
parent
8ac36c8525
commit
d2548ad9e7
@ -22,11 +22,16 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- Many interfaces moved from `client::ClientStreamHandle` to `trust_dns_proto::DnsStreamHandle`
|
||||
- `Message::sign` has been renamed and change to the more general method `Message::finalize`
|
||||
- Some `io::Error`s have been converted to `trust_dns_proto::ProtoError`
|
||||
- `SyncClient` and `SecureSyncClient` are now `Send + Sync`
|
||||
|
||||
### Fixed
|
||||
|
||||
- Server signing issues when loading from persistence
|
||||
|
||||
### Removed
|
||||
|
||||
- Removed the `NativeTls` and `OpenSSL` `ClientConnection` variants, used the Rustls impls or the tokio based `TlsClientStream` instead. This was required for `SyncClient` being `Send + Sync`
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Fixed
|
||||
|
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1239,11 +1239,13 @@ dependencies = [
|
||||
"openssl 0.9.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rusqlite 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustls 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"trust-dns 0.12.0",
|
||||
"trust-dns-openssl 0.1.0",
|
||||
"trust-dns-proto 0.1.0",
|
||||
"trust-dns-resolver 0.6.0",
|
||||
"trust-dns-rustls 0.1.5",
|
||||
"trust-dns-server 0.12.0",
|
||||
]
|
||||
|
||||
|
@ -12,13 +12,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::sync::Arc;
|
||||
use std::io;
|
||||
|
||||
use futures::Stream;
|
||||
use tokio_core::reactor::Core;
|
||||
use tokio_core::reactor::{Core, Handle};
|
||||
|
||||
use client::{ClientHandle, BasicClientHandle, ClientConnection, ClientFuture};
|
||||
use client::{BasicClientHandle, ClientHandle, ClientConnection, ClientFuture};
|
||||
#[cfg(any(feature = "openssl", feature = "ring"))]
|
||||
use client::SecureClientHandle;
|
||||
use error::*;
|
||||
@ -42,11 +42,10 @@ use op::Message;
|
||||
/// 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 `ClientFuture` API).
|
||||
pub trait Client<C: ClientHandle> {
|
||||
/// get a mutable reference to the tokio Core associated to the Client
|
||||
fn get_io_loop(&self) -> RefMut<Core>;
|
||||
|
||||
/// Get a mutable handle reference tot the Core associated to the Client
|
||||
fn get_client_handle(&self) -> RefMut<C>;
|
||||
/// Return the inner Futures items
|
||||
///
|
||||
/// Consumes the connection and allows for future based operations afterward.
|
||||
fn new_future(&self, handle: &Handle) -> ClientResult<C>;
|
||||
|
||||
/// A *classic* DNS query, i.e. does not perform any DNSSec operations
|
||||
///
|
||||
@ -64,11 +63,10 @@ pub trait Client<C: ClientHandle> {
|
||||
query_class: DNSClass,
|
||||
query_type: RecordType,
|
||||
) -> ClientResult<Message> {
|
||||
self.get_io_loop().run(self.get_client_handle().query(
|
||||
name.clone(),
|
||||
query_class,
|
||||
query_type,
|
||||
))
|
||||
let mut reactor = Core::new()?;
|
||||
let mut client = self.new_future(&reactor.handle())?;
|
||||
let future = client.query(name.clone(), query_class, query_type);
|
||||
reactor.run(future)
|
||||
}
|
||||
|
||||
/// Sends a NOTIFY message to the remote system
|
||||
@ -89,12 +87,10 @@ pub trait Client<C: ClientHandle> {
|
||||
where
|
||||
R: IntoRecordSet,
|
||||
{
|
||||
self.get_io_loop().run(self.get_client_handle().notify(
|
||||
name,
|
||||
query_class,
|
||||
query_type,
|
||||
rrset,
|
||||
))
|
||||
let mut reactor = Core::new()?;
|
||||
let mut client = self.new_future(&reactor.handle())?;
|
||||
let future = client.notify(name, query_class, query_type, rrset);
|
||||
reactor.run(future)
|
||||
}
|
||||
|
||||
/// Sends a record to create on the server, this will fail if the record exists (atomicity
|
||||
@ -134,10 +130,10 @@ pub trait Client<C: ClientHandle> {
|
||||
where
|
||||
R: IntoRecordSet,
|
||||
{
|
||||
self.get_io_loop().run(self.get_client_handle().create(
|
||||
rrset,
|
||||
zone_origin,
|
||||
))
|
||||
let mut reactor = Core::new()?;
|
||||
let mut client = self.new_future(&reactor.handle())?;
|
||||
let future = client.create(rrset, zone_origin);
|
||||
reactor.run(future)
|
||||
}
|
||||
|
||||
/// Appends a record to an existing rrset, optionally require the rrset to exist (atomicity
|
||||
@ -183,11 +179,10 @@ pub trait Client<C: ClientHandle> {
|
||||
where
|
||||
R: IntoRecordSet,
|
||||
{
|
||||
self.get_io_loop().run(self.get_client_handle().append(
|
||||
rrset,
|
||||
zone_origin,
|
||||
must_exist,
|
||||
))
|
||||
let mut reactor = Core::new()?;
|
||||
let mut client = self.new_future(&reactor.handle())?;
|
||||
let future = client.append(rrset, zone_origin, must_exist);
|
||||
reactor.run(future)
|
||||
}
|
||||
|
||||
/// Compares and if it matches, swaps it for the new value (atomicity depends on the server)
|
||||
@ -241,13 +236,10 @@ pub trait Client<C: ClientHandle> {
|
||||
CR: IntoRecordSet,
|
||||
NR: IntoRecordSet,
|
||||
{
|
||||
self.get_io_loop().run(
|
||||
self.get_client_handle().compare_and_swap(
|
||||
current,
|
||||
new,
|
||||
zone_origin,
|
||||
),
|
||||
)
|
||||
let mut reactor = Core::new()?;
|
||||
let mut client = self.new_future(&reactor.handle())?;
|
||||
let future = client.compare_and_swap(current, new, zone_origin);
|
||||
reactor.run(future)
|
||||
}
|
||||
|
||||
/// Deletes a record (by rdata) from an rrset, optionally require the rrset to exist.
|
||||
@ -289,12 +281,10 @@ pub trait Client<C: ClientHandle> {
|
||||
where
|
||||
R: IntoRecordSet,
|
||||
{
|
||||
self.get_io_loop().run(
|
||||
self.get_client_handle().delete_by_rdata(
|
||||
record,
|
||||
zone_origin,
|
||||
),
|
||||
)
|
||||
let mut reactor = Core::new()?;
|
||||
let mut client = self.new_future(&reactor.handle())?;
|
||||
let future = client.delete_by_rdata(record, zone_origin);
|
||||
reactor.run(future)
|
||||
}
|
||||
|
||||
/// Deletes an entire rrset, optionally require the rrset to exist.
|
||||
@ -333,12 +323,10 @@ pub trait Client<C: ClientHandle> {
|
||||
/// 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.
|
||||
fn delete_rrset(&self, record: Record, zone_origin: domain::Name) -> ClientResult<Message> {
|
||||
self.get_io_loop().run(
|
||||
self.get_client_handle().delete_rrset(
|
||||
record,
|
||||
zone_origin,
|
||||
),
|
||||
)
|
||||
let mut reactor = Core::new()?;
|
||||
let mut client = self.new_future(&reactor.handle())?;
|
||||
let future = client.delete_rrset(record, zone_origin);
|
||||
reactor.run(future)
|
||||
}
|
||||
|
||||
/// Deletes all records at the specified name
|
||||
@ -371,11 +359,10 @@ pub trait Client<C: ClientHandle> {
|
||||
zone_origin: domain::Name,
|
||||
dns_class: DNSClass,
|
||||
) -> ClientResult<Message> {
|
||||
self.get_io_loop().run(self.get_client_handle().delete_all(
|
||||
name_of_records,
|
||||
zone_origin,
|
||||
dns_class,
|
||||
))
|
||||
let mut reactor = Core::new()?;
|
||||
let mut client = self.new_future(&reactor.handle())?;
|
||||
let future = client.delete_all(name_of_records, zone_origin, dns_class);
|
||||
reactor.run(future)
|
||||
}
|
||||
}
|
||||
|
||||
@ -384,28 +371,25 @@ pub trait Client<C: ClientHandle> {
|
||||
///
|
||||
/// Usage of TCP or UDP is up to the user. Some DNS servers
|
||||
/// disallow TCP in some cases, so if TCP double check if UDP works.
|
||||
pub struct SyncClient {
|
||||
client_handle: RefCell<BasicClientHandle>,
|
||||
io_loop: RefCell<Core>,
|
||||
pub struct SyncClient<CC> {
|
||||
conn: CC,
|
||||
signer: Option<Arc<Signer>>,
|
||||
}
|
||||
|
||||
impl SyncClient {
|
||||
impl<CC> SyncClient<CC>
|
||||
where
|
||||
CC: ClientConnection,
|
||||
<CC as ClientConnection>::MessageStream: Stream<Item = Vec<u8>, Error = io::Error> + 'static
|
||||
{
|
||||
/// Creates a new DNS client with the specified connection type
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `client_connection` - the client_connection to use for all communication
|
||||
pub fn new<CC: ClientConnection>(client_connection: CC) -> SyncClient
|
||||
where
|
||||
<CC as ClientConnection>::MessageStream: Stream<Item = Vec<u8>, Error = io::Error> + 'static,
|
||||
{
|
||||
let (io_loop, stream, stream_handle) = client_connection.unwrap();
|
||||
|
||||
let client = ClientFuture::new(stream, stream_handle, &io_loop.handle(), None);
|
||||
|
||||
/// * `conn` - the [`ClientConnection`] to use for all communication
|
||||
pub fn new(conn: CC) -> Self {
|
||||
SyncClient {
|
||||
client_handle: RefCell::new(client),
|
||||
io_loop: RefCell::new(io_loop),
|
||||
conn,
|
||||
signer: None
|
||||
}
|
||||
}
|
||||
|
||||
@ -415,54 +399,48 @@ impl SyncClient {
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `client_connection` - the client_connection to use for all communication
|
||||
/// * `conn` - the [`ClientConnection`] to use for all communication
|
||||
/// * `signer` - signer to use, this needs an associated private key
|
||||
pub fn with_signer<CC: ClientConnection>(client_connection: CC, signer: Signer) -> SyncClient
|
||||
where
|
||||
<CC as ClientConnection>::MessageStream: Stream<Item = Vec<u8>, Error = io::Error> + 'static,
|
||||
{
|
||||
let (io_loop, stream, stream_handle) = client_connection.unwrap();
|
||||
|
||||
let client = ClientFuture::new(stream, stream_handle, &io_loop.handle(), Some(signer));
|
||||
|
||||
SyncClient {
|
||||
client_handle: RefCell::new(client),
|
||||
io_loop: RefCell::new(io_loop),
|
||||
}
|
||||
pub fn with_signer(conn: CC, signer: Signer) -> Self {
|
||||
SyncClient { conn, signer: Some(Arc::new(signer)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Client<BasicClientHandle> for SyncClient {
|
||||
fn get_io_loop(&self) -> RefMut<Core> {
|
||||
self.io_loop.borrow_mut()
|
||||
}
|
||||
impl<CC> Client<BasicClientHandle> for SyncClient<CC>
|
||||
where
|
||||
CC: ClientConnection,
|
||||
<CC as ClientConnection>::MessageStream: Stream<Item = Vec<u8>, Error = io::Error>
|
||||
+ 'static,
|
||||
{
|
||||
fn new_future(&self, handle: &Handle) -> ClientResult<BasicClientHandle> {
|
||||
let (stream, stream_handle) = self.conn.new_stream(handle)?;
|
||||
|
||||
fn get_client_handle(&self) -> RefMut<BasicClientHandle> {
|
||||
self.client_handle.borrow_mut()
|
||||
let client = ClientFuture::new(stream, stream_handle, &handle, self.signer.clone());
|
||||
Ok(client)
|
||||
}
|
||||
}
|
||||
|
||||
/// A DNS client which will validate DNSSec records upon receipt
|
||||
#[cfg(any(feature = "openssl", feature = "ring"))]
|
||||
pub struct SecureSyncClient {
|
||||
client_handle: RefCell<SecureClientHandle<BasicClientHandle>>,
|
||||
io_loop: RefCell<Core>,
|
||||
#[cfg(feature = "dnssec")]
|
||||
pub struct SecureSyncClient<CC> {
|
||||
conn: CC,
|
||||
signer: Option<Arc<Signer>>,
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "openssl", feature = "ring"))]
|
||||
impl SecureSyncClient {
|
||||
#[cfg(feature = "dnssec")]
|
||||
impl<CC> SecureSyncClient<CC>
|
||||
where
|
||||
CC: ClientConnection,
|
||||
<CC as ClientConnection>::MessageStream: Stream<Item = Vec<u8>, Error = io::Error> + 'static,
|
||||
{
|
||||
/// Creates a new DNS client with the specified connection type
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `client_connection` - the client_connection to use for all communication
|
||||
pub fn new<CC>(client_connection: CC) -> SecureSyncClientBuilder<CC>
|
||||
where
|
||||
CC: ClientConnection,
|
||||
<CC as ClientConnection>::MessageStream: Stream<Item = Vec<u8>, Error = io::Error> + 'static,
|
||||
{
|
||||
pub fn new(conn: CC) -> SecureSyncClientBuilder<CC> {
|
||||
SecureSyncClientBuilder {
|
||||
client_connection: client_connection,
|
||||
conn: conn,
|
||||
trust_anchor: None,
|
||||
signer: None,
|
||||
}
|
||||
@ -472,24 +450,24 @@ impl SecureSyncClient {
|
||||
/// validated against the trust_anchor.
|
||||
///
|
||||
/// *Deprecated* This function only exists for backward compatibility. It's just a wrapper around `Client::query` at this point
|
||||
///
|
||||
/// When the resolver receives an answer via the normal DNS lookup process, it then checks to
|
||||
/// make sure that the answer is correct. Then starts
|
||||
/// with verifying the DS and DNSKEY records at the DNS root. Then use the DS
|
||||
/// records for the top level domain found at the root, e.g. 'com', to verify the DNSKEY
|
||||
/// records in the 'com' zone. From there see if there is a DS record for the
|
||||
/// subdomain, e.g. 'example.com', in the 'com' zone, and if there is use the
|
||||
/// DS record to verify a DNSKEY record found in the 'example.com' zone. Finally,
|
||||
/// verify the RRSIG record found in the answer for the rrset, e.g. 'www.example.com'.
|
||||
///
|
||||
/// *Note* As of now, this will not recurse on PTR or CNAME record responses, that is up to
|
||||
/// the caller.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `query_name` - the label to lookup
|
||||
/// * `query_class` - most likely this should always be DNSClass::IN
|
||||
/// * `query_type` - record type to lookup
|
||||
///
|
||||
/// When the resolver receives an answer via the normal DNS lookup process, it then checks to
|
||||
/// make sure that the answer is correct. Then starts
|
||||
/// with verifying the DS and DNSKEY records at the DNS root. Then use the DS
|
||||
/// records for the top level domain found at the root, e.g. 'com', to verify the DNSKEY
|
||||
/// records in the 'com' zone. From there see if there is a DS record for the
|
||||
/// subdomain, e.g. 'example.com', in the 'com' zone, and if there is use the
|
||||
/// DS record to verify a DNSKEY record found in the 'example.com' zone. Finally,
|
||||
/// verify the RRSIG record found in the answer for the rrset, e.g. 'www.example.com'.
|
||||
///
|
||||
/// *Note* As of now, this will not recurse on PTR or CNAME record responses, that is up to
|
||||
/// the caller.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `query_name` - the label to lookup
|
||||
/// * `query_class` - most likely this should always be DNSClass::IN
|
||||
/// * `query_type` - record type to lookup
|
||||
#[deprecated(note = "use `Client::query` instead")]
|
||||
pub fn secure_query(
|
||||
&self,
|
||||
@ -497,40 +475,48 @@ impl SecureSyncClient {
|
||||
query_class: DNSClass,
|
||||
query_type: RecordType,
|
||||
) -> ClientResult<Message> {
|
||||
self.get_io_loop().run(self.get_client_handle().query(
|
||||
let mut reactor = Core::new()?;
|
||||
let mut client = self.new_future(&reactor.handle())?;
|
||||
let future = client.query(
|
||||
query_name.clone(),
|
||||
query_class,
|
||||
query_type,
|
||||
))
|
||||
);
|
||||
reactor.run(future)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "openssl", feature = "ring"))]
|
||||
impl Client<SecureClientHandle<BasicClientHandle>> for SecureSyncClient {
|
||||
fn get_io_loop(&self) -> RefMut<Core> {
|
||||
self.io_loop.borrow_mut()
|
||||
}
|
||||
#[cfg(feature = "dnssec")]
|
||||
impl<CC> Client<SecureClientHandle<BasicClientHandle>> for SecureSyncClient<CC>
|
||||
where
|
||||
CC: ClientConnection,
|
||||
<CC as ClientConnection>::MessageStream: Stream<Item = Vec<u8>, Error = io::Error> + 'static,
|
||||
{
|
||||
fn new_future(&self, handle: &Handle) -> ClientResult<SecureClientHandle<BasicClientHandle>> {
|
||||
let (stream, stream_handle) = self.conn.new_stream(handle)?;
|
||||
|
||||
fn get_client_handle(&self) -> RefMut<SecureClientHandle<BasicClientHandle>> {
|
||||
self.client_handle.borrow_mut()
|
||||
let client = ClientFuture::new(stream, stream_handle, &handle, self.signer.clone());
|
||||
Ok(SecureClientHandle::new(client))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "openssl", feature = "ring"))]
|
||||
#[cfg(feature = "dnssec")]
|
||||
pub struct SecureSyncClientBuilder<CC>
|
||||
where
|
||||
CC: ClientConnection,
|
||||
<CC as ClientConnection>::MessageStream: Stream<Item = Vec<u8>, Error = io::Error> + 'static,
|
||||
{
|
||||
client_connection: CC,
|
||||
conn: CC,
|
||||
trust_anchor: Option<TrustAnchor>,
|
||||
signer: Option<Signer>,
|
||||
signer: Option<Arc<Signer>>,
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "openssl", feature = "ring"))]
|
||||
#[cfg(feature = "dnssec")]
|
||||
impl<CC> SecureSyncClientBuilder<CC>
|
||||
where CC: ClientConnection,
|
||||
<CC as ClientConnection>::MessageStream: Stream<Item=Vec<u8>, Error=io::Error> + 'static {
|
||||
where
|
||||
CC: ClientConnection,
|
||||
<CC as ClientConnection>::MessageStream: Stream<Item=Vec<u8>, Error=io::Error> + 'static
|
||||
{
|
||||
|
||||
/// This variant allows for the trust_anchor to be replaced
|
||||
///
|
||||
@ -551,21 +537,36 @@ where CC: ClientConnection,
|
||||
///
|
||||
/// * `signer` - signer to use, this needs an associated private key
|
||||
pub fn signer(mut self, signer: Signer) -> Self {
|
||||
self.signer = Some(signer);
|
||||
self.signer = Some(Arc::new(signer));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> SecureSyncClient {
|
||||
let (io_loop, stream, stream_handle) = self.client_connection.unwrap();
|
||||
|
||||
let client = ClientFuture::new(
|
||||
stream,
|
||||
stream_handle,
|
||||
&io_loop.handle(),
|
||||
self.signer);
|
||||
|
||||
let client = SecureClientHandle::with_trust_anchor(client, self.trust_anchor.unwrap_or(Default::default()));
|
||||
|
||||
SecureSyncClient{ client_handle: RefCell::new(client), io_loop: RefCell::new(io_loop) }
|
||||
pub fn build(self) -> SecureSyncClient<CC> {
|
||||
SecureSyncClient {
|
||||
conn: self.conn,
|
||||
signer: self.signer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn assert_send_and_sync<T: Send + Sync>() {
|
||||
assert!(true)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sync_client_send_and_sync() {
|
||||
use udp::UdpClientConnection;
|
||||
use tcp::TcpClientConnection;
|
||||
assert_send_and_sync::<SyncClient<UdpClientConnection>>();
|
||||
assert_send_and_sync::<SyncClient<TcpClientConnection>>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "dnssec")]
|
||||
fn test_secure_client_send_and_sync() {
|
||||
use udp::UdpClientConnection;
|
||||
use tcp::TcpClientConnection;
|
||||
assert_send_and_sync::<SecureSyncClient<UdpClientConnection>>();
|
||||
assert_send_and_sync::<SecureSyncClient<TcpClientConnection>>();
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
use std::io;
|
||||
|
||||
use futures::Future;
|
||||
use tokio_core::reactor::Core;
|
||||
use tokio_core::reactor::Handle;
|
||||
|
||||
use trust_dns_proto::DnsStreamHandle;
|
||||
|
||||
@ -31,7 +31,5 @@ pub trait ClientConnection: Sized {
|
||||
/// Return the inner Futures items
|
||||
///
|
||||
/// Consumes the connection and allows for future based operations afterward.
|
||||
fn unwrap(
|
||||
self,
|
||||
) -> (Core, Box<Future<Item = Self::MessageStream, Error = io::Error>>, Box<DnsStreamHandle<Error = ClientError>>);
|
||||
fn new_stream(&self, handle: &Handle) -> ClientResult<(Box<Future<Item = Self::MessageStream, Error = io::Error>>, Box<DnsStreamHandle<Error = ClientError>>)>;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::marker::PhantomData;
|
||||
use std::io;
|
||||
use std::time::Duration;
|
||||
@ -46,7 +47,7 @@ impl<S: Stream<Item = Vec<u8>, Error = io::Error> + 'static> ClientFuture<S> {
|
||||
stream: Box<Future<Item = S, Error = io::Error>>,
|
||||
stream_handle: Box<ClientStreamHandle<Error = ClientError>>,
|
||||
loop_handle: &Handle,
|
||||
signer: Option<Signer>,
|
||||
signer: Option<Arc<Signer>>,
|
||||
) -> BasicClientHandle {
|
||||
Self::with_timeout(
|
||||
stream,
|
||||
@ -74,7 +75,7 @@ impl<S: Stream<Item = Vec<u8>, Error = io::Error> + 'static> ClientFuture<S> {
|
||||
stream_handle: Box<DnsStreamHandle<Error = ClientError>>,
|
||||
loop_handle: &Handle,
|
||||
timeout_duration: Duration,
|
||||
finalizer: Option<Signer>,
|
||||
finalizer: Option<Arc<Signer>>,
|
||||
) -> BasicClientHandle {
|
||||
let dns_future_handle = DnsFuture::with_timeout(
|
||||
stream,
|
||||
|
@ -253,6 +253,7 @@ pub struct Signer {
|
||||
|
||||
/// Placeholder type for when OpenSSL and *ring* are disabled; enable OpenSSL and Ring for support
|
||||
#[cfg(not(any(feature = "openssl", feature = "ring")))]
|
||||
#[derive(Clone)]
|
||||
pub struct Signer;
|
||||
|
||||
#[cfg(any(feature = "openssl", feature = "ring"))]
|
||||
@ -585,6 +586,15 @@ mod tests {
|
||||
|
||||
pub use super::*;
|
||||
|
||||
fn assert_send_and_sync<T: Send + Sync>() {
|
||||
assert!(true)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_send_and_sync() {
|
||||
assert_send_and_sync::<Signer>();
|
||||
}
|
||||
|
||||
fn pre_sig0(signer: &Signer, inception_time: u32, expiration_time: u32) -> SIG {
|
||||
SIG::new(
|
||||
// type covered in SIG(0) is 0 which is what makes this SIG0 vs a standard SIG
|
||||
|
@ -20,20 +20,20 @@ use std::time::Duration;
|
||||
|
||||
use futures::Future;
|
||||
use tokio_core::net::TcpStream;
|
||||
use tokio_core::reactor::Core;
|
||||
use tokio_core::reactor::Handle;
|
||||
use trust_dns_proto::DnsStreamHandle;
|
||||
|
||||
use error::*;
|
||||
use client::{ClientConnection, ClientStreamHandle};
|
||||
use client::ClientConnection;
|
||||
use tcp::TcpClientStream;
|
||||
|
||||
/// Tcp client connection
|
||||
///
|
||||
/// Use with `trust_dns::client::Client` impls
|
||||
#[derive(Clone)]
|
||||
pub struct TcpClientConnection {
|
||||
io_loop: Core,
|
||||
tcp_client_stream: Box<Future<Item = TcpClientStream<TcpStream>, Error = io::Error>>,
|
||||
client_stream_handle: Box<ClientStreamHandle<Error = ClientError>>,
|
||||
name_server: SocketAddr,
|
||||
timeout: Duration,
|
||||
}
|
||||
|
||||
impl TcpClientConnection {
|
||||
@ -60,14 +60,9 @@ impl TcpClientConnection {
|
||||
///
|
||||
/// * `name_server` - address of the name server to use for queries
|
||||
pub fn with_timeout(name_server: SocketAddr, timeout: Duration) -> ClientResult<Self> {
|
||||
let io_loop = try!(Core::new());
|
||||
let (tcp_client_stream, handle) =
|
||||
TcpClientStream::<TcpStream>::with_timeout(name_server, &io_loop.handle(), timeout);
|
||||
|
||||
Ok(TcpClientConnection {
|
||||
io_loop: io_loop,
|
||||
tcp_client_stream: tcp_client_stream,
|
||||
client_stream_handle: handle,
|
||||
name_server,
|
||||
timeout,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -75,13 +70,17 @@ impl TcpClientConnection {
|
||||
impl ClientConnection for TcpClientConnection {
|
||||
type MessageStream = TcpClientStream<TcpStream>;
|
||||
|
||||
fn unwrap(
|
||||
self,
|
||||
) -> (Core, Box<Future<Item = Self::MessageStream, Error = io::Error>>, Box<DnsStreamHandle<Error = ClientError>>) {
|
||||
(
|
||||
self.io_loop,
|
||||
self.tcp_client_stream,
|
||||
self.client_stream_handle,
|
||||
)
|
||||
fn new_stream(
|
||||
&self,
|
||||
handle: &Handle,
|
||||
) -> ClientResult<
|
||||
(Box<Future<Item = Self::MessageStream, Error = io::Error>>,
|
||||
Box<DnsStreamHandle<Error = ClientError>>),
|
||||
> {
|
||||
let (tcp_client_stream, handle) =
|
||||
TcpClientStream::<TcpStream>::with_timeout(self.name_server, handle, self.timeout);
|
||||
|
||||
Ok((tcp_client_stream, handle))
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -18,20 +18,19 @@ use std::io;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use futures::Future;
|
||||
use tokio_core::reactor::Core;
|
||||
use tokio_core::reactor::Handle;
|
||||
use trust_dns_proto::DnsStreamHandle;
|
||||
|
||||
use error::*;
|
||||
use client::{ClientConnection, ClientStreamHandle};
|
||||
use client::ClientConnection;
|
||||
use udp::UdpClientStream;
|
||||
|
||||
/// UDP based DNS Client connection
|
||||
///
|
||||
/// Use with `trust_dns::client::Client` impls
|
||||
#[derive(Clone)]
|
||||
pub struct UdpClientConnection {
|
||||
io_loop: Core,
|
||||
udp_client_stream: Box<Future<Item = UdpClientStream, Error = io::Error>>,
|
||||
client_stream_handle: Box<ClientStreamHandle<Error = ClientError>>,
|
||||
name_server: SocketAddr,
|
||||
}
|
||||
|
||||
impl UdpClientConnection {
|
||||
@ -44,27 +43,22 @@ impl UdpClientConnection {
|
||||
///
|
||||
/// * `name_server` - address of the name server to use for queries
|
||||
pub fn new(name_server: SocketAddr) -> ClientResult<Self> {
|
||||
let io_loop = try!(Core::new());
|
||||
let (udp_client_stream, handle) = UdpClientStream::new(name_server, &io_loop.handle());
|
||||
|
||||
Ok(UdpClientConnection {
|
||||
io_loop: io_loop,
|
||||
udp_client_stream: udp_client_stream,
|
||||
client_stream_handle: handle,
|
||||
})
|
||||
Ok(UdpClientConnection { name_server })
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientConnection for UdpClientConnection {
|
||||
type MessageStream = UdpClientStream;
|
||||
|
||||
fn unwrap(
|
||||
self,
|
||||
) -> (Core, Box<Future<Item = Self::MessageStream, Error = io::Error>>, Box<DnsStreamHandle<Error = ClientError>>) {
|
||||
(
|
||||
self.io_loop,
|
||||
self.udp_client_stream,
|
||||
self.client_stream_handle,
|
||||
)
|
||||
fn new_stream(
|
||||
&self,
|
||||
handle: &Handle,
|
||||
) -> ClientResult<
|
||||
(Box<Future<Item = Self::MessageStream, Error = io::Error>>,
|
||||
Box<DnsStreamHandle<Error = ClientError>>),
|
||||
> {
|
||||
let (udp_client_stream, handle) = UdpClientStream::new(self.name_server, handle);
|
||||
|
||||
Ok((udp_client_stream, handle))
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ fn test_get() {
|
||||
}
|
||||
}
|
||||
|
||||
fn create_sig0_ready_client<CC>(conn: CC) -> SyncClient
|
||||
fn create_sig0_ready_client<CC>(conn: CC) -> SyncClient<CC>
|
||||
where
|
||||
CC: ClientConnection,
|
||||
<CC as ClientConnection>::MessageStream: Stream<Item = Vec<u8>, Error = io::Error> + 'static,
|
||||
|
@ -63,10 +63,12 @@ futures = "^0.1.6"
|
||||
openssl = { version = "^0.9.8", features = ["v102", "v110"] }
|
||||
rand = "^0.3"
|
||||
rusqlite = { version = "^0.9.5", features = ["bundled"] }
|
||||
rustls = { version = "^0.11.0" }
|
||||
tokio-core = "^0.1"
|
||||
trust-dns = { version = "*", path = "../client" }
|
||||
trust-dns-openssl = { version = "*", path = "../openssl" }
|
||||
trust-dns-proto = { version = "*", path = "../proto" }
|
||||
trust-dns-resolver = { version = "*", path = "../resolver" }
|
||||
trust-dns-rustls = { version = "*", path = "../rustls" }
|
||||
trust-dns-server = { version = "*", path = "../server" }
|
||||
|
||||
|
@ -8,6 +8,7 @@ extern crate trust_dns;
|
||||
extern crate trust_dns_proto;
|
||||
extern crate trust_dns_server;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
|
||||
@ -15,7 +16,7 @@ use futures::{Async, Future, finished, Poll};
|
||||
use futures::stream::{Fuse, Stream};
|
||||
use futures::sync::mpsc::{unbounded, UnboundedReceiver};
|
||||
use futures::task;
|
||||
use tokio_core::reactor::Core;
|
||||
use tokio_core::reactor::Handle;
|
||||
|
||||
use trust_dns::error::{ClientError, ClientResult};
|
||||
use trust_dns::client::ClientConnection;
|
||||
@ -32,14 +33,14 @@ pub mod mock_client;
|
||||
|
||||
#[allow(unused)]
|
||||
pub struct TestClientStream {
|
||||
catalog: Catalog,
|
||||
catalog: Arc<Catalog>,
|
||||
outbound_messages: Fuse<UnboundedReceiver<Vec<u8>>>,
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
impl TestClientStream {
|
||||
pub fn new<E: FromProtoError>(
|
||||
catalog: Catalog,
|
||||
catalog: Arc<Catalog>,
|
||||
) -> (Box<Future<Item = Self, Error = io::Error>>, StreamHandle<E>) {
|
||||
let (message_sender, outbound_messages) = unbounded();
|
||||
let message_sender = StreamHandle::new(message_sender);
|
||||
@ -143,31 +144,21 @@ impl fmt::Debug for NeverReturnsClientStream {
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct NeverReturnsClientConnection {
|
||||
io_loop: Core,
|
||||
client_stream: Box<Future<Item = NeverReturnsClientStream, Error = io::Error>>,
|
||||
client_stream_handle: StreamHandle<ClientError>,
|
||||
}
|
||||
pub struct NeverReturnsClientConnection {}
|
||||
|
||||
impl NeverReturnsClientConnection {
|
||||
pub fn new() -> ClientResult<Self> {
|
||||
let io_loop = try!(Core::new());
|
||||
let (client_stream, handle) = NeverReturnsClientStream::new();
|
||||
|
||||
Ok(NeverReturnsClientConnection {
|
||||
io_loop: io_loop,
|
||||
client_stream: client_stream,
|
||||
client_stream_handle: handle,
|
||||
})
|
||||
Ok(NeverReturnsClientConnection {})
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientConnection for NeverReturnsClientConnection {
|
||||
type MessageStream = NeverReturnsClientStream;
|
||||
|
||||
fn unwrap(
|
||||
self,
|
||||
) -> (Core, Box<Future<Item = Self::MessageStream, Error = io::Error>>, Box<DnsStreamHandle<Error = ClientError>>) {
|
||||
(self.io_loop, self.client_stream, Box::new(self.client_stream_handle))
|
||||
fn new_stream(&self, _: &Handle) -> ClientResult<(Box<Future<Item = Self::MessageStream, Error = io::Error>>,
|
||||
Box<DnsStreamHandle<Error = ClientError>>)> {
|
||||
let (client_stream, handle) = NeverReturnsClientStream::new();
|
||||
|
||||
Ok((client_stream, Box::new(handle)))
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ extern crate trust_dns_integration;
|
||||
|
||||
use std::net::*;
|
||||
use std::cmp::Ordering;
|
||||
use std::sync::Arc;
|
||||
|
||||
use chrono::Duration;
|
||||
use futures::Future;
|
||||
@ -35,7 +36,7 @@ fn test_query_nonet() {
|
||||
catalog.upsert(authority.origin().clone(), authority);
|
||||
|
||||
let mut io_loop = Core::new().unwrap();
|
||||
let (stream, sender) = TestClientStream::new(catalog);
|
||||
let (stream, sender) = TestClientStream::new(Arc::new(catalog));
|
||||
let mut client = ClientFuture::new(stream, Box::new(sender), &io_loop.handle(), None);
|
||||
|
||||
io_loop.run(test_query(&mut client)).unwrap();
|
||||
@ -157,7 +158,7 @@ fn test_notify() {
|
||||
catalog.upsert(authority.origin().clone(), authority);
|
||||
|
||||
let mut io_loop = Core::new().unwrap();
|
||||
let (stream, sender) = TestClientStream::new(catalog);
|
||||
let (stream, sender) = TestClientStream::new(Arc::new(catalog));
|
||||
let mut client = ClientFuture::new(stream, Box::new(sender), &io_loop.handle(), None);
|
||||
|
||||
let name = domain::Name::from_labels(vec!["ping", "example", "com"]);
|
||||
@ -207,8 +208,8 @@ fn create_sig0_ready_client(io_loop: &Core) -> (BasicClientHandle, domain::Name)
|
||||
let mut catalog = Catalog::new();
|
||||
catalog.upsert(authority.origin().clone(), authority);
|
||||
|
||||
let (stream, sender) = TestClientStream::new(catalog);
|
||||
let client = ClientFuture::new(stream, Box::new(sender), &io_loop.handle(), Some(signer));
|
||||
let (stream, sender) = TestClientStream::new(Arc::new(catalog));
|
||||
let client = ClientFuture::new(stream, Box::new(sender), &io_loop.handle(), Some(Arc::new(signer)));
|
||||
|
||||
(client, origin)
|
||||
}
|
||||
|
@ -5,50 +5,55 @@ extern crate tokio_core;
|
||||
extern crate trust_dns;
|
||||
extern crate trust_dns_integration;
|
||||
extern crate trust_dns_proto;
|
||||
extern crate trust_dns_rustls;
|
||||
extern crate trust_dns_server;
|
||||
|
||||
use std::io;
|
||||
use std::net::*;
|
||||
use std::sync::Arc;
|
||||
use std::time;
|
||||
|
||||
use chrono::Duration;
|
||||
use futures::Future;
|
||||
use futures::{Future, Stream};
|
||||
use openssl::rsa::Rsa;
|
||||
use tokio_core::reactor::Core;
|
||||
use tokio_core::reactor::Handle;
|
||||
|
||||
#[allow(deprecated)]
|
||||
use trust_dns::client::{Client, ClientConnection, SecureSyncClient, SyncClient};
|
||||
use trust_dns::error::ClientError;
|
||||
use trust_dns::error::{ClientError, ClientResult};
|
||||
use trust_dns::op::*;
|
||||
use trust_dns::rr::{DNSClass, Record, RecordType, domain, RData};
|
||||
use trust_dns::rr::dnssec::{Algorithm, KeyPair, Signer, TrustAnchor};
|
||||
use trust_dns::rr::dnssec::{Algorithm, KeyPair, Signer};
|
||||
use trust_dns::rr::rdata::*;
|
||||
use trust_dns::tcp::TcpClientConnection;
|
||||
use trust_dns::udp::UdpClientConnection;
|
||||
use trust_dns_proto::DnsStreamHandle;
|
||||
use trust_dns_server::authority::Catalog;
|
||||
use trust_dns_integration::{TestClientStream, NeverReturnsClientConnection};
|
||||
use trust_dns_integration::authority::{create_example, create_secure_example};
|
||||
use trust_dns_integration::authority::create_example;
|
||||
|
||||
pub struct TestClientConnection {
|
||||
catalog: Catalog,
|
||||
catalog: Arc<Catalog>,
|
||||
}
|
||||
|
||||
impl TestClientConnection {
|
||||
pub fn new(catalog: Catalog) -> TestClientConnection {
|
||||
TestClientConnection { catalog: catalog }
|
||||
TestClientConnection { catalog: Arc::new(catalog) }
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientConnection for TestClientConnection {
|
||||
type MessageStream = TestClientStream;
|
||||
|
||||
fn unwrap(
|
||||
self,
|
||||
) -> (Core, Box<Future<Item = Self::MessageStream, Error = io::Error>>, Box<DnsStreamHandle<Error = ClientError>>) {
|
||||
let io_loop = Core::new().unwrap();
|
||||
let (stream, handle) = TestClientStream::new(self.catalog);
|
||||
(io_loop, stream, Box::new(handle))
|
||||
fn new_stream(
|
||||
&self,
|
||||
_: &Handle,
|
||||
) -> ClientResult<
|
||||
(Box<Future<Item = Self::MessageStream, Error = io::Error>>,
|
||||
Box<DnsStreamHandle<Error = ClientError>>),
|
||||
> {
|
||||
let (stream, handle) = TestClientStream::new(self.catalog.clone());
|
||||
Ok((stream, Box::new(handle)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,7 +92,11 @@ fn test_query_tcp() {
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
fn test_query(client: SyncClient) {
|
||||
fn test_query<CC>(client: SyncClient<CC>)
|
||||
where
|
||||
CC: ClientConnection,
|
||||
<CC as ClientConnection>::MessageStream: Stream<Item = Vec<u8>, Error = io::Error> + 'static
|
||||
{
|
||||
use std::cmp::Ordering;
|
||||
let name = domain::Name::from_labels(vec!["WWW", "example", "com"]);
|
||||
|
||||
@ -119,36 +128,6 @@ fn test_query(client: SyncClient) {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(deprecated)]
|
||||
fn test_secure_query_example_nonet() {
|
||||
let authority = create_secure_example();
|
||||
|
||||
let trust_anchor = {
|
||||
let signers = authority.secure_keys();
|
||||
let public_key = signers
|
||||
.first()
|
||||
.expect("expected a key in the authority")
|
||||
.key()
|
||||
.to_public_key()
|
||||
.expect("could not convert keypair to public_key");
|
||||
|
||||
let mut trust_anchor = TrustAnchor::new();
|
||||
trust_anchor.insert_trust_anchor(public_key);
|
||||
|
||||
trust_anchor
|
||||
};
|
||||
|
||||
let mut catalog = Catalog::new();
|
||||
catalog.upsert(authority.origin().clone(), authority);
|
||||
|
||||
let client = SecureSyncClient::new(TestClientConnection::new(catalog))
|
||||
.trust_anchor(trust_anchor)
|
||||
.build();
|
||||
|
||||
test_secure_query_example(client);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
#[allow(deprecated)]
|
||||
@ -172,7 +151,11 @@ fn test_secure_query_example_tcp() {
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
fn test_secure_query_example(client: SecureSyncClient) {
|
||||
fn test_secure_query_example<CC>(client: SecureSyncClient<CC>)
|
||||
where
|
||||
CC: ClientConnection,
|
||||
<CC as ClientConnection>::MessageStream: Stream<Item = Vec<u8>, Error = io::Error> + 'static
|
||||
{
|
||||
let name = domain::Name::from_labels(vec!["www", "example", "com"]);
|
||||
let response = client.secure_query(&name, DNSClass::IN, RecordType::A);
|
||||
|
||||
@ -200,7 +183,11 @@ fn test_secure_query_example(client: SecureSyncClient) {
|
||||
}
|
||||
}
|
||||
|
||||
fn test_timeout_query(client: SyncClient) {
|
||||
fn test_timeout_query<CC>(client: SyncClient<CC>)
|
||||
where
|
||||
CC: ClientConnection,
|
||||
<CC as ClientConnection>::MessageStream: Stream<Item = Vec<u8>, Error = io::Error> + 'static
|
||||
{
|
||||
let name = domain::Name::from_labels(vec!["WWW", "example", "com"]);
|
||||
|
||||
let response = client.query(&name, DNSClass::IN, RecordType::A);
|
||||
@ -295,35 +282,6 @@ fn test_dnssec_rollernet_td_tcp_mixed_case() {
|
||||
).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(deprecated)]
|
||||
fn test_nsec_query_example_nonet() {
|
||||
let authority = create_secure_example();
|
||||
|
||||
let trust_anchor = {
|
||||
let signers = authority.secure_keys();
|
||||
let public_key = signers
|
||||
.first()
|
||||
.expect("expected a key in the authority")
|
||||
.key()
|
||||
.to_public_key()
|
||||
.expect("could not convert keypair to public_key");
|
||||
|
||||
let mut trust_anchor = TrustAnchor::new();
|
||||
trust_anchor.insert_trust_anchor(public_key);
|
||||
|
||||
trust_anchor
|
||||
};
|
||||
|
||||
let mut catalog = Catalog::new();
|
||||
catalog.upsert(authority.origin().clone(), authority);
|
||||
|
||||
let client = SecureSyncClient::new(TestClientConnection::new(catalog))
|
||||
.trust_anchor(trust_anchor)
|
||||
.build();
|
||||
test_nsec_query_example::<TestClientConnection>(client);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
#[allow(deprecated)]
|
||||
@ -345,7 +303,11 @@ fn test_nsec_query_example_tcp() {
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
fn test_nsec_query_example<C: ClientConnection>(client: SecureSyncClient) {
|
||||
fn test_nsec_query_example<CC>(client: SecureSyncClient<CC>)
|
||||
where
|
||||
CC: ClientConnection,
|
||||
<CC as ClientConnection>::MessageStream: Stream<Item = Vec<u8>, Error = io::Error> + 'static
|
||||
{
|
||||
let name = domain::Name::from_labels(vec!["none", "example", "com"]);
|
||||
|
||||
let response = client.secure_query(&name, DNSClass::IN, RecordType::A);
|
||||
@ -411,7 +373,7 @@ fn test_nsec_query_type() {
|
||||
// }
|
||||
|
||||
#[allow(deprecated)]
|
||||
fn create_sig0_ready_client(mut catalog: Catalog) -> (SyncClient, domain::Name) {
|
||||
fn create_sig0_ready_client(mut catalog: Catalog) -> (SyncClient<TestClientConnection>, domain::Name) {
|
||||
let mut authority = create_example();
|
||||
authority.set_allow_update(true);
|
||||
let origin = authority.origin().clone();
|
||||
|
@ -33,8 +33,13 @@ fn test_lookup() {
|
||||
catalog.upsert(authority.origin().clone(), authority);
|
||||
|
||||
let mut io_loop = Core::new().unwrap();
|
||||
let (stream, sender) = TestClientStream::new(catalog);
|
||||
let client = DnsFuture::new(stream, Box::new(sender), &io_loop.handle(), NoopMessageFinalizer::new());
|
||||
let (stream, sender) = TestClientStream::new(Arc::new(catalog));
|
||||
let client = DnsFuture::new(
|
||||
stream,
|
||||
Box::new(sender),
|
||||
&io_loop.handle(),
|
||||
NoopMessageFinalizer::new(),
|
||||
);
|
||||
|
||||
let lookup = InnerLookupFuture::lookup(
|
||||
vec![domain::Name::from_str("www.example.com.").unwrap()],
|
||||
@ -56,8 +61,13 @@ fn test_lookup_hosts() {
|
||||
catalog.upsert(authority.origin().clone(), authority);
|
||||
|
||||
let mut io_loop = Core::new().unwrap();
|
||||
let (stream, sender) = TestClientStream::new(catalog);
|
||||
let client = DnsFuture::new(stream, Box::new(sender), &io_loop.handle(), NoopMessageFinalizer::new());
|
||||
let (stream, sender) = TestClientStream::new(Arc::new(catalog));
|
||||
let client = DnsFuture::new(
|
||||
stream,
|
||||
Box::new(sender),
|
||||
&io_loop.handle(),
|
||||
NoopMessageFinalizer::new(),
|
||||
);
|
||||
|
||||
let mut hosts = Hosts::default();
|
||||
|
||||
|
@ -4,6 +4,7 @@ extern crate trust_dns_server;
|
||||
extern crate trust_dns_integration;
|
||||
|
||||
use std::net::*;
|
||||
use std::sync::Arc;
|
||||
|
||||
use tokio_core::reactor::Core;
|
||||
|
||||
@ -222,7 +223,7 @@ where
|
||||
catalog.upsert(authority.origin().clone(), authority);
|
||||
|
||||
let io_loop = Core::new().unwrap();
|
||||
let (stream, sender) = TestClientStream::new(catalog);
|
||||
let (stream, sender) = TestClientStream::new(Arc::new(catalog));
|
||||
let client = ClientFuture::new(stream, Box::new(sender), &io_loop.handle(), None);
|
||||
let client = MemoizeClientHandle::new(client);
|
||||
let secure_client = SecureClientHandle::with_trust_anchor(client, trust_anchor);
|
||||
|
@ -1,11 +1,16 @@
|
||||
extern crate futures;
|
||||
extern crate openssl;
|
||||
extern crate rustls;
|
||||
extern crate trust_dns;
|
||||
extern crate trust_dns_openssl;
|
||||
extern crate trust_dns_server;
|
||||
extern crate trust_dns_integration;
|
||||
extern crate trust_dns_openssl;
|
||||
extern crate trust_dns_rustls;
|
||||
extern crate trust_dns_server;
|
||||
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::Read;
|
||||
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket, TcpListener};
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
@ -13,22 +18,15 @@ use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use futures::Stream;
|
||||
use openssl::asn1::*;
|
||||
use openssl::bn::*;
|
||||
use openssl::hash::MessageDigest;
|
||||
use openssl::nid;
|
||||
use openssl::pkcs12::Pkcs12;
|
||||
use openssl::pkey::PKey;
|
||||
use openssl::rsa::Rsa;
|
||||
use openssl::x509::*;
|
||||
use openssl::x509::extension::*;
|
||||
use rustls::Certificate;
|
||||
|
||||
use trust_dns::client::*;
|
||||
use trust_dns::op::*;
|
||||
use trust_dns::rr::*;
|
||||
use trust_dns::udp::UdpClientConnection;
|
||||
use trust_dns::tcp::TcpClientConnection;
|
||||
use trust_dns_openssl::TlsClientConnection;
|
||||
use trust_dns_rustls::TlsClientConnection;
|
||||
|
||||
use trust_dns_server::ServerFuture;
|
||||
use trust_dns_server::authority::*;
|
||||
@ -89,67 +87,27 @@ fn test_server_www_tcp() {
|
||||
server_thread.join().unwrap();;
|
||||
}
|
||||
|
||||
fn read_file(path: &str) -> Vec<u8> {
|
||||
let mut bytes = vec![];
|
||||
|
||||
let mut file = File::open(path).expect(&format!("failed to open file: {}", path));
|
||||
file.read_to_end(&mut bytes).expect(&format!(
|
||||
"failed to read file: {}",
|
||||
path
|
||||
));
|
||||
bytes
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_server_www_tls() {
|
||||
let subject_name = "ns.example.com";
|
||||
let rsa = Rsa::generate(2048).unwrap();
|
||||
let pkey = PKey::from_rsa(rsa).unwrap();
|
||||
let dns_name = "ns.example.com";
|
||||
|
||||
let mut x509_name = X509NameBuilder::new().unwrap();
|
||||
x509_name
|
||||
.append_entry_by_nid(nid::COMMONNAME, subject_name)
|
||||
.unwrap();
|
||||
let x509_name = x509_name.build();
|
||||
let server_path = env::var("TDNS_SERVER_SRC_ROOT").unwrap_or("../server".to_owned());
|
||||
println!("using server src path: {}", server_path);
|
||||
|
||||
let mut serial: BigNum = BigNum::new().unwrap();
|
||||
serial.pseudo_rand(32, MSB_MAYBE_ZERO, false).unwrap();
|
||||
let serial = serial.to_asn1_integer().unwrap();
|
||||
let cert_der = read_file(&format!("{}/../tests/ca.der", server_path));
|
||||
|
||||
let mut x509_build = X509::builder().unwrap();
|
||||
x509_build
|
||||
.set_not_before(&Asn1Time::days_from_now(0).unwrap())
|
||||
.unwrap();
|
||||
x509_build
|
||||
.set_not_after(&Asn1Time::days_from_now(256).unwrap())
|
||||
.unwrap();
|
||||
x509_build.set_issuer_name(&x509_name).unwrap();
|
||||
x509_build.set_subject_name(&x509_name).unwrap();
|
||||
x509_build.set_pubkey(&pkey).unwrap();
|
||||
x509_build.set_serial_number(&serial).unwrap();
|
||||
|
||||
let ext_key_usage = ExtendedKeyUsage::new()
|
||||
.client_auth()
|
||||
.server_auth()
|
||||
.build()
|
||||
.unwrap();
|
||||
x509_build.append_extension(ext_key_usage).unwrap();
|
||||
|
||||
let subject_key_identifier = SubjectKeyIdentifier::new()
|
||||
.build(&x509_build.x509v3_context(None, None))
|
||||
.unwrap();
|
||||
x509_build.append_extension(subject_key_identifier).unwrap();
|
||||
|
||||
let authority_key_identifier = AuthorityKeyIdentifier::new()
|
||||
.keyid(true)
|
||||
.build(&x509_build.x509v3_context(None, None))
|
||||
.unwrap();
|
||||
x509_build
|
||||
.append_extension(authority_key_identifier)
|
||||
.unwrap();
|
||||
|
||||
// CA:FALSE
|
||||
let basic_constraints = BasicConstraints::new().critical().build().unwrap();
|
||||
x509_build.append_extension(basic_constraints).unwrap();
|
||||
|
||||
x509_build.sign(&pkey, MessageDigest::sha256()).unwrap();
|
||||
let cert = x509_build.build();
|
||||
let cert_der = cert.to_der().unwrap();
|
||||
|
||||
let pkcs12_builder = Pkcs12::builder();
|
||||
let pkcs12 = pkcs12_builder
|
||||
.build("mypass", subject_name, &pkey, &cert)
|
||||
.unwrap();
|
||||
let pkcs12_der = pkcs12.to_der().unwrap();
|
||||
let pkcs12_der = read_file(&format!("{}/../tests/cert.p12", server_path));
|
||||
|
||||
// Server address
|
||||
let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 0));
|
||||
@ -170,7 +128,7 @@ fn test_server_www_tls() {
|
||||
let client_thread = thread::Builder::new()
|
||||
.name("test_server:tcp:client".to_string())
|
||||
.spawn(move || {
|
||||
client_thread_www(lazy_tls_client(ipaddr, subject_name.to_string(), cert_der))
|
||||
client_thread_www(lazy_tls_client(ipaddr, dns_name.to_string(), cert_der))
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
@ -189,17 +147,13 @@ fn lazy_tcp_client(ipaddr: SocketAddr) -> TcpClientConnection {
|
||||
TcpClientConnection::new(ipaddr).unwrap()
|
||||
}
|
||||
|
||||
fn lazy_tls_client(
|
||||
ipaddr: SocketAddr,
|
||||
subject_name: String,
|
||||
cert_der: Vec<u8>,
|
||||
) -> TlsClientConnection {
|
||||
fn lazy_tls_client(ipaddr: SocketAddr, dns_name: String, cert_der: Vec<u8>) -> TlsClientConnection {
|
||||
let mut builder = TlsClientConnection::builder();
|
||||
|
||||
let trust_chain = X509::from_der(&cert_der).unwrap();
|
||||
let trust_chain = Certificate(cert_der);
|
||||
|
||||
builder.add_ca(trust_chain);
|
||||
builder.build(ipaddr, subject_name).unwrap()
|
||||
builder.build(ipaddr, dns_name).unwrap()
|
||||
}
|
||||
|
||||
fn client_thread_www<C: ClientConnection>(conn: C)
|
||||
|
@ -25,11 +25,9 @@ extern crate tokio_tls;
|
||||
extern crate trust_dns;
|
||||
extern crate trust_dns_proto;
|
||||
|
||||
pub mod tls_client_connection;
|
||||
pub mod tls_client_stream;
|
||||
pub mod tls_stream;
|
||||
|
||||
pub use self::tls_client_connection::{TlsClientConnection, TlsClientConnectionBuilder};
|
||||
pub use self::tls_client_stream::{TlsClientStream, TlsClientStreamBuilder};
|
||||
pub use self::tls_stream::{TlsStream, TlsStreamBuilder};
|
||||
|
||||
|
@ -87,7 +87,7 @@ fn tls_client_stream_test(server_addr: IpAddr, mtls: bool) {
|
||||
let root_cert_der = read_file(&format!("{}/../tests/ca.der", server_path));
|
||||
|
||||
// Generate X509 certificate
|
||||
let subject_name = "ns.example.com";
|
||||
let dns_name = "ns.example.com";
|
||||
let server_pkcs12_der = read_file(&format!("{}/../tests/cert.p12", server_path));
|
||||
|
||||
// TODO: need a timeout on listen
|
||||
@ -189,7 +189,7 @@ fn tls_client_stream_test(server_addr: IpAddr, mtls: bool) {
|
||||
// config_mtls(&root_pkey, &root_name, &root_cert, &mut builder);
|
||||
// }
|
||||
|
||||
let (stream, sender) = builder.build(server_addr, subject_name.to_string(), &io_loop.handle());
|
||||
let (stream, sender) = builder.build(server_addr, dns_name.to_string(), &io_loop.handle());
|
||||
|
||||
// TODO: there is a race failure here... a race with the server thread most likely...
|
||||
let mut stream = io_loop.run(stream).ok().expect("run failed to get stream");
|
||||
|
@ -1,104 +0,0 @@
|
||||
// Copyright (C) 2015 Benjamin Fry <benjaminfry@me.com>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! TLS based DNS client connection for Client impls
|
||||
|
||||
use std::net::SocketAddr;
|
||||
use std::io;
|
||||
|
||||
use futures::Future;
|
||||
use native_tls::Certificate;
|
||||
#[cfg(feature = "mtls")]
|
||||
use native_tls::Pkcs12;
|
||||
use tokio_core::reactor::Core;
|
||||
|
||||
use trust_dns::error::*;
|
||||
use trust_dns::client::ClientConnection;
|
||||
use trust_dns_proto::DnsStreamHandle;
|
||||
|
||||
use {TlsClientStream, TlsClientStreamBuilder};
|
||||
|
||||
/// Tls client connection
|
||||
///
|
||||
/// Use with `trust_dns::client::Client` impls
|
||||
pub struct TlsClientConnection {
|
||||
io_loop: Core,
|
||||
tls_client_stream: Box<Future<Item = TlsClientStream, Error = io::Error>>,
|
||||
client_stream_handle: Box<DnsStreamHandle<Error = ClientError>>,
|
||||
}
|
||||
|
||||
impl TlsClientConnection {
|
||||
/// Creates a new builder for the construction of a TlsClientConnection.
|
||||
pub fn builder() -> TlsClientConnectionBuilder {
|
||||
TlsClientConnectionBuilder(TlsClientStreamBuilder::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientConnection for TlsClientConnection {
|
||||
type MessageStream = TlsClientStream;
|
||||
|
||||
fn unwrap(
|
||||
self,
|
||||
) -> (Core, Box<Future<Item = Self::MessageStream, Error = io::Error>>, Box<DnsStreamHandle<Error = ClientError>>) {
|
||||
(
|
||||
self.io_loop,
|
||||
self.tls_client_stream,
|
||||
self.client_stream_handle,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// A builder for the TlsClientStream.
|
||||
pub struct TlsClientConnectionBuilder(TlsClientStreamBuilder);
|
||||
|
||||
impl TlsClientConnectionBuilder {
|
||||
/// Add a custom trusted peer certificate or certificate auhtority.
|
||||
///
|
||||
/// If this is the 'client' then the 'server' must have it associated as it's `identity`, or have had the `identity` signed by this certificate.
|
||||
pub fn add_ca(&mut self, ca: Certificate) {
|
||||
self.0.add_ca(ca);
|
||||
}
|
||||
|
||||
/// Client side identity for client auth in TLS (aka mutual TLS auth)
|
||||
#[cfg(feature = "mtls")]
|
||||
pub fn identity(&mut self, pkcs12: Pkcs12) {
|
||||
self.0.identity(pkcs12);
|
||||
}
|
||||
|
||||
/// Creates a new client connection.
|
||||
///
|
||||
/// *Note* this has side affects of establishing the connection to the specified DNS server and
|
||||
/// starting the event_loop. Expect this to change in the future.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `name_server` - IP and Port for the remote DNS resolver
|
||||
/// * `subject_name` - The Subject Public Key Info (SPKI) name as associated to a certificate
|
||||
/// * `loop_handle` - The reactor Core handle
|
||||
pub fn build(
|
||||
self,
|
||||
name_server: SocketAddr,
|
||||
subject_name: String,
|
||||
) -> ClientResult<TlsClientConnection> {
|
||||
let io_loop = try!(Core::new());
|
||||
let (tls_client_stream, handle) =
|
||||
self.0.build(name_server, subject_name, &io_loop.handle());
|
||||
|
||||
Ok(TlsClientConnection {
|
||||
io_loop: io_loop,
|
||||
tls_client_stream: tls_client_stream,
|
||||
client_stream_handle: handle,
|
||||
})
|
||||
}
|
||||
}
|
@ -56,15 +56,15 @@ impl TlsClientStreamBuilder {
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `name_server` - IP and Port for the remote DNS resolver
|
||||
/// * `subject_name` - The Subject Public Key Info (SPKI) name as associated to a certificate
|
||||
/// * `dns_name` - The DNS name, Subject Public Key Info (SPKI) name, as associated to a certificate
|
||||
/// * `loop_handle` - The reactor Core handle
|
||||
pub fn build(
|
||||
self,
|
||||
name_server: SocketAddr,
|
||||
subject_name: String,
|
||||
dns_name: String,
|
||||
loop_handle: &Handle,
|
||||
) -> (Box<Future<Item = TlsClientStream, Error = io::Error>>, Box<DnsStreamHandle<Error = ClientError>>) {
|
||||
let (stream_future, sender) = self.0.build(name_server, subject_name, loop_handle);
|
||||
let (stream_future, sender) = self.0.build(name_server, dns_name, loop_handle);
|
||||
|
||||
let new_future: Box<Future<Item = TlsClientStream, Error = io::Error>> = Box::new(
|
||||
stream_future.map(move |tls_stream| TcpClientStream::from_stream(tls_stream)),
|
||||
|
@ -133,12 +133,12 @@ impl TlsStreamBuilder {
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `name_server` - IP and Port for the remote DNS resolver
|
||||
/// * `subject_name` - The Subject Public Key Info (SPKI) name as associated to a certificate
|
||||
/// * `dns_name` - The DNS name, Public Key Info (SPKI) name, as associated to a certificate
|
||||
/// * `loop_handle` - The reactor Core handle
|
||||
pub fn build(
|
||||
self,
|
||||
name_server: SocketAddr,
|
||||
subject_name: String,
|
||||
dns_name: String,
|
||||
loop_handle: &Handle,
|
||||
) -> (Box<Future<Item = TlsStream, Error = io::Error>>, BufStreamHandle<ClientError>) {
|
||||
let (message_sender, outbound_messages) = unbounded();
|
||||
@ -167,7 +167,7 @@ impl TlsStreamBuilder {
|
||||
Box::new(
|
||||
tcp.and_then(move |tcp_stream| {
|
||||
tls_connector
|
||||
.connect_async(&subject_name, tcp_stream)
|
||||
.connect_async(&dns_name, tcp_stream)
|
||||
.map(move |s| {
|
||||
TcpStream::from_stream_with_receiver(s, name_server, outbound_messages)
|
||||
})
|
||||
|
@ -23,11 +23,9 @@ extern crate tokio_openssl;
|
||||
extern crate trust_dns;
|
||||
extern crate trust_dns_proto;
|
||||
|
||||
mod tls_client_connection;
|
||||
mod tls_client_stream;
|
||||
pub mod tls_server;
|
||||
mod tls_stream;
|
||||
|
||||
pub use self::tls_client_connection::{TlsClientConnection, TlsClientConnectionBuilder};
|
||||
pub use self::tls_client_stream::{TlsClientStream, TlsClientStreamBuilder};
|
||||
pub use self::tls_stream::{TlsStream, TlsStreamBuilder, tls_stream_from_existing_tls_stream};
|
||||
|
@ -1,102 +0,0 @@
|
||||
// Copyright (C) 2015 Benjamin Fry <benjaminfry@me.com>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! TLS based DNS client connection for Client impls
|
||||
|
||||
use std::net::SocketAddr;
|
||||
use std::io;
|
||||
|
||||
use futures::Future;
|
||||
use openssl::x509::X509 as OpensslX509;
|
||||
use tokio_core::reactor::Core;
|
||||
|
||||
use trust_dns::error::*;
|
||||
use trust_dns::client::ClientConnection;
|
||||
use trust_dns_proto::DnsStreamHandle;
|
||||
|
||||
use super::{TlsClientStream, TlsClientStreamBuilder};
|
||||
|
||||
/// Tls client connection
|
||||
///
|
||||
/// Use with `trust_dns::client::Client` impls
|
||||
pub struct TlsClientConnection {
|
||||
io_loop: Core,
|
||||
tls_client_stream: Box<Future<Item = TlsClientStream, Error = io::Error>>,
|
||||
client_stream_handle: Box<DnsStreamHandle<Error = ClientError>>,
|
||||
}
|
||||
|
||||
impl TlsClientConnection {
|
||||
/// Creates a new builder for the construction of a TlsClientConnection.
|
||||
pub fn builder() -> TlsClientConnectionBuilder {
|
||||
TlsClientConnectionBuilder(TlsClientStreamBuilder::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientConnection for TlsClientConnection {
|
||||
type MessageStream = TlsClientStream;
|
||||
|
||||
fn unwrap(
|
||||
self,
|
||||
) -> (Core, Box<Future<Item = Self::MessageStream, Error = io::Error>>, Box<DnsStreamHandle<Error = ClientError>>) {
|
||||
(
|
||||
self.io_loop,
|
||||
self.tls_client_stream,
|
||||
self.client_stream_handle,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// A builder for the TlsClientStream.
|
||||
pub struct TlsClientConnectionBuilder(TlsClientStreamBuilder);
|
||||
|
||||
impl TlsClientConnectionBuilder {
|
||||
/// Add a custom trusted peer certificate or certificate auhtority.
|
||||
///
|
||||
/// If this is the 'client' then the 'server' must have it associated as it's `identity`, or have had the `identity` signed by this certificate.
|
||||
pub fn add_ca(&mut self, ca: OpensslX509) {
|
||||
self.0.add_ca(ca);
|
||||
}
|
||||
|
||||
/// Client side identity for client auth in TLS (aka mutual TLS auth)
|
||||
#[cfg(feature = "mtls")]
|
||||
pub fn identity(&mut self, pkcs12: Pkcs12) {
|
||||
self.0.identity(pkcs12);
|
||||
}
|
||||
|
||||
/// Creates a new client connection.
|
||||
///
|
||||
/// *Note* this has side affects of establishing the connection to the specified DNS server and
|
||||
/// starting the event_loop. Expect this to change in the future.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `name_server` - IP and Port for the remote DNS resolver
|
||||
/// * `subject_name` - The Subject Public Key Info (SPKI) name as associated to a certificate
|
||||
/// * `loop_handle` - The reactor Core handle
|
||||
pub fn build(
|
||||
self,
|
||||
name_server: SocketAddr,
|
||||
subject_name: String,
|
||||
) -> ClientResult<TlsClientConnection> {
|
||||
let io_loop = try!(Core::new());
|
||||
let (tls_client_stream, handle) =
|
||||
self.0.build(name_server, subject_name, &io_loop.handle());
|
||||
|
||||
Ok(TlsClientConnection {
|
||||
io_loop: io_loop,
|
||||
tls_client_stream: tls_client_stream,
|
||||
client_stream_handle: handle,
|
||||
})
|
||||
}
|
||||
}
|
@ -64,16 +64,16 @@ impl TlsClientStreamBuilder {
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `name_server` - IP and Port for the remote DNS resolver
|
||||
/// * `subject_name` - The Subject Public Key Info (SPKI) name as associated to a certificate
|
||||
/// * `dns_name` - The DNS name, Subject Public Key Info (SPKI) name, as associated to a certificate
|
||||
/// * `loop_handle` - The reactor Core handle
|
||||
pub fn build(
|
||||
self,
|
||||
name_server: SocketAddr,
|
||||
subject_name: String,
|
||||
dns_name: String,
|
||||
loop_handle: &Handle,
|
||||
) -> (Box<Future<Item = TlsClientStream, Error = io::Error>>,
|
||||
Box<DnsStreamHandle<Error = ClientError>>) {
|
||||
let (stream_future, sender) = self.0.build(name_server, subject_name, loop_handle);
|
||||
let (stream_future, sender) = self.0.build(name_server, dns_name, loop_handle);
|
||||
|
||||
let new_future: Box<Future<Item = TlsClientStream, Error = io::Error>> = Box::new(
|
||||
stream_future.map(move |tls_stream| TcpClientStream::from_stream(tls_stream)),
|
||||
|
@ -178,12 +178,12 @@ impl TlsStreamBuilder {
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `name_server` - IP and Port for the remote DNS resolver
|
||||
/// * `subject_name` - The Subject Public Key Info (SPKI) name as associated to a certificate
|
||||
/// * `dns_name` - The DNS name, Subject Public Key Info (SPKI) name, as associated to a certificate
|
||||
/// * `loop_handle` - The reactor Core handle
|
||||
pub fn build(
|
||||
self,
|
||||
name_server: SocketAddr,
|
||||
subject_name: String,
|
||||
dns_name: String,
|
||||
loop_handle: &Handle,
|
||||
) -> (Box<Future<Item = TlsStream, Error = io::Error>>, BufStreamHandle<ClientError>) {
|
||||
let (message_sender, outbound_messages) = unbounded();
|
||||
@ -212,7 +212,7 @@ impl TlsStreamBuilder {
|
||||
Box::new(
|
||||
tcp.and_then(move |tcp_stream| {
|
||||
tls_connector
|
||||
.connect_async(&subject_name, tcp_stream)
|
||||
.connect_async(&dns_name, tcp_stream)
|
||||
.map(move |s| {
|
||||
TcpStream::from_stream_with_receiver(s, name_server, outbound_messages)
|
||||
})
|
||||
|
@ -5,6 +5,8 @@
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
|
||||
use std::borrow::Borrow;
|
||||
use std::sync::Arc;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::io;
|
||||
use std::marker::PhantomData;
|
||||
@ -80,7 +82,7 @@ where
|
||||
stream_handle: Box<DnsStreamHandle<Error = E>>,
|
||||
new_receiver: Peekable<StreamFuse<UnboundedReceiver<(Message, Complete<Result<Message, E>>)>>>,
|
||||
active_requests: HashMap<u16, (Complete<Result<Message, E>>, Timeout)>,
|
||||
signer: Option<MF>,
|
||||
signer: Option<Arc<MF>>,
|
||||
}
|
||||
|
||||
impl<S, E, MF> DnsFuture<S, E, MF>
|
||||
@ -103,7 +105,7 @@ where
|
||||
stream: Box<Future<Item = S, Error = io::Error>>,
|
||||
stream_handle: Box<DnsStreamHandle<Error = E>>,
|
||||
loop_handle: &Handle,
|
||||
signer: Option<MF>,
|
||||
signer: Option<Arc<MF>>,
|
||||
) -> BasicDnsHandle<E> {
|
||||
Self::with_timeout(
|
||||
stream,
|
||||
@ -131,7 +133,7 @@ where
|
||||
stream_handle: Box<DnsStreamHandle<Error = E>>,
|
||||
loop_handle: &Handle,
|
||||
timeout_duration: Duration,
|
||||
signer: Option<MF>,
|
||||
signer: Option<Arc<MF>>,
|
||||
) -> BasicDnsHandle<E> {
|
||||
let (sender, rx) = unbounded();
|
||||
|
||||
@ -275,7 +277,7 @@ where
|
||||
// update messages need to be signed.
|
||||
if let OpCode::Update = message.op_code() {
|
||||
if let Some(ref signer) = self.signer {
|
||||
if let Err(e) = message.finalize(signer, now) {
|
||||
if let Err(e) = message.finalize::<MF>(signer.borrow(), now) {
|
||||
warn!("could not sign message: {}", e);
|
||||
complete.send(Err(e.into())).expect(
|
||||
"error notifying wait, possible future leak",
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
//! Basic protocol message for DNS
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::mem;
|
||||
|
||||
use error::*;
|
||||
@ -648,7 +649,7 @@ pub struct NoopMessageFinalizer;
|
||||
|
||||
impl NoopMessageFinalizer {
|
||||
/// Always returns None
|
||||
pub fn new() -> Option<Self> {
|
||||
pub fn new() -> Option<Arc<Self>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
- Resolver no longer depends on Client
|
||||
- *breaking* Resolver no longer returns io:Errors, use `From<ResolveError>` for `io::Error`
|
||||
- Resolver is now `Send`
|
||||
|
||||
### Added
|
||||
|
||||
|
@ -17,7 +17,7 @@ use futures::{Async, Future, Poll, task};
|
||||
|
||||
use trust_dns_proto::DnsHandle;
|
||||
use trust_dns_proto::op::{Message, Query, ResponseCode};
|
||||
use trust_dns_proto::rr::{Name, RData, RecordType};
|
||||
use trust_dns_proto::rr::{RData, RecordType};
|
||||
|
||||
use error::*;
|
||||
use lookup::Lookup;
|
||||
@ -46,10 +46,10 @@ impl LruValue {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct DnsLru(LruCache<Query, LruValue>);
|
||||
pub(crate) struct DnsLru(LruCache<Query, LruValue>);
|
||||
|
||||
impl DnsLru {
|
||||
fn new(capacity: usize) -> Self {
|
||||
pub(crate) fn new(capacity: usize) -> Self {
|
||||
DnsLru(LruCache::new(capacity))
|
||||
}
|
||||
|
||||
@ -160,7 +160,7 @@ impl<C: DnsHandle<Error = ResolveError> + 'static> CachingClient<C> {
|
||||
Self::with_cache(Arc::new(Mutex::new(DnsLru::new(max_size))), client)
|
||||
}
|
||||
|
||||
fn with_cache(lru: Arc<Mutex<DnsLru>>, client: C) -> Self {
|
||||
pub(crate) fn with_cache(lru: Arc<Mutex<DnsLru>>, client: C) -> Self {
|
||||
CachingClient { lru, client }
|
||||
}
|
||||
|
||||
|
@ -6,12 +6,11 @@
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
|
||||
//! Structs for creating and using a Resolver
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::net::IpAddr;
|
||||
use std::io;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use tokio_core::reactor::Core;
|
||||
use tokio_core::reactor::{Core, Handle};
|
||||
use trust_dns_proto::rr::RecordType;
|
||||
|
||||
use config::{ResolverConfig, ResolverOpts};
|
||||
@ -19,14 +18,18 @@ use error::*;
|
||||
use lookup;
|
||||
use lookup::Lookup;
|
||||
use lookup_ip::LookupIp;
|
||||
use lookup_state::DnsLru;
|
||||
use ResolverFuture;
|
||||
|
||||
/// The Resolver is used for performing DNS queries.
|
||||
///
|
||||
/// For forward (A) lookups, hostname -> IP address, see: `Resolver::lookup_ip`
|
||||
///
|
||||
/// Special note about resource consumption. The Resolver and all TRust-DNS software is built around the Tokio async-io library. This synchronous Resolver is intended to be a simpler wrapper for of the [`trust_dns_resolver::ResolverFuture`]. To allow the Resolver to be [`Send`] + [`Sync`], the construction of the `ResolverFuture` is lazy, this means some of the features of the `ResolverFuture`, like performance based resolution via the most efficient `NameServer` will be lost (the lookup cache is shared across invocations of the `Resolver`). If these other features of the TRust-DNS Resolver are desired, please use the tokio based `ResolverFuture`.
|
||||
pub struct Resolver {
|
||||
resolver_future: RefCell<ResolverFuture>,
|
||||
io_loop: RefCell<Core>,
|
||||
config: ResolverConfig,
|
||||
options: ResolverOpts,
|
||||
lru: Arc<Mutex<DnsLru>>,
|
||||
}
|
||||
|
||||
macro_rules! lookup_fn {
|
||||
@ -39,11 +42,9 @@ macro_rules! lookup_fn {
|
||||
///
|
||||
/// * `query` - a str which parses to a domain name, failure to parse will return an error
|
||||
pub fn $p(&self, query: &str) -> ResolveResult<$l> {
|
||||
self.io_loop.borrow_mut().run(
|
||||
self.resolver_future
|
||||
.borrow()
|
||||
.$p(query),
|
||||
)
|
||||
let mut reactor = Core::new()?;
|
||||
let future = self.construct_and_run(&reactor.handle())?;
|
||||
reactor.run(future.$p(query))
|
||||
}
|
||||
};
|
||||
($p:ident, $l:ty, $t:ty) => {
|
||||
@ -53,11 +54,9 @@ pub fn $p(&self, query: &str) -> ResolveResult<$l> {
|
||||
///
|
||||
/// * `query` - a type which can be converted to `Name` via `From`.
|
||||
pub fn $p(&self, query: $t) -> ResolveResult<$l> {
|
||||
self.io_loop.borrow_mut().run(
|
||||
self.resolver_future
|
||||
.borrow()
|
||||
.$p(query),
|
||||
)
|
||||
let mut reactor = Core::new()?;
|
||||
let future = self.construct_and_run(&reactor.handle())?;
|
||||
reactor.run(future.$p(query))
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -71,41 +70,63 @@ impl Resolver {
|
||||
/// * `client_connection` - ClientConnection for establishing the connection to the DNS server
|
||||
///
|
||||
/// # Returns
|
||||
/// A new Resolver
|
||||
///
|
||||
/// A new Resolver or an error if there was an error with the configuration.
|
||||
pub fn new(config: ResolverConfig, options: ResolverOpts) -> io::Result<Self> {
|
||||
let io_loop = Core::new()?;
|
||||
let resolver = ResolverFuture::new(config, options, &io_loop.handle());
|
||||
|
||||
let lru = Arc::new(Mutex::new(DnsLru::new(options.cache_size)));
|
||||
Ok(Resolver {
|
||||
resolver_future: RefCell::new(resolver),
|
||||
io_loop: RefCell::new(io_loop),
|
||||
config,
|
||||
options,
|
||||
lru,
|
||||
})
|
||||
}
|
||||
|
||||
/// Constructs a new Resolver with default config and default options.
|
||||
///
|
||||
/// See [`ResolverConfig::default`] and [`ResolverOpts::default`] for more information.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A new Resolver or an error if there was an error with the configuration.
|
||||
pub fn default() -> io::Result<Self> {
|
||||
Self::new(ResolverConfig::default(), ResolverOpts::default())
|
||||
}
|
||||
|
||||
/// Constructs a new Resolver with the system configuration.
|
||||
///
|
||||
/// This will use `/etc/resolv.conf` on Unix OSes and the registry on Windows.
|
||||
#[cfg(any(unix,
|
||||
all(feature = "ipconfig", target_os = "windows", target_pointer_width = "64")))]
|
||||
all(feature = "ipconfig", target_os = "windows", target_pointer_width = "64")))]
|
||||
pub fn from_system_conf() -> io::Result<Self> {
|
||||
let (config, options) = super::system_conf::read_system_conf()?;
|
||||
Self::new(config, options)
|
||||
}
|
||||
|
||||
/// Constructs a new Core
|
||||
fn construct_and_run(&self, reactor: &Handle) -> ResolveResult<ResolverFuture> {
|
||||
// TODO: get a pair of the Future and the Handle, to run on the same Core.
|
||||
let future = ResolverFuture::with_cache(
|
||||
self.config.clone(),
|
||||
self.options.clone(),
|
||||
self.lru.clone(),
|
||||
reactor,
|
||||
);
|
||||
|
||||
Ok(future)
|
||||
}
|
||||
|
||||
/// Generic lookup for any RecordType
|
||||
///
|
||||
/// *WARNING* This interface may change in the future
|
||||
/// *WARNING* This interface may change in the future, please use [`Self::lookkup_ip`] or another variant for more stable interfaces.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `name` - name of the record to lookup, if name is not a valid domain name, an error will be returned
|
||||
/// * `record_type` - type of record to lookup
|
||||
pub fn lookup(&self, name: &str, record_type: RecordType) -> ResolveResult<Lookup> {
|
||||
self.io_loop.borrow_mut().run(
|
||||
self.resolver_future
|
||||
.borrow()
|
||||
.lookup(name, record_type),
|
||||
)
|
||||
let mut reactor = Core::new()?;
|
||||
let future = self.construct_and_run(&reactor.handle())?;
|
||||
reactor.run(future.lookup(name, record_type))
|
||||
}
|
||||
|
||||
/// Performs a dual-stack DNS lookup for the IP for the given hostname.
|
||||
@ -116,11 +137,9 @@ impl Resolver {
|
||||
///
|
||||
/// * `host` - string hostname, if this is an invalid hostname, an error will be returned.
|
||||
pub fn lookup_ip(&self, host: &str) -> ResolveResult<LookupIp> {
|
||||
self.io_loop.borrow_mut().run(
|
||||
self.resolver_future
|
||||
.borrow()
|
||||
.lookup_ip(host),
|
||||
)
|
||||
let mut reactor = Core::new()?;
|
||||
let future = self.construct_and_run(&reactor.handle())?;
|
||||
reactor.run(future.lookup_ip(host))
|
||||
}
|
||||
|
||||
/// Performs a DNS lookup for an SRV record for the specified service type and protocol at the given name.
|
||||
@ -138,13 +157,9 @@ impl Resolver {
|
||||
protocol: &str,
|
||||
name: &str,
|
||||
) -> ResolveResult<lookup::SrvLookup> {
|
||||
self.io_loop.borrow_mut().run(
|
||||
self.resolver_future.borrow().lookup_service(
|
||||
service,
|
||||
protocol,
|
||||
name,
|
||||
),
|
||||
)
|
||||
let mut reactor = Core::new()?;
|
||||
let future = self.construct_and_run(&reactor.handle())?;
|
||||
reactor.run(future.lookup_service(service, protocol, name))
|
||||
}
|
||||
|
||||
lookup_fn!(reverse_lookup, lookup::ReverseLookup, IpAddr);
|
||||
@ -161,6 +176,15 @@ mod tests {
|
||||
|
||||
use super::*;
|
||||
|
||||
fn require_send_sync<S: Send + Sync>() {
|
||||
assert!(true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_resolver_sendable() {
|
||||
require_send_sync::<Resolver>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lookup() {
|
||||
let resolver = Resolver::new(ResolverConfig::default(), ResolverOpts::default()).unwrap();
|
||||
@ -193,7 +217,7 @@ mod tests {
|
||||
#[test]
|
||||
#[ignore]
|
||||
#[cfg(any(unix,
|
||||
all(feature = "ipconfig", target_os = "windows", target_pointer_width = "64")))]
|
||||
all(feature = "ipconfig", target_os = "windows", target_pointer_width = "64")))]
|
||||
fn test_system_lookup() {
|
||||
let resolver = Resolver::from_system_conf().unwrap();
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
//! Structs for creating and using a ResolverFuture
|
||||
use std::net::IpAddr;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use futures::Future;
|
||||
use tokio_core::reactor::Handle;
|
||||
@ -23,11 +23,12 @@ use error::*;
|
||||
use lookup_state::CachingClient;
|
||||
use name_server_pool::{NameServerPool, StandardConnection};
|
||||
use lookup_ip::{InnerLookupIpFuture, LookupIpFuture};
|
||||
use lookup_state::DnsLru;
|
||||
use lookup;
|
||||
use lookup::{InnerLookupFuture, LookupEither, LookupFuture};
|
||||
use hosts::Hosts;
|
||||
|
||||
/// Root Handle to communicate with teh ResolverFuture
|
||||
/// Root Handle to communicate with the ResolverFuture
|
||||
///
|
||||
/// This can be used directly to perform queries. See [`trust_dns_proto::SecureClientHandle`] for
|
||||
/// a DNSSEc chain validator.
|
||||
@ -94,8 +95,28 @@ pub fn $p(&self, query: $t) -> $f {
|
||||
}
|
||||
|
||||
impl ResolverFuture {
|
||||
/// Construct a new ResolverFuture with the associated Client.
|
||||
/// Construct a new ResolverFuture with the associated Client and configuration.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `config` - configuration, name_servers, etc. for the Resolver
|
||||
/// * `options` - basic lookup options for the resolver
|
||||
/// * `reactor` - the [`tokio_core::Core`] to use with this future
|
||||
pub fn new(config: ResolverConfig, options: ResolverOpts, reactor: &Handle) -> Self {
|
||||
let lru = Arc::new(Mutex::new(DnsLru::new(options.cache_size)));
|
||||
|
||||
Self::with_cache(config, options, lru, reactor)
|
||||
}
|
||||
|
||||
/// Construct a new ResolverFuture with the associated Client and configuration.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `config` - configuration, name_servers, etc. for the Resolver
|
||||
/// * `options` - basic lookup options for the resolver
|
||||
/// * `lru` - the cache to be used with the resolver
|
||||
/// * `reactor` - the [`tokio_core::Core`] to use with this future
|
||||
pub(crate) fn with_cache(config: ResolverConfig, options: ResolverOpts, lru: Arc<Mutex<DnsLru>>, reactor: &Handle) -> Self {
|
||||
let pool = NameServerPool::<BasicResolverHandle, StandardConnection>::from_config(
|
||||
&config,
|
||||
&options,
|
||||
@ -126,7 +147,7 @@ impl ResolverFuture {
|
||||
ResolverFuture {
|
||||
config,
|
||||
options,
|
||||
client_cache: CachingClient::new(options.cache_size, either),
|
||||
client_cache: CachingClient::with_cache(lru, either),
|
||||
hosts: hosts,
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ fn tls_client_stream_test(server_addr: IpAddr, mtls: bool) {
|
||||
let root_cert_der_copy = root_cert_der.clone();
|
||||
|
||||
// Generate X509 certificate
|
||||
let subject_name = "ns.example.com";
|
||||
let dns_name = "ns.example.com";
|
||||
let server_pkcs12_der = read_file(&format!("{}/../tests/cert.p12", server_path));
|
||||
|
||||
// TODO: need a timeout on listen
|
||||
@ -201,7 +201,7 @@ fn tls_client_stream_test(server_addr: IpAddr, mtls: bool) {
|
||||
// config_mtls(&root_pkey, &root_name, &root_cert, &mut builder);
|
||||
// }
|
||||
|
||||
let (stream, sender) = builder.build(server_addr, subject_name.to_string(), &io_loop.handle());
|
||||
let (stream, sender) = builder.build(server_addr, dns_name.to_string(), &io_loop.handle());
|
||||
|
||||
// TODO: there is a race failure here... a race with the server thread most likely...
|
||||
let mut stream = io_loop.run(stream).ok().expect("run failed to get stream");
|
||||
|
@ -19,7 +19,7 @@ use std::io;
|
||||
|
||||
use futures::Future;
|
||||
use rustls::Certificate;
|
||||
use tokio_core::reactor::Core;
|
||||
use tokio_core::reactor::Handle;
|
||||
|
||||
use trust_dns::error::*;
|
||||
use trust_dns::client::ClientConnection;
|
||||
@ -33,9 +33,9 @@ use TlsClientStreamBuilder;
|
||||
///
|
||||
/// Use with `trust_dns::client::Client` impls
|
||||
pub struct TlsClientConnection {
|
||||
io_loop: Core,
|
||||
tls_client_stream: Box<Future<Item = TlsClientStream, Error = io::Error>>,
|
||||
client_stream_handle: Box<DnsStreamHandle<Error = ClientError>>,
|
||||
builder: TlsClientStreamBuilder,
|
||||
name_server: SocketAddr,
|
||||
dns_name: String,
|
||||
}
|
||||
|
||||
impl TlsClientConnection {
|
||||
@ -47,14 +47,20 @@ impl TlsClientConnection {
|
||||
impl ClientConnection for TlsClientConnection {
|
||||
type MessageStream = TlsClientStream;
|
||||
|
||||
fn unwrap(
|
||||
self,
|
||||
) -> (Core, Box<Future<Item = Self::MessageStream, Error = io::Error>>, Box<DnsStreamHandle<Error = ClientError>>) {
|
||||
(
|
||||
self.io_loop,
|
||||
self.tls_client_stream,
|
||||
self.client_stream_handle,
|
||||
)
|
||||
fn new_stream(
|
||||
&self,
|
||||
handle: &Handle,
|
||||
) -> ClientResult<
|
||||
(Box<Future<Item = Self::MessageStream, Error = io::Error>>,
|
||||
Box<DnsStreamHandle<Error = ClientError>>),
|
||||
> {
|
||||
let (tls_client_stream, handle) = self.builder.clone().build(
|
||||
self.name_server,
|
||||
self.dns_name.clone(),
|
||||
handle,
|
||||
);
|
||||
|
||||
Ok((tls_client_stream, handle))
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,21 +88,17 @@ impl TlsClientConnectionBuilder {
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `name_server` - IP and Port for the remote DNS resolver
|
||||
/// * `subject_name` - The Subject Public Key Info (SPKI) name as associated to a certificate
|
||||
/// * `dns_name` - The DNS name, Subject Public Key Info (SPKI) name, as associated to a certificate
|
||||
/// * `loop_handle` - The reactor Core handle
|
||||
pub fn build(
|
||||
self,
|
||||
name_server: SocketAddr,
|
||||
subject_name: String,
|
||||
dns_name: String,
|
||||
) -> ClientResult<TlsClientConnection> {
|
||||
let io_loop = try!(Core::new());
|
||||
let (tls_client_stream, handle) =
|
||||
self.0.build(name_server, subject_name, &io_loop.handle());
|
||||
|
||||
Ok(TlsClientConnection {
|
||||
io_loop: io_loop,
|
||||
tls_client_stream: tls_client_stream,
|
||||
client_stream_handle: handle,
|
||||
builder: self.0,
|
||||
name_server,
|
||||
dns_name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ use TlsStreamBuilder;
|
||||
|
||||
pub type TlsClientStream = TcpClientStream<TokioTlsStream<TokioTcpStream, ClientSession>>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TlsClientStreamBuilder(TlsStreamBuilder);
|
||||
|
||||
impl TlsClientStreamBuilder {
|
||||
@ -47,15 +48,15 @@ impl TlsClientStreamBuilder {
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `name_server` - IP and Port for the remote DNS resolver
|
||||
/// * `subject_name` - The Subject Public Key Info (SPKI) name as associated to a certificate
|
||||
/// * `dns_name` - The DNS name, Subject Public Key Info (SPKI) name, as associated to a certificate
|
||||
/// * `loop_handle` - The reactor Core handle
|
||||
pub fn build(
|
||||
self,
|
||||
name_server: SocketAddr,
|
||||
subject_name: String,
|
||||
dns_name: String,
|
||||
loop_handle: &Handle,
|
||||
) -> (Box<Future<Item = TlsClientStream, Error = io::Error>>, Box<DnsStreamHandle<Error = ClientError>>) {
|
||||
let (stream_future, sender) = self.0.build(name_server, subject_name, loop_handle);
|
||||
let (stream_future, sender) = self.0.build(name_server, dns_name, loop_handle);
|
||||
|
||||
let new_future: Box<Future<Item = TlsClientStream, Error = io::Error>> = Box::new(
|
||||
stream_future.map(move |tls_stream| TcpClientStream::from_stream(tls_stream)),
|
||||
|
@ -66,6 +66,7 @@ pub fn tls_from_stream(
|
||||
(stream, message_sender)
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TlsStreamBuilder {
|
||||
ca_chain: Vec<Certificate>,
|
||||
//identity: Option<Pkcs12>,
|
||||
@ -117,12 +118,12 @@ impl TlsStreamBuilder {
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `name_server` - IP and Port for the remote DNS resolver
|
||||
/// * `subject_name` - The Subject Public Key Info (SPKI) name as associated to a certificate
|
||||
/// * `dns_name` - The DNS name, Subject Public Key Info (SPKI) name, as associated to a certificate
|
||||
/// * `loop_handle` - The reactor Core handle
|
||||
pub fn build(
|
||||
self,
|
||||
name_server: SocketAddr,
|
||||
subject_name: String,
|
||||
dns_name: String,
|
||||
loop_handle: &Handle,
|
||||
) -> (Box<Future<Item = TlsStream, Error = io::Error>>, BufStreamHandle<ClientError>) {
|
||||
let (message_sender, outbound_messages) = unbounded();
|
||||
@ -151,7 +152,7 @@ impl TlsStreamBuilder {
|
||||
Box::new(
|
||||
tcp.and_then(move |tcp_stream| {
|
||||
tls_connector
|
||||
.connect_async(&subject_name, tcp_stream)
|
||||
.connect_async(&dns_name, tcp_stream)
|
||||
.map(move |s| {
|
||||
TcpStream::from_stream_with_receiver(s, name_server, outbound_messages)
|
||||
})
|
||||
|
@ -35,7 +35,7 @@ export TDNS_SERVER_SRC_ROOT=./server
|
||||
export COVERALLS_PARALLEL=true
|
||||
|
||||
SRC_PATHS=client/src,native-tls/src,openssl/src,proto/src,resolver/src,rustls/src,server/src
|
||||
EXCLUDE_PATHS=client/src/error,proto/src/error.rs,server/src/error
|
||||
EXCLUDE_PATHS=client/src/error,proto/src/error.rs,server/src/error,compatibility-tests/src/lib.rs
|
||||
|
||||
for i in target/debug/deps/trust_dns*-* target/debug/deps/*_tests-* ; do
|
||||
if [ -f $i ] && [ -x $i ]; then
|
||||
|
@ -20,8 +20,9 @@ use trust_dns::client::*;
|
||||
use trust_dns::rr::*;
|
||||
use trust_dns::tcp::TcpClientStream;
|
||||
|
||||
#[cfg(feature = "tls")]
|
||||
use trust_dns_openssl::TlsClientStreamBuilder;
|
||||
// TODO: Needed for when TLS tests are added back
|
||||
// #[cfg(feature = "tls")]
|
||||
// use trust_dns_openssl::TlsClientStreamBuilder;
|
||||
|
||||
use server_harness::{named_test_harness, query_a};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user