mirror of
https://github.com/tun2proxy/tun2proxy.git
synced 2025-04-21 14:29:10 +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;
|
||||
|
||||
struct ConnectionState {
|
||||
smoltcp_handle: Option<SocketHandle>,
|
||||
smoltcp_handle: SocketHandle,
|
||||
mio_stream: TcpStream,
|
||||
token: Token,
|
||||
proxy_handler: Box<dyn ProxyHandler>,
|
||||
|
@ -259,9 +259,8 @@ impl<'a> TunToProxy<'a> {
|
|||
.register(&mut exit_receiver, EXIT_TOKEN, Interest::READABLE)?;
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
#[rustfmt::skip]
|
||||
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::Ieee802154 => todo!(),
|
||||
};
|
||||
|
@ -352,16 +351,15 @@ impl<'a> TunToProxy<'a> {
|
|||
/// Destroy connection state machine
|
||||
fn remove_connection(&mut self, info: &ConnectionInfo) -> Result<(), Error> {
|
||||
if let Some(mut state) = self.connection_map.remove(info) {
|
||||
_ = state.mio_stream.shutdown(Shutdown::Both);
|
||||
if let Some(handle) = state.smoltcp_handle {
|
||||
self.expect_smoltcp_send()?;
|
||||
|
||||
{
|
||||
let handle = state.smoltcp_handle;
|
||||
let socket = self.sockets.get_mut::<tcp::Socket>(handle);
|
||||
socket.close();
|
||||
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) {
|
||||
// FIXME: The function `deregister` will frequently fail for unknown reasons.
|
||||
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);
|
||||
}
|
||||
Ok(())
|
||||
|
@ -397,11 +399,10 @@ impl<'a> TunToProxy<'a> {
|
|||
.proxy_handler
|
||||
.have_data(Direction::Outgoing(OutgoingDirection::ToClient))
|
||||
{
|
||||
if let Some(handle) = state.smoltcp_handle {
|
||||
// Close tun interface
|
||||
let socket = self.sockets.get_mut::<tcp::Socket>(handle);
|
||||
socket.close();
|
||||
}
|
||||
// Close tun interface
|
||||
let socket = self.sockets.get_mut::<tcp::Socket>(state.smoltcp_handle);
|
||||
socket.close();
|
||||
|
||||
closed_ends += 1;
|
||||
}
|
||||
|
||||
|
@ -414,7 +415,9 @@ impl<'a> TunToProxy<'a> {
|
|||
.have_data(Direction::Outgoing(OutgoingDirection::ToServer))
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -433,10 +436,7 @@ impl<'a> TunToProxy<'a> {
|
|||
Some(state) => state,
|
||||
None => return Ok(()),
|
||||
};
|
||||
let socket = match state.smoltcp_handle {
|
||||
Some(handle) => self.sockets.get_mut::<tcp::Socket>(handle),
|
||||
None => return Ok(()),
|
||||
};
|
||||
let socket = self.sockets.get_mut::<tcp::Socket>(state.smoltcp_handle);
|
||||
let mut error = Ok(());
|
||||
while socket.can_recv() && error.is_ok() {
|
||||
socket.recv(|data| {
|
||||
|
@ -692,6 +692,45 @@ impl<'a> TunToProxy<'a> {
|
|||
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.
|
||||
fn receive_tun(&mut self, frame: &mut [u8]) -> Result<(), Error> {
|
||||
let mut handler = || -> Result<(), Error> {
|
||||
|
@ -700,41 +739,14 @@ impl<'a> TunToProxy<'a> {
|
|||
log::debug!("{}, ignored", error);
|
||||
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 info = self.preprocess_origin_connection_info(info)?;
|
||||
|
||||
let manager = self.get_connection_manager().ok_or("get connection manager")?;
|
||||
|
||||
if info.protocol == IpProtocol::Tcp {
|
||||
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)?;
|
||||
self.process_incoming_tcp_packets(first_packet, &manager, &info, origin_dst, frame)?;
|
||||
} else if info.protocol == IpProtocol::Udp {
|
||||
let port = info.dst.port();
|
||||
let payload = &frame[payload_offset..payload_offset + payload_size];
|
||||
|
@ -795,7 +807,7 @@ impl<'a> TunToProxy<'a> {
|
|||
(None, None)
|
||||
};
|
||||
let state = ConnectionState {
|
||||
smoltcp_handle: Some(handle),
|
||||
smoltcp_handle: handle,
|
||||
mio_stream: client,
|
||||
token,
|
||||
proxy_handler,
|
||||
|
@ -881,15 +893,11 @@ impl<'a> TunToProxy<'a> {
|
|||
|
||||
fn write_to_client(&mut self, token: Token, info: &ConnectionInfo) -> Result<(), Error> {
|
||||
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 buflen = event.buffer.len();
|
||||
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 let Some(virtual_dns) = &mut self.options.virtual_dns {
|
||||
// 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
|
||||
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
|
||||
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);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue