dndx_fork_tokio_tun/
tun.rs1use 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
17pub 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 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 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 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 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 pub fn try_recv(&self, buf: &mut [u8]) -> io::Result<usize> {
157 self.io.get_ref().recv(buf)
158 }
159
160 pub fn try_send(&self, buf: &[u8]) -> io::Result<usize> {
166 self.io.get_ref().send(buf)
167 }
168
169 pub fn name(&self) -> &str {
171 self.iface.name()
172 }
173
174 pub fn mtu(&self) -> Result<i32> {
176 self.iface.mtu(None)
177 }
178
179 pub fn address(&self) -> Result<IpAddr> {
181 self.iface.address(None, 0)
182 }
183
184 pub fn destination(&self) -> Result<Ipv4Addr> {
186 self.iface.destination(None)
187 }
188
189 pub fn broadcast(&self) -> Result<Ipv4Addr> {
191 self.iface.broadcast(None)
192 }
193
194 pub fn netmask(&self) -> Result<Ipv4Addr> {
196 self.iface.netmask(None)
197 }
198
199 pub fn flags(&self) -> Result<i16> {
201 self.iface.flags(None)
202 }
203}