mirror of
https://github.com/tun2proxy/tun2proxy.git
synced 2025-06-18 23:20:54 +00:00
Merge branch 'master' into linux
This commit is contained in:
commit
513702e35f
1 changed files with 67 additions and 55 deletions
122
src/tun2proxy.rs
122
src/tun2proxy.rs
|
@ -178,7 +178,7 @@ const UDP_ASSO_TIMEOUT: u64 = 10; // seconds
|
||||||
const DNS_PORT: u16 = 53;
|
const DNS_PORT: u16 = 53;
|
||||||
|
|
||||||
struct ConnectionState {
|
struct ConnectionState {
|
||||||
smoltcp_handle: Option<SocketHandle>,
|
smoltcp_handle: SocketHandle,
|
||||||
mio_stream: TcpStream,
|
mio_stream: TcpStream,
|
||||||
token: Token,
|
token: Token,
|
||||||
proxy_handler: Box<dyn ProxyHandler>,
|
proxy_handler: Box<dyn ProxyHandler>,
|
||||||
|
@ -259,9 +259,8 @@ impl<'a> TunToProxy<'a> {
|
||||||
.register(&mut exit_receiver, EXIT_TOKEN, Interest::READABLE)?;
|
.register(&mut exit_receiver, EXIT_TOKEN, Interest::READABLE)?;
|
||||||
|
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
#[rustfmt::skip]
|
|
||||||
let config = match tun.capabilities().medium {
|
let config = match tun.capabilities().medium {
|
||||||
Medium::Ethernet => Config::new(smoltcp::wire::EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into()),
|
Medium::Ethernet => Config::new(smoltcp::wire::EthernetAddress([0x02, 0, 0, 0, 0, 0x01]).into()),
|
||||||
Medium::Ip => Config::new(smoltcp::wire::HardwareAddress::Ip),
|
Medium::Ip => Config::new(smoltcp::wire::HardwareAddress::Ip),
|
||||||
Medium::Ieee802154 => todo!(),
|
Medium::Ieee802154 => todo!(),
|
||||||
};
|
};
|
||||||
|
@ -352,16 +351,15 @@ impl<'a> TunToProxy<'a> {
|
||||||
/// Destroy connection state machine
|
/// Destroy connection state machine
|
||||||
fn remove_connection(&mut self, info: &ConnectionInfo) -> Result<(), Error> {
|
fn remove_connection(&mut self, info: &ConnectionInfo) -> Result<(), Error> {
|
||||||
if let Some(mut state) = self.connection_map.remove(info) {
|
if let Some(mut state) = self.connection_map.remove(info) {
|
||||||
_ = state.mio_stream.shutdown(Shutdown::Both);
|
self.expect_smoltcp_send()?;
|
||||||
if let Some(handle) = state.smoltcp_handle {
|
|
||||||
|
{
|
||||||
|
let handle = state.smoltcp_handle;
|
||||||
let socket = self.sockets.get_mut::<tcp::Socket>(handle);
|
let socket = self.sockets.get_mut::<tcp::Socket>(handle);
|
||||||
socket.close();
|
socket.close();
|
||||||
self.sockets.remove(handle);
|
self.sockets.remove(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Does this line should be moved up to the beginning of this function?
|
|
||||||
self.expect_smoltcp_send()?;
|
|
||||||
|
|
||||||
if let Err(e) = self.poll.registry().deregister(&mut state.mio_stream) {
|
if let Err(e) = self.poll.registry().deregister(&mut state.mio_stream) {
|
||||||
// FIXME: The function `deregister` will frequently fail for unknown reasons.
|
// FIXME: The function `deregister` will frequently fail for unknown reasons.
|
||||||
log::trace!("{}", e);
|
log::trace!("{}", e);
|
||||||
|
@ -373,6 +371,10 @@ impl<'a> TunToProxy<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Err(err) = state.mio_stream.shutdown(Shutdown::Both) {
|
||||||
|
log::trace!("Shutdown 0 {} error \"{}\"", info, err);
|
||||||
|
}
|
||||||
|
|
||||||
log::info!("Close {}", info);
|
log::info!("Close {}", info);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -397,11 +399,10 @@ impl<'a> TunToProxy<'a> {
|
||||||
.proxy_handler
|
.proxy_handler
|
||||||
.have_data(Direction::Outgoing(OutgoingDirection::ToClient))
|
.have_data(Direction::Outgoing(OutgoingDirection::ToClient))
|
||||||
{
|
{
|
||||||
if let Some(handle) = state.smoltcp_handle {
|
// Close tun interface
|
||||||
// Close tun interface
|
let socket = self.sockets.get_mut::<tcp::Socket>(state.smoltcp_handle);
|
||||||
let socket = self.sockets.get_mut::<tcp::Socket>(handle);
|
socket.close();
|
||||||
socket.close();
|
|
||||||
}
|
|
||||||
closed_ends += 1;
|
closed_ends += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,7 +415,9 @@ impl<'a> TunToProxy<'a> {
|
||||||
.have_data(Direction::Outgoing(OutgoingDirection::ToServer))
|
.have_data(Direction::Outgoing(OutgoingDirection::ToServer))
|
||||||
{
|
{
|
||||||
// Close remote server
|
// Close remote server
|
||||||
_ = state.mio_stream.shutdown(Shutdown::Write);
|
if let Err(err) = state.mio_stream.shutdown(Shutdown::Write) {
|
||||||
|
log::trace!("Shutdown 1 {} error \"{}\"", info, err);
|
||||||
|
}
|
||||||
closed_ends += 1;
|
closed_ends += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,10 +436,7 @@ impl<'a> TunToProxy<'a> {
|
||||||
Some(state) => state,
|
Some(state) => state,
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
let socket = match state.smoltcp_handle {
|
let socket = self.sockets.get_mut::<tcp::Socket>(state.smoltcp_handle);
|
||||||
Some(handle) => self.sockets.get_mut::<tcp::Socket>(handle),
|
|
||||||
None => return Ok(()),
|
|
||||||
};
|
|
||||||
let mut error = Ok(());
|
let mut error = Ok(());
|
||||||
while socket.can_recv() && error.is_ok() {
|
while socket.can_recv() && error.is_ok() {
|
||||||
socket.recv(|data| {
|
socket.recv(|data| {
|
||||||
|
@ -692,6 +692,45 @@ impl<'a> TunToProxy<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn process_incoming_tcp_packets(
|
||||||
|
&mut self,
|
||||||
|
first_packet: bool,
|
||||||
|
manager: &Rc<dyn ConnectionManager>,
|
||||||
|
info: &ConnectionInfo,
|
||||||
|
origin_dst: SocketAddr,
|
||||||
|
frame: &[u8],
|
||||||
|
) -> Result<()> {
|
||||||
|
if first_packet {
|
||||||
|
let proxy_handler = manager.new_proxy_handler(info, false)?;
|
||||||
|
let server = manager.get_server_addr();
|
||||||
|
let state = self.create_new_tcp_connection_state(server, origin_dst, proxy_handler, false)?;
|
||||||
|
self.connection_map.insert(info.clone(), state);
|
||||||
|
|
||||||
|
log::info!("Connect done {} ({})", info, origin_dst);
|
||||||
|
} else if !self.connection_map.contains_key(info) {
|
||||||
|
log::trace!("Drop middle session {} ({})", info, origin_dst);
|
||||||
|
return Ok(());
|
||||||
|
} else {
|
||||||
|
log::trace!("Subsequent packet {} ({})", info, origin_dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inject the packet to advance the remote proxy server smoltcp socket state
|
||||||
|
self.device.inject_packet(frame);
|
||||||
|
|
||||||
|
// Having advanced the socket state, we expect the socket to ACK
|
||||||
|
// Exfiltrate the response packets generated by the socket and inject them
|
||||||
|
// into the tunnel interface.
|
||||||
|
self.expect_smoltcp_send()?;
|
||||||
|
|
||||||
|
// Read from the smoltcp socket and push the data to the connection handler.
|
||||||
|
self.tunsocket_read_and_forward(info)?;
|
||||||
|
|
||||||
|
// The connection handler builds up the connection or encapsulates the data.
|
||||||
|
// Therefore, we now expect it to write data to the server.
|
||||||
|
self.write_to_server(info)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// A raw packet was received on the tunnel interface.
|
// A raw packet was received on the tunnel interface.
|
||||||
fn receive_tun(&mut self, frame: &mut [u8]) -> Result<(), Error> {
|
fn receive_tun(&mut self, frame: &mut [u8]) -> Result<(), Error> {
|
||||||
let mut handler = || -> Result<(), Error> {
|
let mut handler = || -> Result<(), Error> {
|
||||||
|
@ -700,41 +739,14 @@ impl<'a> TunToProxy<'a> {
|
||||||
log::debug!("{}, ignored", error);
|
log::debug!("{}, ignored", error);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let (info, _first_packet, payload_offset, payload_size) = result?;
|
let (info, first_packet, payload_offset, payload_size) = result?;
|
||||||
let origin_dst = SocketAddr::try_from(&info.dst)?;
|
let origin_dst = SocketAddr::try_from(&info.dst)?;
|
||||||
let info = self.preprocess_origin_connection_info(info)?;
|
let info = self.preprocess_origin_connection_info(info)?;
|
||||||
|
|
||||||
let manager = self.get_connection_manager().ok_or("get connection manager")?;
|
let manager = self.get_connection_manager().ok_or("get connection manager")?;
|
||||||
|
|
||||||
if info.protocol == IpProtocol::Tcp {
|
if info.protocol == IpProtocol::Tcp {
|
||||||
if _first_packet {
|
self.process_incoming_tcp_packets(first_packet, &manager, &info, origin_dst, frame)?;
|
||||||
let proxy_handler = manager.new_proxy_handler(&info, false)?;
|
|
||||||
let server = manager.get_server_addr();
|
|
||||||
let state = self.create_new_tcp_connection_state(server, origin_dst, proxy_handler, false)?;
|
|
||||||
self.connection_map.insert(info.clone(), state);
|
|
||||||
|
|
||||||
log::info!("Connect done {} ({})", info, origin_dst);
|
|
||||||
} else if !self.connection_map.contains_key(&info) {
|
|
||||||
log::trace!("Drop middle session {} ({})", info, origin_dst);
|
|
||||||
return Ok(());
|
|
||||||
} else {
|
|
||||||
log::trace!("Subsequent packet {} ({})", info, origin_dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inject the packet to advance the remote proxy server smoltcp socket state
|
|
||||||
self.device.inject_packet(frame);
|
|
||||||
|
|
||||||
// Having advanced the socket state, we expect the socket to ACK
|
|
||||||
// Exfiltrate the response packets generated by the socket and inject them
|
|
||||||
// into the tunnel interface.
|
|
||||||
self.expect_smoltcp_send()?;
|
|
||||||
|
|
||||||
// Read from the smoltcp socket and push the data to the connection handler.
|
|
||||||
self.tunsocket_read_and_forward(&info)?;
|
|
||||||
|
|
||||||
// The connection handler builds up the connection or encapsulates the data.
|
|
||||||
// Therefore, we now expect it to write data to the server.
|
|
||||||
self.write_to_server(&info)?;
|
|
||||||
} else if info.protocol == IpProtocol::Udp {
|
} else if info.protocol == IpProtocol::Udp {
|
||||||
let port = info.dst.port();
|
let port = info.dst.port();
|
||||||
let payload = &frame[payload_offset..payload_offset + payload_size];
|
let payload = &frame[payload_offset..payload_offset + payload_size];
|
||||||
|
@ -795,7 +807,7 @@ impl<'a> TunToProxy<'a> {
|
||||||
(None, None)
|
(None, None)
|
||||||
};
|
};
|
||||||
let state = ConnectionState {
|
let state = ConnectionState {
|
||||||
smoltcp_handle: Some(handle),
|
smoltcp_handle: handle,
|
||||||
mio_stream: client,
|
mio_stream: client,
|
||||||
token,
|
token,
|
||||||
proxy_handler,
|
proxy_handler,
|
||||||
|
@ -881,15 +893,11 @@ impl<'a> TunToProxy<'a> {
|
||||||
|
|
||||||
fn write_to_client(&mut self, token: Token, info: &ConnectionInfo) -> Result<(), Error> {
|
fn write_to_client(&mut self, token: Token, info: &ConnectionInfo) -> Result<(), Error> {
|
||||||
while let Some(state) = self.connection_map.get_mut(info) {
|
while let Some(state) = self.connection_map.get_mut(info) {
|
||||||
let handle = match state.smoltcp_handle {
|
|
||||||
Some(handle) => handle,
|
|
||||||
None => break,
|
|
||||||
};
|
|
||||||
let event = state.proxy_handler.peek_data(OutgoingDirection::ToClient);
|
let event = state.proxy_handler.peek_data(OutgoingDirection::ToClient);
|
||||||
let buflen = event.buffer.len();
|
let buflen = event.buffer.len();
|
||||||
let consumed;
|
let consumed;
|
||||||
{
|
{
|
||||||
let socket = self.sockets.get_mut::<tcp::Socket>(handle);
|
let socket = self.sockets.get_mut::<tcp::Socket>(state.smoltcp_handle);
|
||||||
if socket.may_send() {
|
if socket.may_send() {
|
||||||
if let Some(virtual_dns) = &mut self.options.virtual_dns {
|
if let Some(virtual_dns) = &mut self.options.virtual_dns {
|
||||||
// Unwrapping is fine because every smoltcp socket is bound to an.
|
// Unwrapping is fine because every smoltcp socket is bound to an.
|
||||||
|
@ -1051,9 +1059,13 @@ impl<'a> TunToProxy<'a> {
|
||||||
|
|
||||||
// The handler request for reset the server connection
|
// The handler request for reset the server connection
|
||||||
if state.proxy_handler.reset_connection() {
|
if state.proxy_handler.reset_connection() {
|
||||||
_ = self.poll.registry().deregister(&mut state.mio_stream);
|
if let Err(err) = self.poll.registry().deregister(&mut state.mio_stream) {
|
||||||
|
log::trace!("{}", err);
|
||||||
|
}
|
||||||
// Closes the connection with the proxy
|
// Closes the connection with the proxy
|
||||||
state.mio_stream.shutdown(Shutdown::Both)?;
|
if let Err(err) = state.mio_stream.shutdown(Shutdown::Both) {
|
||||||
|
log::trace!("Shutdown 2 error \"{}\"", err);
|
||||||
|
}
|
||||||
|
|
||||||
log::info!("RESET {}", conn_info);
|
log::info!("RESET {}", conn_info);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue