1use std::io;
2use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
3use std::sync::LazyLock;
4
5use bytes::{Buf, BufMut, Bytes, BytesMut};
6
7use crate::io::{AsyncRead, AsyncReadExt};
8
9#[derive(Debug, Clone, PartialEq)]
35pub enum Address {
36 IPv4(SocketAddrV4),
37 IPv6(SocketAddrV6),
38 Domain(Domain, u16),
39}
40
41static UNSPECIFIED_ADDRESS: LazyLock<Address> =
42 LazyLock::new(|| Address::IPv4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0)));
43
44#[rustfmt::skip]
45impl Address {
46 pub const PORT_LENGTH: usize = 2;
47 pub const IPV4_ADDRESS_LENGTH: usize = 4;
48 pub const IPV6_ADDRESS_LENGTH: usize = 16;
49
50 pub const SOCKS5_ADDRESS_TYPE_IPV4: u8 = 0x01;
51 pub const SOCKS5_ADDRESS_TYPE_DOMAIN_NAME: u8 = 0x03;
52 pub const SOCKS5_ADDRESS_TYPE_IPV6: u8 = 0x04;
53}
54
55impl Address {
56 #[inline]
57 pub fn unspecified() -> &'static Self {
58 &UNSPECIFIED_ADDRESS
59 }
60
61 pub async fn from_async_read<R: AsyncRead + Unpin>(reader: &mut R) -> io::Result<Self> {
62 let address_type = reader.read_u8().await?;
63
64 match address_type {
65 Self::SOCKS5_ADDRESS_TYPE_IPV4 => {
66 let mut buf = [0u8; Self::IPV4_ADDRESS_LENGTH + Self::PORT_LENGTH];
67 reader.read_exact(&mut buf).await?;
68
69 let ip = Ipv4Addr::new(buf[0], buf[1], buf[2], buf[3]);
70 let port = u16::from_be_bytes([buf[4], buf[5]]);
71
72 Ok(Address::IPv4(SocketAddrV4::new(ip, port)))
73 }
74
75 Self::SOCKS5_ADDRESS_TYPE_IPV6 => {
76 let mut buf = [0u8; Self::IPV6_ADDRESS_LENGTH + Self::PORT_LENGTH];
77 reader.read_exact(&mut buf).await?;
78
79 let ip = Ipv6Addr::from([
80 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9],
81 buf[10], buf[11], buf[12], buf[13], buf[14], buf[15],
82 ]);
83 let port = u16::from_be_bytes([buf[16], buf[17]]);
84
85 Ok(Address::IPv6(SocketAddrV6::new(ip, port, 0, 0)))
86 }
87
88 Self::SOCKS5_ADDRESS_TYPE_DOMAIN_NAME => {
89 let domain_len = reader.read_u8().await? as usize;
90
91 let mut buf = vec![0u8; domain_len + Self::PORT_LENGTH];
92 reader.read_exact(&mut buf).await?;
93
94 let domain = Bytes::copy_from_slice(&buf[..domain_len]);
95 let port = u16::from_be_bytes([buf[domain_len], buf[domain_len + 1]]);
96
97 Ok(Address::Domain(Domain(domain), port))
98 }
99
100 n => Err(io::Error::new(
101 io::ErrorKind::InvalidData,
102 format!("Invalid address type: {}", n),
103 )),
104 }
105 }
106
107 pub fn from_bytes<B: Buf>(buf: &mut B) -> io::Result<Self> {
108 if buf.remaining() < 1 {
109 return Err(io::Error::new(
110 io::ErrorKind::InvalidData,
111 "Insufficient data for address",
112 ));
113 }
114
115 let address_type = buf.get_u8();
116
117 match address_type {
118 Self::SOCKS5_ADDRESS_TYPE_IPV4 => {
119 if buf.remaining() < Self::IPV4_ADDRESS_LENGTH + Self::PORT_LENGTH {
120 return Err(io::Error::new(
121 io::ErrorKind::InvalidData,
122 "Insufficient data for IPv4 address",
123 ));
124 }
125
126 let mut ip = [0u8; Self::IPV4_ADDRESS_LENGTH];
127 buf.copy_to_slice(&mut ip);
128
129 let port = buf.get_u16();
130
131 Ok(Address::IPv4(SocketAddrV4::new(Ipv4Addr::from(ip), port)))
132 }
133
134 Self::SOCKS5_ADDRESS_TYPE_IPV6 => {
135 if buf.remaining() < Self::IPV6_ADDRESS_LENGTH + Self::PORT_LENGTH {
136 return Err(io::Error::new(
137 io::ErrorKind::InvalidData,
138 "Insufficient data for IPv6 address",
139 ));
140 }
141
142 let mut ip = [0u8; Self::IPV6_ADDRESS_LENGTH];
143 buf.copy_to_slice(&mut ip);
144
145 let port = buf.get_u16();
146
147 Ok(Address::IPv6(SocketAddrV6::new(
148 Ipv6Addr::from(ip),
149 port,
150 0,
151 0,
152 )))
153 }
154
155 Self::SOCKS5_ADDRESS_TYPE_DOMAIN_NAME => {
156 if buf.remaining() < 1 {
157 return Err(io::Error::new(
158 io::ErrorKind::InvalidData,
159 "Insufficient data for domain length",
160 ));
161 }
162
163 let domain_len = buf.get_u8() as usize;
164
165 if buf.remaining() < domain_len + Self::PORT_LENGTH {
166 return Err(io::Error::new(
167 io::ErrorKind::InvalidData,
168 "Insufficient data for domain name",
169 ));
170 }
171
172 let mut domain = vec![0u8; domain_len];
173 buf.copy_to_slice(&mut domain);
174
175 let port = buf.get_u16();
176
177 Ok(Address::Domain(Domain(Bytes::from(domain)), port))
178 }
179
180 n => Err(io::Error::new(
181 io::ErrorKind::InvalidData,
182 format!("Invalid address type: {}", n),
183 )),
184 }
185 }
186
187 #[inline]
188 pub fn to_bytes(&self) -> Bytes {
189 let mut bytes = BytesMut::new();
190
191 match self {
192 Self::Domain(domain, port) => {
193 let domain_bytes = domain.as_bytes();
194 bytes.put_u8(Self::SOCKS5_ADDRESS_TYPE_DOMAIN_NAME);
195 bytes.put_u8(domain_bytes.len() as u8);
196 bytes.extend_from_slice(domain_bytes);
197 bytes.extend_from_slice(&port.to_be_bytes());
198 }
199 Self::IPv4(addr) => {
200 bytes.put_u8(Self::SOCKS5_ADDRESS_TYPE_IPV4);
201 bytes.extend_from_slice(&addr.ip().octets());
202 bytes.extend_from_slice(&addr.port().to_be_bytes());
203 }
204 Self::IPv6(addr) => {
205 bytes.put_u8(Self::SOCKS5_ADDRESS_TYPE_IPV6);
206 bytes.extend_from_slice(&addr.ip().octets());
207 bytes.extend_from_slice(&addr.port().to_be_bytes());
208 }
209 }
210
211 bytes.freeze()
212 }
213
214 #[inline]
215 pub fn port(&self) -> u16 {
216 match self {
217 Self::IPv4(addr) => addr.port(),
218 Self::IPv6(addr) => addr.port(),
219 Self::Domain(_, port) => *port,
220 }
221 }
222
223 pub async fn to_socket_addr(self) -> io::Result<SocketAddr> {
224 use tokio::net::lookup_host;
225
226 match self {
227 Address::IPv4(addr) => Ok(SocketAddr::V4(addr)),
228 Address::IPv6(addr) => Ok(SocketAddr::V6(addr)),
229 Address::Domain(domain, port) => {
230 let domain = domain.format_as_str();
231
232 lookup_host((domain, port))
233 .await?
234 .next()
235 .ok_or(io::Error::other(format!(
236 "Failed to resolve domain {}",
237 domain
238 )))
239 }
240 }
241 }
242}
243
244impl From<SocketAddr> for Address {
245 #[inline]
246 fn from(value: SocketAddr) -> Self {
247 match value {
248 SocketAddr::V4(addr) => Self::IPv4(addr),
249 SocketAddr::V6(addr) => Self::IPv6(addr),
250 }
251 }
252}
253
254impl std::fmt::Display for Address {
255 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
256 let value = match self {
257 Self::Domain(domain, port) => format!("{}:{}", domain.format_as_str(), port),
258 Self::IPv4(addr) => addr.to_string(),
259 Self::IPv6(addr) => addr.to_string(),
260 };
261
262 write!(f, "{value}")
263 }
264}
265
266impl TryFrom<&str> for Address {
267 type Error = io::Error;
268
269 #[inline]
270 fn try_from(value: &str) -> Result<Self, Self::Error> {
271 use std::str::FromStr;
272
273 if let Ok(ipv4_addr) = SocketAddrV4::from_str(value) {
274 return Ok(Address::IPv4(ipv4_addr));
275 }
276
277 if let Ok(addr) = SocketAddrV6::from_str(value) {
278 return Ok(Address::IPv6(addr));
279 }
280
281 if let Some((domain, port_str)) = value.rsplit_once(':') {
282 if let Ok(port) = port_str.parse::<u16>() {
283 if !domain.is_empty() {
284 return Ok(Address::Domain(Domain::try_from(domain)?, port));
285 }
286 }
287 }
288
289 Err(io::Error::new(
290 io::ErrorKind::InvalidInput,
291 format!("Invalid address format: {}", value),
292 ))
293 }
294}
295
296impl TryFrom<String> for Address {
297 type Error = io::Error;
298
299 #[inline]
300 fn try_from(value: String) -> Result<Self, Self::Error> {
301 Address::try_from(value.as_str())
302 }
303}
304
305#[derive(Debug, Clone, PartialEq)]
307pub struct Domain(Bytes);
308
309impl Domain {
310 const MAX_LENGTH: usize = 254;
311
312 #[inline]
313 pub fn from_bytes(bytes: Bytes) -> io::Result<Self> {
314 if bytes.is_empty() {
315 return Err(io::Error::new(
316 io::ErrorKind::InvalidData,
317 "Domain is empty",
318 ));
319 }
320
321 let domain_str = std::str::from_utf8(&bytes)
322 .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
323
324 if domain_str.len() > Self::MAX_LENGTH {
325 return Err(io::Error::new(
326 io::ErrorKind::InvalidData,
327 "Punycode domain exceeds maximum length",
328 ));
329 }
330
331 Ok(Self(bytes))
332 }
333
334 #[inline]
335 pub fn from_string(value: String) -> io::Result<Self> {
336 Self::from_bytes(value.into())
337 }
338
339 #[inline]
340 pub fn format_as_str(&self) -> &str {
341 use std::str::from_utf8;
342
343 from_utf8(&self.0).expect("Invalid UTF-8")
344 }
345
346 #[inline]
347 pub fn as_bytes(&self) -> &Bytes {
348 &self.0
349 }
350
351 #[inline]
352 pub fn len(&self) -> usize {
353 self.0.len()
354 }
355
356 #[inline]
357 pub fn is_empty(&self) -> bool {
358 self.0.is_empty()
359 }
360}
361
362impl TryFrom<&[u8]> for Domain {
363 type Error = io::Error;
364
365 #[inline]
366 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
367 Self::from_bytes(Bytes::copy_from_slice(value))
368 }
369}
370
371impl TryFrom<&str> for Domain {
372 type Error = io::Error;
373
374 #[inline]
375 fn try_from(value: &str) -> Result<Self, Self::Error> {
376 Self::from_bytes(Bytes::copy_from_slice(value.as_bytes()))
377 }
378}
379
380impl TryFrom<String> for Domain {
381 type Error = io::Error;
382
383 #[inline]
384 fn try_from(value: String) -> Result<Self, Self::Error> {
385 Self::from_string(value)
386 }
387}
388
389impl TryFrom<Bytes> for Domain {
390 type Error = io::Error;
391
392 #[inline]
393 fn try_from(value: Bytes) -> Result<Self, Self::Error> {
394 Self::from_bytes(value)
395 }
396}
397
398impl AsRef<[u8]> for Domain {
399 #[inline]
400 fn as_ref(&self) -> &[u8] {
401 self.as_bytes()
402 }
403}
404
405#[cfg(test)]
406mod tests {
407 use tokio::io::BufReader;
408
409 use super::*;
410
411 use std::{
412 io::Cursor,
413 net::{Ipv4Addr, Ipv6Addr},
414 };
415
416 #[test]
417 fn test_ipv4_serialization() {
418 let addr = Address::IPv4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080));
419 let bytes = addr.to_bytes();
420 let mut buf = &bytes[..];
421 let parsed = Address::from_bytes(&mut buf).unwrap();
422 assert_eq!(addr, parsed);
423 }
424
425 #[test]
426 fn test_ipv6_serialization() {
427 let addr = Address::IPv6(SocketAddrV6::new(Ipv6Addr::LOCALHOST, 8080, 0, 0));
428 let bytes = addr.to_bytes();
429 let mut buf = &bytes[..];
430 let parsed = Address::from_bytes(&mut buf).unwrap();
431 assert_eq!(addr, parsed);
432 }
433
434 #[test]
435 fn test_domain_serialization() {
436 let domain = Domain::try_from("example.com").unwrap();
437 let addr = Address::Domain(domain, 8080);
438 let bytes = addr.to_bytes();
439 let mut buf = &bytes[..];
440
441 let parsed = Address::from_bytes(&mut buf).unwrap();
442
443 if let Address::Domain(d, p) = parsed {
444 assert_eq!(d.format_as_str(), "example.com");
445 assert_eq!(p, 8080);
446 } else {
447 panic!("Parsed address is not Domain type");
448 }
449 }
450
451 #[test]
452 fn test_invalid_atyp() {
453 let mut buf = bytes::BytesMut::new();
454 buf.put_u8(0x04);
455 let mut buf = buf.freeze();
456 let result = Address::from_bytes(&mut buf);
457 assert!(result.is_err());
458 }
459
460 #[test]
461 fn test_domain_too_long() {
462 let result = Domain::try_from(vec![b'a'; 255].as_slice());
463 assert!(result.is_err())
464 }
465
466 #[tokio::test]
467 async fn test_domain_resolution() {
468 let domain = Domain::try_from("localhost").unwrap();
469 let addr = Address::Domain(domain, 8080);
470 let socket_addr = addr.to_socket_addr().await.unwrap();
471 assert!(socket_addr.port() == 8080);
472 }
473
474 #[test]
475 fn test_domain_utf8_error() {
476 let result = Domain::from_bytes(Bytes::copy_from_slice(vec![0xff, 0xfe].as_slice()));
477 assert!(result.is_err())
478 }
479
480 #[test]
481 fn test_socket_addr_conversion() {
482 let socket_v4 = SocketAddrV4::new(Ipv4Addr::LOCALHOST, 8080);
483 let addr: Address = SocketAddr::V4(socket_v4).into();
484 assert!(matches!(addr, Address::IPv4(_)));
485
486 let socket_v6 = SocketAddrV6::new(Ipv6Addr::LOCALHOST, 8080, 0, 0);
487 let addr: Address = SocketAddr::V6(socket_v6).into();
488 assert!(matches!(addr, Address::IPv6(_)));
489 }
490
491 #[tokio::test]
492 async fn test_address_unspecified() {
493 let unspecified = Address::unspecified();
494 match unspecified {
495 Address::IPv4(addr) => {
496 assert_eq!(addr.ip(), &Ipv4Addr::UNSPECIFIED);
497 assert_eq!(addr.port(), 0);
498 }
499 _ => panic!("Unspecified address should be IPv4"),
500 }
501 }
502
503 #[tokio::test]
504 async fn test_address_from_socket_addr_ipv4() {
505 let socket = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080));
506 let address = Address::from(socket);
507
508 match address {
509 Address::IPv4(addr) => {
510 assert_eq!(addr.ip().octets(), [127, 0, 0, 1]);
511 assert_eq!(addr.port(), 8080);
512 }
513 _ => panic!("Should be IPv4 address"),
514 }
515 }
516
517 #[tokio::test]
518 async fn test_address_from_socket_addr_ipv6() {
519 let socket = SocketAddr::V6(SocketAddrV6::new(
520 Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
521 8080,
522 0,
523 0,
524 ));
525 let address = Address::from(socket);
526
527 match address {
528 Address::IPv6(addr) => {
529 assert_eq!(
530 addr.ip().octets(),
531 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
532 );
533 assert_eq!(addr.port(), 8080);
534 }
535 _ => panic!("Should be IPv6 address"),
536 }
537 }
538
539 #[tokio::test]
540 async fn test_address_to_bytes_ipv4() {
541 let addr = Address::IPv4(SocketAddrV4::new(Ipv4Addr::new(192, 168, 1, 1), 80));
542 let bytes = addr.to_bytes();
543
544 assert_eq!(bytes[0], Address::SOCKS5_ADDRESS_TYPE_IPV4);
545 assert_eq!(bytes[1..5], [192, 168, 1, 1]);
546 assert_eq!(bytes[5..7], [0, 80]); }
548
549 #[tokio::test]
550 async fn test_address_to_bytes_ipv6() {
551 let addr = Address::IPv6(SocketAddrV6::new(
552 Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1),
553 443,
554 0,
555 0,
556 ));
557 let bytes = addr.to_bytes();
558
559 assert_eq!(bytes[0], Address::SOCKS5_ADDRESS_TYPE_IPV6);
560 assert_eq!(
561 bytes[1..17],
562 [0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
563 );
564 assert_eq!(bytes[17..19], [1, 187]); }
566
567 #[tokio::test]
568 async fn test_address_to_bytes_domain() {
569 let domain = Domain(Bytes::from("example.com"));
570 let addr = Address::Domain(domain, 8080);
571 let bytes = addr.to_bytes();
572
573 assert_eq!(bytes[0], Address::SOCKS5_ADDRESS_TYPE_DOMAIN_NAME);
574 assert_eq!(bytes[1], 11); assert_eq!(&bytes[2..13], b"example.com");
576 assert_eq!(bytes[13..15], [31, 144]); }
578
579 #[tokio::test]
580 async fn test_address_from_bytes_ipv4() {
581 let mut buffer = BytesMut::new();
582 buffer.put_u8(Address::SOCKS5_ADDRESS_TYPE_IPV4);
583 buffer.put_slice(&[192, 168, 1, 1]); buffer.put_u16(80); let mut bytes = buffer.freeze();
587 let addr = Address::from_bytes(&mut bytes).unwrap();
588
589 match addr {
590 Address::IPv4(socket_addr) => {
591 assert_eq!(socket_addr.ip().octets(), [192, 168, 1, 1]);
592 assert_eq!(socket_addr.port(), 80);
593 }
594 _ => panic!("Should be IPv4 address"),
595 }
596 }
597
598 #[tokio::test]
599 async fn test_address_from_bytes_ipv6() {
600 let mut buffer = BytesMut::new();
601 buffer.put_u8(Address::SOCKS5_ADDRESS_TYPE_IPV6);
602 buffer.put_slice(&[0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); buffer.put_u16(443); let mut bytes = buffer.freeze();
606 let addr = Address::from_bytes(&mut bytes).unwrap();
607
608 match addr {
609 Address::IPv6(socket_addr) => {
610 assert_eq!(
611 socket_addr.ip().octets(),
612 [0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
613 );
614 assert_eq!(socket_addr.port(), 443);
615 }
616 _ => panic!("Should be IPv6 address"),
617 }
618 }
619
620 #[tokio::test]
621 async fn test_address_from_bytes_domain() {
622 let mut buffer = BytesMut::new();
623 buffer.put_u8(Address::SOCKS5_ADDRESS_TYPE_DOMAIN_NAME);
624 buffer.put_u8(11); buffer.put_slice(b"example.com"); buffer.put_u16(8080); let mut bytes = buffer.freeze();
629 let addr = Address::from_bytes(&mut bytes).unwrap();
630
631 match addr {
632 Address::Domain(domain, port) => {
633 assert_eq!(**domain.as_bytes(), *b"example.com");
634 assert_eq!(port, 8080);
635 }
636 _ => panic!("Should be domain address"),
637 }
638 }
639
640 #[tokio::test]
641 async fn test_address_from_async_read_ipv4() {
642 let mut buffer = BytesMut::new();
643 buffer.put_u8(Address::SOCKS5_ADDRESS_TYPE_IPV4);
644 buffer.put_slice(&[192, 168, 1, 1]); buffer.put_u16(80); let bytes = buffer.freeze();
648 let mut cursor = Cursor::new(bytes);
649 let mut reader = BufReader::new(&mut cursor);
650
651 let addr = Address::from_async_read(&mut reader).await.unwrap();
652
653 match addr {
654 Address::IPv4(socket_addr) => {
655 assert_eq!(socket_addr.ip().octets(), [192, 168, 1, 1]);
656 assert_eq!(socket_addr.port(), 80);
657 }
658 _ => panic!("Should be IPv4 address"),
659 }
660 }
661
662 #[tokio::test]
663 async fn test_address_from_async_read_ipv6() {
664 let mut buffer = BytesMut::new();
665 buffer.put_u8(Address::SOCKS5_ADDRESS_TYPE_IPV6);
666 buffer.put_slice(&[0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); buffer.put_u16(443); let bytes = buffer.freeze();
670 let mut cursor = Cursor::new(bytes);
671 let mut reader = BufReader::new(&mut cursor);
672
673 let addr = Address::from_async_read(&mut reader).await.unwrap();
674
675 match addr {
676 Address::IPv6(socket_addr) => {
677 assert_eq!(
678 socket_addr.ip().octets(),
679 [0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
680 );
681 assert_eq!(socket_addr.port(), 443);
682 }
683 _ => panic!("Should be IPv6 address"),
684 }
685 }
686
687 #[tokio::test]
688 async fn test_address_from_async_read_domain() {
689 let mut buffer = BytesMut::new();
690 buffer.put_u8(Address::SOCKS5_ADDRESS_TYPE_DOMAIN_NAME);
691 buffer.put_u8(11); buffer.put_slice(b"example.com"); buffer.put_u16(8080); let bytes = buffer.freeze();
696 let mut cursor = Cursor::new(bytes);
697 let mut reader = BufReader::new(&mut cursor);
698
699 let addr = Address::from_async_read(&mut reader).await.unwrap();
700
701 match addr {
702 Address::Domain(domain, port) => {
703 assert_eq!(**domain.as_bytes(), *b"example.com");
704 assert_eq!(port, 8080);
705 }
706 _ => panic!("Should be domain address"),
707 }
708 }
709
710 #[tokio::test]
711 async fn test_address_from_bytes_invalid_type() {
712 let mut buffer = BytesMut::new();
713 buffer.put_u8(0xFF); let mut bytes = buffer.freeze();
716 let result = Address::from_bytes(&mut bytes);
717
718 assert!(result.is_err());
719 }
720
721 #[tokio::test]
722 async fn test_address_from_bytes_insufficient_data() {
723 let mut buffer = BytesMut::new();
725 buffer.put_u8(Address::SOCKS5_ADDRESS_TYPE_IPV4);
726 buffer.put_slice(&[192, 168]); let mut bytes = buffer.freeze();
729 let result = Address::from_bytes(&mut bytes);
730
731 assert!(result.is_err());
732 }
733
734 #[tokio::test]
735 async fn test_address_port() {
736 let addr1 = Address::IPv4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080));
737 assert_eq!(addr1.port(), 8080);
738
739 let addr2 = Address::IPv6(SocketAddrV6::new(
740 Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
741 443,
742 0,
743 0,
744 ));
745 assert_eq!(addr2.port(), 443);
746
747 let addr3 = Address::Domain(Domain(Bytes::from("example.com")), 80);
748 assert_eq!(addr3.port(), 80);
749 }
750
751 #[tokio::test]
752 async fn test_address_format_as_string() {
753 let addr1 = Address::IPv4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080));
754 assert_eq!(addr1.to_string(), "127.0.0.1:8080");
755
756 let addr2 = Address::IPv6(SocketAddrV6::new(
757 Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
758 443,
759 0,
760 0,
761 ));
762 assert_eq!(addr2.to_string(), "[::1]:443");
763
764 let addr3 = Address::Domain(Domain(Bytes::from("example.com")), 80);
766 assert_eq!(addr3.to_string(), "example.com:80");
767 }
768}