4 Commits

Author SHA1 Message Date
Datong Sun
b42ed82147 docs(readme): bump copyright year 2025-08-22 20:55:13 -07:00
Datong Sun
7c3864a3ed chore(cargo): bump fake-tcp to 0.7.1 and phantun to 0.8.1 2025-08-22 20:54:22 -07:00
Datong Sun
6a39e9e9d0 perf(phantun): avoid heap allocation with udp_recv_from_pktinfo() 2025-08-23 11:53:41 +08:00
Datong Sun
cedee0c699 docs(readme): release 0.8.0 and add note about MIPS build
Some checks are pending
Docker image build / build (push) Waiting to run
Rust / build (push) Waiting to run
2025-08-23 01:20:53 +08:00
7 changed files with 35 additions and 21 deletions

4
Cargo.lock generated
View File

@@ -253,7 +253,7 @@ dependencies = [
[[package]]
name = "fake-tcp"
version = "0.7.0"
version = "0.7.1"
dependencies = [
"bytes",
"flume",
@@ -585,7 +585,7 @@ dependencies = [
[[package]]
name = "phantun"
version = "0.8.0"
version = "0.8.1"
dependencies = [
"clap",
"fake-tcp",

View File

@@ -35,7 +35,14 @@ Table of Contents
# Latest release
[v0.7.0](https://github.com/dndx/phantun/releases/tag/v0.7.0)
[v0.8.0](https://github.com/dndx/phantun/releases/tag/v0.8.0)
<details>
<summary>MIPS architecture support for Phantun</summary>
[Rust only provides Tier 3 supports for MIPS based platforms](https://github.com/rust-lang/compiler-team/issues/648)
since 2023. Phantun's MIPS build are therefore built using nightly Rust toolchain and provided on a best effort basis only.
</details>
# Overview

View File

@@ -1,6 +1,6 @@
[package]
name = "fake-tcp"
version = "0.7.0"
version = "0.7.1"
edition = "2024"
authors = ["Datong Sun <dndx@idndx.com>"]
license = "MIT OR Apache-2.0"

View File

@@ -5,7 +5,7 @@ packet oriented tunneling with minimum overhead.
## License
Copyright 2021 Datong Sun <dndx@idndx.com>
Copyright 2021-2025 Datong Sun <dndx@idndx.com>
Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)> or the MIT license

View File

@@ -1,6 +1,6 @@
[package]
name = "phantun"
version = "0.8.0"
version = "0.8.1"
edition = "2024"
authors = ["Datong Sun <dndx@idndx.com>"]
license = "MIT OR Apache-2.0"

View File

@@ -4,7 +4,7 @@ Client/Server crate, see [Phantun Project README.md](https://github.com/dndx/pha
## License
Copyright 2021 Datong Sun <dndx@idndx.com>
Copyright 2021-2025 Datong Sun <dndx@idndx.com>
Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)> or the MIT license

View File

@@ -10,8 +10,12 @@ use neli::{
types::RtBuffer,
utils::Groups,
};
use nix::sys::socket::{CmsgIterator, ControlMessageOwned, SockaddrLike as _};
use nix::sys::socket::{
CmsgIterator, ControlMessageOwned, MsgFlags, SockaddrLike, SockaddrStorage, cmsg_space,
};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use std::os::unix::io::AsRawFd;
use tokio::io::Interest;
use tokio::net::UdpSocket;
pub fn new_udp_reuseport(local_addr: SocketAddr) -> UdpSocket {
@@ -49,26 +53,28 @@ pub fn new_udp_reuseport(local_addr: SocketAddr) -> UdpSocket {
udp_sock.try_into().unwrap()
}
/// Similiar to `UdpSocket::recv_from()`, but returns a 3rd value `IPAddr`
/// which corresponds to where the UDP datagram was destined to, this is useful
/// for disambigous when socket can receive on multiple IP address
/// or interfaces.
pub async fn udp_recv_pktinfo(
sock: &UdpSocket,
buf: &mut [u8],
) -> std::io::Result<(usize, std::net::SocketAddr, std::net::IpAddr)> {
use std::os::unix::io::AsRawFd;
use tokio::io::Interest;
use nix::sys::socket::cmsg_space;
) -> std::io::Result<(usize, SocketAddr, IpAddr)> {
sock.async_io(Interest::READABLE, || {
let control_buffer_size = std::cmp::max(
cmsg_space::<nix::libc::in_pktinfo>(),
cmsg_space::<nix::libc::in6_pktinfo>(),
);
let mut control_buffer = vec![0u8; control_buffer_size];
// according to documented struct definition in RFC 3542,
// sizeof(in6_pktinfo) should always be larger than sizeof(in_pktinfo),
// this assert just double checks that. The goal is to avoid
// a heap allocation with Vec at runtime.
assert!(cmsg_space::<nix::libc::in6_pktinfo>() >= cmsg_space::<nix::libc::in_pktinfo>());
let mut control_message_buffer = [0u8; cmsg_space::<nix::libc::in6_pktinfo>()];
let iov = &mut [std::io::IoSliceMut::new(buf)];
let res = nix::sys::socket::recvmsg::<nix::sys::socket::SockaddrStorage>(
let res = nix::sys::socket::recvmsg::<SockaddrStorage>(
sock.as_raw_fd(),
iov,
Some(&mut control_buffer),
nix::sys::socket::MsgFlags::empty(),
Some(&mut control_message_buffer),
MsgFlags::empty(),
)?;
let src_addr = res.address.expect("missing source address");
@@ -104,6 +110,7 @@ fn dst_addr_from_cmsgs(cmsgs: CmsgIterator) -> Option<IpAddr> {
return Some(Ipv6Addr::from(pktinfo.ipi6_addr.s6_addr).into());
}
}
None
}