Support outbound socket options in configuration

- outbound_fwmark
- outbound_user_cookie
- outbound_bind_interface
- outbound_bind_addr
This commit is contained in:
zonyitoo
2023-01-07 21:32:19 +08:00
parent 8b3d1b5998
commit d826b0a8d8
2 changed files with 55 additions and 9 deletions

View File

@@ -480,7 +480,9 @@ Example configuration:
"mode": "tcp_and_udp",
// OPTIONAL. Authentication configuration file
// Configuration file document could be found in the next section.
"socks5_auth_config_path": "/path/to/auth.json"
"socks5_auth_config_path": "/path/to/auth.json",
// OPTIONAL. Instance specific ACL
"acl": "/path/to/acl/file.acl",
},
{
// SOCKS5, SOCKS4/4a local server
@@ -594,6 +596,9 @@ Example configuration:
// The higher weight, the server may rank higher.
"tcp_weight": 1.0,
"udp_weight": 1.0,
// OPTIONAL. Instance specific ACL
"acl": "/path/to/acl/file.acl",
},
{
// Same key as basic format "server" and "server_port"
@@ -676,6 +681,16 @@ Example configuration:
// Only valid for locals and servers listening on `::`
"ipv6_only": false,
// Outbound socket options
// Linux Only (SO_MARK)
"outbound_fwmark": 255,
// FreeBSD only (SO_USER_COOKIE)
"outbound_user_cookie": 255,
// `SO_BINDTODEVICE` (Linux), `IP_BOUND_IF` (BSD), `IP_UNICAST_IF` (Windows) socket option for outbound sockets
"outbound_bind_interface": "eth1",
// Outbound socket bind() to this IP (choose a specific interface)
"outbound_bind_addr": "11.22.33.44",
// Balancer customization
"balancer": {
// MAX Round-Trip-Time (RTT) of servers

View File

@@ -66,14 +66,7 @@ use serde::{Deserialize, Serialize};
use shadowsocks::relay::socks5::Address;
use shadowsocks::{
config::{
ManagerAddr,
Mode,
ReplayAttackPolicy,
ServerAddr,
ServerConfig,
ServerUser,
ServerUserManager,
ServerWeight,
ManagerAddr, Mode, ReplayAttackPolicy, ServerAddr, ServerConfig, ServerUser, ServerUserManager, ServerWeight,
},
crypto::CipherKind,
plugin::PluginConfig,
@@ -190,6 +183,16 @@ struct SSConfig {
#[cfg(any(target_os = "linux", target_os = "android"))]
outbound_fwmark: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
#[cfg(target_os = "freebsd")]
outbound_user_cookie: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
outbound_bind_addr: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
outbound_bind_interface: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
security: Option<SSSecurityConfig>,
@@ -1924,6 +1927,26 @@ impl Config {
nconfig.outbound_fwmark = Some(fwmark);
}
// SO_USER_COOKIE
#[cfg(target_os = "freebsd")]
if let Some(user_cookie) = config.outbound_user_cookie {
nconfig.outbound_user_cookie = Some(user_cookie);
}
// Outbound bind() address
if let Some(bind_addr) = config.outbound_bind_addr {
match bind_addr.parse::<IpAddr>() {
Ok(b) => nconfig.outbound_bind_addr = Some(b),
Err(..) => {
let err = Error::new(ErrorKind::Invalid, "invalid outbound_bind_addr", None);
return Err(err);
}
}
}
// Bind device / interface
nconfig.outbound_bind_interface = config.outbound_bind_interface;
// Security
if let Some(sec) = config.security {
if let Some(replay_attack) = sec.replay_attack {
@@ -2581,6 +2604,14 @@ impl fmt::Display for Config {
jconf.outbound_fwmark = self.outbound_fwmark;
}
#[cfg(target_os = "freebsd")]
{
jconf.outbound_user_cookie = self.outbound_user_cookie;
}
jconf.outbound_bind_addr = self.outbound_bind_addr.map(|i| i.to_string());
jconf.outbound_bind_interface = self.outbound_bind_interface.clone();
// Security
if self.security.replay_attack.policy != ReplayAttackPolicy::default() {
jconf.security = Some(SSSecurityConfig {