Skip to content

Commit 08f23d5

Browse files
committed
Use boxed domain strings, improve address conversions, and add server bind backlog
- Use `Box<str>` for `DomainAddress` to reduce allocations and conversions - Return boxed domain strings from parsers and conversions (use `into_boxed_str`) - Fix example connect to pass `&str` when connecting to domain - Add `bind_with_backlog` and default `bind` wrapper; use backlog for `listen` - Update `to_socket_addrs`, TryFrom/From impls and tests to use boxed/borrowed domain
1 parent 3a62c41 commit 08f23d5

File tree

3 files changed

+18
-12
lines changed

3 files changed

+18
-12
lines changed

examples/s5-server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ where
132132
}
133133
ClientConnection::Connect(connect, addr) => {
134134
let target = match addr {
135-
Address::DomainAddress(domain, port) => TcpStream::connect((domain, port)).await,
135+
Address::DomainAddress(domain, port) => TcpStream::connect((&*domain, port)).await,
136136
Address::SocketAddress(addr) => TcpStream::connect(addr).await,
137137
};
138138

src/protocol/address.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub enum Address {
5555
/// Represents an IPv4 or IPv6 socket address.
5656
SocketAddress(SocketAddr),
5757
/// Represents a domain name and a port.
58-
DomainAddress(String, u16),
58+
DomainAddress(Box<str>, u16),
5959
}
6060

6161
impl Address {
@@ -85,7 +85,7 @@ impl Address {
8585
pub fn domain(&self) -> String {
8686
match self {
8787
Self::SocketAddress(addr) => addr.ip().to_string(),
88-
Self::DomainAddress(addr, _) => addr.clone(),
88+
Self::DomainAddress(addr, _) => addr.to_string(),
8989
}
9090
}
9191

@@ -135,7 +135,7 @@ impl StreamOperation for Address {
135135

136136
let addr = String::from_utf8(domain_buf)
137137
.map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, format!("Invalid address encoding: {err}")))?;
138-
Ok(Self::DomainAddress(addr, port))
138+
Ok(Self::DomainAddress(addr.into_boxed_str(), port))
139139
}
140140
AddressType::IPv6 => {
141141
let mut buf = [0; 18];
@@ -203,7 +203,7 @@ impl AsyncStreamOperation for Address {
203203

204204
let addr = String::from_utf8(domain_buf)
205205
.map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, format!("Invalid address encoding: {err}")))?;
206-
Ok(Self::DomainAddress(addr, port))
206+
Ok(Self::DomainAddress(addr.into_boxed_str(), port))
207207
}
208208
AddressType::IPv6 => {
209209
let mut addr_bytes = [0; 16];
@@ -221,7 +221,7 @@ impl ToSocketAddrs for Address {
221221
fn to_socket_addrs(&self) -> std::io::Result<Self::Iter> {
222222
match self {
223223
Address::SocketAddress(addr) => Ok(vec![*addr].into_iter()),
224-
Address::DomainAddress(addr, port) => Ok((addr.as_str(), *port).to_socket_addrs()?),
224+
Address::DomainAddress(addr, port) => Ok((&**addr, *port).to_socket_addrs()?),
225225
}
226226
}
227227
}
@@ -246,6 +246,8 @@ impl TryFrom<Address> for SocketAddr {
246246
Ok(SocketAddr::from((addr, port)))
247247
} else if let Ok(addr) = addr.parse::<Ipv6Addr>() {
248248
Ok(SocketAddr::from((addr, port)))
249+
} else if let Ok(addr) = addr.parse::<SocketAddr>() {
250+
Ok(addr)
249251
} else {
250252
let err = format!("domain address {addr} is not supported");
251253
Err(Self::Error::new(std::io::ErrorKind::Unsupported, err))
@@ -321,13 +323,13 @@ impl From<(IpAddr, u16)> for Address {
321323

322324
impl From<(String, u16)> for Address {
323325
fn from((addr, port): (String, u16)) -> Self {
324-
Address::DomainAddress(addr, port)
326+
Address::DomainAddress(addr.into_boxed_str(), port)
325327
}
326328
}
327329

328330
impl From<(&str, u16)> for Address {
329331
fn from((addr, port): (&str, u16)) -> Self {
330-
Address::DomainAddress(addr.to_owned(), port)
332+
Address::DomainAddress(addr.into(), port)
331333
}
332334
}
333335

@@ -350,7 +352,7 @@ impl TryFrom<&str> for Address {
350352
(addr, "0")
351353
};
352354
let port = port.parse::<u16>()?;
353-
Ok(Address::DomainAddress(addr.to_owned(), port))
355+
Ok(Address::DomainAddress(addr.into(), port))
354356
}
355357
}
356358
}
@@ -371,7 +373,7 @@ fn test_address() {
371373
let addr2 = Address::retrieve_from_stream(&mut Cursor::new(&buf)).unwrap();
372374
assert_eq!(addr, addr2);
373375

374-
let addr = Address::from(("sex.com".to_owned(), 8080));
376+
let addr = Address::from(("sex.com", 8080));
375377
let mut buf = Vec::new();
376378
addr.write_to_buf(&mut buf);
377379
assert_eq!(buf, vec![0x03, 0x07, b's', b'e', b'x', b'.', b'c', b'o', b'm', 0x1f, 0x90]);
@@ -396,7 +398,7 @@ async fn test_address_async() {
396398
let addr2 = Address::retrieve_from_async_stream(&mut Cursor::new(&buf)).await.unwrap();
397399
assert_eq!(addr, addr2);
398400

399-
let addr = Address::from(("sex.com".to_owned(), 8080));
401+
let addr = Address::from(("sex.com", 8080));
400402
let mut buf = Vec::new();
401403
addr.write_to_async_stream(&mut buf).await.unwrap();
402404
assert_eq!(buf, vec![0x03, 0x07, b's', b'e', b'x', b'.', b'c', b'o', b'm', 0x1f, 0x90]);

src/server/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,18 @@ impl<O: 'static> Server<O> {
3838
/// Create a new socks5 server on the given socket address and authentication method.
3939
#[inline]
4040
pub async fn bind(addr: SocketAddr, auth: AuthAdaptor<O>) -> std::io::Result<Self> {
41+
Self::bind_with_backlog(addr, auth, 1024).await
42+
}
43+
44+
pub async fn bind_with_backlog(addr: SocketAddr, auth: AuthAdaptor<O>, backlog: u32) -> std::io::Result<Self> {
4145
let socket = if addr.is_ipv4() {
4246
tokio::net::TcpSocket::new_v4()?
4347
} else {
4448
tokio::net::TcpSocket::new_v6()?
4549
};
4650
socket.set_reuseaddr(true)?;
4751
socket.bind(addr)?;
48-
let listener = socket.listen(1024)?;
52+
let listener = socket.listen(backlog)?;
4953
Ok(Self::new(listener, auth))
5054
}
5155

0 commit comments

Comments
 (0)