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