Skip to content

Commit 22a3a2c

Browse files
committed
Add hops argument to get_options
1 parent 6e1c52a commit 22a3a2c

1 file changed

Lines changed: 26 additions & 7 deletions

File tree

src/socks5.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ pub async fn handle_associate(
5555
&settings,
5656
&mut addr_to_cid,
5757
&buf[..size],
58+
hops,
5859
)
5960
.await
6061
else {
@@ -80,6 +81,7 @@ async fn process_socks5_packet(
8081
settings: &Arc<ArcSwap<TunnelSettings>>,
8182
addr_to_cid: &mut HashMap<Address, u32>,
8283
buf: &[u8],
84+
hops: u8,
8385
) -> Option<(SocketAddr, Vec<u8>, u32)> {
8486
let header = match UdpHeader::read_from(&mut Cursor::new(buf)).await {
8587
Ok(header) => header,
@@ -91,16 +93,20 @@ async fn process_socks5_packet(
9193

9294
let pkt = &buf[header.serialized_len()..].to_vec();
9395
let address = &header.address;
94-
let Some(circuit_id) = select_circuit(address, associated_socket, circuits, addr_to_cid) else {
95-
warn!("No circuits available, dropping packet");
96+
let Some(circuit_id) = select_circuit(address, associated_socket, circuits, addr_to_cid, hops)
97+
else {
98+
warn!("No {}-hop circuits available, dropping packet", hops);
9699
return None;
97100
};
98101

99102
match circuits.lock().unwrap().get_mut(&circuit_id) {
100103
Some(circuit) => {
101104
if circuit.socket.is_none() {
102105
circuit.socket = Some(associated_socket.clone());
103-
info!("Associated socket for circuit {}", circuit_id);
106+
info!(
107+
"Associated socket ({} hops) for circuit {} ({})",
108+
hops, circuit_id, circuit.goal_hops
109+
);
104110
}
105111

106112
let guard = settings.load();
@@ -126,6 +132,7 @@ fn select_circuit(
126132
socket: &Arc<UdpSocket>,
127133
circuits: &Arc<Mutex<HashMap<u32, Circuit>>>,
128134
addr_to_cid: &mut HashMap<Address, u32>,
135+
hops: u8,
129136
) -> Option<u32> {
130137
// Deal with hidden services
131138
if let Address::SocketAddress(SocketAddr::V4(addr)) = address {
@@ -154,7 +161,7 @@ fn select_circuit(
154161
match addr_to_cid.get(address) {
155162
Some(cid) => Some(*cid),
156163
None => {
157-
let options = get_options(&socket, &circuits);
164+
let options = get_options(&socket, &circuits, hops, 2);
158165
let Some(&cid) = options.choose(&mut rand::rng()) else {
159166
return None;
160167
};
@@ -164,13 +171,25 @@ fn select_circuit(
164171
}
165172
}
166173

167-
fn get_options(socket: &Arc<UdpSocket>, circuits: &Arc<Mutex<HashMap<u32, Circuit>>>) -> Vec<u32> {
174+
fn get_options(
175+
socket: &Arc<UdpSocket>,
176+
circuits: &Arc<Mutex<HashMap<u32, Circuit>>>,
177+
hops: u8,
178+
limit: u8,
179+
) -> Vec<u32> {
168180
let guard = circuits.lock().unwrap();
169-
guard
181+
let mut circuits: Vec<&Circuit> = guard
170182
.values()
171183
.filter(|c| {
172-
c.data_ready() && (c.socket.is_none() || Arc::ptr_eq(c.socket.as_ref().unwrap(), &socket))
184+
c.goal_hops == hops
185+
&& c.data_ready()
186+
&& (c.socket.is_none() || Arc::ptr_eq(c.socket.as_ref().unwrap(), &socket))
173187
})
188+
.collect();
189+
circuits.sort_by_key(|c| c.socket.is_none() as u8);
190+
circuits
191+
.iter()
174192
.map(|c| c.circuit_id)
193+
.take(limit as usize)
175194
.collect()
176195
}

0 commit comments

Comments
 (0)