mirror of
https://github.com/tun2proxy/tun2proxy.git
synced 2025-04-23 23:39:10 +00:00
receive_dns_over_tcp_packet_and_write_to_client
This commit is contained in:
parent
9880741dc1
commit
d7d69ce927
2 changed files with 83 additions and 3 deletions
|
@ -41,7 +41,7 @@ struct Args {
|
|||
#[arg(short, long, value_name = "level", value_enum, default_value = "info")]
|
||||
verbosity: ArgVerbosity,
|
||||
|
||||
/// DNS over TCP
|
||||
/// Enable DNS over TCP
|
||||
#[arg(long)]
|
||||
dns_over_tcp: bool,
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use smoltcp::{
|
|||
wire::{IpCidr, IpProtocol, Ipv4Packet, Ipv6Packet, TcpPacket, UdpPacket, UDP_HEADER_LEN},
|
||||
};
|
||||
use socks5_impl::protocol::{Address, StreamOperation, UdpHeader, UserKey};
|
||||
use std::collections::LinkedList;
|
||||
use std::{collections::LinkedList, convert::TryInto};
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
convert::{From, TryFrom},
|
||||
|
@ -535,6 +535,77 @@ impl<'a> TunToProxy<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn receive_dns_over_tcp_packet_and_write_to_client(&mut self, info: &ConnectionInfo) -> Result<()> {
|
||||
let err = "udp connection state not found";
|
||||
let state = self.connection_map.get_mut(info).ok_or(err)?;
|
||||
assert!(state.udp_over_tcp_expiry.is_some());
|
||||
state.udp_over_tcp_expiry = Some(Self::common_udp_life_timeout());
|
||||
|
||||
let mut buf = Vec::<u8>::new();
|
||||
let read = match state.mio_stream.read_to_end(&mut buf) {
|
||||
Ok(read_result) => read_result,
|
||||
Err(error) => {
|
||||
if error.kind() != std::io::ErrorKind::WouldBlock {
|
||||
log::error!("{} Read from proxy: {}", info.dst, error);
|
||||
}
|
||||
buf.len()
|
||||
}
|
||||
};
|
||||
if read == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
let mut buf = buf[..read].to_vec();
|
||||
let mut to_send: LinkedList<Vec<u8>> = LinkedList::new();
|
||||
loop {
|
||||
if buf.len() < 2 {
|
||||
break;
|
||||
}
|
||||
let len = u16::from_be_bytes([buf[0], buf[1]]) as usize;
|
||||
if buf.len() < len + 2 {
|
||||
break;
|
||||
}
|
||||
let data = buf[2..len + 2].to_vec();
|
||||
|
||||
let message = dns::parse_data_to_dns_message(&data, false)?;
|
||||
let name = dns::extract_domain_from_dns_message(&message)?;
|
||||
let ip = dns::extract_ipaddr_from_dns_message(&message)?;
|
||||
log::trace!("DNS over TCP ======== {} -> {}", name, ip);
|
||||
|
||||
to_send.push_back(data);
|
||||
if len + 2 == buf.len() {
|
||||
break;
|
||||
}
|
||||
buf = buf[len + 2..].to_vec();
|
||||
}
|
||||
|
||||
// Write to client
|
||||
let src = info.dst.clone().try_into()?;
|
||||
while let Some(packet) = to_send.pop_front() {
|
||||
self.send_udp_packet_to_client(src, info.src, &packet)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn udp_over_tcp_timeout_expired(&self, info: &ConnectionInfo) -> bool {
|
||||
if let Some(state) = self.connection_map.get(info) {
|
||||
if let Some(expiry) = state.udp_over_tcp_expiry {
|
||||
return expiry < ::std::time::Instant::now();
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn clearup_expired_udp_over_tcp(&mut self) -> Result<()> {
|
||||
let keys = self.connection_map.keys().cloned().collect::<Vec<_>>();
|
||||
for key in keys {
|
||||
if self.udp_over_tcp_timeout_expired(&key) {
|
||||
log::trace!("UDP over TCP timeout: {}", key);
|
||||
self.remove_connection(&key)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn process_incoming_udp_packets(
|
||||
&mut self,
|
||||
manager: &Rc<dyn ConnectionManager>,
|
||||
|
@ -904,7 +975,15 @@ impl<'a> TunToProxy<'a> {
|
|||
|
||||
let mut block = || -> Result<(), Error> {
|
||||
if event.is_readable() || event.is_read_closed() {
|
||||
{
|
||||
let established = self
|
||||
.connection_map
|
||||
.get(&conn_info)
|
||||
.ok_or("")?
|
||||
.tcp_proxy_handler
|
||||
.connection_established();
|
||||
if self.options.dns_over_tcp && conn_info.dst.port() == DNS_PORT && established {
|
||||
self.receive_dns_over_tcp_packet_and_write_to_client(&conn_info)?;
|
||||
} else {
|
||||
let e = "connection state not found";
|
||||
let state = self.connection_map.get_mut(&conn_info).ok_or(e)?;
|
||||
|
||||
|
@ -1005,6 +1084,7 @@ impl<'a> TunToProxy<'a> {
|
|||
}
|
||||
self.send_to_smoltcp()?;
|
||||
self.clearup_expired_udp_associate()?;
|
||||
self.clearup_expired_udp_over_tcp()?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue