Skip to content

Commit

Permalink
g3proxy: support bind_interface on escapers
Browse files Browse the repository at this point in the history
  • Loading branch information
zh-jq committed Sep 22, 2024
1 parent 26ae1c6 commit 3c1c239
Show file tree
Hide file tree
Showing 30 changed files with 229 additions and 12 deletions.
2 changes: 1 addition & 1 deletion g3bench/src/module/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use tokio::net::TcpStream;

use g3_socket::BindAddr;
#[cfg(any(target_os = "linux", target_os = "android"))]
use g3_socket::InterfaceName;
use g3_types::net::InterfaceName;

const SOCKET_ARG_LOCAL_ADDRESS: &str = "local-address";
#[cfg(any(target_os = "linux", target_os = "android"))]
Expand Down
1 change: 1 addition & 0 deletions g3proxy/doc/configuration/escapers/direct_fixed.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ The following common keys are supported:

* :ref:`tcp_sock_speed_limit <conf_escaper_common_tcp_sock_speed_limit>`
* :ref:`udp_sock_speed_limit <conf_escaper_common_udp_sock_speed_limit>`
* :ref:`bind_interface <conf_escaper_common_bind_interface>`
* :ref:`no_ipv4 <conf_escaper_common_no_ipv4>`
* :ref:`no_ipv6 <conf_escaper_common_no_ipv6>`
* :ref:`tcp_connect <conf_escaper_common_tcp_connect>`
Expand Down
1 change: 1 addition & 0 deletions g3proxy/doc/configuration/escapers/divert_tcp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ The following common keys are supported:
* :ref:`resolver <conf_escaper_common_resolver>`, **required** only if *proxy_addr* is domain
* :ref:`resolve_strategy <conf_escaper_common_resolve_strategy>`
* :ref:`tcp_sock_speed_limit <conf_escaper_common_tcp_sock_speed_limit>`
* :ref:`bind_interface <conf_escaper_common_bind_interface>`
* :ref:`no_ipv4 <conf_escaper_common_no_ipv4>`
* :ref:`no_ipv6 <conf_escaper_common_no_ipv6>`
* :ref:`tcp_connect <conf_escaper_common_tcp_connect>`
Expand Down
15 changes: 15 additions & 0 deletions g3proxy/doc/configuration/escapers/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,21 @@ Set speed limit for each udp socket.

.. versionchanged:: 1.4.0 changed name to udp_sock_speed_limit

.. _conf_escaper_common_bind_interface:

bind_interface
--------------

**optional**: **type**: :ref:`interface name <conf_value_interface_name>`

Bind the outgoing socket to a particular device like “eth0”.

.. note:: This is only supported on Linux based OS.

**default**: not set

.. versionadded:: 1.9.9

.. _conf_escaper_common_no_ipv4:

no_ipv4
Expand Down
1 change: 1 addition & 0 deletions g3proxy/doc/configuration/escapers/proxy_float.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Config Keys
The following common keys are supported:

