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 From<Domain> for Bytes {
363 #[inline]
364 fn from(value: Domain) -> Self {
365 value.0
366 }
367}
368
369impl From<Domain> for Vec<u8> {
370 #[inline]
371 fn from(value: Domain) -> Self {
372 value.0.to_vec()
373 }
374}
375
376impl TryFrom<&[u8]> for Domain {
377 type Error = io::Error;
378
379 #[inline]
380 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
381 Self::from_bytes(Bytes::copy_from_slice(value))
382 }
383}
384
385impl TryFrom<&str> for Domain {
386 type Error = io::Error;
387
388 #[inline]
389 fn try_from(value: &str) -> Result<Self, Self::Error> {
390 Self::from_bytes(Bytes::copy_from_slice(value.as_bytes()))
391 }
392}
393
394impl TryFrom<String> for Domain {
395 type Error = io::Error;
396
397 #[inline]
398 fn try_from(value: String) -> Result<Self, Self::Error> {
399 Self::from_string(value)
400 }
401}
402
403impl TryFrom<Bytes> for Domain {
404 type Error = io::Error;
405
406 #[inline]
407 fn try_from(value: Bytes) -> Result<Self, Self::Error> {
408 Self::from_bytes(value)
409 }
410}
411
412impl AsRef<[u8]> for Domain {
413 #[inline]
414 fn as_ref(&self) -> &[u8] {
415 self.as_bytes()
416 }
417}
418
419#[cfg(test)]
420mod tests {
421 use tokio::io::BufReader;
422
423 use super::*;
424
425 use std::{
426 io::Cursor,
427 net::{Ipv4Addr, Ipv6Addr},
428 };
429
430 #[test]
431 fn test_ipv4_serialization() {
432 let addr = Address::IPv4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080));
433 let bytes = addr.to_bytes();
434 let mut buf = &bytes[..];
435 let parsed = Address::from_bytes(&mut buf).unwrap();
436 assert_eq!(addr, parsed);
437 }
438
439 #[test]
440 fn test_ipv6_serialization() {
441 let addr = Address::IPv6(SocketAddrV6::new(Ipv6Addr::LOCALHOST, 8080, 0, 0));
442 let bytes = addr.to_bytes();
443 let mut buf = &bytes[..];
444 let parsed = Address::from_bytes(&mut buf).unwrap();
445 assert_eq!(addr, parsed);
446 }
447
448 #[test]
449 fn test_domain_serialization() {
450 let domain = Domain::try_from("example.com").unwrap();
451 let addr = Address::Domain(domain, 8080);
452 let bytes = addr.to_bytes();
453 let mut buf = &bytes[..];
454
455 let parsed = Address::from_bytes(&mut buf).unwrap();
456
457 if let Address::Domain(d, p) = parsed {
458 assert_eq!(d.format_as_str(), "example.com");
459 assert_eq!(p, 8080);
460 } else {
461 panic!("Parsed address is not Domain type");
462 }
463 }
464
465 #[test]
466 fn test_invalid_atyp() {
467 let mut buf = bytes::BytesMut::new();
468 buf.put_u8(0x04);
469 let mut buf = buf.freeze();
470 let result = Address::from_bytes(&mut buf);
471 assert!(result.is_err());
472 }
473
474 #[test]
475 fn test_domain_too_long() {
476 let result = Domain::try_from(vec![b'a'; 255].as_slice());
477 assert!(result.is_err())
478 }
479
480 #[tokio::test]
481 async fn test_domain_resolution() {
482 let domain = Domain::try_from("localhost").unwrap();
483 let addr = Address::Domain(domain, 8080);
484 let socket_addr = addr.to_socket_addr().await.unwrap();
485 assert!(socket_addr.port() == 8080);
486 }
487
488 #[test]
489 fn test_domain_utf8_error() {
490 let result = Domain::from_bytes(Bytes::copy_from_slice(vec![0xff, 0xfe].as_slice()));
491 assert!(result.is_err())
492 }
493
494 #[test]
495 fn test_socket_addr_conversion() {
496 let socket_v4 = SocketAddrV4::new(Ipv4Addr::LOCALHOST, 8080);
497 let addr: Address = SocketAddr::V4(socket_v4).into();
498 assert!(matches!(addr, Address::IPv4(_)));
499
500 let socket_v6 = SocketAddrV6::new(Ipv6Addr::LOCALHOST, 8080, 0, 0);
501 let addr: Address = SocketAddr::V6(socket_v6).into();
502 assert!(matches!(addr, Address::IPv6(_)));
503 }
504
505 #[tokio::test]
506 async fn test_address_unspecified() {
507 let unspecified = Address::unspecified();
508 match unspecified {
509 Address::IPv4(addr) => {
510 assert_eq!(addr.ip(), &Ipv4Addr::UNSPECIFIED);
511 assert_eq!(addr.port(), 0);
512 }
513 _ => panic!("Unspecified address should be IPv4"),
514 }
515 }
516
517 #[tokio::test]
518 async fn test_address_from_socket_addr_ipv4() {
519 let socket = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080));
520 let address = Address::from(socket);
521
522 match address {
523 Address::IPv4(addr) => {
524 assert_eq!(addr.ip().octets(), [127, 0, 0, 1]);
525 assert_eq!(addr.port(), 8080);
526 }
527 _ => panic!("Should be IPv4 address"),
528 }
529 }
530
531 #[tokio::test]
532 async fn test_address_from_socket_addr_ipv6() {
533 let socket = SocketAddr::V6(SocketAddrV6::new(
534 Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
535 8080,
536 0,
537 0,
538 ));
539 let address = Address::from(socket);
540
541 match address {
542 Address::IPv6(addr) => {
543 assert_eq!(
544 addr.ip().octets(),
545 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
546 );
547 assert_eq!(addr.port(), 8080);
548 }
549 _ => panic!("Should be IPv6 address"),
550 }
551 }
552
553 #[tokio::test]
554 async fn test_address_to_bytes_ipv4() {
555 let addr = Address::IPv4(SocketAddrV4::new(Ipv4Addr::new(192, 168, 1, 1), 80));
556 let bytes = addr.to_bytes();
557
558 assert_eq!(bytes[0], Address::SOCKS5_ADDRESS_TYPE_IPV4);
559 assert_eq!(bytes[1..5], [192, 168, 1, 1]);
560 assert_eq!(bytes[5..7], [0, 80]); }
562
563 #[tokio::test]
564 async fn test_address_to_bytes_ipv6() {
565 let addr = Address::IPv6(SocketAddrV6::new(
566 Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1),
567 443,
568 0,
569 0,
570 ));
571 let bytes = addr.to_bytes();
572
573 assert_eq!(bytes[0], Address::SOCKS5_ADDRESS_TYPE_IPV6);
574 assert_eq!(
575 bytes[1..17],
576 [0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
577 );
578 assert_eq!(bytes[17..19], [1, 187]); }
580
581 #[tokio::test]
582 async fn test_address_to_bytes_domain() {
583 let domain = Domain(Bytes::from("example.com"));
584 let addr = Address::Domain(domain, 8080);
585 let bytes = addr.to_bytes();
586
587 assert_eq!(bytes[0], Address::SOCKS5_ADDRESS_TYPE_DOMAIN_NAME);
588 assert_eq!(bytes[1], 11); assert_eq!(&bytes[2..13], b"example.com");
590 assert_eq!(bytes[13..15], [31, 144]); }
592
593 #[tokio::test]
594 async fn test_address_from_bytes_ipv4() {
595 let mut buffer = BytesMut::new();
596 buffer.put_u8(Address::SOCKS5_ADDRESS_TYPE_IPV4);
597 buffer.put_slice(&[192, 168, 1, 1]); buffer.put_u16(80); let mut bytes = buffer.freeze();
601 let addr = Address::from_bytes(&mut bytes).unwrap();
602
603 match addr {
604 Address::IPv4(socket_addr) => {
605 assert_eq!(socket_addr.ip().octets(), [192, 168, 1, 1]);
606 assert_eq!(socket_addr.port(), 80);
607 }
608 _ => panic!("Should be IPv4 address"),
609 }
610 }
611
612 #[tokio::test]
613 async fn test_address_from_bytes_ipv6() {
614 let mut buffer = BytesMut::new();
615 buffer.put_u8(Address::SOCKS5_ADDRESS_TYPE_IPV6);
616 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();
620 let addr = Address::from_bytes(&mut bytes).unwrap();
621
622 match addr {
623 Address::IPv6(socket_addr) => {
624 assert_eq!(
625 socket_addr.ip().octets(),
626 [0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
627 );
628 assert_eq!(socket_addr.port(), 443);
629 }
630 _ => panic!("Should be IPv6 address"),
631 }
632 }
633
634 #[tokio::test]
635 async fn test_address_from_bytes_domain() {
636 let mut buffer = BytesMut::new();
637 buffer.put_u8(Address::SOCKS5_ADDRESS_TYPE_DOMAIN_NAME);
638 buffer.put_u8(11); buffer.put_slice(b"example.com"); buffer.put_u16(8080); let mut bytes = buffer.freeze();
643 let addr = Address::from_bytes(&mut bytes).unwrap();
644
645 match addr {
646 Address::Domain(domain, port) => {
647 assert_eq!(**domain.as_bytes(), *b"example.com");
648 assert_eq!(port, 8080);
649 }
650 _ => panic!("Should be domain address"),
651 }
652 }
653
654 #[tokio::test]
655 async fn test_address_from_async_read_ipv4() {
656 let mut buffer = BytesMut::new();
657 buffer.put_u8(Address::SOCKS5_ADDRESS_TYPE_IPV4);
658 buffer.put_slice(&[192, 168, 1, 1]); buffer.put_u16(80); let bytes = buffer.freeze();
662 let mut cursor = Cursor::new(bytes);
663 let mut reader = BufReader::new(&mut cursor);
664
665 let addr = Address::from_async_read(&mut reader).await.unwrap();
666
667 match addr {
668 Address::IPv4(socket_addr) => {
669 assert_eq!(socket_addr.ip().octets(), [192, 168, 1, 1]);
670 assert_eq!(socket_addr.port(), 80);
671 }
672 _ => panic!("Should be IPv4 address"),
673 }
674 }
675
676 #[tokio::test]
677 async fn test_address_from_async_read_ipv6() {
678 let mut buffer = BytesMut::new();
679 buffer.put_u8(Address::SOCKS5_ADDRESS_TYPE_IPV6);
680 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();
684 let mut cursor = Cursor::new(bytes);
685 let mut reader = BufReader::new(&mut cursor);
686
687 let addr = Address::from_async_read(&mut reader).await.unwrap();
688
689 match addr {
690 Address::IPv6(socket_addr) => {
691 assert_eq!(
692 socket_addr.ip().octets(),
693 [0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
694 );
695 assert_eq!(socket_addr.port(), 443);
696 }
697 _ => panic!("Should be IPv6 address"),
698 }
699 }
700
701 #[tokio::test]
702 async fn test_address_from_async_read_domain() {
703 let mut buffer = BytesMut::new();
704 buffer.put_u8(Address::SOCKS5_ADDRESS_TYPE_DOMAIN_NAME);
705 buffer.put_u8(11); buffer.put_slice(b"example.com"); buffer.put_u16(8080); let bytes = buffer.freeze();
710 let mut cursor = Cursor::new(bytes);
711 let mut reader = BufReader::new(&mut cursor);
712
713 let addr = Address::from_async_read(&mut reader).await.unwrap();
714
715 match addr {
716 Address::Domain(domain, port) => {
717 assert_eq!(**domain.as_bytes(), *b"example.com");
718 assert_eq!(port, 8080);
719 }
720 _ => panic!("Should be domain address"),
721 }
722 }
723
724 #[tokio::test]
725 async fn test_address_from_bytes_invalid_type() {
726 let mut buffer = BytesMut::new();
727 buffer.put_u8(0xFF); let mut bytes = buffer.freeze();
730 let result = Address::from_bytes(&mut bytes);
731
732 assert!(result.is_err());
733 }
734
735 #[tokio::test]
736 async fn test_address_from_bytes_insufficient_data() {
737 let mut buffer = BytesMut::new();
739 buffer.put_u8(Address::SOCKS5_ADDRESS_TYPE_IPV4);
740 buffer.put_slice(&[192, 168]); let mut bytes = buffer.freeze();
743 let result = Address::from_bytes(&mut bytes);
744
745 assert!(result.is_err());
746 }
747
748 #[tokio::test]
749 async fn test_address_port() {
750 let addr1 = Address::IPv4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080));
751 assert_eq!(addr1.port(), 8080);
752
753 let addr2 = Address::IPv6(SocketAddrV6::new(
754 Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
755 443,
756 0,
757 0,
758 ));
759 assert_eq!(addr2.port(), 443);
760
761 let addr3 = Address::Domain(Domain(Bytes::from("example.com")), 80);
762 assert_eq!(addr3.port(), 80);
763 }
764
765 #[tokio::test]
766 async fn test_address_format_as_string() {
767 let addr1 = Address::IPv4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080));
768 assert_eq!(addr1.to_string(), "127.0.0.1:8080");
769
770 let addr2 = Address::IPv6(SocketAddrV6::new(
771 Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
772 443,
773 0,
774 0,
775 ));
776 assert_eq!(addr2.to_string(), "[::1]:443");
777
778 let addr3 = Address::Domain(Domain(Bytes::from("example.com")), 80);
780 assert_eq!(addr3.to_string(), "example.com:80");
781 }
782}