Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
1912fd8
refine code
ssrlive Feb 18, 2025
5c2aa85
improve InvalidTcpPacket detail
ssrlive Feb 20, 2025
5be5321
refine code
ssrlive Feb 20, 2025
ba10b6f
rustfmt max_width = 140
ssrlive Feb 21, 2025
6cd3850
refine code
ssrlive Feb 21, 2025
32486e4
remove useless IpStackPacketProtocol
ssrlive Feb 23, 2025
240959f
Make the terminated UDP Session removed smoothly
ssrlive Feb 24, 2025
4995594
rename tcp_timeout to timeout_interval
ssrlive Feb 25, 2025
3f448e0
use SeqNum data type
ssrlive Feb 25, 2025
afa00cf
rename udp_timeout to timeout_interval
ssrlive Feb 25, 2025
95ec6f6
use SeqNum in create_rev_packet
ssrlive Feb 26, 2025
b55293a
rename calculate_payload_len to calculate_payload_max_len
ssrlive Feb 26, 2025
d1e17bb
re-format code
ssrlive Feb 28, 2025
8beadd0
refactor TCP logic
ssrlive Feb 28, 2025
e8ba6f7
remove the logic of DROP_TTL
ssrlive Mar 2, 2025
5f10ae5
mod tcp_wrapper removed
ssrlive Mar 2, 2025
d81fd0d
TcpHeaderWrapper removed
ssrlive Mar 2, 2025
6ff3a90
find_inflight_packet & get_all_inflight_packets
ssrlive Mar 2, 2025
dba2683
incoming_seq
ssrlive Mar 2, 2025
3c60021
hide some log::trace
ssrlive Mar 2, 2025
98bf25f
refactor retransmission logic
ssrlive Mar 3, 2025
21a5a9c
packet_to_send: Option<NetworkPacket> removed
ssrlive Mar 3, 2025
bfd468b
minor changes in SeqNum
ssrlive Mar 3, 2025
227f76e
payload alias
ssrlive Mar 3, 2025
9cab122
Refactor completed
ssrlive Mar 3, 2025
3736ec2
.env file support in examples
ssrlive Mar 3, 2025
0d9a467
network_tuple method for IpStackTcpStream
ssrlive Mar 3, 2025
2b94d4f
refine code
ssrlive Mar 4, 2025
dda57b8
move timeout timer from tcb to tcp
ssrlive Mar 4, 2025
9f48ba8
refine code
ssrlive Mar 4, 2025
fb1b1fe
refine log info
ssrlive Mar 9, 2025
6c90e6f
refine code
ssrlive Mar 9, 2025
f02436b
rename example tun2 to tun
ssrlive Mar 9, 2025
dda0369
refactor add_inflight_packet
ssrlive Mar 10, 2025
d5648d7
minor changes
ssrlive Mar 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.env
.vscode/
.VSCodeCounter/
/target/
Expand Down
26 changes: 12 additions & 14 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,29 @@ readme = "README.md"

[dependencies]
ahash = "0.8"
tokio = { version = "1.43", features = [
etherparse = { version = "0.17", default-features = false, features = ["std"] }
log = { version = "0.4", default-features = false }
rand = { version = "0.9", default-features = false, features = ["thread_rng"] }
thiserror = { version = "2.0", default-features = false }
tokio = { version = "1.43", default-features = false, features = [
"sync",
"rt",
"time",
"io-util",
"macros",
], default-features = false }
etherparse = { version = "0.17", default-features = false, features = ["std"] }
thiserror = { version = "2.0", default-features = false }
log = { version = "0.4", default-features = false }
rand = { version = "0.9", default-features = false, features = ["thread_rng"] }
] }

[dev-dependencies]
tokio = { version = "1.43", features = [
"rt-multi-thread",
], default-features = false }
clap = { version = "4.5", features = ["derive"] }
criterion = { version = "0.5" } # Benchmarks
dotenvy = "0.15"
env_logger = "0.11"
tokio = { version = "1.43", default-features = false, features = [
"rt-multi-thread",
] }
tun = { version = "0.7.13", default-features = false, features = ["async"] }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also rename tun2.rs example to tun.rs if you wish

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