* :ref:`shared_logger <conf_escaper_common_shared_logger>`
* :ref:`bind_interface <conf_escaper_common_bind_interface>`
* :ref:`tcp_sock_speed_limit <conf_escaper_common_tcp_sock_speed_limit>`
* :ref:`tcp_misc_opts <conf_escaper_common_tcp_misc_opts>`
* :ref:`peer negotiation timeout <conf_escaper_common_peer_negotiation_timeout>`
Expand Down
1 change: 1 addition & 0 deletions g3proxy/doc/configuration/escapers/proxy_http.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ The following common keys are supported:
* :ref:`resolver <conf_escaper_common_resolver>`, **required** only if *proxy_addr* is domain
* :ref:`resolve_strategy <conf_escaper_common_resolve_strategy>`
* :ref:`tcp_sock_speed_limit <conf_escaper_common_tcp_sock_speed_limit>`
* :ref:`bind_interface <conf_escaper_common_bind_interface>`
* :ref:`no_ipv4 <conf_escaper_common_no_ipv4>`
* :ref:`no_ipv6 <conf_escaper_common_no_ipv6>`
* :ref:`tcp_connect <conf_escaper_common_tcp_connect>`
Expand Down
1 change: 1 addition & 0 deletions g3proxy/doc/configuration/escapers/proxy_https.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ The following common keys are supported:
* :ref:`resolver <conf_escaper_common_resolver>`, **required** only if *proxy_addr* is domain
* :ref:`resolve_strategy <conf_escaper_common_resolve_strategy>`
* :ref:`tcp_sock_speed_limit <conf_escaper_common_tcp_sock_speed_limit>`
* :ref:`bind_interface <conf_escaper_common_bind_interface>`
* :ref:`no_ipv4 <conf_escaper_common_no_ipv4>`
* :ref:`no_ipv6 <conf_escaper_common_no_ipv6>`
* :ref:`tcp_connect <conf_escaper_common_tcp_connect>`
Expand Down
1 change: 1 addition & 0 deletions g3proxy/doc/configuration/escapers/proxy_socks5.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ The following common keys are supported:
* :ref:`resolve_strategy <conf_escaper_common_resolve_strategy>`
* :ref:`tcp_sock_speed_limit <conf_escaper_common_tcp_sock_speed_limit>`
* :ref:`udp_sock_speed_limit <conf_escaper_common_udp_sock_speed_limit>`
* :ref:`bind_interface <conf_escaper_common_bind_interface>`
* :ref:`no_ipv4 <conf_escaper_common_no_ipv4>`
* :ref:`no_ipv6 <conf_escaper_common_no_ipv6>`
* :ref:`tcp_connect <conf_escaper_common_tcp_connect>`
Expand Down
1 change: 1 addition & 0 deletions g3proxy/doc/configuration/escapers/proxy_socks5s.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ The following common keys are supported:
* :ref:`resolve_strategy <conf_escaper_common_resolve_strategy>`
* :ref:`tcp_sock_speed_limit <conf_escaper_common_tcp_sock_speed_limit>`
* :ref:`udp_sock_speed_limit <conf_escaper_common_udp_sock_speed_limit>`
* :ref:`bind_interface <conf_escaper_common_bind_interface>`
* :ref:`no_ipv4 <conf_escaper_common_no_ipv4>`
* :ref:`no_ipv6 <conf_escaper_common_no_ipv6>`
* :ref:`tcp_connect <conf_escaper_common_tcp_connect>`
Expand Down
10 changes: 9 additions & 1 deletion g3proxy/doc/configuration/values/network.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

.. _configure_network_value_types:

*******
Expand Down Expand Up @@ -77,6 +76,15 @@ ip network str

The string should be a network address in CIDR format, or just an ip address.

.. _conf_value_interface_name:

interface name
==============

**yaml value**: str

The string should be a network interface name.

.. _conf_value_egress_area:

egress area
Expand Down
13 changes: 13 additions & 0 deletions g3proxy/src/config/escaper/direct_fixed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ use yaml_rust::{yaml, Yaml};

