snowstorm/socks/
server.rs1use 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 #[cfg(not(any(target_os = "android", target_os = "macos")))]
29 {
30 server_config.outbound_bind_interface = outbound_bind_interface;
31 }
32
33 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}