dns/
lib.rs

1// Copyright 2020 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use async_trait::async_trait;
6use fuchsia_async::{self as fasync, TimeoutExt};
7
8use futures::future::FutureExt;
9use futures::Future;
10use std::io;
11use std::time::Duration;
12use trust_dns_proto::{Executor, Time};
13
14pub mod async_resolver;
15pub mod config;
16pub mod tcp;
17pub mod test_util;
18pub mod udp;
19
20/// Default DNS server port.
21pub const DEFAULT_PORT: u16 = 53;
22
23/// A Fuchsia LocalExecutor which implements the `trust_dns_proto::Executor` trait.
24pub struct FuchsiaExec(fasync::LocalExecutor);
25
26impl FuchsiaExec {
27    /// Constructs a Fuchsia LocalExecutor.
28    pub fn new() -> Result<Self, zx::Status> {
29        Ok(Self(fasync::LocalExecutor::new()))
30    }
31
32    /// Gets a mutable reference to the internal `fuchsia_async::LocalExecutor`.
33    pub fn get(&mut self) -> &mut fasync::LocalExecutor {
34        &mut self.0
35    }
36}
37
38impl Executor for FuchsiaExec {
39    fn new() -> Self {
40        Self::new().expect("failed to create fuchsia executor")
41    }
42
43    fn block_on<F: Future>(&mut self, future: F) -> F::Output {
44        self.0.run_singlethreaded(future)
45    }
46}
47
48/// A Fuchsia Time with time-related capabilities which implements the `trust_dns_proto::Time` trait.
49pub struct FuchsiaTime;
50
51#[async_trait]
52impl Time for FuchsiaTime {
53    async fn timeout<F: 'static + Future + Send>(
54        duration: Duration,
55        future: F,
56    ) -> Result<F::Output, io::Error> {
57        let nanos = i64::try_from(duration.as_nanos()).expect("failed to cast the input into i64 ");
58        let zx_duration = zx::MonotonicDuration::from_nanos(nanos);
59
60        future
61            .map(|output| Ok(output))
62            .on_timeout(fasync::MonotonicInstant::after(zx_duration), || {
63                Err(io::Error::new(io::ErrorKind::TimedOut, "future timed out"))
64            })
65            .await
66    }
67
68    async fn delay_for(duration: Duration) -> () {
69        let nanos = i64::try_from(duration.as_nanos()).expect("failed to cast the input into i64");
70        let zx_duration = zx::MonotonicDuration::from_nanos(nanos);
71        fasync::Timer::new(fasync::MonotonicInstant::after(zx_duration)).await
72    }
73}