Skip to content

Commit

Permalink
sslocal support customizing udp assoc bind address
Browse files Browse the repository at this point in the history
  • Loading branch information
zonyitoo committed Oct 11, 2020
1 parent 3b21cc3 commit ab730ba
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 3 deletions.
6 changes: 6 additions & 0 deletions src/bin/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ fn main() {

(@arg UDP_TIMEOUT: --("udp-timeout") +takes_value {validator::validate_u64} "Timeout seconds for UDP relay")
(@arg UDP_MAX_ASSOCIATIONS: --("udp-max-associations") +takes_value {validator::validate_u64} "Maximum associations to be kept simultaneously for UDP relay")

(@arg UDP_BIND_ADDR: --("udp-bind-addr") +takes_value {validator::validate_server_addr} "UDP relay's bind address, default is the same as local-addr")
);

// FIXME: -6 is not a identifier, so we cannot build it with clap_app!
Expand Down Expand Up @@ -338,6 +340,10 @@ fn main() {
config.udp_max_associations = Some(udp_max_assoc.parse::<usize>().expect("udp-max-associations"));
}

if let Some(udp_bind_addr) = matches.value_of("UDP_BIND_ADDR") {
config.udp_bind_addr = Some(udp_bind_addr.parse::<ServerAddr>().expect("udp-bind-addr"));
}

// DONE READING options

if config.local_addr.is_none() {
Expand Down
41 changes: 41 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,42 @@ impl<I: Into<String>> From<(I, u16)> for ServerAddr {
}
}

impl From<Address> for ServerAddr {
fn from(addr: Address) -> ServerAddr {
match addr {
Address::SocketAddress(sa) => ServerAddr::SocketAddr(sa),
Address::DomainNameAddress(dn, port) => ServerAddr::DomainName(dn, port),
}
}
}

impl From<&Address> for ServerAddr {
fn from(addr: &Address) -> ServerAddr {
match *addr {
Address::SocketAddress(sa) => ServerAddr::SocketAddr(sa),
Address::DomainNameAddress(ref dn, port) => ServerAddr::DomainName(dn.clone(), port),
}
}
}

impl From<ServerAddr> for Address {
fn from(addr: ServerAddr) -> Address {
match addr {
ServerAddr::SocketAddr(sa) => Address::SocketAddress(sa),
ServerAddr::DomainName(dn, port) => Address::DomainNameAddress(dn, port),
}
}
}

impl From<&ServerAddr> for Address {
fn from(addr: &ServerAddr) -> Address {
match *addr {
ServerAddr::SocketAddr(sa) => Address::SocketAddress(sa),
ServerAddr::DomainName(ref dn, port) => Address::DomainNameAddress(dn.clone(), port),
}
}
}

/// Configuration for a server
#[derive(Clone, Debug)]
pub struct ServerConfig {
Expand Down Expand Up @@ -1011,6 +1047,10 @@ pub struct Config {
pub udp_timeout: Option<Duration>,
/// Maximum number of UDP Associations, default is unconfigured
pub udp_max_associations: Option<usize>,
/// UDP relay's bind address, it uses `local_addr` by default
///
/// Resolving Android's issue: https://github.com/shadowsocks/shadowsocks-android/issues/2571
pub udp_bind_addr: Option<ClientConfig>,
/// `RLIMIT_NOFILE` option for *nix systems
pub nofile: Option<u64>,
/// ACL configuration
Expand Down Expand Up @@ -1129,6 +1169,7 @@ impl Config {
config_type,
udp_timeout: None,
udp_max_associations: None,
udp_bind_addr: None,
nofile: None,
acl: None,
tcp_redir: RedirType::tcp_default(),
Expand Down
12 changes: 11 additions & 1 deletion src/relay/tcprelay/socks5_local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,17 @@ async fn handle_socks5_client(
Ok(())
}
socks5::Command::UdpAssociate => {
if udp_conf.enable_udp {
if let Some(ref bind_addr) = server.config().udp_bind_addr {
debug!("UDP ASSOCIATE {}", addr);

let rh = TcpResponseHeader::new(socks5::Reply::Succeeded, bind_addr.into());
rh.write_to(&mut s).await?;

// Hold the connection until it ends by its own
ignore_until_end(&mut s).await?;

Ok(())
} else if udp_conf.enable_udp {
debug!("UDP ASSOCIATE {}", addr);
let rh = TcpResponseHeader::new(socks5::Reply::Succeeded, From::from(udp_conf.client_addr));
rh.write_to(&mut s).await?;
Expand Down
9 changes: 7 additions & 2 deletions src/relay/udprelay/socks5_local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,13 @@ fn assemble_packet(addr: Address, pkt: &[u8]) -> Bytes {

/// Starts a UDP local server
pub async fn run(context: SharedContext) -> io::Result<()> {
let local_addr = context.config().local_addr.as_ref().expect("local config");
let bind_addr = local_addr.bind_addr(&context).await?;
let bind_addr = match context.config().udp_bind_addr {
Some(ref bind_addr) => bind_addr.bind_addr(&context).await?,
None => {
let local_addr = context.config().local_addr.as_ref().expect("local config");
local_addr.bind_addr(&context).await?
}
};

let l = create_udp_socket(&bind_addr).await?;
let local_addr = l.local_addr().expect("determine port bound to");
Expand Down

0 comments on commit ab730ba

Please sign in to comment.