-
Notifications
You must be signed in to change notification settings - Fork 86
Open
Description
我在使用shoes作为anytls服务端,surge作为客户端时发现shoes日志有错误
unknown UoT ATYP: 2
经人指点后,把shoes和sing-box的uot源码扔给AI,得出shoes的uot实现可能有问题的结论。
下面是AI给出的解决代码
之后编译了一下shoes,AnyTLS再没有报错,其他支持uot的协议没有测试。
shoes的trace日志显示
Shadowrocket:V2(connect=1)
Surge:V2(connect=0)
Shadowrocket在编译前后的使用都没有问题,或许shoes的uot对connect=0的兼容有问题。
- src/uot/uot_v1_server_stream.rs
- use super::uot_common::{parse_uot_address, write_uot_address};
+ use super::uot_common::{parse_uot_addrparser_address, write_uot_addrparser_address};
- let (location, addr_len) = match parse_uot_address(data)? {
+ let (location, addr_len) = match parse_uot_addrparser_address(data)? {
- let offset = write_uot_address(&mut this.write_buf, source);
+ let offset = write_uot_addrparser_address(&mut this.write_buf, source);
- src/uot/uot_common.rs 都是+
// NEW: Parse AddrParser format
#[inline]
pub fn parse_uot_addrparser_address(data: &[u8]) -> std::io::Result<Option<(NetLocation, usize)>> {
if data.is_empty() {
return Ok(None);
}
let atyp = data[0];
match atyp {
ADDRPARSER_ATYP_IPV4 => {
if data.len() < 7 {
return Ok(None);
}
let ip = Ipv4Addr::new(data[1], data[2], data[3], data[4]);
let port = u16::from_be_bytes([data[5], data[6]]);
Ok(Some((NetLocation::new(Address::Ipv4(ip), port), 7)))
}
ADDRPARSER_ATYP_IPV6 => {
if data.len() < 19 {
return Ok(None);
}
let ip_bytes: [u8; 16] = data[1..17].try_into().unwrap();
let ip = Ipv6Addr::from(ip_bytes);
let port = u16::from_be_bytes([data[17], data[18]]);
Ok(Some((NetLocation::new(Address::Ipv6(ip), port), 19)))
}
ADDRPARSER_ATYP_DOMAIN => {
if data.len() < 2 {
return Ok(None);
}
let domain_len = data[1] as usize;
let total_len = 1 + 1 + domain_len + 2;
if data.len() < total_len {
return Ok(None);
}
let domain = std::str::from_utf8(&data[2..2 + domain_len])
.map_err(|e| std::io::Error::other(format!("invalid domain: {e}")))?;
let port = u16::from_be_bytes([data[2 + domain_len], data[3 + domain_len]]);
Ok(Some((
NetLocation::new(Address::Hostname(domain.to_string()), port),
total_len,
)))
}
_ => Err(std::io::Error::other(format!("unknown UoT AddrParser ATYP: {atyp}"))),
}
}
// NEW: Write AddrParser format
#[inline]
pub fn write_uot_addrparser_address(buf: &mut [u8], addr: &SocketAddr) -> usize {
match addr {
SocketAddr::V4(v4) => {
buf[0] = ADDRPARSER_ATYP_IPV4;
buf[1..5].copy_from_slice(&v4.ip().octets());
buf[5..7].copy_from_slice(&v4.port().to_be_bytes());
7
}
SocketAddr::V6(v6) => {
buf[0] = ADDRPARSER_ATYP_IPV6;
buf[1..17].copy_from_slice(&v6.ip().octets());
buf[17..19].copy_from_slice(&v6.port().to_be_bytes());
19
}
}
}
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels