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