dndx_fork_tokio_tun/
tun.rs

1use crate::linux::interface::Interface;
2use crate::linux::io::TunIo;
3use crate::linux::params::Params;
4use crate::result::Result;
5use futures::ready;
6use std::ffi::CString;
7use std::io;
8use std::io::{Read, Write};
9use std::net::{IpAddr, Ipv4Addr};
10use std::os::unix::io::{AsRawFd, RawFd};
11use std::pin::Pin;
12use std::sync::Arc;
13use std::task::{self, Context, Poll};
14use tokio::io::unix::AsyncFd;
15use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
16
17/// Represents a Tun/Tap device. Use [`TunBuilder`](struct.TunBuilder.html) to create a new instance of [`Tun`](struct.Tun.html).
18pub struct Tun {
19    iface: Arc<Interface>,
20    io: AsyncFd<TunIo>,
21}
22
23impl AsRawFd for Tun {
24    fn as_raw_fd(&self) -> RawFd {
25        self.io.as_raw_fd()
26    }
27}
28
29impl AsyncRead for Tun {
30    fn poll_read(
31        self: Pin<&mut Self>,
32        cx: &mut Context<'_>,
33        buf: &mut ReadBuf<'_>,
34    ) -> task::Poll<io::Result<()>> {
35        let self_mut = self.get_mut();
36        let mut b = vec![0; buf.capacity()];
37        loop {
38            let mut guard = ready!(self_mut.io.poll_read_ready_mut(cx))?;
39
40            match guard.try_io(|inner| inner.get_mut().read(&mut b)) {
41                Ok(n) => return Poll::Ready(n.map(|n| buf.put_slice(&b[..n]))),
42                Err(_) => continue,
43            }
44        }
45    }
46}
47
48impl AsyncWrite for Tun {
49    fn poll_write(
50        self: Pin<&mut Self>,
51        cx: &mut Context<'_>,
52        buf: &[u8],
53    ) -> task::Poll<io::Result<usize>> {
54        let self_mut = self.get_mut();
55        loop {
56            let mut guard = ready!(self_mut.io.poll_write_ready_mut(cx))?;
57
58            match guard.try_io(|inner| inner.get_mut().write(buf)) {
59                Ok(result) => return Poll::Ready(result),
60                Err(_would_block) => continue,
61            }
62        }
63    }
64
65    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> task::Poll<io::Result<()>> {
66        let self_mut = self.get_mut();
67        loop {
68            let mut guard = ready!(self_mut.io.poll_write_ready_mut(cx))?;
69
70            match guard.try_io(|inner| inner.get_mut().flush()) {
71                Ok(result) => return Poll::Ready(result),
72                Err(_) => continue,
73            }
74        }
75    }
76
77    fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context<'_>) -> task::Poll<io::Result<()>> {
78        Poll::Ready(Ok(()))
79    }
80}
81
82impl Tun {
83    /// Creates a new instance of Tun/Tap device.
84    pub(crate) fn new(params: Params) -> Result<Self> {
85        let iface = Self::allocate(params, 1)?;
86        let fd = iface.files()[0];
87        Ok(Self {
88            iface: Arc::new(iface),
89            io: AsyncFd::new(TunIo::from(fd))?,
90        })
91    }
92
93    /// Creates a new instance of Tun/Tap device.
94    pub(crate) fn new_mq(params: Params, queues: usize) -> Result<Vec<Self>> {
95        let iface = Self::allocate(params, queues)?;
96        let mut tuns = Vec::with_capacity(queues);
97        let files = iface.files().to_vec();
98        let iface = Arc::new(iface);
99        for fd in files.into_iter() {
100            tuns.push(Self {
101                iface: iface.clone(),
102                io: AsyncFd::new(TunIo::from(fd))?,
103            })
104        }
105        Ok(tuns)
106    }
107
108    fn allocate(params: Params, queues: usize) -> Result<Interface> {
109        let mut fds = Vec::with_capacity(queues);
110        let path = CString::new("/dev/net/tun")?;
111        for _ in 0..queues {
112            fds.push(unsafe { libc::open(path.as_ptr(), libc::O_RDWR | libc::O_NONBLOCK) });
113        }
114        let iface = Interface::new(
115            fds,
116            params.name.as_deref().unwrap_or_default(),
117            params.flags,
118        )?;
119        iface.init(params)?;
120        Ok(iface)
121    }
122
123    /// Receives a packet from the Tun/Tap interface
124    ///
125    /// This method takes &self, so it is possible to call this method concurrently with other methods on this struct.
126    pub async fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
127        loop {
128            let mut guard = self.io.readable().await?;
129
130            match guard.try_io(|inner| inner.get_ref().recv(buf)) {
131                Ok(res) => return res,
132                Err(_) => continue,
133            }
134        }
135    }
136
137    /// Sends a packet to the Tun/Tap interface
138    ///
139    /// This method takes &self, so it is possible to call this method concurrently with other methods on this struct.
140    pub async fn send(&self, buf: &[u8]) -> io::Result<usize> {
141        loop {
142            let mut guard = self.io.writable().await?;
143
144            match guard.try_io(|inner| inner.get_ref().send(buf)) {
145                Ok(res) => return res,
146                Err(_) => continue,
147            }
148        }
149    }
150
151    /// Try to receive a packet from the Tun/Tap interface
152    ///
153    /// When there is no pending data, `Err(io::ErrorKind::WouldBlock)` is returned.
154    ///
155    /// This method takes &self, so it is possible to call this method concurrently with other methods on this struct.
156    pub fn try_recv(&self, buf: &mut [u8]) -> io::Result<usize> {
157        self.io.get_ref().recv(buf)
158    }
159
160    /// Try to send a packet to the Tun/Tap interface
161    ///
162    /// When the socket buffer is full, `Err(io::ErrorKind::WouldBlock)` is returned.
163    ///
164    /// This method takes &self, so it is possible to call this method concurrently with other methods on this struct.
165    pub fn try_send(&self, buf: &[u8]) -> io::Result<usize> {
166        self.io.get_ref().send(buf)
167    }
168
169    /// Returns the name of Tun/Tap device.
170    pub fn name(&self) -> &str {
171        self.iface.name()
172    }
173
174    /// Returns the value of MTU.
175    pub fn mtu(&self) -> Result<i32> {
176        self.iface.mtu(None)
177    }
178
179    /// Returns the IPv4 address of MTU.
180    pub fn address(&self) -> Result<IpAddr> {
181        self.iface.address(None, 0)
182    }
183
184    /// Returns the IPv4 destination address of MTU.
185    pub fn destination(&self) -> Result<Ipv4Addr> {
186        self.iface.destination(None)
187    }
188
189    /// Returns the IPv4 broadcast address of MTU.
190    pub fn broadcast(&self) -> Result<Ipv4Addr> {
191        self.iface.broadcast(None)
192    }
193
194    /// Returns the IPv4 netmask address of MTU.
195    pub fn netmask(&self) -> Result<Ipv4Addr> {
196        self.iface.netmask(None)
197    }
198
199    /// Returns the flags of MTU.
200    pub fn flags(&self) -> Result<i16> {
201        self.iface.flags(None)
202    }
203}