dns/
tcp.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 crate::FuchsiaTime;
6use async_trait::async_trait;
7use fuchsia_async::net::TcpStream;
8use futures::io::{AsyncRead, AsyncWrite};
9use futures::task::{Context, Poll};
10use std::io;
11use std::net::SocketAddr;
12use std::pin::Pin;
13use trust_dns_proto::tcp::Connect;
14
15/// A Fuchsia-compatible implementation of trust-dns's `Connect` trait which allows
16/// creating a `TcpStream` to a particular destination.
17pub struct DnsTcpStream(TcpStream);
18
19impl trust_dns_proto::tcp::DnsTcpStream for DnsTcpStream {
20    type Time = FuchsiaTime;
21}
22
23#[async_trait]
24impl Connect for DnsTcpStream {
25    async fn connect(addr: SocketAddr) -> io::Result<Self> {
26        TcpStream::connect(addr)?.await.map(Self)
27    }
28
29    async fn connect_with_bind(
30        addr: SocketAddr,
31        bind_addr: Option<SocketAddr>,
32    ) -> io::Result<Self> {
33        match bind_addr {
34            Some(bind_addr) => {
35                unimplemented!(
36                    "https://fxbug.dev/42180092: cannot bind to {:?}; `connect_with_bind` is \
37                    unimplemented",
38                    bind_addr,
39                )
40            }
41            None => Self::connect(addr).await,
42        }
43    }
44}
45
46impl AsyncRead for DnsTcpStream {
47    fn poll_read(
48        mut self: Pin<&mut Self>,
49        cx: &mut Context<'_>,
50        buf: &mut [u8],
51    ) -> Poll<io::Result<usize>> {
52        Pin::new(&mut self.0).poll_read(cx, buf)
53    }
54}
55
56impl AsyncWrite for DnsTcpStream {
57    fn poll_write(
58        mut self: Pin<&mut Self>,
59        cx: &mut Context<'_>,
60        buf: &[u8],
61    ) -> Poll<Result<usize, io::Error>> {
62        Pin::new(&mut self.0).poll_write(cx, buf)
63    }
64    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
65        Pin::new(&mut self.0).poll_flush(cx)
66    }
67
68    fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
69        Pin::new(&mut self.0).poll_close(cx)
70    }
71}
72
73#[cfg(test)]
74mod test {
75    use super::*;
76
77    use crate::FuchsiaExec;
78    use net_declare::std::ip;
79
80    #[test]
81    fn test_tcp_stream_ipv4() {
82        use trust_dns_proto::tests::tcp_stream_test;
83        let exec = FuchsiaExec::new().expect("failed to create fuchsia executor");
84        tcp_stream_test::<DnsTcpStream, FuchsiaExec, FuchsiaTime>(ip!("127.0.0.1"), exec)
85    }
86
87    #[test]
88    fn test_tcp_stream_ipv6() {
89        use trust_dns_proto::tests::tcp_stream_test;
90        let exec = FuchsiaExec::new().expect("failed to create fuchsia executor");
91        tcp_stream_test::<DnsTcpStream, FuchsiaExec, FuchsiaTime>(ip!("::1"), exec)
92    }
93
94    #[test]
95    fn test_tcp_client_stream_ipv4() {
96        use trust_dns_proto::tests::tcp_client_stream_test;
97        let exec = FuchsiaExec::new().expect("failed to create fuchsia executor");
98        tcp_client_stream_test::<DnsTcpStream, FuchsiaExec, FuchsiaTime>(ip!("127.0.0.1"), exec)
99    }
100
101    #[test]
102    fn test_tcp_client_stream_ipv6() {
103        use trust_dns_proto::tests::tcp_client_stream_test;
104        let exec = FuchsiaExec::new().expect("failed to create fuchsia executor");
105        tcp_client_stream_test::<DnsTcpStream, FuchsiaExec, FuchsiaTime>(ip!("::1"), exec)
106    }
107}