Skip to content

Commit 487044c

Browse files
authored
fix ss 2022 udp (#668)
1 parent 8de5c14 commit 487044c

File tree

3 files changed

+66
-10
lines changed

3 files changed

+66
-10
lines changed

clash/tests/data/config/ss.yaml

+13-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ port: 8888
33
socks-port: 8889
44
mixed-port: 8899
55

6-
76
dns:
87
enable: true
98
listen: 127.0.0.1:53533
@@ -17,14 +16,14 @@ dns:
1716
enhanced-mode: fake-ip # or fake-ip
1817
fake-ip-range: 198.18.0.1/16 # Fake IP addresses pool CIDR
1918
# use-hosts: true # lookup hosts and return IP record
20-
19+
2120
# Hostnames in this list will not be resolved with fake IPs
2221
# i.e. questions to these domain names will always be answered with their
2322
# real IP addresses
2423
# fake-ip-filter:
2524
# - '*.lan'
2625
# - localhost.ptlogin2.qq.com
27-
26+
2827
# Supports UDP, TCP, DoT, DoH. You can specify the port to connect to.
2928
# All DNS questions are sent directly to the nameserver, without proxies
3029
# involved. Clash answers the DNS question with the first result gathered.
@@ -61,12 +60,19 @@ proxies:
6160
password: "password"
6261
udp: true
6362

63+
- name: ss-2022
64+
type: ss
65+
server: 127.0.0.1
66+
port: 8390
67+
cipher: 2022-blake3-aes-256-gcm
68+
password: 3SYJ/f8nmVuzKvKglykRQDSgg10e/ADilkdRWrrY9HU=:4w0GKJ9U3Ox7CIXGU4A3LDQAqP6qrp/tUi/ilpOR9p4=
69+
6470
proxy-groups:
6571
- name: "udp-relay"
6672
type: relay
6773
proxies:
68-
- ss-01
69-
- ss-02
74+
- ss-01
75+
- ss-02
76+
- ss-2022
7077
rules:
71-
- MATCH, udp-relay
72-
...
78+
- MATCH, ss-2022
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"servers": [
3+
{
4+
// AEAD-2022
5+
"server": "::",
6+
"mode": "tcp_and_udp",
7+
"server_port": 8390,
8+
"method": "2022-blake3-aes-256-gcm",
9+
"password": "3SYJ/f8nmVuzKvKglykRQDSgg10e/ADilkdRWrrY9HU=",
10+
// For Server (OPTIONAL)
11+
// Support multiple users with Extensible Identity Header
12+
// https://github.com/Shadowsocks-NET/shadowsocks-specs/blob/main/2022-2-shadowsocks-2022-extensible-identity-headers.md
13+
"users": [
14+
{
15+
"name": "username",
16+
// User's password must have the same length as server's password
17+
"password": "4w0GKJ9U3Ox7CIXGU4A3LDQAqP6qrp/tUi/ilpOR9p4="
18+
}
19+
],
20+
}
21+
],
22+
}

clash_lib/src/proxy/shadowsocks/datagram.rs

+31-3
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ use futures::{
1212
Sink, SinkExt, Stream, StreamExt,
1313
};
1414
use shadowsocks::{
15-
relay::udprelay::{DatagramReceive, DatagramSend},
15+
relay::udprelay::{
16+
options::UdpSocketControlData, DatagramReceive, DatagramSend,
17+
},
1618
ProxySocket,
1719
};
1820
use tokio::io::ReadBuf;
19-
use tracing::{debug, instrument};
21+
use tracing::{debug, error, instrument};
2022

2123
use crate::{
2224
common::errors::new_io_error,
@@ -32,16 +34,23 @@ pub struct OutboundDatagramShadowsocks<S> {
3234
flushed: bool,
3335
pkt: Option<UdpPacket>,
3436
buf: Vec<u8>,
37+
38+
ss_control: UdpSocketControlData,
3539
}
3640

3741
impl<S> OutboundDatagramShadowsocks<S> {
3842
pub fn new(inner: ProxySocket<S>, remote_addr: SocketAddr) -> Self {
43+
let mut ss_control = UdpSocketControlData::default();
44+
ss_control.client_session_id = rand::random::<u64>();
45+
3946
Self {
4047
inner,
4148
flushed: true,
4249
pkt: None,
4350
remote_addr,
4451
buf: vec![0u8; 65535],
52+
53+
ss_control,
4554
}
4655
}
4756
}
@@ -87,6 +96,8 @@ where
8796
ref mut pkt,
8897
ref remote_addr,
8998
ref mut flushed,
99+
100+
ref mut ss_control,
90101
..
91102
} = *self;
92103

@@ -97,14 +108,31 @@ where
97108
let addr: shadowsocks::relay::Address =
98109
(pkt.dst_addr.host(), pkt.dst_addr.port()).into();
99110

100-
let n = ready!(inner.poll_send_to(*remote_addr, &addr, data, cx))?;
111+
let n = ready!(inner.poll_send_to_with_ctrl(
112+
*remote_addr,
113+
&addr,
114+
ss_control,
115+
data,
116+
cx
117+
))?;
101118

102119
debug!(
103120
"send udp packet to remote ss server, len: {}, remote_addr: {}, \
104121
dst_addr: {}",
105122
n, remote_addr, addr
106123
);
107124

125+
ss_control.packet_id = match ss_control.packet_id.checked_add(1) {
126+
Some(id) => id,
127+
None => {
128+
error!("packet_id overflow, closing socket");
129+
return Poll::Ready(Err(io::Error::new(
130+
io::ErrorKind::Other,
131+
"packet_id overflow",
132+
)));
133+
}
134+
};
135+
108136
let wrote_all = n == data.len();
109137
*pkt_container = None;
110138
*flushed = true;

0 commit comments

Comments
 (0)