shadowsocks_service/local/redir/
server.rs1use std::{io, sync::Arc, time::Duration};
4
5use futures::{FutureExt, future};
6use shadowsocks::{ServerAddr, config::Mode};
7
8use crate::{
9 config::RedirType,
10 local::{context::ServiceContext, loadbalancing::PingBalancer},
11};
12
13use super::{tcprelay::RedirTcpServer, udprelay::RedirUdpServer};
14
15pub struct RedirBuilder {
17 context: Arc<ServiceContext>,
18 mode: Mode,
19 udp_expiry_duration: Option<Duration>,
20 udp_capacity: Option<usize>,
21 tcp_redir: RedirType,
22 udp_redir: RedirType,
23 client_addr: ServerAddr,
24 udp_bind_addr: Option<ServerAddr>,
25 balancer: PingBalancer,
26}
27
28impl RedirBuilder {
29 pub fn new(client_addr: ServerAddr, balancer: PingBalancer) -> Self {
31 let context = ServiceContext::new();
32 Self::with_context(Arc::new(context), client_addr, balancer)
33 }
34
35 pub fn with_context(context: Arc<ServiceContext>, client_addr: ServerAddr, balancer: PingBalancer) -> Self {
37 Self {
38 context,
39 mode: Mode::TcpOnly,
40 udp_expiry_duration: None,
41 udp_capacity: None,
42 tcp_redir: RedirType::tcp_default(),
43 udp_redir: RedirType::udp_default(),
44 client_addr,
45 udp_bind_addr: None,
46 balancer,
47 }
48 }
49
50 pub fn set_udp_expiry_duration(&mut self, d: Duration) {
52 self.udp_expiry_duration = Some(d);
53 }
54
55 pub fn set_udp_capacity(&mut self, c: usize) {
57 self.udp_capacity = Some(c);
58 }
59
60 pub fn set_mode(&mut self, mode: Mode) {
62 self.mode = mode;
63 }
64
65 pub fn set_tcp_redir(&mut self, ty: RedirType) {
67 self.tcp_redir = ty;
68 }
69
70 pub fn set_udp_redir(&mut self, ty: RedirType) {
72 self.udp_redir = ty;
73 }
74
75 pub fn set_udp_bind_addr(&mut self, addr: ServerAddr) {
77 self.udp_bind_addr = Some(addr);
78 }
79
80 pub async fn build(self) -> io::Result<Redir> {
81 let mut tcp_server = None;
82 if self.mode.enable_tcp() {
83 let server = RedirTcpServer::new(
84 self.context.clone(),
85 &self.client_addr,
86 self.balancer.clone(),
87 self.tcp_redir,
88 )
89 .await?;
90 tcp_server = Some(server);
91 }
92
93 let mut udp_server = None;
94 if self.mode.enable_udp() {
95 let udp_addr = self.udp_bind_addr.as_ref().unwrap_or(&self.client_addr);
96
97 let server = RedirUdpServer::new(
98 self.context,
99 self.udp_redir,
100 udp_addr,
101 self.udp_expiry_duration,
102 self.udp_capacity,
103 self.balancer,
104 )
105 .await?;
106 udp_server = Some(server);
107 }
108
109 Ok(Redir { tcp_server, udp_server })
110 }
111}
112
113pub struct Redir {
115 tcp_server: Option<RedirTcpServer>,
116 udp_server: Option<RedirUdpServer>,
117}
118
119impl Redir {
120 pub fn tcp_server(&self) -> Option<&RedirTcpServer> {
122 self.tcp_server.as_ref()
123 }
124
125 pub fn udp_server(&self) -> Option<&RedirUdpServer> {
127 self.udp_server.as_ref()
128 }
129
130 pub async fn run(self) -> io::Result<()> {
132 let mut vfut = Vec::new();
133
134 if let Some(tcp_server) = self.tcp_server {
135 vfut.push(tcp_server.run().boxed());
136 }
137
138 if let Some(udp_server) = self.udp_server {
139 vfut.push(udp_server.run().boxed());
140 }
141
142 let (res, ..) = future::select_all(vfut).await;
143 res
144 }
145}