use g3_types::acl::{AclAction, AclNetworkRuleBuilder};
use g3_types::metrics::{MetricsName, StaticMetricsTags};
#[cfg(any(target_os = "linux", target_os = "android"))]
use g3_types::net::InterfaceName;
use g3_types::net::{HappyEyeballsConfig, TcpKeepAliveConfig, TcpMiscSockOpts, UdpMiscSockOpts};
use g3_types::resolve::{QueryStrategy, ResolveRedirectionBuilder, ResolveStrategy};
use g3_yaml::YamlDocPosition;
Expand All @@ -36,6 +38,8 @@ pub(crate) struct DirectFixedEscaperConfig {
pub(crate) name: MetricsName,
position: Option<YamlDocPosition>,
pub(crate) shared_logger: Option<AsciiString>,
#[cfg(any(target_os = "linux", target_os = "android"))]
pub(crate) bind_interface: Option<InterfaceName>,
pub(crate) bind4: Vec<IpAddr>,
pub(crate) bind6: Vec<IpAddr>,
pub(crate) no_ipv4: bool,
Expand All @@ -59,6 +63,8 @@ impl DirectFixedEscaperConfig {
name: MetricsName::default(),
position,
shared_logger: None,
#[cfg(any(target_os = "linux", target_os = "android"))]
bind_interface: None,
bind4: Vec::new(),
bind6: Vec::new(),
no_ipv4: false,
Expand Down Expand Up @@ -107,6 +113,13 @@ impl DirectFixedEscaperConfig {
self.extra_metrics_tags = Some(Arc::new(tags));
Ok(())
}
#[cfg(any(target_os = "linux", target_os = "android"))]
"bind_interface" => {
let interface = g3_yaml::value::as_interface_name(v)
.context(format!("invalid interface name value for key {k}"))?;
self.bind_interface = Some(interface);
Ok(())
}
"bind_ip" => {
let ips = g3_yaml::value::as_list(v, g3_yaml::value::as_ipaddr)
.context(format!("invalid ip address list value for key {k}"))?;
Expand Down
13 changes: 13 additions & 0 deletions g3proxy/src/config/escaper/divert_tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ use yaml_rust::{yaml, Yaml};

use g3_types::collection::SelectivePickPolicy;
use g3_types::metrics::{MetricsName, StaticMetricsTags};
#[cfg(any(target_os = "linux", target_os = "android"))]
use g3_types::net::InterfaceName;
use g3_types::net::{
HappyEyeballsConfig, Host, TcpKeepAliveConfig, TcpMiscSockOpts, WeightedUpstreamAddr,
};
Expand All @@ -40,6 +42,8 @@ pub(crate) struct DivertTcpEscaperConfig {
pub(crate) shared_logger: Option<AsciiString>,
pub(crate) proxy_nodes: Vec<WeightedUpstreamAddr>,
pub(crate) proxy_pick_policy: SelectivePickPolicy,
#[cfg(any(target_os = "linux", target_os = "android"))]
pub(crate) bind_interface: Option<InterfaceName>,
pub(crate) bind_v4: Option<Ipv4Addr>,
pub(crate) bind_v6: Option<Ipv6Addr>,
pub(crate) no_ipv4: bool,
Expand All @@ -61,6 +65,8 @@ impl DivertTcpEscaperConfig {
shared_logger: None,
proxy_nodes: Vec::with_capacity(1),
proxy_pick_policy: SelectivePickPolicy::Random,
#[cfg(any(target_os = "linux", target_os = "android"))]
bind_interface: None,
bind_v4: None,
bind_v6: None,
no_ipv4: false,
Expand Down Expand Up @@ -118,6 +124,13 @@ impl DivertTcpEscaperConfig {
self.proxy_pick_policy = g3_yaml::value::as_selective_pick_policy(v)?;
Ok(())
}
#[cfg(any(target_os = "linux", target_os = "android"))]
"bind_interface" => {
let interface = g3_yaml::value::as_interface_name(v)
.context(format!("invalid interface name value for key {k}"))?;
self.bind_interface = Some(interface);
Ok(())
}
"bind_ipv4" => {
let ip4 = g3_yaml::value::as_ipv4addr(v)?;
self.bind_v4 = Some(ip4);
Expand Down
13 changes: 13 additions & 0 deletions g3proxy/src/config/escaper/proxy_float/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ use log::warn;
use yaml_rust::{yaml, Yaml};

use g3_types::metrics::{MetricsName, StaticMetricsTags};
#[cfg(any(target_os = "linux", target_os = "android"))]
use g3_types::net::InterfaceName;
use g3_types::net::{
OpensslClientConfigBuilder, TcpKeepAliveConfig, TcpMiscSockOpts, UdpMiscSockOpts,
};
Expand All @@ -43,6 +45,8 @@ pub(crate) struct ProxyFloatEscaperConfig {
pub(crate) name: MetricsName,
position: Option<YamlDocPosition>,
pub(crate) shared_logger: Option<AsciiString>,
#[cfg(any(target_os = "linux", target_os = "android"))]
pub(crate) bind_interface: Option<InterfaceName>,
pub(crate) bind_v4: Option<IpAddr>,
pub(crate) bind_v6: Option<IpAddr>,
pub(crate) tls_config: OpensslClientConfigBuilder,
Expand All @@ -64,6 +68,8 @@ impl ProxyFloatEscaperConfig {
name: MetricsName::default(),
position,
shared_logger: None,
#[cfg(any(target_os = "linux", target_os = "android"))]
bind_interface: None,
bind_v4: None,
bind_v6: None,
tls_config: OpensslClientConfigBuilder::with_cache_for_many_sites(),
Expand Down Expand Up @@ -110,6 +116,13 @@ impl ProxyFloatEscaperConfig {
self.extra_metrics_tags = Some(Arc::new(tags));
Ok(())
}
#[cfg(any(target_os = "linux", target_os = "android"))]
"bind_interface" => {
let interface = g3_yaml::value::as_interface_name(v)
.context(format!("invalid interface name value for key {k}"))?;
self.bind_interface = Some(interface);
Ok(())
}
"bind_ipv4" => {
let ip4 = g3_yaml::value::as_ipv4addr(v)?;
self.bind_v4 = Some(IpAddr::V4(ip4));
Expand Down
13 changes: 13 additions & 0 deletions g3proxy/src/config/escaper/proxy_http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ use yaml_rust::{yaml, Yaml};
use g3_types::auth::{Password, Username};
use g3_types::collection::SelectivePickPolicy;
use g3_types::metrics::{MetricsName, StaticMetricsTags};
#[cfg(any(target_os = "linux", target_os = "android"))]
use g3_types::net::InterfaceName;
use g3_types::net::{
HappyEyeballsConfig, Host, HttpForwardCapability, ProxyProtocolVersion, TcpKeepAliveConfig,
TcpMiscSockOpts, WeightedUpstreamAddr,
Expand All @@ -45,6 +47,8 @@ pub(crate) struct ProxyHttpEscaperConfig {
pub(crate) proxy_pick_policy: SelectivePickPolicy,
proxy_username: Username,
proxy_password: Password,
#[cfg(any(target_os = "linux", target_os = "android"))]
pub(crate) bind_interface: Option<InterfaceName>,
pub(crate) bind_v4: Option<Ipv4Addr>,
pub(crate) bind_v6: Option<Ipv6Addr>,
pub(crate) no_ipv4: bool,
Expand Down Expand Up @@ -74,6 +78,8 @@ impl ProxyHttpEscaperConfig {
proxy_pick_policy: SelectivePickPolicy::Random,
proxy_username: Username::empty(),
proxy_password: Password::empty(),
#[cfg(any(target_os = "linux", target_os = "android"))]
bind_interface: None,
bind_v4: None,
bind_v6: None,
no_ipv4: false,
Expand Down Expand Up @@ -147,6 +153,13 @@ impl ProxyHttpEscaperConfig {
.context(format!("invalid password value for key {k}"))?;
Ok(())
}
#[cfg(any(target_os = "linux", target_os = "android"))]
"bind_interface" => {
let interface = g3_yaml::value::as_interface_name(v)
.context(format!("invalid interface name value for key {k}"))?;
self.bind_interface = Some(interface);
Ok(())
}
"bind_ipv4" => {
let ip4 = g3_yaml::value::as_ipv4addr(v)?;
self.bind_v4 = Some(ip4);
Expand Down
13 changes: 13 additions & 0 deletions g3proxy/src/config/escaper/proxy_https.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ use yaml_rust::{yaml, Yaml};
use g3_types::auth::{Password, Username};
use g3_types::collection::SelectivePickPolicy;
use g3_types::metrics::{MetricsName, StaticMetricsTags};
#[cfg(any(target_os = "linux", target_os = "android"))]
use g3_types::net::InterfaceName;
use g3_types::net::{
HappyEyeballsConfig, Host, HttpForwardCapability, OpensslClientConfigBuilder,
ProxyProtocolVersion, TcpKeepAliveConfig, TcpMiscSockOpts, WeightedUpstreamAddr,
Expand All @@ -45,6 +47,8 @@ pub(crate) struct ProxyHttpsEscaperConfig {
pub(crate) proxy_pick_policy: SelectivePickPolicy,
proxy_username: Username,
proxy_password: Password,
#[cfg(any(target_os = "linux", target_os = "android"))]
pub(crate) bind_interface: Option<InterfaceName>,
pub(crate) bind_v4: Option<Ipv4Addr>,
pub(crate) bind_v6: Option<Ipv6Addr>,
pub(crate) no_ipv4: bool,
Expand Down Expand Up @@ -76,6 +80,8 @@ impl ProxyHttpsEscaperConfig {
proxy_pick_policy: SelectivePickPolicy::Random,
proxy_username: Username::empty(),
proxy_password: Password::empty(),
#[cfg(any(target_os = "linux", target_os = "android"))]
bind_interface: None,
bind_v4: None,
bind_v6: None,
no_ipv4: false,
Expand Down Expand Up @@ -151,6 +157,13 @@ impl ProxyHttpsEscaperConfig {
.context(format!("invalid password value for key {k}"))?;
Ok(())
}
#[cfg(any(target_os = "linux", target_os = "android"))]
"bind_interface" => {
let interface = g3_yaml::value::as_interface_name(v)
.context(format!("invalid interface name value for key {k}"))?;
self.bind_interface = Some(interface);
Ok(())
}
"bind_ipv4" => {
let ip4 = g3_yaml::value::as_ipv4addr(v)?;
self.bind_v4 = Some(ip4);
Expand Down
13 changes: 13 additions & 0 deletions g3proxy/src/config/escaper/proxy_socks5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ use yaml_rust::{yaml, Yaml};
use g3_types::auth::{Password, Username};
use g3_types::collection::SelectivePickPolicy;
use g3_types::metrics::{MetricsName, StaticMetricsTags};
#[cfg(any(target_os = "linux", target_os = "android"))]
use g3_types::net::InterfaceName;
use g3_types::net::{
HappyEyeballsConfig, Host, SocksAuth, TcpKeepAliveConfig, TcpMiscSockOpts, UdpMiscSockOpts,
WeightedUpstreamAddr,
Expand All @@ -46,6 +48,8 @@ pub(crate) struct ProxySocks5EscaperConfig {
pub(crate) proxy_pick_policy: SelectivePickPolicy,
proxy_username: Username,
proxy_password: Password,
#[cfg(any(target_os = "linux", target_os = "android"))]
pub(crate) bind_interface: Option<InterfaceName>,
pub(crate) bind_v4: Option<Ipv4Addr>,
pub(crate) bind_v6: Option<Ipv6Addr>,
pub(crate) no_ipv4: bool,
Expand Down Expand Up @@ -74,6 +78,8 @@ impl ProxySocks5EscaperConfig {
proxy_pick_policy: SelectivePickPolicy::Random,
proxy_username: Username::empty(),
proxy_password: Password::empty(),
#[cfg(any(target_os = "linux", target_os = "android"))]
bind_interface: None,
bind_v4: None,
bind_v6: None,
no_ipv4: false,
Expand Down Expand Up @@ -146,6 +152,13 @@ impl ProxySocks5EscaperConfig {
.context(format!("invalid password value for key {k}"))?;
Ok(())
}
#[cfg(any(target_os = "linux", target_os = "android"))]
"bind_interface" => {
let interface = g3_yaml::value::as_interface_name(v)
.context(format!("invalid interface name value for key {k}"))?;
self.bind_interface = Some(interface);
Ok(())
}
"bind_ipv4" => {
let ip4 = g3_yaml::value::as_ipv4addr(v)?;
self.bind_v4 = Some(ip4);
Expand Down
13 changes: 13 additions & 0 deletions g3proxy/src/config/escaper/proxy_socks5s.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ use yaml_rust::{yaml, Yaml};
use g3_types::auth::{Password, Username};
use g3_types::collection::SelectivePickPolicy;
use g3_types::metrics::{MetricsName, StaticMetricsTags};
#[cfg(any(target_os = "linux", target_os = "android"))]
use g3_types::net::InterfaceName;
use g3_types::net::{
HappyEyeballsConfig, Host, OpensslClientConfigBuilder, SocksAuth, TcpKeepAliveConfig,
TcpMiscSockOpts, UdpMiscSockOpts, WeightedUpstreamAddr,
Expand All @@ -46,6 +48,8 @@ pub(crate) struct ProxySocks5sEscaperConfig {
pub(crate) proxy_pick_policy: SelectivePickPolicy,
proxy_username: Username,
proxy_password: Password,
#[cfg(any(target_os = "linux", target_os = "android"))]
pub(crate) bind_interface: Option<InterfaceName>,
pub(crate) bind_v4: Option<Ipv4Addr>,
pub(crate) bind_v6: Option<Ipv6Addr>,
pub(crate) no_ipv4: bool,
Expand Down Expand Up @@ -76,6 +80,8 @@ impl ProxySocks5sEscaperConfig {
proxy_pick_policy: SelectivePickPolicy::Random,
proxy_username: Username::empty(),
proxy_password: Password::empty(),
#[cfg(any(target_os = "linux", target_os = "android"))]
bind_interface: None,
bind_v4: None,
bind_v6: None,
no_ipv4: false,
Expand Down Expand Up @@ -150,6 +156,13 @@ impl ProxySocks5sEscaperConfig {
.context(format!("invalid password value for key {k}"))?;
Ok(())
}
#[cfg(any(target_os = "linux", target_os = "android"))]
"bind_interface" => {
let interface = g3_yaml::value::as_interface_name(v)
.context(format!("invalid interface name value for key {k}"))?;
self.bind_interface = Some(interface);
Ok(())
}
"bind_ipv4" => {
let ip4 = g3_yaml::value::as_ipv4addr(v)?;
self.bind_v4 = Some(ip4);
Expand Down
Loading

0 comments on commit 3c1c239

Please sign in to comment.