tokio_tun/
tun.rs

1use crate::Result;
2use crate::TunBuilder;
3use crate::linux::interface::Interface;
4use crate::linux::io::TunIo;
5use crate::linux::params::Params;
6use std::io::{self, ErrorKind, IoSlice, Read, Write};
7use std::mem;
8use std::net::Ipv4Addr;
9use std::os::raw::c_char;
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
17static TUN: &[u8] = b"/dev/net/tun\0";
18
19// Taken from the `futures` crate
20macro_rules! ready {
21    ($e:expr $(,)?) => {
22        match $e {
23            std::task::Poll::Ready(t) => t,
24            std::task::Poll::Pending => return std::task::Poll::Pending,
25        }
26    };
27}
28
29/// Represents a Tun/Tap device. Use [`TunBuilder`](struct.TunBuilder.html) to create a new instance of [`Tun`](struct.Tun.html).
30pub struct Tun {
31    iface: Arc<Interface>,
32    io: AsyncFd<TunIo>,
33}
34
35impl AsRawFd for Tun {
36    fn as_raw_fd(&self) -> RawFd {
37        self.io.as_raw_fd()
38    }
39}
40
41impl AsyncRead for Tun {
42    fn poll_read(
43        self: Pin<&mut Self>,
44        cx: &mut Context<'_>,
45        buf: &mut ReadBuf<'_>,
46    ) -> task::Poll<io::Result<()>> {
47        let self_mut = self.get_mut();
48        loop {
49            let mut guard = ready!(self_mut.io.poll_read_ready_mut(cx))?;
50
51            match guard.try_io(|inner| inner.get_mut().read(buf.initialize_unfilled())) {
52                Ok(Ok(n)) => {
53                    buf.set_filled(buf.filled().len() + n);
54                    return Poll::Ready(Ok(()));
55                }
56                Ok(Err(err)) => return Poll::Ready(Err(err)),
57                Err(_) => continue,
58            }
59        }
60    }
61}
62
63impl AsyncWrite for Tun {
64    fn poll_write(
65        self: Pin<&mut Self>,
66        cx: &mut Context<'_>,
67        buf: &[u8],
68    ) -> task::Poll<io::Result<usize>> {
69        let self_mut = self.get_mut();
70        loop {
71            let mut guard = ready!(self_mut.io.poll_write_ready_mut(cx))?;
72
73            match guard.try_io(|inner| inner.get_mut().write(buf)) {
74                Ok(result) => return Poll::Ready(result),
75                Err(_would_block) => continue,
76            }
77        }
78    }
79
80    fn poll_write_vectored(
81        self: Pin<&mut Self>,
82        cx: &mut Context<'_>,
83        bufs: &[IoSlice<'_>],
84    ) -> Poll<std::result::Result<usize, io::Error>> {
85        let self_mut = self.get_mut();
86        loop {
87            let mut guard = ready!(self_mut.io.poll_write_ready_mut(cx))?;
88
89            match guard.try_io(|inner| inner.get_mut().write_vectored(bufs)) {
90                Ok(result) => return Poll::Ready(result),
91                Err(_would_block) => continue,
92            }
93        }
94    }
95
96    fn is_write_vectored(&self) -> bool {
97        true
98    }
99
100    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> task::Poll<io::Result<()>> {
101        let self_mut = self.get_mut();
102        loop {
103            let mut guard = ready!(self_mut.io.poll_write_ready_mut(cx))?;
104
105            match guard.try_io(|inner| inner.get_mut().flush()) {
106                Ok(result) => return Poll::Ready(result),
107                Err(_) => continue,
108            }
109        }
110    }
111
112    fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context<'_>) -> task::Poll<io::Result<()>> {
113        Poll::Ready(Ok(()))
114    }
115}
116
117impl Tun {
118    pub fn builder() -> TunBuilder {
119        TunBuilder::new()
120    }
121
122    /// Creates a new instance of Tun/Tap device.
123    pub(crate) fn new(params: Params) -> Result<Self> {
124        let iface = Self::allocate(params, 1)?;
125        let fd = iface.files()[0];
126        Ok(Self {
127            iface: Arc::new(iface),
128            io: AsyncFd::new(TunIo::from(fd))?,
129        })
130    }
131
132    /// Creates a new instance of Tun/Tap device.
133    pub(crate) fn new_mq(params: Params, queues: usize) -> Result<Vec<Self>> {
134        let iface = Self::allocate(params, queues)?;
135        let mut tuns = Vec::with_capacity(queues);
136        let iface = Arc::new(iface);
137        for &fd in iface.files() {
138            tuns.push(Self {
139                iface: iface.clone(),
140                io: AsyncFd::new(TunIo::from(fd))?,
141            })
142        }
143        Ok(tuns)
144    }
145
146    fn allocate(params: Params, queues: usize) -> Result<Interface> {
147        let extra_flags = if params.cloexec { libc::O_CLOEXEC } else { 0 };
148
149        let fds = (0..queues)
150            .map(|_| unsafe {
151                match libc::open(
152                    TUN.as_ptr().cast::<c_char>(),
153                    libc::O_RDWR | libc::O_NONBLOCK | extra_flags,
154                ) {
155                    fd if fd >= 0 => Ok(fd),
156                    _ => Err(io::Error::last_os_error().into()),
157                }
158            })
159            .collect::<Result<Vec<_>>>()?;
160
161        let iface = Interface::new(
162            fds,
163            params.name.as_deref().unwrap_or_default(),
164            params.flags,
165            params.cloexec,
166        )?;
167        iface.init(params)?;
168        Ok(iface)
169    }
170
171    /// Receives a packet from the Tun/Tap interface.
172    ///
173    /// This method takes &self, so it is possible to call this method concurrently with other methods on this struct.
174    pub async fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
175        loop {
176            let mut guard = self.io.readable().await?;
177            match guard.try_io(|inner| inner.get_ref().recv(buf)) {
178                Ok(res) => return res,
179                Err(_) => continue,
180            }
181        }
182    }
183
184    /// Sends a buffer to the Tun/Tap interface. Returns the number of bytes written to the device.
185    ///
186    /// This method takes &self, so it is possible to call this method concurrently with other methods on this struct.
187    pub async fn send(&self, buf: &[u8]) -> io::Result<usize> {
188        loop {
189            let mut guard = self.io.writable().await?;
190            match guard.try_io(|inner| inner.get_ref().send(buf)) {
191                Ok(res) => return res,
192                Err(_) => continue,
193            }
194        }
195    }
196
197    /// Sends all of a buffer to the Tun/Tap interface.
198    ///
199    /// This method takes &self, so it is possible to call this method concurrently with other methods on this struct.
200    pub async fn send_all(&self, buf: &[u8]) -> io::Result<()> {
201        let mut remaining = buf;
202        while !remaining.is_empty() {
203            match self.send(remaining).await? {
204                0 => return Err(ErrorKind::WriteZero.into()),
205                n => {
206                    let (_, rest) = mem::take(&mut remaining).split_at(n);
207                    remaining = rest;
208                }
209            }
210        }
211        Ok(())
212    }
213
214    /// Sends vectored buffers to the Tun/Tap interface. Returns the number of bytes written to the device.
215    ///
216    /// This method takes &self, so it is possible to call this method concurrently with other methods on this struct.
217    pub async fn sendv(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
218        loop {
219            let mut guard = self.io.writable().await?;
220            match guard.try_io(|inner| inner.get_ref().sendv(bufs)) {
221                Ok(res) => return res,
222                Err(_) => continue,
223            }
224        }
225    }
226
227    /// Attempts to write an entire vectored buffer to this writer.
228    ///
229    /// This method will continuously call `sendv` until all data has been
230    /// written or an error occurs. This method will not return until all data has
231    /// been written.
232    ///
233    /// This implementation provides optimal performance for high-throughput scenarios
234    /// by advancing buffers in-place without allocations.
235    ///
236    /// # Errors
237    ///
238    /// This function will return the first error that `sendv` returns.
239    pub async fn sendv_all(&self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
240        let mut bufs = bufs;
241        while !bufs.is_empty() {
242            match self.sendv(bufs).await? {
243                0 => {
244                    return Err(std::io::Error::new(
245                        std::io::ErrorKind::WriteZero,
246                        "failed to write whole buffer",
247                    ));
248                }
249                n => {
250                    IoSlice::advance_slices(&mut bufs, n);
251                }
252            }
253        }
254        Ok(())
255    }
256
257    /// Tries to receive a buffer from the Tun/Tap interface.
258    ///
259    /// When there is no pending data, `Err(io::ErrorKind::WouldBlock)` is returned.
260    ///
261    /// This method takes &self, so it is possible to call this method concurrently with other methods on this struct.
262    pub fn try_recv(&self, buf: &mut [u8]) -> io::Result<usize> {
263        self.io.get_ref().recv(buf)
264    }
265
266    /// Tries to send a packet to the Tun/Tap interface.
267    ///
268    /// When the socket buffer is full, `Err(io::ErrorKind::WouldBlock)` is returned.
269    ///
270    /// This method takes &self, so it is possible to call this method concurrently with other methods on this struct.
271    pub fn try_send(&self, buf: &[u8]) -> io::Result<usize> {
272        self.io.get_ref().send(buf)
273    }
274
275    /// Tries to send several different buffers to the Tun/Tap interface.
276    ///
277    /// When the socket buffer is full, `Err(io::ErrorKind::WouldBlock)` is returned.
278    ///
279    /// This method takes &self, so it is possible to call this method concurrently with other methods on this struct.
280    pub fn try_sendv(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
281        self.io.get_ref().sendv(bufs)
282    }
283
284    /// Returns the name of Tun/Tap device.
285    pub fn name(&self) -> &str {
286        self.iface.name()
287    }
288
289    /// Returns the value of MTU.
290    pub fn mtu(&self) -> Result<i32> {
291        self.iface.mtu(None)
292    }
293
294    /// Returns the IPv4 address of MTU.
295    pub fn address(&self) -> Result<Ipv4Addr> {
296        self.iface.address(None)
297    }
298
299    /// Returns the IPv4 destination address of MTU.
300    pub fn destination(&self) -> Result<Ipv4Addr> {
301        self.iface.destination(None)
302    }
303
304    /// Returns the IPv4 broadcast address of MTU.
305    pub fn broadcast(&self) -> Result<Ipv4Addr> {
306        self.iface.broadcast(None)
307    }
308
309    /// Returns the IPv4 netmask address of MTU.
310    pub fn netmask(&self) -> Result<Ipv4Addr> {
311        self.iface.netmask(None)
312    }
313
314    /// Returns the flags of MTU.
315    pub fn flags(&self) -> Result<i16> {
316        self.iface.flags(None)
317    }
318}