@@ -2,7 +2,64 @@ extern crate alloc;
22use crate :: error:: DnsError ;
33use crate :: util:: IpAddr ;
44use alloc:: vec:: Vec ;
5+ use core:: ptr;
6+ use libc:: { addrinfo, sockaddr_in, AF_INET , AF_INET6 } ;
57
6- pub fn resolve_host ( _host : & str ) -> Result < Vec < IpAddr > , DnsError > {
7- Err ( DnsError :: Unsupported )
8+ pub fn resolve_host ( host : & str ) -> Result < Vec < IpAddr > , DnsError > {
9+ let mut host_cstring = Vec :: with_capacity ( host. len ( ) + 1 ) ;
10+ host_cstring. extend_from_slice ( host. as_bytes ( ) ) ;
11+ host_cstring. push ( 0 ) ;
12+
13+ let hints = addrinfo {
14+ ai_family : 0 ,
15+ ai_socktype : 0 ,
16+ ai_protocol : 0 ,
17+ ai_flags : 0 ,
18+ ai_addrlen : 0 ,
19+ ai_canonname : ptr:: null_mut ( ) ,
20+ ai_addr : ptr:: null_mut ( ) ,
21+ ai_next : ptr:: null_mut ( ) ,
22+ } ;
23+
24+ let mut result: * mut addrinfo = ptr:: null_mut ( ) ;
25+
26+ let ret = unsafe {
27+ libc:: getaddrinfo (
28+ host_cstring. as_ptr ( ) as * const i8 ,
29+ ptr:: null ( ) ,
30+ & raw const hints,
31+ & raw mut result,
32+ )
33+ } ;
34+
35+ if ret != 0 {
36+ return Err ( DnsError :: ResolutionFailed ( ret) ) ;
37+ }
38+
39+ let mut addresses = Vec :: new ( ) ;
40+ let mut current = result;
41+
42+ unsafe {
43+ while !current. is_null ( ) {
44+ let info = & * current;
45+
46+ if info. ai_family == AF_INET && !info. ai_addr . is_null ( ) {
47+ let sockaddr = ptr:: read_unaligned ( info. ai_addr . cast :: < sockaddr_in > ( ) ) ;
48+ let addr_bytes = sockaddr. sin_addr . s_addr . to_ne_bytes ( ) ;
49+ addresses. push ( IpAddr :: V4 ( addr_bytes) ) ;
50+ } else if info. ai_family == AF_INET6 && !info. ai_addr . is_null ( ) {
51+ // IPv6 support can be added here if needed
52+ }
53+
54+ current = info. ai_next ;
55+ }
56+
57+ libc:: freeaddrinfo ( result) ;
58+ }
59+
60+ if addresses. is_empty ( ) {
61+ return Err ( DnsError :: NoAddressesFound ) ;
62+ }
63+
64+ Ok ( addresses)
865}
0 commit comments