Skip to content

Commit d8ffc60

Browse files
wrap tcp listener
1 parent d0df93a commit d8ffc60

File tree

3 files changed

+55
-25
lines changed

3 files changed

+55
-25
lines changed

examples/forward.rs

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
use std::{
2-
net::{Ipv4Addr, SocketAddr},
3-
sync::Arc,
4-
};
1+
use std::net::{Ipv4Addr, SocketAddr};
52

63
use futures::{SinkExt, StreamExt};
7-
use netstack_system::{Nat, UdpSocket};
4+
use netstack_system::UdpSocket;
85
use structopt::StructOpt;
9-
use tokio::net::{TcpListener, TcpSocket, TcpStream};
6+
use tokio::net::{TcpSocket, TcpStream};
107
use tracing::{error, info, warn};
118
use tun2::AbstractDevice;
129

@@ -99,7 +96,6 @@ async fn main_exec(opt: Opt) {
9996
.inet4_addr(addr)
10097
.build()
10198
.await;
102-
let nat = stack.nat();
10399
let listener = listener.unwrap();
104100
let udp_socket = udp_socket.unwrap();
105101

@@ -117,7 +113,7 @@ async fn main_exec(opt: Opt) {
117113
futs.push(tokio_spawn!({
118114
let interface = opt.interface.clone();
119115
async move {
120-
handle_inbound_stream(nat, listener, interface).await;
116+
handle_inbound_stream(listener, interface).await;
121117
}
122118
}));
123119
futs.push(tokio_spawn!({
@@ -137,25 +133,19 @@ async fn main_exec(opt: Opt) {
137133
}
138134

139135
/// simply forward tcp stream
140-
async fn handle_inbound_stream(nat: Arc<Nat>, listener: TcpListener, interface: String) {
141-
while let Ok((mut stream, _addr)) = listener.accept().await {
136+
async fn handle_inbound_stream(listener: netstack_system::TcpListener, interface: String) {
137+
while let Ok((mut stream, target)) = listener.accept().await {
142138
let interface: String = interface.clone();
143-
let nat = nat.clone();
139+
// let nat = nat.clone();
144140
tokio::spawn(async move {
145141
let remote = stream.peer_addr().unwrap();
146142
let local = stream.local_addr().unwrap();
147-
info!("new tcp connection: {:?} => {:?}", remote, local);
148-
let nat_port = remote.port();
149-
let nat_session = match nat.look_back(nat_port).await {
150-
Some(session) => session,
151-
None => {
152-
warn!("session not found, allocated port: {:?}", remote.port());
153-
return;
154-
}
155-
};
156-
let actual_remote = (nat_session.dst, nat_session.dport);
143+
info!(
144+
"new tcp connection: {:?} => {:?}, actual remote: {}",
145+
remote, local, target
146+
);
157147

158-
match new_tcp_stream(actual_remote.into(), &interface).await {
148+
match new_tcp_stream(target.into(), &interface).await {
159149
Ok(mut remote_stream) => {
160150
// pipe between two tcp stream
161151
match tokio::io::copy_bidirectional(&mut stream, &mut remote_stream).await {

src/lib.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ mod checksum;
44
mod error;
55
mod nat;
66
mod packet;
7+
mod tcp;
78
mod udp;
89

910
use checksum::UpdateCsum;
1011
pub use error::StackError;
1112
pub use nat::*;
13+
pub use tcp::TcpListener;
1214
pub use udp::UdpSocket;
1315
pub type Result<T> = std::result::Result<T, StackError>;
1416

@@ -19,7 +21,6 @@ use std::{
1921
sync::Arc,
2022
};
2123
use tokio::{
22-
net::TcpListener,
2324
sync::mpsc::{Receiver, Sender, channel},
2425
task::JoinHandle,
2526
};
@@ -72,7 +73,7 @@ impl StackBuilder {
7273
self,
7374
) -> (
7475
SystemStack,
75-
Option<TcpListener>,
76+
Option<crate::TcpListener>,
7677
Option<UdpSocket>,
7778
Sender<Vec<u8>>,
7879
) {
@@ -88,7 +89,9 @@ impl StackBuilder {
8889
};
8990

9091
let tcp_listener = if self.enable_tcp {
91-
TcpListener::bind((self.inet4_server_addr, 0)).await.ok()
92+
tokio::net::TcpListener::bind((self.inet4_server_addr, 0))
93+
.await
94+
.ok()
9295
} else {
9396
None
9497
};
@@ -109,6 +112,8 @@ impl StackBuilder {
109112

110113
let udp_socket = udp_rx.map(|rx| UdpSocket::new(rx, udp_writeback_tx));
111114

115+
let tcp_listener = tcp_listener.map(|l| crate::TcpListener::new(l, stack.nat()));
116+
112117
(stack, tcp_listener, udp_socket, stack_tx)
113118
}
114119
}

src/tcp.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use std::{net::SocketAddr, sync::Arc};
2+
3+
use crate::Nat;
4+
5+
pub struct TcpListener {
6+
listener: tokio::net::TcpListener,
7+
nat: Arc<Nat>,
8+
}
9+
10+
impl TcpListener {
11+
pub fn new(listener: tokio::net::TcpListener, nat: Arc<Nat>) -> Self {
12+
Self { listener, nat }
13+
}
14+
15+
pub fn inner(&self) -> &tokio::net::TcpListener {
16+
&self.listener
17+
}
18+
19+
pub async fn accept(&self) -> std::io::Result<(tokio::net::TcpStream, std::net::SocketAddr)> {
20+
let (stream, remote) = self.listener.accept().await?;
21+
let remote_port = remote.port();
22+
let nat_session = match self.nat.look_back(remote_port).await {
23+
Some(session) => session,
24+
None => {
25+
tracing::warn!("session not found, allocated port: {:?}", remote.port());
26+
return Err(std::io::Error::new(
27+
std::io::ErrorKind::Other,
28+
"session not found",
29+
));
30+
}
31+
};
32+
let actual_remote = SocketAddr::new(nat_session.dst, nat_session.dport);
33+
return Ok((stream, actual_remote));
34+
}
35+
}

0 commit comments

Comments
 (0)