去除-o的ip指定

This commit is contained in:
lubeilin
2023-07-30 10:52:07 +08:00
parent c3f134e332
commit 6311d75ac0
9 changed files with 115 additions and 84 deletions
+40 -14
View File
@@ -1,6 +1,6 @@
use std::net::Ipv4Addr; use std::net::Ipv4Addr;
pub fn ips_parse(ips: &Vec<String>,in_ip:bool) -> Result<Vec<(u32, u32, Ipv4Addr)>, String> { pub fn ips_parse(ips: &Vec<String>) -> Result<Vec<(u32, u32, Ipv4Addr)>, String> {
let mut in_ips_c = vec![]; let mut in_ips_c = vec![];
for x in ips { for x in ips {
let mut split = x.split(","); let mut split = x.split(",");
@@ -12,10 +12,7 @@ pub fn ips_parse(ips: &Vec<String>,in_ip:bool) -> Result<Vec<(u32, u32, Ipv4Addr
let ip = if let Some(ip) = split.next() { let ip = if let Some(ip) = split.next() {
ip ip
} else { } else {
if in_ip{ return Err("ipv4/mask,ipv4".to_string());
return Err("ipv4/mask,ipv4".to_string());
}
"0.0.0.0"
}; };
let ip = if let Ok(ip) = ip.parse::<Ipv4Addr>() { let ip = if let Ok(ip) = ip.parse::<Ipv4Addr>() {
ip ip
@@ -38,16 +35,45 @@ pub fn ips_parse(ips: &Vec<String>,in_ip:bool) -> Result<Vec<(u32, u32, Ipv4Addr
} else { } else {
return Err("not ipv4".to_string()); return Err("not ipv4".to_string());
}; };
let mask = if let Ok(m) = mask.parse::<u32>() { let mask = to_ip(mask)?;
let mut mask = 0 as u32;
for i in 0..m {
mask = mask | (1 << (31 - i));
}
mask
} else {
return Err("not netmask".to_string());
};
in_ips_c.push((u32::from_be_bytes(dest.octets()), mask, ip)); in_ips_c.push((u32::from_be_bytes(dest.octets()), mask, ip));
} }
Ok(in_ips_c) Ok(in_ips_c)
} }
pub fn out_ips_parse(ips: &Vec<String>) -> Result<Vec<(u32, u32)>, String> {
let mut in_ips_c = vec![];
for x in ips {
let mut split = x.split("/");
let dest = if let Some(dest) = split.next() {
dest
} else {
return Err("no ipv4/mask".to_string());
};
let mask = if let Some(mask) = split.next() {
mask
} else {
return Err("no netmask".to_string());
};
let dest = if let Ok(dest) = dest.parse::<Ipv4Addr>() {
dest
} else {
return Err("not ipv4".to_string());
};
let mask = to_ip(mask)?;
in_ips_c.push((u32::from_be_bytes(dest.octets()), mask));
}
Ok(in_ips_c)
}
pub fn to_ip(mask: &str) -> Result<u32, String> {
if let Ok(m) = mask.parse::<u32>() {
let mut mask = 0 as u32;
for i in 0..m {
mask = mask | (1 << (31 - i));
}
Ok(mask)
} else {
Err("not netmask".to_string())
}
}
+8 -6
View File
@@ -5,7 +5,7 @@ use std::str::FromStr;
use console::style; use console::style;
use getopts::Options; use getopts::Options;
use tokio::io::{AsyncBufReadExt, BufReader}; use tokio::io::{AsyncBufReadExt, BufReader};
use common::args_parse::ips_parse; use common::args_parse::{ips_parse, out_ips_parse};
use vnt::core::{Config, VntUtil}; use vnt::core::{Config, VntUtil};
use vnt::handle::registration_handler::ReqEnum; use vnt::handle::registration_handler::ReqEnum;
@@ -33,16 +33,16 @@ async fn main0() {
let mut opts = Options::new(); let mut opts = Options::new();
opts.optopt("k", "", &format!("{}", green("必选,使用相同的token,就能组建一个局域网络".to_string())), "<token>"); opts.optopt("k", "", &format!("{}", green("必选,使用相同的token,就能组建一个局域网络".to_string())), "<token>");
opts.optopt("n", "", "给设备一个名字,默认使用系统版本", "<name>"); opts.optopt("n", "", "给设备一个名字,默认使用系统版本", "<name>");
opts.optopt("d", "", "设备唯一标识符,不使用--ip参数时,服务端凭此参数分配ip", "<id>"); opts.optopt("d", "", "设备唯一标识符,不使用--ip参数时,服务端凭此参数分配虚拟ip", "<id>");
opts.optflag("c", "", "关闭交互式命令,使用此参数禁用控制台输入"); opts.optflag("c", "", "关闭交互式命令,使用此参数禁用控制台输入");
opts.optopt("s", "", "注册和中继服务器地址", "<server>"); opts.optopt("s", "", "注册和中继服务器地址", "<server>");
opts.optopt("e", "", "NAT探测服务器地址,使用逗号分隔", "<addr1,addr2>"); opts.optopt("e", "", "NAT探测服务器地址,使用逗号分隔", "<addr1,addr2>");
opts.optflag("a", "", "使用tap模式,默认使用tun模式"); opts.optflag("a", "", "使用tap模式,默认使用tun模式");
opts.optmulti("i", "", "配置点对网(IP代理)时使用,-i 192.168.0.0/24,10.26.0.3 \n表示允许接收网段192.168.0.0/24的数据并转发到10.26.0.3", "<in-ip>"); opts.optmulti("i", "", "配置点对网(IP代理)时使用,-i 192.168.0.0/24,10.26.0.3 \n表示允许接收网段192.168.0.0/24的数据并转发到10.26.0.3", "<in-ip>");
opts.optmulti("o", "", "配置点对网时使用,-o 192.168.0.0/24,192.168.0.10 \n表示允许目标为192.168.0.0/24的数据从网卡192.168.0.10转发出去,不指定出口地址则使用默认网卡", "<out-ip>"); opts.optmulti("o", "", "配置点对网时使用,-o 192.168.0.0/24 \n表示允许目标为192.168.0.0/24的数据转发出去", "<out-ip>");
opts.optopt("w", "", "使用该密码生成的密钥对客户端数据进行加密,并且服务端无法解密,使用相同密码的客户端才能通信", "<password>"); opts.optopt("w", "", "使用该密码生成的密钥对客户端数据进行加密,并且服务端无法解密,使用相同密码的客户端才能通信", "<password>");
opts.optflag("m", "", "模拟组播,默认情况下组播数据会被当作广播发送,开启后会模拟真实组播的数据发送"); opts.optflag("m", "", "模拟组播,默认情况下组播数据会被当作广播发送,开启后会模拟真实组播的数据发送");
opts.optopt("u", "", "虚拟网卡mtu值", "<mtu>"); opts.optopt("u", "", "自定义mtu(默认为1430)", "<mtu>");
opts.optflag("", "tcp", "和服务端使用tcp通信,默认使用udp,一般来说udp延迟和消耗更低"); opts.optflag("", "tcp", "和服务端使用tcp通信,默认使用udp,一般来说udp延迟和消耗更低");
opts.optopt("", "ip", "指定虚拟ip,指定的ip不能和其他设备重复,必须有效并且在服务端所属网段下,默认情况由服务端分配", "<IP>"); opts.optopt("", "ip", "指定虚拟ip,指定的ip不能和其他设备重复,必须有效并且在服务端所属网段下,默认情况由服务端分配", "<IP>");
opts.optflag("", "relay", "仅使用服务器转发,不使用p2p,默认情况允许使用p2p"); opts.optflag("", "relay", "仅使用服务器转发,不使用p2p,默认情况允许使用p2p");
@@ -139,22 +139,24 @@ async fn main0() {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let in_ip = matches.opt_strs("i"); let in_ip = matches.opt_strs("i");
let in_ip = match ips_parse(&in_ip, true) { let in_ip = match ips_parse(&in_ip) {
Ok(in_ip) => { in_ip } Ok(in_ip) => { in_ip }
Err(e) => { Err(e) => {
print_usage(&program, opts); print_usage(&program, opts);
println!(); println!();
println!("-i {}", e); println!("-i {}", e);
println!("example: -i 192.168.0.0/24,10.26.0.3");
return; return;
} }
}; };
let out_ip = matches.opt_strs("o"); let out_ip = matches.opt_strs("o");
let out_ip = match ips_parse(&out_ip, false) { let out_ip = match out_ips_parse(&out_ip) {
Ok(out_ip) => { out_ip } Ok(out_ip) => { out_ip }
Err(e) => { Err(e) => {
print_usage(&program, opts); print_usage(&program, opts);
println!(); println!();
println!("-o {}", e); println!("-o {}", e);
println!("example: -o 0.0.0.0/0");
return; return;
} }
}; };
+6 -14
View File
@@ -1,4 +1,3 @@
use std::collections::HashSet;
use std::io; use std::io;
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use std::sync::Arc; use std::sync::Arc;
@@ -18,7 +17,7 @@ use crate::channel::sender::ChannelSender;
use crate::cipher::Cipher; use crate::cipher::Cipher;
use crate::core::status::VntStatusManger; use crate::core::status::VntStatusManger;
use crate::error::Error; use crate::error::Error;
use crate::external_route::ExternalRoute; use crate::external_route::{AllowExternalRoute, ExternalRoute};
use crate::handle::{ConnectStatus, CurrentDeviceInfo, heartbeat_handler, PeerDeviceInfo, punch_handler, registration_handler}; use crate::handle::{ConnectStatus, CurrentDeviceInfo, heartbeat_handler, PeerDeviceInfo, punch_handler, registration_handler};
use crate::handle::recv_handler::ChannelDataHandler; use crate::handle::recv_handler::ChannelDataHandler;
use crate::handle::registration_handler::{RegResponse, ReqEnum}; use crate::handle::registration_handler::{RegResponse, ReqEnum};
@@ -183,25 +182,18 @@ impl VntUtil {
let local_port = context.main_local_port()?; let local_port = context.main_local_port()?;
// NAT检测 // NAT检测
let nat_test = NatTest::new(config.nat_test_server.clone(), response.public_ip, response.public_port, local_ip, local_port); let nat_test = NatTest::new(config.nat_test_server.clone(), response.public_ip, response.public_port, local_ip, local_port);
let mut out_ip_list = config.out_ips;
for (_, _, ip) in out_ip_list.iter_mut() {
if ip == &Ipv4Addr::UNSPECIFIED {
*ip = local_ip;
}
}
let out_ips = out_ip_list.iter().map(|(_, _, ip)| *ip).collect::<HashSet<Ipv4Addr>>();
let out_external_route = ExternalRoute::new(out_ip_list);
let in_external_route = if config.in_ips.is_empty() { let in_external_route = if config.in_ips.is_empty() {
None None
} else { } else {
Some(ExternalRoute::new(config.in_ips)) Some(ExternalRoute::new(config.in_ips))
}; };
let (tcp_proxy, udp_proxy, ip_proxy_map) = if out_ips.is_empty() { let (tcp_proxy, udp_proxy, ip_proxy_map) = if config.out_ips.is_empty() {
(None, None, None) (None, None, None)
} else { } else {
let (tcp_proxy, udp_proxy, ip_proxy_map) = crate::ip_proxy::init_proxy(channel_sender.clone(), out_ips, current_device.clone()).await?; let (tcp_proxy, udp_proxy, ip_proxy_map) = crate::ip_proxy::init_proxy(channel_sender.clone(), current_device.clone()).await?;
(Some(tcp_proxy), Some(udp_proxy), Some(ip_proxy_map)) (Some(tcp_proxy), Some(udp_proxy), Some(ip_proxy_map))
}; };
let out_external_route = AllowExternalRoute::new(config.out_ips);
let igmp_server = if config.simulate_multicast { let igmp_server = if config.simulate_multicast {
Some(IgmpServer::new(device_writer.clone())) Some(IgmpServer::new(device_writer.clone()))
@@ -345,7 +337,7 @@ pub struct Config {
pub server_address_str: String, pub server_address_str: String,
pub nat_test_server: Vec<SocketAddr>, pub nat_test_server: Vec<SocketAddr>,
pub in_ips: Vec<(u32, u32, Ipv4Addr)>, pub in_ips: Vec<(u32, u32, Ipv4Addr)>,
pub out_ips: Vec<(u32, u32, Ipv4Addr)>, pub out_ips: Vec<(u32, u32)>,
pub password: Option<String>, pub password: Option<String>,
pub simulate_multicast: bool, pub simulate_multicast: bool,
pub mtu: Option<u16>, pub mtu: Option<u16>,
@@ -362,7 +354,7 @@ impl Config {
server_address: SocketAddr, server_address: SocketAddr,
server_address_str: String, server_address_str: String,
nat_test_server: Vec<SocketAddr>, nat_test_server: Vec<SocketAddr>,
in_ips: Vec<(u32, u32, Ipv4Addr)>, out_ips: Vec<(u32, u32, Ipv4Addr)>, in_ips: Vec<(u32, u32, Ipv4Addr)>, out_ips: Vec<(u32, u32)>,
password: Option<String>, simulate_multicast: bool, mtu: Option<u16>, tcp: bool, password: Option<String>, simulate_multicast: bool, mtu: Option<u16>, tcp: bool,
ip: Option<Ipv4Addr>, ip: Option<Ipv4Addr>,
relay: bool, ) -> Self { relay: bool, ) -> Self {
+23 -1
View File
@@ -11,7 +11,7 @@ pub struct ExternalRoute {
impl ExternalRoute { impl ExternalRoute {
pub fn new(route_table: Vec<(u32, u32, Ipv4Addr)>) -> Self { pub fn new(route_table: Vec<(u32, u32, Ipv4Addr)>) -> Self {
Self { Self {
route_table:Arc::new(route_table) route_table: Arc::new(route_table)
} }
} }
pub fn route(&self, ip: &Ipv4Addr) -> Option<Ipv4Addr> { pub fn route(&self, ip: &Ipv4Addr) -> Option<Ipv4Addr> {
@@ -24,3 +24,25 @@ impl ExternalRoute {
None None
} }
} }
#[derive(Clone)]
pub struct AllowExternalRoute {
route_table: Arc<Vec<(u32, u32)>>,
}
impl AllowExternalRoute {
pub fn new(route_table: Vec<(u32, u32)>) -> Self {
Self {
route_table: Arc::new(route_table)
}
}
pub fn allow(&self, ip: &Ipv4Addr) -> bool {
let ip = u32::from_be_bytes(ip.octets());
for (dest, mask) in self.route_table.iter() {
if *mask & ip == *mask & *dest {
return true;
}
}
false
}
}
+8 -10
View File
@@ -17,7 +17,7 @@ use crate::channel::{Route, RouteKey};
use crate::cipher::Cipher; use crate::cipher::Cipher;
use crate::error::Error; use crate::error::Error;
use crate::external_route::ExternalRoute; use crate::external_route::AllowExternalRoute;
use crate::handle::{check_dest, ConnectStatus, CurrentDeviceInfo, PeerDeviceInfo, PeerDeviceStatus}; use crate::handle::{check_dest, ConnectStatus, CurrentDeviceInfo, PeerDeviceInfo, PeerDeviceStatus};
use crate::handle::registration_handler::Register; use crate::handle::registration_handler::Register;
use crate::igmp_server::IgmpServer; use crate::igmp_server::IgmpServer;
@@ -41,7 +41,7 @@ pub struct ChannelDataHandler {
connect_status: Arc<AtomicCell<ConnectStatus>>, connect_status: Arc<AtomicCell<ConnectStatus>>,
peer_nat_info_map: Arc<SkipMap<Ipv4Addr, NatInfo>>, peer_nat_info_map: Arc<SkipMap<Ipv4Addr, NatInfo>>,
ip_proxy_map: Option<IpProxyMap>, ip_proxy_map: Option<IpProxyMap>,
out_external_route: ExternalRoute, out_external_route: AllowExternalRoute,
cone_sender: Sender<(Ipv4Addr, NatInfo)>, cone_sender: Sender<(Ipv4Addr, NatInfo)>,
symmetric_sender: Sender<(Ipv4Addr, NatInfo)>, symmetric_sender: Sender<(Ipv4Addr, NatInfo)>,
cipher: Cipher, cipher: Cipher,
@@ -58,7 +58,7 @@ impl ChannelDataHandler {
connect_status: Arc<AtomicCell<ConnectStatus>>, connect_status: Arc<AtomicCell<ConnectStatus>>,
peer_nat_info_map: Arc<SkipMap<Ipv4Addr, NatInfo>>, peer_nat_info_map: Arc<SkipMap<Ipv4Addr, NatInfo>>,
ip_proxy_map: Option<IpProxyMap>, ip_proxy_map: Option<IpProxyMap>,
out_external_route: ExternalRoute, out_external_route: AllowExternalRoute,
cone_sender: Sender<(Ipv4Addr, NatInfo)>, cone_sender: Sender<(Ipv4Addr, NatInfo)>,
symmetric_sender: Sender<(Ipv4Addr, NatInfo)>, symmetric_sender: Sender<(Ipv4Addr, NatInfo)>,
cipher: Cipher, cipher: Cipher,
@@ -185,7 +185,7 @@ impl ChannelDataHandler {
} }
if not_broadcast && ipv4.destination_ip() != destination { if not_broadcast && ipv4.destination_ip() != destination {
if let Some(ip_proxy_map) = &self.ip_proxy_map { if let Some(ip_proxy_map) = &self.ip_proxy_map {
if let Some(gate_way) = self.out_external_route.route(&ipv4.destination_ip()) { if self.out_external_route.allow(&ipv4.destination_ip()) {
match ipv4.protocol() { match ipv4.protocol() {
ipv4::protocol::Protocol::Tcp => { ipv4::protocol::Protocol::Tcp => {
let dest_ip = ipv4.destination_ip(); let dest_ip = ipv4.destination_ip();
@@ -197,8 +197,7 @@ impl ChannelDataHandler {
tcp_packet.update_checksum(); tcp_packet.update_checksum();
ipv4.set_destination_ip(destination); ipv4.set_destination_ip(destination);
ipv4.update_checksum(); ipv4.update_checksum();
ip_proxy_map.tcp_proxy_map.insert(SocketAddrV4::new(source, source_port), ip_proxy_map.tcp_proxy_map.insert(SocketAddrV4::new(source, source_port), SocketAddrV4::new(dest_ip, dest_port));
(SocketAddrV4::new(gate_way, 0), SocketAddrV4::new(dest_ip, dest_port)));
} }
ipv4::protocol::Protocol::Udp => { ipv4::protocol::Protocol::Udp => {
let dest_ip = ipv4.destination_ip(); let dest_ip = ipv4.destination_ip();
@@ -210,8 +209,7 @@ impl ChannelDataHandler {
udp_packet.update_checksum(); udp_packet.update_checksum();
ipv4.set_destination_ip(destination); ipv4.set_destination_ip(destination);
ipv4.update_checksum(); ipv4.update_checksum();
ip_proxy_map.udp_proxy_map.insert(SocketAddrV4::new(source, source_port), ip_proxy_map.udp_proxy_map.insert(SocketAddrV4::new(source, source_port), SocketAddrV4::new(dest_ip, dest_port));
(SocketAddrV4::new(gate_way, 0), SocketAddrV4::new(dest_ip, dest_port)));
} }
ipv4::protocol::Protocol::Icmp => { ipv4::protocol::Protocol::Icmp => {
let dest_ip = ipv4.destination_ip(); let dest_ip = ipv4.destination_ip();
@@ -220,7 +218,7 @@ impl ChannelDataHandler {
match icmp_packet.header_other() { match icmp_packet.header_other() {
HeaderOther::Identifier(id, seq) => { HeaderOther::Identifier(id, seq) => {
ip_proxy_map.icmp_proxy_map.insert((dest_ip, id, seq), source); ip_proxy_map.icmp_proxy_map.insert((dest_ip, id, seq), source);
ip_proxy_map.send_icmp(ipv4.payload(), &gate_way, &dest_ip)?; ip_proxy_map.send_icmp(ipv4.payload(), &dest_ip)?;
} }
_ => { _ => {
return Ok(()); return Ok(());
@@ -419,7 +417,7 @@ impl ChannelDataHandler {
ControlPacket::AddrRequest => { ControlPacket::AddrRequest => {
match route_key.addr.ip() { match route_key.addr.ip() {
std::net::IpAddr::V4(ipv4) => { std::net::IpAddr::V4(ipv4) => {
let mut packet = NetPacket::new([0;12+6])?; let mut packet = NetPacket::new([0; 12 + 6])?;
packet.set_version(Version::V1); packet.set_version(Version::V1);
packet.set_protocol(Protocol::Control); packet.set_protocol(Protocol::Control);
packet.set_transport_protocol( packet.set_transport_protocol(
+2 -2
View File
@@ -190,7 +190,7 @@ pub async fn base_handle(sender: &ChannelSender, buf: &mut [u8],
SocketAddrV4::new(dest_ip, tcp_packet.destination_port()) SocketAddrV4::new(dest_ip, tcp_packet.destination_port())
}; };
if let Some(entry) = proxy_map.tcp_proxy_map.get(&dest_addr) { if let Some(entry) = proxy_map.tcp_proxy_map.get(&dest_addr) {
let source_addr = entry.value().1; let source_addr = entry.value();
let source_ip = *source_addr.ip(); let source_ip = *source_addr.ip();
let mut tcp_packet = TcpPacket::new(source_ip, dest_ip, &mut net_packet.buffer_mut()[12 + ip_head_len..data_len])?; let mut tcp_packet = TcpPacket::new(source_ip, dest_ip, &mut net_packet.buffer_mut()[12 + ip_head_len..data_len])?;
tcp_packet.set_source_port(source_addr.port()); tcp_packet.set_source_port(source_addr.port());
@@ -206,7 +206,7 @@ pub async fn base_handle(sender: &ChannelSender, buf: &mut [u8],
SocketAddrV4::new(dest_ip, udp_packet.destination_port()) SocketAddrV4::new(dest_ip, udp_packet.destination_port())
}; };
if let Some(entry) = proxy_map.udp_proxy_map.get(&dest_addr) { if let Some(entry) = proxy_map.udp_proxy_map.get(&dest_addr) {
let source_addr = entry.value().1; let source_addr = entry.value();
let source_ip = *source_addr.ip(); let source_ip = *source_addr.ip();
let mut udp_packet = UdpPacket::new(source_ip, dest_ip, &mut net_packet.buffer_mut()[12 + ip_head_len..data_len])?; let mut udp_packet = UdpPacket::new(source_ip, dest_ip, &mut net_packet.buffer_mut()[12 + ip_head_len..data_len])?;
udp_packet.set_source_port(source_addr.port()); udp_packet.set_source_port(source_addr.port());
+16 -25
View File
@@ -1,5 +1,4 @@
use std::{io, thread}; use std::{io, thread};
use std::collections::{HashMap, HashSet};
use std::net::{Ipv4Addr, SocketAddrV4}; use std::net::{Ipv4Addr, SocketAddrV4};
use std::sync::Arc; use std::sync::Arc;
use crossbeam_utils::atomic::AtomicCell; use crossbeam_utils::atomic::AtomicCell;
@@ -27,28 +26,23 @@ pub enum Protocol {
pub struct IpProxyMap { pub struct IpProxyMap {
pub(crate) tcp_proxy_port: u16, pub(crate) tcp_proxy_port: u16,
pub(crate) udp_proxy_port: u16, pub(crate) udp_proxy_port: u16,
//真实源地址 -> (绑定地址,目的地址) //真实源地址 -> 目的地址
pub(crate) tcp_proxy_map: Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>>, pub(crate) tcp_proxy_map: Arc<SkipMap<SocketAddrV4, SocketAddrV4>>,
pub(crate) udp_proxy_map: Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>>, pub(crate) udp_proxy_map: Arc<SkipMap<SocketAddrV4, SocketAddrV4>>,
// icmp用Identifier来区分,没有Identifier的一律不转发 // icmp用Identifier来区分,没有Identifier的一律不转发
pub(crate) icmp_proxy_map: Arc<SkipMap<(Ipv4Addr, u16, u16), Ipv4Addr>>, pub(crate) icmp_proxy_map: Arc<SkipMap<(Ipv4Addr, u16, u16), Ipv4Addr>>,
icmp_sockets: HashMap<Ipv4Addr, Arc<Socket>>, icmp_socket: Arc<Socket>,
} }
impl IpProxyMap { impl IpProxyMap {
pub fn send_icmp(&self, buf: &[u8], src: &Ipv4Addr, dest: &Ipv4Addr) -> io::Result<usize> { pub fn send_icmp(&self, buf: &[u8], dest: &Ipv4Addr) -> io::Result<usize> {
if let Some(socket) = self.icmp_sockets.get(src) { self.icmp_socket.send_to(buf, &SockAddr::from(SocketAddrV4::new(*dest, 0)))
socket.send_to(buf, &SockAddr::from(SocketAddrV4::new(*dest, 0)))
} else {
Err(io::Error::new(io::ErrorKind::Other, format!("not found src:{},dest:{}", src, dest)))
}
} }
} }
pub async fn init_proxy(sender: ChannelSender, bind_ips: HashSet<Ipv4Addr>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>) -> io::Result<(TcpProxy, UdpProxy, IpProxyMap)> { pub async fn init_proxy(sender: ChannelSender, current_device: Arc<AtomicCell<CurrentDeviceInfo>>) -> io::Result<(TcpProxy, UdpProxy, IpProxyMap)> {
let mut icmp_sockets = HashMap::new(); let tcp_proxy_map: Arc<SkipMap<SocketAddrV4, SocketAddrV4>> = Arc::new(SkipMap::new());
let tcp_proxy_map: Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>> = Arc::new(SkipMap::new()); let udp_proxy_map: Arc<SkipMap<SocketAddrV4, SocketAddrV4>> = Arc::new(SkipMap::new());
let udp_proxy_map: Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>> = Arc::new(SkipMap::new());
let icmp_proxy_map: Arc<SkipMap<(Ipv4Addr, u16, u16), Ipv4Addr>> = Arc::new(SkipMap::new()); let icmp_proxy_map: Arc<SkipMap<(Ipv4Addr, u16, u16), Ipv4Addr>> = Arc::new(SkipMap::new());
let tcp_listener = TcpListener::bind("0.0.0.0:0").await?; let tcp_listener = TcpListener::bind("0.0.0.0:0").await?;
let udp_socket = UdpSocket::bind("0.0.0.0:0").await?; let udp_socket = UdpSocket::bind("0.0.0.0:0").await?;
@@ -56,15 +50,12 @@ pub async fn init_proxy(sender: ChannelSender, bind_ips: HashSet<Ipv4Addr>, curr
let udp_proxy_port = udp_socket.local_addr()?.port(); let udp_proxy_port = udp_socket.local_addr()?.port();
let tcp_proxy = TcpProxy::new(tcp_listener, tcp_proxy_map.clone()); let tcp_proxy = TcpProxy::new(tcp_listener, tcp_proxy_map.clone());
let udp_proxy = UdpProxy::new(udp_socket, udp_proxy_map.clone()); let udp_proxy = UdpProxy::new(udp_socket, udp_proxy_map.clone());
for ip in bind_ips { let addr = SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0);
let addr = SocketAddrV4::new(ip, 0); let icmp_proxy = IcmpProxy::new(addr, icmp_proxy_map.clone(), sender.clone(), current_device.clone())?;
let icmp_proxy_map = icmp_proxy_map.clone(); let icmp_socket = icmp_proxy.icmp_socket();
let icmp_proxy = IcmpProxy::new(addr, icmp_proxy_map, sender.clone(), current_device.clone())?; thread::spawn(move || {
icmp_sockets.insert(ip, icmp_proxy.icmp_socket()); icmp_proxy.start();
thread::spawn(move || { });
icmp_proxy.start();
});
}
Ok((tcp_proxy, udp_proxy, IpProxyMap { Ok((tcp_proxy, udp_proxy, IpProxyMap {
tcp_proxy_port, tcp_proxy_port,
@@ -72,6 +63,6 @@ pub async fn init_proxy(sender: ChannelSender, bind_ips: HashSet<Ipv4Addr>, curr
tcp_proxy_map, tcp_proxy_map,
udp_proxy_map, udp_proxy_map,
icmp_proxy_map, icmp_proxy_map,
icmp_sockets, icmp_socket,
})) }))
} }
+5 -5
View File
@@ -6,11 +6,11 @@ use tokio::net::{TcpListener, TcpStream};
pub struct TcpProxy { pub struct TcpProxy {
tcp_listener: TcpListener, tcp_listener: TcpListener,
map: Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>>, map: Arc<SkipMap<SocketAddrV4, SocketAddrV4>>,
} }
impl TcpProxy { impl TcpProxy {
pub fn new(tcp_listener: TcpListener, map: Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>>) -> Self { pub fn new(tcp_listener: TcpListener, map: Arc<SkipMap<SocketAddrV4, SocketAddrV4>>) -> Self {
Self { Self {
tcp_listener, tcp_listener,
map, map,
@@ -25,11 +25,11 @@ impl TcpProxy {
match sender_addr { match sender_addr {
SocketAddr::V4(sender_addr) => { SocketAddr::V4(sender_addr) => {
if let Some(entry) = map.get(&sender_addr) { if let Some(entry) = map.get(&sender_addr) {
let (src_addr, dest_addr) = *entry.value(); let dest_addr = *entry.value();
let peer_tcp_stream = match TcpStream::connect(dest_addr).await { let peer_tcp_stream = match TcpStream::connect(dest_addr).await {
Ok(peer_tcp_stream) => {peer_tcp_stream} Ok(peer_tcp_stream) => {peer_tcp_stream}
Err(e) => { Err(e) => {
log::warn!("tcp代理异常:{:?},来源:{},目标:{}",e,src_addr,dest_addr); log::warn!("tcp代理异常:{:?},来源:{},目标:{}",e,sender_addr,dest_addr);
continue; continue;
} }
}; };
@@ -38,7 +38,7 @@ impl TcpProxy {
match proxy(tcp_stream, peer_tcp_stream).await { match proxy(tcp_stream, peer_tcp_stream).await {
Ok(_) => {} Ok(_) => {}
Err(e) => { Err(e) => {
log::warn!("tcp代理异常:{:?},来源:{},目标:{}",e,src_addr,dest_addr); log::warn!("tcp代理异常:{:?},来源:{},目标:{}",e,sender_addr,dest_addr);
} }
} }
map.remove(&sender_addr); map.remove(&sender_addr);
+7 -7
View File
@@ -8,11 +8,11 @@ use tokio::net::UdpSocket;
/// 一个udp代理,作用是利用系统协议栈,将udp数据报解析出来再转发到目的地址 /// 一个udp代理,作用是利用系统协议栈,将udp数据报解析出来再转发到目的地址
pub struct UdpProxy { pub struct UdpProxy {
udp_socket: Arc<UdpSocket>, udp_socket: Arc<UdpSocket>,
map: Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>>, map: Arc<SkipMap<SocketAddrV4, SocketAddrV4>>,
} }
impl UdpProxy { impl UdpProxy {
pub fn new(udp_socket: UdpSocket, map: Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>>) -> Self { pub fn new(udp_socket: UdpSocket, map: Arc<SkipMap<SocketAddrV4, SocketAddrV4>>) -> Self {
let udp_socket = Arc::new(udp_socket); let udp_socket = Arc::new(udp_socket);
Self { Self {
udp_socket, udp_socket,
@@ -48,11 +48,11 @@ impl UdpProxy {
} }
} }
async fn start0(buf: &[u8], sender_addr: SocketAddrV4, inner_map: &Arc<SkipMap<SocketAddrV4, Arc<UdpSocket>>>, map: &Arc<SkipMap<SocketAddrV4, (SocketAddrV4, SocketAddrV4)>>, udp_socket: &Arc<UdpSocket>) -> io::Result<()> { async fn start0(buf: &[u8], sender_addr: SocketAddrV4, inner_map: &Arc<SkipMap<SocketAddrV4, Arc<UdpSocket>>>, map: &Arc<SkipMap<SocketAddrV4, SocketAddrV4>>, udp_socket: &Arc<UdpSocket>) -> io::Result<()> {
if let Some(entry) = inner_map.get(&sender_addr) { if let Some(entry) = inner_map.get(&sender_addr) {
entry.value().send(buf).await?; entry.value().send(buf).await?;
} else if let Some(entry) = map.get(&sender_addr) { } else if let Some(entry) = map.get(&sender_addr) {
let (src_addr, dest_addr) = *entry.value(); let dest_addr = *entry.value();
let peer_udp_socket = UdpSocket::bind("0.0.0.0:0").await?; let peer_udp_socket = UdpSocket::bind("0.0.0.0:0").await?;
peer_udp_socket.connect(dest_addr).await?; peer_udp_socket.connect(dest_addr).await?;
peer_udp_socket.send(buf).await?; peer_udp_socket.send(buf).await?;
@@ -71,20 +71,20 @@ async fn start0(buf: &[u8], sender_addr: SocketAddrV4, inner_map: &Arc<SkipMap<S
match udp_socket.send_to(&buf[..len], sender_addr).await { match udp_socket.send_to(&buf[..len], sender_addr).await {
Ok(_) => {} Ok(_) => {}
Err(e) => { Err(e) => {
log::warn!("udp代理异常:{:?},来源:{},目标:{}",e,src_addr,dest_addr); log::warn!("udp代理异常:{:?},来源:{},目标:{}",e,sender_addr,dest_addr);
break; break;
} }
} }
} }
Err(e) => { Err(e) => {
log::warn!("udp代理异常:{:?},来源:{},目标:{}",e,src_addr,dest_addr); log::warn!("udp代理异常:{:?},来源:{},目标:{}",e,sender_addr,dest_addr);
break; break;
} }
} }
} }
Err(_) => { Err(_) => {
//超时关闭 //超时关闭
log::warn!("udp代理超时关闭,来源:{},目标:{}",src_addr,dest_addr); log::warn!("udp代理超时关闭,来源:{},目标:{}",sender_addr,dest_addr);
break; break;
} }
} }