pub fn machine<F>(addr: Ipv4Addr, mask: u8, plug: Plug, task: F) -> thread::JoinHandle<F::Output>
where
    F: Future + Send + 'static,
    F::Output: Send + 'static,
{
    thread::spawn(move || {
        namespace::unshare_network().unwrap();

        let create_tun_iface = || {
            let iface = iface::Iface::new().unwrap();
            iface.set_ipv4_addr(addr, mask).unwrap();
            iface.put_up().unwrap();
            iface.add_ipv4_route(Ipv4Range::global().into()).unwrap();

            #[cfg(not(feature = "tokio2"))]
            let iface = smol::Async::new(iface).unwrap();
            #[cfg(feature = "tokio2")]
            let iface = tokio::TokioFd::new(iface).unwrap();

            let (mut tx, mut rx) = plug.split();
            let (mut reader, mut writer) = iface.split();

            let reader_task = async move {
                loop {
                    let mut buf = [0; libc::ETH_FRAME_LEN as usize];
                    let n = reader.read(&mut buf).await.unwrap();
                    if n == 0 {
                        break;
                    }
                    // drop ipv6 packets
                    if buf[0] >> 4 != 4 {
                        continue;
                    }
                    log::debug!("machine {}: sending packet", addr);
                    if tx.send(buf[..n].to_vec()).await.is_err() {
                        break;
                    }
                }
            };

            let writer_task = async move {
                loop {
                    if let Some(packet) = rx.next().await {
                        log::debug!("machine {}: received packet", addr);
                        let n = writer.write(&packet).await.unwrap();
                        if n == 0 {
                            break;
                        }
                    } else {
                        break;
                    }
                }
            };

            (reader_task, writer_task)
        };

        #[cfg(not(feature = "tokio2"))]
        let result = smol::run(async move {
            let (reader_task, writer_task) = create_tun_iface();
            smol::Task::spawn(reader_task).detach();
            smol::Task::spawn(writer_task).detach();
            task.await
        });
        #[cfg(feature = "tokio2")]
        let result = {
            let mut rt = ::tokio::runtime::Builder::new()
                .threaded_scheduler()
                .enable_all()
                .build()
                .unwrap();
            rt.block_on(async move {
                let (reader_task, writer_task) = create_tun_iface();
                ::tokio::task::spawn(reader_task);
                ::tokio::task::spawn(writer_task);
                task.await
            })
        };

        result
    })
}
/// Spawns a thread in a new network namespace and configures a TUN interface that sends and
/// receives IP packets from the tx/rx channels and runs some UDP/TCP networking code in task.
Spawns a thread in a new network namespace and configures a TUN interface that sends and
receives IP packets from the tx/rx channels and runs some UDP/TCP networking code in task.
Spawns a thread in a new network namespace and configures a TUN interface that sends and receives IP packets from the tx / rx channels and runs some UDP / TCP networking code in task .
pub fn machine<F>(addr: Ipv4Addr, mask: u8, plug: Plug, task: F) -> thread::JoinHandle<F::Output>
where
    F: Future + Send + 'static,
    F::Output: Send + 'static,
{
    thread::spawn(move || {
        namespace::unshare_network().unwrap();
        let create_tun_iface = || {
            let iface = iface::Iface::new().unwrap();
            iface.set_ipv4_addr(addr, mask).unwrap();
            iface.put_up().unwrap();
            iface.add_ipv4_route(Ipv4Range::global().into()).unwrap();
            #[cfg(not(feature = "tokio2"))]
            let iface = smol::Async::new(iface).unwrap();
            #[cfg(feature = "tokio2")]
            let iface = tokio::TokioFd::new(iface).unwrap();
            let (mut tx, mut rx) = plug.split();
            let (mut reader, mut writer) = iface.split();
            let reader_task = async move {
                loop {
                    let mut buf = [0; libc::ETH_FRAME_LEN as usize];
                    let n = reader.read(&mut buf).await.unwrap();
                    if n == 0 {
                        break;
                    }
                    // drop ipv6 packets
                    if buf[0] >> 4 != 4 {
                        continue;
                    }
                    log::debug!("machine {}: sending packet", addr);
                    if tx.send(buf[..n].to_vec()).await.is_err() {
                        break;
                    }
                }
            };
            let writer_task = async move {
                loop {
                    if let Some(packet) = rx.next().await {
                        log::debug!("machine {}: received packet", addr);
                        let n = writer.write(&packet).await.unwrap();
                        if n == 0 {
                            break;
                        }
                    } else {
                        break;
                    }
                }
            };
            (reader_task, writer_task)
        };
        #[cfg(not(feature = "tokio2"))]
        let result = smol::run(async move {
            let (reader_task, writer_task) = create_tun_iface();
            smol::Task::spawn(reader_task).detach();
            smol::Task::spawn(writer_task).detach();
            task.await
        });
        #[cfg(feature = "tokio2")]
        let result = {
            let mut rt = ::tokio::runtime::Builder::new()
                .threaded_scheduler()
                .enable_all()
                .build()
                .unwrap();
            rt.block_on(async move {
                let (reader_task, writer_task) = create_tun_iface();
                ::tokio::task::spawn(reader_task);
                ::tokio::task::spawn(writer_task);
                task.await
            })
        };
        result
    })
}
pub fn machine < F > ( addr : Ipv4Addr , mask : u8 , plug : Plug , task : F ) -> thread :: JoinHandle < F :: Output > where F : Future + Send + ' static , F :: Output : Send + ' static , { thread :: spawn ( move | | { namespace :: unshare_network ( ) . unwrap ( ) ; let create_tun_iface = | | { let iface = iface :: Iface :: new ( ) . unwrap ( ) ; iface . set_ipv4_addr ( addr , mask ) . unwrap ( ) ; iface . put_up ( ) . unwrap ( ) ; iface . add_ipv4_route ( Ipv4Range :: global ( ) . into ( ) ) . unwrap ( ) ; # [ cfg ( not ( feature " " ) ) ] let iface = smol :: Async :: new ( iface ) . unwrap ( ) ; # [ cfg ( feature " " ) ] let iface = tokio :: TokioFd :: new ( iface ) . unwrap ( ) ; let ( mut tx , mut rx ) = plug . split ( ) ; let ( mut reader , mut writer ) = iface . split ( ) ; let reader_task = async move { loop { let mut buf = [ 0 ; libc :: ETH_FRAME_LEN as usize ] ; let n = reader . read ( & mut buf ) . await . unwrap ( ) ; if n == 0 { break ; } // drop ipv6 packets if buf [ 0 ] >> 4 != 4 { continue ; } log :: debug ! ( " " addr ) ; if tx . send ( buf [ .. n ] . to_vec ( ) ) . await . is_err ( ) { break ; } } } ; let writer_task = async move { loop { if let Some ( packet ) = rx . next ( ) . await { log :: debug ! ( " " addr ) ; let n = writer . write ( & packet ) . await . unwrap ( ) ; if n == 0 { break ; } } else { break ; } } } ; ( reader_task , writer_task ) } ; # [ cfg ( not ( feature " " ) ) ] let result = smol :: run ( async move { let ( reader_task , writer_task ) = create_tun_iface ( ) ; smol :: Task :: spawn ( reader_task ) . detach ( ) ; smol :: Task :: spawn ( writer_task ) . detach ( ) ; task . await } ) ; # [ cfg ( feature " " ) ] let result = { let mut rt = :: tokio :: runtime :: Builder :: new ( ) . threaded_scheduler ( ) . enable_all ( ) . build ( ) . unwrap ( ) ; rt . block_on ( async move { let ( reader_task , writer_task ) = create_tun_iface ( ) ; :: tokio :: task :: spawn ( reader_task ) ; :: tokio :: task :: spawn ( writer_task ) ; task . await } ) } ; result } ) }
Spawns a thread in a new network namespace and configures a TUN interface that sends and
receives IP packets from the tx/rx channels and runs some UDP/TCP networking code in task.
Spawns a thread in a new network namespace and configures a TUN interface that sends and receives IP packets from the tx / rx channels and runs some UDP / TCP networking code in task .
addr
Ipv4Addr
mask
u8
plug
Plug
task
F