Skip to content

Commit 4fb5cfe

Browse files
authored
Merge pull request #831 from ryanfowler/fix/zig-res-query-link
fix: link glibc resolver symbol for zigbuild
2 parents 5072da5 + 36ad1a1 commit 4fb5cfe

2 files changed

Lines changed: 35 additions & 36 deletions

File tree

src/dns/svcb/system.rs

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,34 @@
1+
#[cfg(target_os = "macos")]
12
use std::ffi::CString;
3+
#[cfg(not(all(unix, not(target_os = "macos"))))]
24
use std::time::Duration;
35
#[cfg(target_os = "macos")]
46
use std::time::Instant;
57

8+
#[cfg(any(target_os = "macos", test))]
69
use crate::dns::wire;
710
use crate::duration::TimeoutBudget;
811
use crate::error::FetchError;
912

10-
use super::{SvcbRecord, parse_rdata};
13+
use super::SvcbRecord;
14+
#[cfg(any(target_os = "macos", windows, test))]
15+
use super::parse_rdata;
16+
17+
#[cfg(all(unix, not(target_os = "macos")))]
18+
pub(super) async fn lookup_https_records(
19+
host: &str,
20+
timeout: TimeoutBudget,
21+
) -> Result<Vec<SvcbRecord>, FetchError> {
22+
let Some(server_addr) = resolv_conf_nameserver() else {
23+
return Ok(Vec::new());
24+
};
25+
match super::lookup_udp_https_records(server_addr, host, timeout).await {
26+
Ok(records) => Ok(records),
27+
Err(_) => Ok(Vec::new()),
28+
}
29+
}
1130

31+
#[cfg(not(all(unix, not(target_os = "macos"))))]
1232
pub(super) async fn lookup_https_records(
1333
host: &str,
1434
timeout: TimeoutBudget,
@@ -200,40 +220,19 @@ fn poll_timeout_ms(deadline: Option<Instant>) -> Option<libc::c_int> {
200220
}
201221

202222
#[cfg(all(unix, not(target_os = "macos")))]
203-
fn lookup_https_records_blocking(
204-
host: &str,
205-
_timeout: Option<Duration>,
206-
) -> Result<Vec<SvcbRecord>, FetchError> {
207-
use std::os::raw::{c_char, c_int};
208-
209-
#[cfg_attr(all(target_os = "linux", target_env = "gnu"), link(name = "resolv"))]
210-
unsafe extern "C" {
211-
fn res_query(
212-
dname: *const c_char,
213-
class: c_int,
214-
typ: c_int,
215-
answer: *mut u8,
216-
anslen: c_int,
217-
) -> c_int;
218-
}
219-
220-
let host = CString::new(host)
221-
.map_err(|_| FetchError::Message("DNS host contains an interior NUL byte".to_string()))?;
222-
let mut response = vec![0_u8; u16::MAX as usize];
223-
let len = unsafe {
224-
res_query(
225-
host.as_ptr(),
226-
c_int::from(wire::CLASS_IN),
227-
c_int::from(wire::TYPE_HTTPS),
228-
response.as_mut_ptr(),
229-
response.len() as c_int,
230-
)
231-
};
232-
if len <= 0 {
233-
return Ok(Vec::new());
223+
fn resolv_conf_nameserver() -> Option<std::net::SocketAddr> {
224+
let resolv_conf = std::fs::read_to_string("/etc/resolv.conf").ok()?;
225+
for line in resolv_conf.lines() {
226+
let line = line.split('#').next().unwrap_or("").trim();
227+
let fields = line.split_whitespace().collect::<Vec<_>>();
228+
if fields.len() < 2 || fields[0] != "nameserver" {
229+
continue;
230+
}
231+
if let Ok(ip) = fields[1].parse::<std::net::IpAddr>() {
232+
return Some(std::net::SocketAddr::new(ip, 53));
233+
}
234234
}
235-
response.truncate(len as usize);
236-
records_from_wire_response(&response)
235+
None
237236
}
238237

239238
#[cfg(windows)]
@@ -409,7 +408,7 @@ fn lookup_https_records_blocking(
409408
Ok(Vec::new())
410409
}
411410

412-
#[cfg(any(all(unix, not(target_os = "macos")), test))]
411+
#[cfg(test)]
413412
fn records_from_wire_response(raw: &[u8]) -> Result<Vec<SvcbRecord>, FetchError> {
414413
let records =
415414
wire::parse_response_without_id(raw).map_err(|err| FetchError::Runtime(err.to_string()))?;

src/dns/wire.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub(crate) fn parse_response<'a>(
6666
parse_response_inner(raw, Some(expected_id))
6767
}
6868

69-
#[cfg(any(all(unix, not(target_os = "macos")), test))]
69+
#[cfg(test)]
7070
pub(crate) fn parse_response_without_id(raw: &[u8]) -> Result<Vec<ResourceRecord<'_>>, WireError> {
7171
parse_response_inner(raw, None)
7272
}

0 commit comments

Comments
 (0)