mirror of
https://github.com/shadowsocks/shadowsocks-rust.git
synced 2026-02-09 01:59:16 +08:00
Allow IP fragmentation for outbound UDP sockets
This commit is contained in:
@@ -815,6 +815,8 @@ Example configuration:
|
||||
"outbound_bind_interface": "eth1",
|
||||
// Outbound socket bind() to this IP (choose a specific interface)
|
||||
"outbound_bind_addr": "11.22.33.44",
|
||||
// Outbound UDP socket allows IP fragmentation (default false)
|
||||
"outbound_udp_allow_fragmentation": false
|
||||
|
||||
// Balancer customization
|
||||
"balancer": {
|
||||
|
||||
@@ -215,6 +215,9 @@ struct SSConfig {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
outbound_bind_interface: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
outbound_udp_allow_fragmentation: Option<bool>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
security: Option<SSSecurityConfig>,
|
||||
|
||||
@@ -401,6 +404,9 @@ struct SSServerExtConfig {
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
outbound_bind_interface: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
outbound_udp_allow_fragmentation: Option<bool>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "local-online-config")]
|
||||
@@ -1240,6 +1246,7 @@ pub struct ServerInstanceConfig {
|
||||
pub outbound_fwmark: Option<u32>,
|
||||
pub outbound_bind_addr: Option<IpAddr>,
|
||||
pub outbound_bind_interface: Option<String>,
|
||||
pub outbound_udp_allow_fragmentation: Option<bool>,
|
||||
}
|
||||
|
||||
impl ServerInstanceConfig {
|
||||
@@ -1252,6 +1259,7 @@ impl ServerInstanceConfig {
|
||||
outbound_fwmark: None,
|
||||
outbound_bind_addr: None,
|
||||
outbound_bind_interface: None,
|
||||
outbound_udp_allow_fragmentation: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1336,6 +1344,8 @@ pub struct Config {
|
||||
pub outbound_bind_interface: Option<String>,
|
||||
/// Outbound sockets will `bind` to this address
|
||||
pub outbound_bind_addr: Option<IpAddr>,
|
||||
/// Outbound UDP sockets allow IP fragmentation
|
||||
pub outbound_udp_allow_fragmentation: bool,
|
||||
/// Path to protect callback unix address, only for Android
|
||||
#[cfg(target_os = "android")]
|
||||
pub outbound_vpn_protect_path: Option<PathBuf>,
|
||||
@@ -1480,6 +1490,7 @@ impl Config {
|
||||
outbound_user_cookie: None,
|
||||
outbound_bind_interface: None,
|
||||
outbound_bind_addr: None,
|
||||
outbound_udp_allow_fragmentation: false,
|
||||
#[cfg(target_os = "android")]
|
||||
outbound_vpn_protect_path: None,
|
||||
|
||||
@@ -1999,6 +2010,7 @@ impl Config {
|
||||
outbound_fwmark: config.outbound_fwmark,
|
||||
outbound_bind_addr,
|
||||
outbound_bind_interface: config.outbound_bind_interface.clone(),
|
||||
outbound_udp_allow_fragmentation: config.outbound_udp_allow_fragmentation,
|
||||
};
|
||||
|
||||
nconfig.server.push(server_instance);
|
||||
@@ -2192,6 +2204,7 @@ impl Config {
|
||||
outbound_fwmark: config.outbound_fwmark,
|
||||
outbound_bind_addr,
|
||||
outbound_bind_interface: config.outbound_bind_interface.clone(),
|
||||
outbound_udp_allow_fragmentation: config.outbound_udp_allow_fragmentation,
|
||||
};
|
||||
|
||||
if let Some(acl_path) = svr.acl {
|
||||
@@ -2222,6 +2235,10 @@ impl Config {
|
||||
server_instance.outbound_bind_interface = Some(outbound_bind_interface.clone());
|
||||
}
|
||||
|
||||
if let Some(outbound_udp_allow_fragmentation) = svr.outbound_udp_allow_fragmentation {
|
||||
server_instance.outbound_udp_allow_fragmentation = Some(outbound_udp_allow_fragmentation);
|
||||
}
|
||||
|
||||
nconfig.server.push(server_instance);
|
||||
}
|
||||
}
|
||||
@@ -2387,6 +2404,10 @@ impl Config {
|
||||
// Bind device / interface
|
||||
nconfig.outbound_bind_interface = config.outbound_bind_interface;
|
||||
|
||||
if let Some(b) = config.outbound_udp_allow_fragmentation {
|
||||
nconfig.outbound_udp_allow_fragmentation = b;
|
||||
}
|
||||
|
||||
// Security
|
||||
if let Some(sec) = config.security {
|
||||
if let Some(replay_attack) = sec.replay_attack {
|
||||
@@ -3045,6 +3066,7 @@ impl fmt::Display for Config {
|
||||
outbound_fwmark: inst.outbound_fwmark,
|
||||
outbound_bind_addr: inst.outbound_bind_addr,
|
||||
outbound_bind_interface: inst.outbound_bind_interface.clone(),
|
||||
outbound_udp_allow_fragmentation: inst.outbound_udp_allow_fragmentation,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3149,6 +3171,7 @@ impl fmt::Display for Config {
|
||||
|
||||
jconf.outbound_bind_addr = self.outbound_bind_addr.map(|i| i.to_string());
|
||||
jconf.outbound_bind_interface.clone_from(&self.outbound_bind_interface);
|
||||
jconf.outbound_udp_allow_fragmentation = Some(self.outbound_udp_allow_fragmentation);
|
||||
|
||||
// Security
|
||||
if self.security.replay_attack.policy != ReplayAttackPolicy::default() {
|
||||
|
||||
@@ -388,6 +388,7 @@ impl Manager {
|
||||
outbound_fwmark: None,
|
||||
outbound_bind_addr: None,
|
||||
outbound_bind_interface: None,
|
||||
outbound_udp_allow_fragmentation: None,
|
||||
};
|
||||
|
||||
let mut config = Config::new(ConfigType::Server);
|
||||
|
||||
@@ -66,6 +66,7 @@ pub async fn run(config: Config) -> io::Result<()> {
|
||||
|
||||
bind_local_addr: config.outbound_bind_addr.map(|ip| SocketAddr::new(ip, 0)),
|
||||
bind_interface: config.outbound_bind_interface,
|
||||
udp_allow_fragmentation: config.outbound_udp_allow_fragmentation,
|
||||
|
||||
..Default::default()
|
||||
};
|
||||
@@ -120,6 +121,10 @@ pub async fn run(config: Config) -> io::Result<()> {
|
||||
connect_opts.bind_interface = Some(bind_interface);
|
||||
}
|
||||
|
||||
if let Some(udp_allow_fragmentation) = inst.outbound_udp_allow_fragmentation {
|
||||
connect_opts.udp_allow_fragmentation = udp_allow_fragmentation;
|
||||
}
|
||||
|
||||
server_builder.set_connect_opts(connect_opts);
|
||||
server_builder.set_accept_opts(accept_opts);
|
||||
|
||||
|
||||
@@ -65,6 +65,9 @@ pub struct ConnectOpts {
|
||||
/// Outbound socket binds to interface
|
||||
pub bind_interface: Option<String>,
|
||||
|
||||
/// Outbound UDP socket allows IP fragmentation
|
||||
pub udp_allow_fragmentation: bool,
|
||||
|
||||
/// TCP options
|
||||
pub tcp: TcpSocketOpts,
|
||||
|
||||
|
||||
@@ -251,8 +251,10 @@ pub async fn bind_outbound_udp_socket(bind_addr: &SocketAddr, _config: &ConnectO
|
||||
UdpSocket::from_std(socket.into())?
|
||||
};
|
||||
|
||||
if let Err(err) = set_disable_ip_fragmentation(af, &socket) {
|
||||
warn!("failed to disable IP fragmentation, error: {}", err);
|
||||
if ! config.udp_allow_fragmentation {
|
||||
if let Err(err) = set_disable_ip_fragmentation(af, &socket) {
|
||||
warn!("failed to disable IP fragmentation, error: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(socket)
|
||||
|
||||
@@ -379,8 +379,10 @@ pub async fn bind_outbound_udp_socket(bind_addr: &SocketAddr, config: &ConnectOp
|
||||
UdpSocket::from_std(socket.into())?
|
||||
};
|
||||
|
||||
if let Err(err) = set_disable_ip_fragmentation(af, &socket) {
|
||||
warn!("failed to disable IP fragmentation, error: {}", err);
|
||||
if ! config.udp_allow_fragmentation {
|
||||
if let Err(err) = set_disable_ip_fragmentation(af, &socket) {
|
||||
warn!("failed to disable IP fragmentation, error: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
// Set IP_BOUND_IF for BSD-like
|
||||
|
||||
@@ -310,8 +310,10 @@ pub async fn bind_outbound_udp_socket(bind_addr: &SocketAddr, config: &ConnectOp
|
||||
UdpSocket::from_std(socket.into())?
|
||||
};
|
||||
|
||||
if let Err(err) = set_disable_ip_fragmentation(af, &socket) {
|
||||
warn!("failed to disable IP fragmentation, error: {}", err);
|
||||
if ! config.udp_allow_fragmentation {
|
||||
if let Err(err) = set_disable_ip_fragmentation(af, &socket) {
|
||||
warn!("failed to disable IP fragmentation, error: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
// Any traffic except localhost should be protected
|
||||
|
||||
@@ -498,9 +498,12 @@ pub async fn bind_outbound_udp_socket(bind_addr: &SocketAddr, opts: &ConnectOpts
|
||||
socket.set_nonblocking(true)?;
|
||||
let socket = UdpSocket::from_std(socket.into())?;
|
||||
|
||||
if let Err(err) = set_disable_ip_fragmentation(af, &socket) {
|
||||
warn!("failed to disable IP fragmentation, error: {}", err);
|
||||
if ! opts.udp_allow_fragmentation {
|
||||
if let Err(err) = set_disable_ip_fragmentation(af, &socket) {
|
||||
warn!("failed to disable IP fragmentation, error: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
disable_connection_reset(&socket)?;
|
||||
|
||||
Ok(socket)
|
||||
|
||||
Reference in New Issue
Block a user