diff --git a/g3proxy/doc/configuration/escapers/proxy_socks5.rst b/g3proxy/doc/configuration/escapers/proxy_socks5.rst index b00fcc15..99d9ace5 100644 --- a/g3proxy/doc/configuration/escapers/proxy_socks5.rst +++ b/g3proxy/doc/configuration/escapers/proxy_socks5.rst @@ -96,7 +96,7 @@ The tcp keepalive set in user config won't be taken into account. transmute_udp_peer_ip --------------------- -**optional**, **type**: bool or map +**optional**, **type**: map | bool Set this option if the UDP peer IP returned from the remote proxy should be transmuted. diff --git a/g3proxy/doc/configuration/servers/socks_proxy.rst b/g3proxy/doc/configuration/servers/socks_proxy.rst index 4c83d5b7..2b9be4d3 100644 --- a/g3proxy/doc/configuration/servers/socks_proxy.rst +++ b/g3proxy/doc/configuration/servers/socks_proxy.rst @@ -124,12 +124,16 @@ Set the buffer config for the udp socket. transmute_udp_echo_ip --------------------- -**optional**, **type**: map +**optional**, **type**: map | bool Set this if you want to reply another ip other then the real bind ip for the udp listen socket to the client. The key of the map should be the local ip, and the value should be the ip you want the client to use. +If no matched key found in the map, the unspecified ip address of the same family will be used. + +For bool value, an empty map will be used if set to true, or disabled if set to false. **default**: not set, **alias**: auto_reply_local_ip_map .. versionchanged:: 1.7.19 change option name to transmute_udp_echo_ip +.. versionchanged:: 1.9.9 allow bool value and change to use unspecified ip if no match records diff --git a/g3proxy/src/config/server/socks_proxy.rs b/g3proxy/src/config/server/socks_proxy.rs index 08220fd6..7b70ded8 100644 --- a/g3proxy/src/config/server/socks_proxy.rs +++ b/g3proxy/src/config/server/socks_proxy.rs @@ -14,7 +14,7 @@ * limitations under the License. */ -use std::net::{IpAddr, SocketAddr}; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; use std::sync::Arc; use std::time::Duration; @@ -296,12 +296,19 @@ impl SocksProxyServerConfig { Ok(()) } "transmute_udp_echo_ip" | "auto_reply_local_ip_map" => { - let map = g3_yaml::value::as_hashmap( - v, - g3_yaml::value::as_ipaddr, - g3_yaml::value::as_ipaddr, - )?; - self.transmute_udp_echo_ip = Some(map.into_iter().collect::>()); + if let Yaml::Hash(_) = v { + let map = g3_yaml::value::as_hashmap( + v, + g3_yaml::value::as_ipaddr, + g3_yaml::value::as_ipaddr, + )?; + self.transmute_udp_echo_ip = Some(map.into_iter().collect::>()); + } else { + let enable = g3_yaml::value::as_bool(v)?; + if enable { + self.transmute_udp_echo_ip = Some(AHashMap::default()); + } + } Ok(()) } _ => Err(anyhow!("invalid key {k}")), @@ -324,9 +331,15 @@ impl SocksProxyServerConfig { pub(crate) fn transmute_udp_echo_addr(&self, local_addr: SocketAddr) -> SocketAddr { if let Some(map) = &self.transmute_udp_echo_ip { - if let Some(ip) = map.get(&local_addr.ip()) { - return SocketAddr::new(*ip, local_addr.port()); - } + let ip = if let Some(ip) = map.get(&local_addr.ip()) { + *ip + } else { + match local_addr.ip() { + IpAddr::V4(_) => IpAddr::V4(Ipv4Addr::UNSPECIFIED), + IpAddr::V6(_) => IpAddr::V6(Ipv6Addr::UNSPECIFIED), + } + }; + return SocketAddr::new(ip, local_addr.port()); } local_addr }