1#[cfg(feature = "tokio")]
2use crate::stream::AsyncStreamOperation;
3use crate::stream::StreamOperation;
4use bytes::BufMut;
5use std::{
6 io::Cursor,
7 net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs},
8};
9#[cfg(feature = "tokio")]
10use tokio::io::{AsyncRead, AsyncReadExt};
11
12#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Default)]
13#[repr(u8)]
14pub enum AddressType {
15 #[default]
16 IPv4 = 0x01,
17 Domain = 0x03,
18 IPv6 = 0x04,
19}
20
21impl TryFrom<u8> for AddressType {
22 type Error = std::io::Error;
23 fn try_from(code: u8) -> core::result::Result<Self, Self::Error> {
24 let err = format!("Unsupported address type code {code:#x}");
25 match code {
26 0x01 => Ok(AddressType::IPv4),
27 0x03 => Ok(AddressType::Domain),
28 0x04 => Ok(AddressType::IPv6),
29 _ => Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, err)),
30 }
31 }
32}
33
34impl From<AddressType> for u8 {
35 fn from(addr_type: AddressType) -> Self {
36 match addr_type {
37 AddressType::IPv4 => 0x01,
38 AddressType::Domain => 0x03,
39 AddressType::IPv6 => 0x04,
40 }
41 }
42}
43
44#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
54#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
55#[cfg_attr(feature = "serde", serde(try_from = "String", into = "String"))]
56pub enum Address {
57 SocketAddress(SocketAddr),
59 DomainAddress(Box<str>, u16),
61}
62
63impl Default for Address {
64 fn default() -> Self {
65 Address::unspecified()
66 }
67}
68
69impl Address {
70 pub fn unspecified() -> Self {
72 Address::SocketAddress(SocketAddr::from((Ipv4Addr::UNSPECIFIED, 0)))
73 }
74
75 pub fn get_type(&self) -> AddressType {
77 match self {
78 Self::SocketAddress(SocketAddr::V4(_)) => AddressType::IPv4,
79 Self::SocketAddress(SocketAddr::V6(_)) => AddressType::IPv6,
80 Self::DomainAddress(_, _) => AddressType::Domain,
81 }
82 }
83
84 pub fn port(&self) -> u16 {
86 match self {
87 Self::SocketAddress(addr) => addr.port(),
88 Self::DomainAddress(_, port) => *port,
89 }
90 }
91
92 pub fn host(&self) -> String {
94 match self {
95 Self::SocketAddress(addr) => addr.ip().to_string(),
96 Self::DomainAddress(addr, _) => addr.to_string(),
97 }
98 }
99
100 #[deprecated(note = "use host() instead")]
102 pub fn domain(&self) -> String {
103 self.host()
104 }
105
106 pub fn is_ipv4(&self) -> bool {
108 matches!(self, Self::SocketAddress(SocketAddr::V4(_)))
109 }
110
111 pub fn is_ipv6(&self) -> bool {
113 matches!(self, Self::SocketAddress(SocketAddr::V6(_)))
114 }
115
116 pub fn is_domain(&self) -> bool {
118 matches!(self, Self::DomainAddress(_, _))
119 }
120
121 pub const fn max_serialized_len() -> usize {
123 1 + 1 + u8::MAX as usize + 2
124 }
125
126 #[cfg(feature = "tokio")]
129 pub async fn resolve_tokio(&self) -> std::io::Result<std::vec::IntoIter<SocketAddr>> {
130 match self {
131 Address::SocketAddress(addr) => Ok(vec![*addr].into_iter()),
132 Address::DomainAddress(host, port) => {
133 let host = host.strip_prefix('[').and_then(|host| host.strip_suffix(']')).unwrap_or(host);
134 if let Ok(ip) = host.parse::<IpAddr>() {
135 return Ok(vec![SocketAddr::new(ip, *port)].into_iter());
136 }
137 Ok(tokio::net::lookup_host((host, *port)).await?.collect::<Vec<_>>().into_iter())
138 }
139 }
140 }
141
142 pub fn resolve(&self) -> std::io::Result<std::vec::IntoIter<SocketAddr>> {
161 self.to_socket_addrs()
162 }
163}
164
165impl StreamOperation for Address {
166 fn retrieve_from_stream<R: std::io::Read>(stream: &mut R) -> std::io::Result<Self> {
167 let mut atyp_buf = [0; 1];
168 stream.read_exact(&mut atyp_buf)?;
169 match AddressType::try_from(atyp_buf[0])? {
170 AddressType::IPv4 => {
171 let mut buf = [0; 6];
172 stream.read_exact(&mut buf)?;
173 let addr = Ipv4Addr::new(buf[0], buf[1], buf[2], buf[3]);
174 let port = u16::from_be_bytes([buf[4], buf[5]]);
175 Ok(Self::SocketAddress(SocketAddr::from((addr, port))))
176 }
177 AddressType::Domain => {
178 let mut len_buf = [0; 1];
179 stream.read_exact(&mut len_buf)?;
180 let len = len_buf[0] as usize;
181 let mut domain_buf = vec![0; len];
182 stream.read_exact(&mut domain_buf)?;
183
184 let mut port_buf = [0; 2];
185 stream.read_exact(&mut port_buf)?;
186 let port = u16::from_be_bytes(port_buf);
187
188 let addr = String::from_utf8(domain_buf)
189 .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, format!("Invalid address encoding: {err}")))?;
190 Ok(Self::DomainAddress(addr.into_boxed_str(), port))
191 }
192 AddressType::IPv6 => {
193 let mut buf = [0; 18];
194 stream.read_exact(&mut buf)?;
195 let port = u16::from_be_bytes([buf[16], buf[17]]);
196 let mut addr_bytes = [0; 16];
197 addr_bytes.copy_from_slice(&buf[..16]);
198 Ok(Self::SocketAddress(SocketAddr::from((Ipv6Addr::from(addr_bytes), port))))
199 }
200 }
201 }
202
203 fn write_to_buf<B: BufMut>(&self, buf: &mut B) {
204 match self {
205 Self::SocketAddress(SocketAddr::V4(addr)) => {
206 buf.put_u8(AddressType::IPv4.into());
207 buf.put_slice(&addr.ip().octets());
208 buf.put_u16(addr.port());
209 }
210 Self::SocketAddress(SocketAddr::V6(addr)) => {
211 buf.put_u8(AddressType::IPv6.into());
212 buf.put_slice(&addr.ip().octets());
213 buf.put_u16(addr.port());
214 }
215 Self::DomainAddress(addr, port) => {
216 let addr = addr.as_bytes();
217 buf.put_u8(AddressType::Domain.into());
218 buf.put_u8(u8::try_from(addr.len()).expect("domain address too long for SOCKS5"));
219 buf.put_slice(addr);
220 buf.put_u16(*port);
221 }
222 }
223 }
224
225 fn len(&self) -> usize {
226 match self {
227 Address::SocketAddress(SocketAddr::V4(_)) => 1 + 4 + 2,
228 Address::SocketAddress(SocketAddr::V6(_)) => 1 + 16 + 2,
229 Address::DomainAddress(addr, _) => 1 + 1 + addr.len() + 2,
230 }
231 }
232}
233
234#[cfg(feature = "tokio")]
235#[async_trait::async_trait]
236impl AsyncStreamOperation for Address {
237 async fn retrieve_from_async_stream<R>(stream: &mut R) -> std::io::Result<Self>
238 where
239 R: AsyncRead + Unpin + Send + ?Sized,
240 {
241 let atyp = stream.read_u8().await?;
242 match AddressType::try_from(atyp)? {
243 AddressType::IPv4 => {
244 let mut addr_bytes = [0; 4];
245 stream.read_exact(&mut addr_bytes).await?;
246 let port = stream.read_u16().await?;
247 let addr = Ipv4Addr::from(addr_bytes);
248 Ok(Self::SocketAddress(SocketAddr::from((addr, port))))
249 }
250 AddressType::Domain => {
251 let len = stream.read_u8().await? as usize;
252 let mut domain_buf = vec![0; len];
253 stream.read_exact(&mut domain_buf).await?;
254 let port = stream.read_u16().await?;
255
256 let addr = String::from_utf8(domain_buf)
257 .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, format!("Invalid address encoding: {err}")))?;
258 Ok(Self::DomainAddress(addr.into_boxed_str(), port))
259 }
260 AddressType::IPv6 => {
261 let mut addr_bytes = [0; 16];
262 stream.read_exact(&mut addr_bytes).await?;
263 let port = stream.read_u16().await?;
264 Ok(Self::SocketAddress(SocketAddr::from((Ipv6Addr::from(addr_bytes), port))))
265 }
266 }
267 }
268}
269
270impl ToSocketAddrs for Address {
271 type Iter = std::vec::IntoIter<SocketAddr>;
272
273 fn to_socket_addrs(&self) -> std::io::Result<Self::Iter> {
274 match self {
275 Address::SocketAddress(addr) => Ok(vec![*addr].into_iter()),
276 Address::DomainAddress(host, port) => {
277 let host = host.strip_prefix('[').and_then(|host| host.strip_suffix(']')).unwrap_or(host);
278 if let Ok(ip) = host.parse::<IpAddr>() {
279 return Ok(vec![SocketAddr::new(ip, *port)].into_iter());
280 }
281 Ok((host, *port).to_socket_addrs()?)
282 }
283 }
284 }
285}
286
287impl std::fmt::Display for Address {
288 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
289 match self {
290 Address::DomainAddress(hostname, port) => write!(f, "{hostname}:{port}"),
291 Address::SocketAddress(socket_addr) => write!(f, "{socket_addr}"),
292 }
293 }
294}
295
296impl TryFrom<String> for Address {
297 type Error = crate::Error;
298
299 fn try_from(addr: String) -> std::result::Result<Self, Self::Error> {
300 Self::try_from(addr.as_str())
301 }
302}
303
304impl TryFrom<&String> for Address {
305 type Error = crate::Error;
306
307 fn try_from(addr: &String) -> std::result::Result<Self, Self::Error> {
308 Self::try_from(addr.as_str())
309 }
310}
311
312impl From<Address> for String {
313 fn from(addr: Address) -> Self {
314 addr.to_string()
315 }
316}
317
318impl From<&Address> for String {
319 fn from(addr: &Address) -> Self {
320 addr.to_string()
321 }
322}
323
324impl TryFrom<&Address> for SocketAddr {
325 type Error = std::io::Error;
326
327 fn try_from(address: &Address) -> std::result::Result<Self, Self::Error> {
328 match address {
329 Address::SocketAddress(addr) => Ok(*addr),
330 Address::DomainAddress(host, port) => {
331 let host = host.strip_prefix('[').and_then(|host| host.strip_suffix(']')).unwrap_or(host);
332 if let Ok(addr) = host.parse::<IpAddr>() {
333 return Ok(SocketAddr::from((addr, *port)));
334 }
335 let err = format!("domain address {host} cannot be converted to a SocketAddr without DNS, use to_socket_addrs instead");
336 Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, err))
337 }
338 }
339 }
340}
341
342impl TryFrom<Address> for SocketAddr {
343 type Error = std::io::Error;
344
345 fn try_from(address: Address) -> std::result::Result<Self, Self::Error> {
346 Self::try_from(&address)
347 }
348}
349
350impl From<Address> for Vec<u8> {
351 fn from(addr: Address) -> Self {
352 let mut buf = Vec::with_capacity(addr.len());
353 addr.write_to_buf(&mut buf);
354 buf
355 }
356}
357
358impl TryFrom<Vec<u8>> for Address {
359 type Error = std::io::Error;
360
361 fn try_from(data: Vec<u8>) -> std::result::Result<Self, Self::Error> {
362 let mut rdr = Cursor::new(data);
363 Self::retrieve_from_stream(&mut rdr)
364 }
365}
366
367impl TryFrom<&[u8]> for Address {
368 type Error = std::io::Error;
369
370 fn try_from(data: &[u8]) -> std::result::Result<Self, Self::Error> {
371 let mut rdr = Cursor::new(data);
372 Self::retrieve_from_stream(&mut rdr)
373 }
374}
375
376impl From<SocketAddr> for Address {
377 fn from(addr: SocketAddr) -> Self {
378 Address::SocketAddress(addr)
379 }
380}
381
382impl From<&SocketAddr> for Address {
383 fn from(addr: &SocketAddr) -> Self {
384 Address::SocketAddress(*addr)
385 }
386}
387
388impl From<(Ipv4Addr, u16)> for Address {
389 fn from((addr, port): (Ipv4Addr, u16)) -> Self {
390 Address::SocketAddress(SocketAddr::from((addr, port)))
391 }
392}
393
394impl From<(Ipv6Addr, u16)> for Address {
395 fn from((addr, port): (Ipv6Addr, u16)) -> Self {
396 Address::SocketAddress(SocketAddr::from((addr, port)))
397 }
398}
399
400impl From<(IpAddr, u16)> for Address {
401 fn from((addr, port): (IpAddr, u16)) -> Self {
402 Address::SocketAddress(SocketAddr::from((addr, port)))
403 }
404}
405
406impl From<(String, u16)> for Address {
407 fn from((addr, port): (String, u16)) -> Self {
408 Address::from((addr.as_str(), port))
409 }
410}
411
412impl From<(&String, u16)> for Address {
413 fn from((addr, port): (&String, u16)) -> Self {
414 Address::from((addr.as_str(), port))
415 }
416}
417
418impl From<(&str, u16)> for Address {
419 fn from((addr, port): (&str, u16)) -> Self {
420 if let Ok(addr) = addr.parse::<IpAddr>() {
421 return Address::SocketAddress(SocketAddr::from((addr, port)));
422 }
423 Address::DomainAddress(addr.into(), port)
424 }
425}
426
427impl From<&Address> for Address {
428 fn from(addr: &Address) -> Self {
429 addr.clone()
430 }
431}
432
433impl TryFrom<&str> for Address {
434 type Error = crate::Error;
435
436 fn try_from(addr: &str) -> std::result::Result<Self, Self::Error> {
437 if let Ok(addr) = addr.parse::<SocketAddr>() {
438 Ok(Address::SocketAddress(addr))
439 } else {
440 if addr.matches(':').count() > 1 {
441 let err = format!("invalid socket address format: {addr}");
442 return Err(crate::Error::InvalidAddress(err));
443 }
444
445 let Some(pos) = addr.rfind(':') else {
446 let err = format!("missing port in address: {addr}");
447 return Err(crate::Error::InvalidAddress(err));
448 };
449
450 let (addr, port) = (&addr[..pos], &addr[pos + 1..]);
451 let port = port.parse::<u16>()?;
452 Ok(Address::from((addr, port)))
453 }
454 }
455}
456
457impl std::str::FromStr for Address {
458 type Err = crate::Error;
459
460 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
461 Self::try_from(s)
462 }
463}
464
465#[test]
466fn test_address() {
467 let addr = Address::from((Ipv4Addr::new(127, 0, 0, 1), 8080));
468 let mut buf = Vec::new();
469 addr.write_to_buf(&mut buf);
470 assert_eq!(buf, vec![0x01, 127, 0, 0, 1, 0x1f, 0x90]);
471 let addr2 = Address::retrieve_from_stream(&mut Cursor::new(&buf)).unwrap();
472 assert_eq!(addr, addr2);
473
474 let addr = Address::from((Ipv6Addr::new(0x45, 0xff89, 0, 0, 0, 0, 0, 1), 8080));
475 let mut buf = Vec::new();
476 addr.write_to_buf(&mut buf);
477 assert_eq!(buf, vec![0x04, 0, 0x45, 0xff, 0x89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0x1f, 0x90]);
478 let addr2 = Address::retrieve_from_stream(&mut Cursor::new(&buf)).unwrap();
479 assert_eq!(addr, addr2);
480
481 let addr = Address::from(("sex.com", 8080));
482 let mut buf = Vec::new();
483 addr.write_to_buf(&mut buf);
484 assert_eq!(buf, vec![0x03, 0x07, b's', b'e', b'x', b'.', b'c', b'o', b'm', 0x1f, 0x90]);
485 let addr2 = Address::retrieve_from_stream(&mut Cursor::new(&buf)).unwrap();
486 assert_eq!(addr, addr2);
487
488 let addr = Address::try_from("example.com:8080").unwrap();
489 assert_eq!(addr.host(), "example.com");
490 assert!(Address::try_from("example.com").is_err());
491
492 let addr = Address::try_from("123.45.67.89:8080").unwrap();
493 assert!(addr.is_ipv4());
494 assert!(Address::try_from("123.45.67.89").is_err());
495
496 let addr = Address::try_from("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:8080").unwrap();
497 assert_eq!(addr.host(), "2001:db8:85a3::8a2e:370:7334");
498 assert!(addr.is_ipv6());
499
500 let addr = Address::from((Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080));
501 assert_eq!(addr.host(), "2001:db8::1");
502
503 assert!(Address::try_from("2001:0db8:85a3:0000:0000:8a2e:0370:7334:8080").is_err());
504}
505
506#[test]
507fn test_address_display_for_ipv6() {
508 let addr = Address::from((Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080));
509 assert_eq!(addr.to_string(), "[2001:db8::1]:8080");
510}
511
512#[cfg(feature = "serde")]
513#[test]
514fn test_address_serde_string_roundtrip() {
515 for value in ["127.0.0.1:8080", "example.com:8080", "[2001:db8::1]:8080"] {
516 let address = value.parse::<Address>().unwrap();
517 let serialized = serde_json::to_string(&address).unwrap();
518
519 assert_eq!(serialized, serde_json::to_string(&address.to_string()).unwrap());
520 assert_eq!(serde_json::from_str::<Address>(&serialized).unwrap(), address);
521 }
522 assert!(serde_json::from_str::<Address>(r#""example.com""#).is_err());
523}
524
525#[test]
526fn test_try_from_address_for_socketaddr() {
527 let addr = Address::from((Ipv4Addr::new(127, 0, 0, 1), 8080));
528 let socket_addr = SocketAddr::try_from(addr.clone()).unwrap();
529 assert_eq!(socket_addr, SocketAddr::from(([127, 0, 0, 1], 8080)));
530
531 let addr = Address::from(("192.168.1.1", 8080));
532 let socket_addr = SocketAddr::try_from(addr).unwrap();
533 assert_eq!(socket_addr, SocketAddr::from(([192, 168, 1, 1], 8080)));
534
535 let addr = Address::from(("example.com", 8080));
536 let err = SocketAddr::try_from(addr).unwrap_err();
537 assert!(format!("{err}").contains("cannot be converted to a SocketAddr without DNS"));
538
539 let addr = Address::from(("baidu.com", 8080));
540 let err = SocketAddr::try_from(addr).unwrap_err();
541 assert!(format!("{err}").contains("cannot be converted to a SocketAddr without DNS"));
542
543 let addr = Address::from(("baidu.com", 8080));
544 let socket_addrs: Vec<SocketAddr> = addr.to_socket_addrs().unwrap().collect();
545 assert!(!socket_addrs.is_empty());
546}
547
548#[cfg(feature = "tokio")]
549#[tokio::test]
550async fn test_address_async() {
551 let addr = Address::from((Ipv4Addr::new(127, 0, 0, 1), 8080));
552 let mut buf = Vec::new();
553 addr.write_to_async_stream(&mut buf).await.unwrap();
554 assert_eq!(buf, vec![0x01, 127, 0, 0, 1, 0x1f, 0x90]);
555 let addr2 = Address::retrieve_from_async_stream(&mut Cursor::new(&buf)).await.unwrap();
556 assert_eq!(addr, addr2);
557
558 let addr = Address::from((Ipv6Addr::new(0x45, 0xff89, 0, 0, 0, 0, 0, 1), 8080));
559 let mut buf = Vec::new();
560 addr.write_to_async_stream(&mut buf).await.unwrap();
561 assert_eq!(buf, vec![0x04, 0, 0x45, 0xff, 0x89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0x1f, 0x90]);
562 let addr2 = Address::retrieve_from_async_stream(&mut Cursor::new(&buf)).await.unwrap();
563 assert_eq!(addr, addr2);
564
565 let addr = Address::from(("sex.com", 8080));
566 let mut buf = Vec::new();
567 addr.write_to_async_stream(&mut buf).await.unwrap();
568 assert_eq!(buf, vec![0x03, 0x07, b's', b'e', b'x', b'.', b'c', b'o', b'm', 0x1f, 0x90]);
569 let addr2 = Address::retrieve_from_async_stream(&mut Cursor::new(&buf)).await.unwrap();
570 assert_eq!(addr, addr2);
571}