Skip to content

Commit 97dfca1

Browse files
i have no way of testing this
1 parent 2d6b7c1 commit 97dfca1

8 files changed

Lines changed: 380 additions & 22 deletions

File tree

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ doctest = true
1616

1717
[dependencies]
1818

19+
[target.'cfg(unix)'.dependencies]
20+
libc = "0.2"
1921

2022
[target.'cfg(windows)'.dependencies]
2123
windows-sys = { version = "0.61.2", features = [

src/dns/os/macos.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
extern crate alloc;
2+
use crate::error::DnsError;
3+
use crate::util::IpAddr;
4+
use alloc::vec::Vec;
5+
6+
/// macOS DNS stub - not yet implemented
7+
pub fn resolve_host(_host: &str) -> Result<Vec<IpAddr>, DnsError> {
8+
Err(DnsError::Unsupported)
9+
}

src/dns/os/mod.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1-
#[cfg(unix)]
1+
#[cfg(target_os = "macos")]
2+
pub mod macos;
3+
4+
#[cfg(all(unix, not(target_os = "macos")))]
25
pub mod unix;
36

47
#[cfg(windows)]
58
pub mod windows;
69

7-
#[cfg(unix)]
10+
#[cfg(target_os = "macos")]
11+
pub use macos::resolve_host;
12+
13+
#[cfg(all(unix, not(target_os = "macos")))]
814
pub use unix::resolve_host;
915

1016
#[cfg(windows)]

src/dns/os/unix.rs

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,64 @@ extern crate alloc;
22
use crate::error::DnsError;
33
use crate::util::IpAddr;
44
use 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
}

src/socket/os/mac.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use crate::error::SocketError;
2+
use crate::socket::{SocketAddr, SocketFlags};
3+
4+
/// macOS socket stub - not yet implemented
5+
pub struct OsSocket {
6+
_placeholder: (),
7+
}
8+
9+
impl OsSocket {
10+
pub fn new() -> Result<Self, SocketError> {
11+
Err(SocketError::Unsupported)
12+
}
13+
14+
pub fn connect(&mut self, _addr: &SocketAddr) -> Result<(), SocketError> {
15+
Err(SocketError::Unsupported)
16+
}
17+
18+
pub fn read(&mut self, _buf: &mut [u8]) -> Result<usize, SocketError> {
19+
Err(SocketError::Unsupported)
20+
}
21+
22+
pub fn write(&mut self, _buf: &[u8]) -> Result<usize, SocketError> {
23+
Err(SocketError::Unsupported)
24+
}
25+
26+
pub fn shutdown(&mut self) -> Result<(), SocketError> {
27+
Err(SocketError::Unsupported)
28+
}
29+
30+
pub fn set_flags(&mut self, _flags: SocketFlags) -> Result<(), SocketError> {
31+
Err(SocketError::Unsupported)
32+
}
33+
34+
pub fn set_read_timeout(&mut self, _timeout_ms: u32) -> Result<(), SocketError> {
35+
Err(SocketError::Unsupported)
36+
}
37+
38+
pub fn set_write_timeout(&mut self, _timeout_ms: u32) -> Result<(), SocketError> {
39+
Err(SocketError::Unsupported)
40+
}
41+
}

src/socket/os/mod.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1-
#[cfg(unix)]
1+
#[cfg(target_os = "macos")]
2+
pub mod macos;
3+
4+
#[cfg(all(unix, not(target_os = "macos")))]
25
pub mod unix;
36

47
#[cfg(windows)]
58
pub mod windows;
69

7-
#[cfg(unix)]
10+
#[cfg(target_os = "macos")]
11+
pub use macos::OsSocket;
12+
13+
#[cfg(all(unix, not(target_os = "macos")))]
814
pub use unix::OsSocket;
915

1016
#[cfg(windows)]

0 commit comments

Comments
 (0)