Skip to content

Commit ff841ac

Browse files
committed
feat: allow empty chains in conn_selector
1 parent e325f1f commit ff841ac

8 files changed

Lines changed: 107 additions & 38 deletions

File tree

common/src/route/conn_selector.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,43 @@ pub trait BuildTracer {
8383
}
8484

8585
#[derive(Debug, Clone)]
86-
pub struct ConnSelector<Addr> {
86+
pub enum ConnSelector<Addr> {
87+
Empty,
88+
Some(ConnSelector1<Addr>),
89+
}
90+
impl<Addr> ConnSelector<Addr>
91+
where
92+
Addr: std::fmt::Debug + fmt::Display + Clone + Send + Sync + 'static,
93+
{
94+
pub fn new<T>(
95+
chains: Vec<WeightedConnChain<Addr>>,
96+
tracer: Option<T>,
97+
active_chains: Option<NonZeroUsize>,
98+
cancellation: CancellationToken,
99+
) -> Result<Self, ConnSelectorError>
100+
where
101+
T: TraceRtt<Addr = Addr> + Send + Sync + 'static,
102+
{
103+
if chains.is_empty() {
104+
return Ok(Self::Empty);
105+
}
106+
Ok(Self::Some(ConnSelector1::new(
107+
chains,
108+
tracer,
109+
active_chains,
110+
cancellation,
111+
)?))
112+
}
113+
}
114+
115+
#[derive(Debug, Clone)]
116+
pub struct ConnSelector1<Addr> {
87117
chains: Arc<[GaugedConnChain<Addr>]>,
88118
cum_weight: NonZeroUsize,
89119
score_store: Arc<RwLock<ScoreStore>>,
90120
active_chains: NonZeroUsize,
91121
}
92-
impl<Addr> ConnSelector<Addr>
122+
impl<Addr> ConnSelector1<Addr>
93123
where
94124
Addr: std::fmt::Debug + fmt::Display + Clone + Send + Sync + 'static,
95125
{

common/src/route/route_table.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ use crate::{
1111
addr::InternetAddr,
1212
config::SharableConfig,
1313
filter::{Matcher, MatcherBuilder},
14+
route::ConnSelector,
1415
};
1516

1617
use super::{
17-
BuildTracer, ConnConfigBuildError, ConnSelector, ConnSelectorBuildContext,
18-
ConnSelectorBuildError, ConnSelectorBuilder, IntoAddr, TraceRtt,
18+
BuildTracer, ConnConfigBuildError, ConnSelectorBuildContext, ConnSelectorBuildError,
19+
ConnSelectorBuilder, IntoAddr, TraceRtt,
1920
};
2021

2122
#[derive(Debug)]

protocol/src/socks5/server/tcp.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -518,17 +518,26 @@ impl Socks5ServerTcpAccessConnHandler {
518518
destination: InternetAddr,
519519
) -> Result<(ConnAndAddr, Option<tokio_chacha20::config::Config>), EstablishProxyChainError>
520520
{
521-
let proxy_chain = conn_selector.choose_chain();
521+
let (chain, payload_crypto) = match &conn_selector {
522+
common::route::ConnSelector::Empty => ([].into(), None),
523+
common::route::ConnSelector::Some(conn_selector1) => {
524+
let proxy_chain = conn_selector1.choose_chain();
525+
(
526+
proxy_chain.chain.clone(),
527+
proxy_chain.payload_crypto.clone(),
528+
)
529+
}
530+
};
522531
let res = client::stream::establish(
523-
&proxy_chain.chain,
532+
&chain,
524533
StreamAddr {
525534
address: destination,
526535
stream_type: ConcreteStreamType::Tcp.to_string().into(),
527536
},
528537
&self.stream_context,
529538
)
530539
.await?;
531-
Ok((res, proxy_chain.payload_crypto.clone()))
540+
Ok((res, payload_crypto))
532541
}
533542
}
534543
#[derive(Debug, Error)]

protocol/src/socks5/server/udp.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,19 @@ impl Socks5ServerUdpAccessConnHandler {
118118

119119
async fn proxy(&self, conn: Conn<UdpSocket, Flow, Packet>) -> Result<(), AccessProxyError> {
120120
// Connect to upstream
121-
let proxy_chain = self.conn_selector.choose_chain();
121+
let (chain, payload_crypto) = match &self.conn_selector {
122+
common::route::ConnSelector::Empty => ([].into(), None),
123+
common::route::ConnSelector::Some(conn_selector1) => {
124+
let proxy_chain = conn_selector1.choose_chain();
125+
(
126+
proxy_chain.chain.clone(),
127+
proxy_chain.payload_crypto.clone(),
128+
)
129+
}
130+
};
122131
let flow = conn.conn_key().clone();
123132
let upstream = UdpProxyClient::establish(
124-
proxy_chain.chain.clone(),
133+
chain,
125134
flow.upstream.as_ref().unwrap().0.clone(),
126135
&self.udp_context,
127136
)
@@ -146,7 +155,6 @@ impl Socks5ServerUdpAccessConnHandler {
146155
};
147156

148157
let speed_limiter = self.speed_limiter.clone();
149-
let payload_crypto = proxy_chain.payload_crypto.clone();
150158
let session_table = self.udp_context.session_table.clone();
151159
let upstream_local = upstream_read.inner().local_addr().ok();
152160
let (dn_read, dn_write) = conn.split();

protocol/src/stream/streams/http_tunnel/mod.rs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,17 @@ impl HttpAccessConnHandler {
215215
};
216216

217217
// Establish proxy chain
218-
let proxy_chain = conn_selector.choose_chain();
219-
let upstream = establish(&proxy_chain.chain, addr.clone(), &self.stream_context).await?;
218+
let (chain, payload_crypto) = match conn_selector.as_ref() {
219+
common::route::ConnSelector::Empty => ([].into(), None),
220+
common::route::ConnSelector::Some(conn_selector1) => {
221+
let proxy_chain = conn_selector1.choose_chain();
222+
(
223+
proxy_chain.chain.clone(),
224+
proxy_chain.payload_crypto.clone(),
225+
)
226+
}
227+
};
228+
let upstream = establish(&chain, addr.clone(), &self.stream_context).await?;
220229

221230
let session_guard = self.stream_context.session_table.as_ref().map(|s| {
222231
s.set_scope_owned(Session {
@@ -231,7 +240,7 @@ impl HttpAccessConnHandler {
231240
dn_gauge: None,
232241
})
233242
});
234-
let res = match &proxy_chain.payload_crypto {
243+
let res = match &payload_crypto {
235244
Some(crypto) => {
236245
// Establish encrypted stream
237246
let (r, w) = tokio::io::split(upstream.stream);
@@ -502,13 +511,17 @@ impl HttpConnect {
502511
address: address.clone(),
503512
stream_type: ConcreteStreamType::Tcp.to_string().into(),
504513
};
505-
let proxy_chain = self.conn_selector.choose_chain();
506-
let upstream = establish(
507-
&proxy_chain.chain,
508-
destination.clone(),
509-
&self.stream_context,
510-
)
511-
.await?;
514+
let (chain, payload_crypto) = match &self.conn_selector.as_ref() {
515+
common::route::ConnSelector::Empty => ([].into(), None),
516+
common::route::ConnSelector::Some(conn_selector1) => {
517+
let proxy_chain = conn_selector1.choose_chain();
518+
(
519+
proxy_chain.chain.clone(),
520+
proxy_chain.payload_crypto.clone(),
521+
)
522+
}
523+
};
524+
let upstream = establish(&chain, destination.clone(), &self.stream_context).await?;
512525

513526
let conn_context = ConnContext {
514527
start: (std::time::Instant::now(), std::time::SystemTime::now()),
@@ -523,7 +536,7 @@ impl HttpConnect {
523536
let io_copy = CopyBidirectional {
524537
downstream: TokioIo::new(upgraded),
525538
upstream: upstream.stream,
526-
payload_crypto: proxy_chain.payload_crypto.clone(),
539+
payload_crypto,
527540
speed_limiter: self.speed_limiter.clone(),
528541
conn_context,
529542
}

protocol/src/stream/streams/tcp/access_server.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,17 @@ impl TcpAccessConnHandler {
125125
where
126126
Downstream: OwnIoStream + HasIoAddr,
127127
{
128-
let proxy_chain = self.conn_selector.choose_chain();
129-
let upstream = establish(
130-
&proxy_chain.chain,
131-
self.destination.clone(),
132-
&self.stream_context,
133-
)
134-
.await?;
128+
let (chain, payload_crypto) = match &self.conn_selector {
129+
common::route::ConnSelector::Empty => ([].into(), None),
130+
common::route::ConnSelector::Some(conn_selector1) => {
131+
let proxy_chain = conn_selector1.choose_chain();
132+
(
133+
proxy_chain.chain.clone(),
134+
proxy_chain.payload_crypto.clone(),
135+
)
136+
}
137+
};
138+
let upstream = establish(&chain, self.destination.clone(), &self.stream_context).await?;
135139

136140
let conn_context = ConnContext {
137141
start: (std::time::Instant::now(), std::time::SystemTime::now()),
@@ -146,7 +150,7 @@ impl TcpAccessConnHandler {
146150
let io_copy = CopyBidirectional {
147151
downstream,
148152
upstream: upstream.stream,
149-
payload_crypto: proxy_chain.payload_crypto.clone(),
153+
payload_crypto,
150154
speed_limiter: self.speed_limiter.clone(),
151155
conn_context,
152156
}

protocol/src/udp/access_server.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,19 +128,23 @@ impl UdpAccessConnHandler {
128128

129129
async fn proxy(&self, conn: Conn<UdpSocket, Flow, Packet>) -> Result<(), AccessProxyError> {
130130
// Connect to upstream
131-
let proxy_chain = self.conn_selector.choose_chain();
132-
let upstream = UdpProxyClient::establish(
133-
proxy_chain.chain.clone(),
134-
self.destination.clone(),
135-
&self.udp_context,
136-
)
137-
.await?;
131+
let (chain, payload_crypto) = match &self.conn_selector {
132+
common::route::ConnSelector::Empty => ([].into(), None),
133+
common::route::ConnSelector::Some(conn_selector1) => {
134+
let proxy_chain = conn_selector1.choose_chain();
135+
(
136+
proxy_chain.chain.clone(),
137+
proxy_chain.payload_crypto.clone(),
138+
)
139+
}
140+
};
141+
let upstream =
142+
UdpProxyClient::establish(chain, self.destination.clone(), &self.udp_context).await?;
138143
let upstream_remote = upstream.remote_addr().clone();
139144

140145
let (upstream_read, upstream_write) = upstream.into_split();
141146

142147
let speed_limiter = self.speed_limiter.clone();
143-
let payload_crypto = proxy_chain.payload_crypto.clone();
144148
let session_table = self.udp_context.session_table.clone();
145149
let upstream_local = upstream_read.inner().local_addr().ok();
146150
let flow = conn.conn_key().clone();

server/config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pool = ["tcp1", "mptcp1"]
3434
{ matcher = "localhost", action = "direct" }, # Forward local traffic directly
3535
# <- At this point, no more local traffic
3636
# { matcher = { }, action = "block" }, # Block all
37-
{ matcher = { }, action = "default" }, # Forward remaining traffic to the "default" proxy group above
37+
{ matcher = { }, action = "default" }, # Forward remaining traffic to the "default" conn_selector above
3838
]
3939

4040
[access_server.udp.conn_selector]

0 commit comments

Comments
 (0)