udp-stream = { version = "0.0", default-features = false }

# Benchmarks
criterion = { version = "0.5" }

[target.'cfg(any(target_os = "linux", target_os = "macos"))'.dev-dependencies]
tun = { version = "0.7.13", features = ["async"], default-features = false }
[target.'cfg(target_os = "windows")'.dev-dependencies]
wintun = { version = "0.5", default-features = false }

Expand Down
14 changes: 5 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ An asynchronous lightweight userspace implementation of TCP/IP stack for Tun dev
Unstable, under development.

[![Crates.io](https://img.shields.io/crates/v/ipstack.svg)](https://crates.io/crates/ipstack)
![ipstack](https://docs.rs/ipstack/badge.svg)
[![ipstack](https://docs.rs/ipstack/badge.svg)](https://docs.rs/ipstack)
[![Documentation](https://img.shields.io/badge/docs-release-brightgreen.svg?style=flat)](https://docs.rs/ipstack)
[![Download](https://img.shields.io/crates/d/ipstack.svg)](https://crates.io/crates/ipstack)
[![License](https://img.shields.io/crates/l/ipstack.svg?style=flat)](https://github.com/narrowlink/ipstack/blob/main/LICENSE)
Expand Down Expand Up @@ -34,7 +34,7 @@ async fn main() {

#[cfg(target_os = "windows")]
config.platform_config(|config| {
config.device_guid(Some(12324323423423434234_u128));
config.device_guid(12324323423423434234_u128);
});

let mut ipstack_config = ipstack::IpStackConfig::default();
Expand All @@ -51,7 +51,7 @@ async fn main() {
});
}
IpStackStream::Udp(mut udp) => {
let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1)), 53);
let addr: SocketAddr = "1.1.1.1:53".parse().unwrap();
let mut rhs = UdpStream::connect(addr).await.unwrap();
tokio::spawn(async move {
let _ = tokio::io::copy_bidirectional(&mut udp, &mut rhs).await;
Expand All @@ -60,12 +60,8 @@ async fn main() {
IpStackStream::UnknownTransport(u) => {
if u.src_addr().is_ipv4() && u.ip_protocol() == IpNumber::ICMP {
let (icmp_header, req_payload) = Icmpv4Header::from_slice(u.payload()).unwrap();
if let etherparse::Icmpv4Type::EchoRequest(req) = icmp_header.icmp_type {
if let etherparse::Icmpv4Type::EchoRequest(echo) = icmp_header.icmp_type {
println!("ICMPv4 echo");
let echo = IcmpEchoHeader {
id: req.id,
seq: req.seq,
};
let mut resp = Icmpv4Header::new(etherparse::Icmpv4Type::EchoReply(echo));
resp.update_checksum(req_payload);
let mut payload = resp.to_bytes().to_vec();
Expand All @@ -86,4 +82,4 @@ async fn main() {
}
```

We also suggest that you take a look at the complete [examples](examples).
We also suggest that you take a look at the complete [examples](./examples).
13 changes: 5 additions & 8 deletions examples/tun2.rs → examples/tun.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//!
//! This example must be run as root or administrator privileges.
//! ```
//! sudo target/debug/examples/tun2 --server-addr 127.0.0.1:8080 # Linux or macOS
//! sudo target/debug/examples/tun --server-addr 127.0.0.1:8080 # Linux or macOS
//! ```
//! Then please run the `echo` example server, which listens on TCP & UDP ports 127.0.0.1:8080.
//! ```
Expand All @@ -28,7 +28,7 @@
//!

use clap::Parser;
use etherparse::{IcmpEchoHeader, Icmpv4Header};
use etherparse::Icmpv4Header;
use ipstack::{stream::IpStackStream, IpNumber};
use std::net::{Ipv4Addr, SocketAddr};
use tokio::net::TcpStream;
Expand Down Expand Up @@ -71,6 +71,7 @@ struct Args {

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
dotenvy::dotenv().ok();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we use environment variables in this example?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, we use .env file.

let args = Args::parse();

let default = format!("{:?}", args.verbosity);
Expand Down Expand Up @@ -154,12 +155,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let n = number;
if u.src_addr().is_ipv4() && u.ip_protocol() == IpNumber::ICMP {
let (icmp_header, req_payload) = Icmpv4Header::from_slice(u.payload())?;
if let etherparse::Icmpv4Type::EchoRequest(req) = icmp_header.icmp_type {
if let etherparse::Icmpv4Type::EchoRequest(echo) = icmp_header.icmp_type {
log::info!("#{n} ICMPv4 echo");
let echo = IcmpEchoHeader {
id: req.id,
seq: req.seq,
};
let mut resp = Icmpv4Header::new(etherparse::Icmpv4Type::EchoReply(echo));
resp.update_checksum(req_payload);
let mut payload = resp.to_bytes().to_vec();
Expand All @@ -174,7 +171,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
continue;
}
IpStackStream::UnknownNetwork(pkt) => {
log::info!("#{number} unknown transport - {} bytes", pkt.len());
log::info!("#{number} unknown network - {} bytes", pkt.len());
continue;
}
};
Expand Down
24 changes: 6 additions & 18 deletions examples/tun_wintun.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::net::{Ipv4Addr, SocketAddr};

use clap::Parser;
use etherparse::{IcmpEchoHeader, Icmpv4Header};
use etherparse::Icmpv4Header;
use ipstack::{stream::IpStackStream, IpNumber};
use tokio::net::TcpStream;
use udp_stream::UdpStream;
Expand All @@ -19,6 +19,7 @@ struct Args {

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
dotenvy::dotenv().ok();
let args = Args::parse();

env_logger::init();
Expand Down Expand Up @@ -46,10 +47,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut ip_stack = ipstack::IpStack::new(ipstack_config, tun::create_as_async(&config)?);

#[cfg(target_os = "windows")]
let mut ip_stack = ipstack::IpStack::new(
ipstack_config,
wintun::WinTunDevice::new(ipv4, Ipv4Addr::new(255, 255, 255, 0)),
);
let mut ip_stack = ipstack::IpStack::new(ipstack_config, wintun::WinTunDevice::new(ipv4, Ipv4Addr::new(255, 255, 255, 0)));

let server_addr = args.server_addr;

Expand Down Expand Up @@ -86,12 +84,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
IpStackStream::UnknownTransport(u) => {
if u.src_addr().is_ipv4() && u.ip_protocol() == IpNumber::ICMP {
let (icmp_header, req_payload) = Icmpv4Header::from_slice(u.payload())?;
if let etherparse::Icmpv4Type::EchoRequest(req) = icmp_header.icmp_type {
if let etherparse::Icmpv4Type::EchoRequest(echo) = icmp_header.icmp_type {
println!("ICMPv4 echo");
let echo = IcmpEchoHeader {
id: req.id,
seq: req.seq,
};
let mut resp = Icmpv4Header::new(etherparse::Icmpv4Type::EchoReply(echo));
resp.update_checksum(req_payload);
let mut payload = resp.to_bytes().to_vec();
Expand Down Expand Up @@ -178,17 +172,11 @@ mod wintun {
std::task::Poll::Ready(Ok(buf.len()))
}

fn poll_flush(
self: std::pin::Pin<&mut Self>,
_cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Result<(), std::io::Error>> {
fn poll_flush(self: std::pin::Pin<&mut Self>, _cx: &mut std::task::Context<'_>) -> std::task::Poll<Result<(), std::io::Error>> {
std::task::Poll::Ready(Ok(()))
}

fn poll_shutdown(
self: std::pin::Pin<&mut Self>,
_cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Result<(), std::io::Error>> {
fn poll_shutdown(self: std::pin::Pin<&mut Self>, _cx: &mut std::task::Context<'_>) -> std::task::Poll<Result<(), std::io::Error>> {
std::task::Poll::Ready(Ok(()))
}
}
Expand Down
1 change: 1 addition & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
max_width = 140
Loading