snowstorm/socks/
server.rs

1use std::{io, net::SocketAddr};
2
3use libp2p::dns::ResolverConfig;
4use log::{error, info};
5use tokio::{self};
6
7use shadowsocks_rust::monitor;
8use shadowsocks_service::{
9    config::{Config, ConfigType, DnsConfig, ServerInstanceConfig},
10    run_server,
11    shadowsocks::{crypto::CipherKind, ServerConfig},
12};
13use tokio_util::sync::CancellationToken;
14
15pub fn start(
16    config: &crate::config::Config,
17    outbound_bind_interface: Option<String>,
18    cancellation_token: CancellationToken,
19) -> io::Result<u16> {
20    let mut server_config = Config::new(ConfigType::Server);
21
22    server_config.fast_open = true;
23    server_config.no_delay = true;
24    // server_config.mptcp = true;
25
26    // Android by default is lacking permissions to bind to a specific interface
27    // Same for mac when running inside of the Network Extension
28    #[cfg(not(any(target_os = "android", target_os = "macos")))]
29    {
30        server_config.outbound_bind_interface = outbound_bind_interface;
31    }
32
33    // parse address and port from config.server_listen_addr
34    let mut addr = config.sserver_listen_addr.parse::<SocketAddr>().unwrap();
35
36    if addr.port() == 0 {
37        addr.set_port(crate::net::get_available_local_port().unwrap());
38    }
39
40    server_config.server = vec![ServerInstanceConfig::with_server_config(ServerConfig::new(
41        addr,
42        "",
43        CipherKind::NONE,
44    ).unwrap())];
45    server_config.dns = DnsConfig::HickoryDns(ResolverConfig::cloudflare());
46
47    let abort_signal = monitor::create_signal_monitor();
48    let server = run_server(server_config);
49
50    tokio::spawn(async move {
51        tokio::pin!(server);
52        tokio::pin!(abort_signal);
53
54        info!("ssocks server started on {}", addr);
55
56        tokio::select! {
57            _ = server => {
58                error!("ssocks server exited unexpectedly");
59                Err(io::Error::new(
60                    io::ErrorKind::Other,
61                    "server exited unexpectedly",
62                ))
63            },
64            _ = abort_signal => {
65                info!("ssocks server stopped (abort signal)");
66                Ok(())
67            },
68            _ = cancellation_token.cancelled() => {
69                info!("ssocks server stopped (sdk stop)");
70                Ok(())
71            },
72        }
73    });
74
75    Ok(addr.port())
76}