Skip to content

Commit

Permalink
wip c-ares main
Browse files Browse the repository at this point in the history
  • Loading branch information
dimbleby committed Sep 18, 2024
1 parent 7a37414 commit de50c17
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 6 deletions.
5 changes: 5 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,10 @@ fn main() {
if version >= 0x1_1e_00 {
println!("cargo:rustc-cfg=cares1_30");
}

println!("cargo::rustc-check-cfg=cfg(cares1_34)");
if version >= 0x1_22_00 {
println!("cargo:rustc-cfg=cares1_34");
}
}
}
2 changes: 1 addition & 1 deletion c-ares-sys/c-ares
Submodule c-ares updated 194 files
8 changes: 4 additions & 4 deletions c-ares-sys/ffi.patch
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
--- src/ffi.rs.orig 2024-08-24 13:21:17.273016107 +0100
+++ src/ffi.rs 2024-08-24 13:21:59.213021947 +0100
--- src/ffi.rs.orig 2024-09-07 12:21:29.220612634 +0100
+++ src/ffi.rs 2024-09-07 12:21:29.230612692 +0100
@@ -1,13 +1,24 @@
/* automatically generated by rust-bindgen 0.70.1 */
+#![allow(non_camel_case_types, non_snake_case)]
Expand Down Expand Up @@ -51,15 +51,15 @@
pub server_failover_opts: ares_server_failover_options,
}
#[repr(C)]
@@ -1518,6 +1536,7 @@
@@ -1567,6 +1585,7 @@
pub struct ares_addrinfo {
pub cnames: *mut ares_addrinfo_cname,
pub nodes: *mut ares_addrinfo_node,
+ #[cfg(cares1_18)]
pub name: *mut ::std::os::raw::c_char,
}
#[repr(C)]
@@ -1728,3 +1747,17 @@
@@ -1777,3 +1796,17 @@
#[doc = " Retrieve the total number of active queries pending answers from servers.\n Some c-ares requests may spawn multiple queries, such as ares_getaddrinfo()\n when using AF_UNSPEC, which will be reflected in this number.\n\n \\param[in] channel Initialized ares channel\n \\return Number of active queries to servers"]
pub fn ares_queue_active_queries(channel: *const ares_channel_t) -> usize;
}
Expand Down
49 changes: 49 additions & 0 deletions c-ares-sys/src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 +1086,8 @@ pub type ares_server_state_callback = ::std::option::Option<
data: *mut ::std::os::raw::c_void,
),
>;
pub type ares_pending_write_cb =
::std::option::Option<unsafe extern "C" fn(data: *mut ::std::os::raw::c_void)>;
extern "C" {
pub fn ares_library_init(flags: ::std::os::raw::c_int) -> ::std::os::raw::c_int;
}
Expand Down Expand Up @@ -1184,6 +1186,16 @@ extern "C" {
user_data: *mut ::std::os::raw::c_void,
);
}
extern "C" {
pub fn ares_set_pending_write_cb(
channel: *mut ares_channel_t,
callback: ares_pending_write_cb,
user_data: *mut ::std::os::raw::c_void,
);
}
extern "C" {
pub fn ares_process_pending_write(channel: *mut ares_channel_t);
}
extern "C" {
pub fn ares_set_sortlist(
channel: *mut ares_channel_t,
Expand Down Expand Up @@ -1380,6 +1392,43 @@ extern "C" {
write_fds: *mut fd_set,
);
}
#[repr(u32)]
#[doc = " Events used by ares_fd_events_t"]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum ares_fd_eventflag_t {
#[doc = "< No events"]
ARES_FD_EVENT_NONE = 0,
#[doc = "< Read event (including disconnect/error)"]
ARES_FD_EVENT_READ = 1,
#[doc = "< Write event"]
ARES_FD_EVENT_WRITE = 2,
}
#[doc = " Type holding a file descriptor and mask of events, used by\n ares_process_fds()"]
#[repr(C)]
pub struct ares_fd_events_t {
#[doc = "< File descriptor"]
pub fd: ares_socket_t,
#[doc = "< Mask of ares_fd_eventflag_t"]
pub events: ::std::os::raw::c_uint,
}
#[repr(u32)]
#[doc = " Flags used by ares_process_fds()"]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum ares_process_flag_t {
#[doc = "< No flag value"]
ARES_PROCESS_FLAG_NONE = 0,
#[doc = "< skip any processing unrelated to\n the file descriptor events passed\n in"]
ARES_PROCESS_FLAG_SKIP_NON_FD = 1,
}
extern "C" {
#[doc = " Process events on multiple file descriptors based on the event mask\n associated with each file descriptor. Recommended over calling\n ares_process_fd() multiple times since it would trigger additional logic\n such as timeout processing on each call.\n\n \\param[in] channel Initialized ares channel\n \\param[in] events Array of file descriptors with events. May be NULL if\n no events, but may have timeouts to process.\n \\param[in] nevents Number of elements in the events array. May be 0 if\n no events, but may have timeouts to process.\n \\param[in] flags Flags to alter behavior of the process command.\n \\return ARES_ENOMEM on out of memory, ARES_EFORMERR on misuse,\n otherwise ARES_SUCCESS"]
pub fn ares_process_fds(
channel: *mut ares_channel_t,
events: *const ares_fd_events_t,
nevents: usize,
flags: ::std::os::raw::c_uint,
) -> ares_status_t;
}
extern "C" {
pub fn ares_process_fd(
channel: *mut ares_channel_t,
Expand Down
77 changes: 76 additions & 1 deletion src/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use crate::aaaa::{query_aaaa_callback, AAAAResults};
use crate::caa::{query_caa_callback, CAAResults};
use crate::cname::{query_cname_callback, CNameResults};
use crate::error::{Error, Result};
#[cfg(cares1_34)]
use crate::events::{FdEvents, ProcessFlags};
use crate::host::{get_host_callback, HostResults};
use crate::mx::{query_mx_callback, MXResults};
use crate::nameinfo::{get_name_info_callback, NameInfoResult};
Expand Down Expand Up @@ -47,6 +49,9 @@ type SocketStateCallback = dyn FnMut(Socket, bool, bool) + Send + 'static;
#[cfg(cares1_29)]
type ServerStateCallback = dyn FnMut(&str, bool, ServerStateFlags) + Send + 'static;

#[cfg(cares1_34)]
type PendingWriteCallback = dyn FnMut() + Send + 'static;

/// Server failover options.
///
/// When a DNS server fails to respond to a query, c-ares will deprioritize the server. On
Expand Down Expand Up @@ -328,6 +333,10 @@ pub struct Channel {
// For ownership only.
#[cfg(cares1_29)]
_server_state_callback: Option<Arc<ServerStateCallback>>,

// For ownership only.
#[cfg(cares1_34)]
_pending_write_callback: Option<Arc<PendingWriteCallback>>,
}

impl Channel {
Expand Down Expand Up @@ -387,6 +396,8 @@ impl Channel {
_socket_state_callback: options.socket_state_callback,
#[cfg(cares1_29)]
_server_state_callback: None,
#[cfg(cares1_34)]
_pending_write_callback: None,
};
Ok(channel)
}
Expand Down Expand Up @@ -416,12 +427,17 @@ impl Channel {
#[cfg(cares1_29)]
let server_state_callback = self._server_state_callback.as_ref().cloned();

#[cfg(cares1_34)]
let pending_write_callback = self._pending_write_callback.as_ref().cloned();

let channel = Channel {
ares_channel,
phantom: PhantomData,
_socket_state_callback: socket_state_callback,
#[cfg(cares1_29)]
_server_state_callback: server_state_callback,
#[cfg(cares1_34)]
_pending_write_callback: pending_write_callback,
};
Ok(channel)
}
Expand All @@ -444,6 +460,27 @@ impl Channel {
panic::propagate();
}

/// Process events on multiple file descriptors based on the event mask associated with each
/// file descriptor. Recommended over calling `process_fd()` multiple times since it would
/// trigger additional logic such as timeout processing on each call.
#[cfg(cares1_34)]
pub fn process_fds(&mut self, events: &[FdEvents], flags: ProcessFlags) -> Result<()> {
let rc = unsafe {
c_ares_sys::ares_process_fds(
self.ares_channel,
events.as_ptr().cast(),
events.len(),
flags.bits(),
)
};
panic::propagate();

if let Ok(err) = Error::try_from(rc) {
return Err(err);
}
return Ok(())
}

/// Retrieve the set of socket descriptors which the calling application should wait on for
/// reading and / or writing.
pub fn get_sock(&self) -> GetSock {
Expand Down Expand Up @@ -554,6 +591,26 @@ impl Channel {
self
}

/// Set a callback function to be invoked when there is potential pending data
/// which needs to be written.
#[cfg(cares1_34)]
pub fn set_pending_write_callback<F>(&mut self, callback: F) -> &mut Self
where
F: FnMut() + Send + 'static,
{
let boxed_callback = Arc::new(callback);
let data = ptr::from_ref(&*boxed_callback).cast_mut().cast();
unsafe {
c_ares_sys::ares_set_pending_write_cb(
self.ares_channel,
Some(pending_write_callback::<F>),
data,
)
}
self._pending_write_callback = Some(boxed_callback);
self
}

/// Initiate a single-question DNS query for the A records associated with `name`.
///
/// On completion, `handler` is called with the result.
Expand Down Expand Up @@ -1122,6 +1179,13 @@ impl Channel {
unsafe { c_ares_sys::ares_cancel(self.ares_channel) }
panic::propagate();
}

/// Kick c-ares to process a pending write.
#[cfg(cares1_34)]
pub fn process_pending_write(&mut self) {
unsafe { c_ares_sys::ares_process_pending_write(self.ares_channel) }
panic::propagate();
}
}

impl Drop for Channel {
Expand Down Expand Up @@ -1162,16 +1226,27 @@ unsafe extern "C" fn server_state_callback<F>(
F: FnMut(&str, bool, ServerStateFlags) + Send + 'static,
{
let handler = data.cast::<F>();
let handler = unsafe { &mut *handler };
let server = c_string_as_str_unchecked(server_string);
panic::catch(|| {
(*handler)(
handler(
server,
success != c_ares_sys::ares_bool_t::ARES_FALSE,
ServerStateFlags::from_bits_truncate(flags),
)
});
}

#[cfg(cares1_34)]
unsafe extern "C" fn pending_write_callback<F>(data: *mut c_void)
where
F: FnMut() + Send + 'static,
{
let handler = data.cast::<F>();
let handler = unsafe { &mut *handler };
panic::catch(|| handler());
}

/// Information about the set of sockets that `c-ares` is interested in, as returned by
/// `get_sock()`.
#[derive(Clone, Copy, Debug)]
Expand Down
37 changes: 37 additions & 0 deletions src/events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use crate::types::Socket;
use bitflags::bitflags;

bitflags!(
/// Events used by FdEvents.
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
pub struct FdEventFlags: u32 {
/// Read event (including disconnect/error).
const Read = c_ares_sys::ares_fd_eventflag_t::ARES_FD_EVENT_READ as u32;
/// Write event.
const Write = c_ares_sys::ares_fd_eventflag_t::ARES_FD_EVENT_WRITE as u32;
}
);

bitflags!(
/// Flags used by [`crate::Channel::process_fds()`].
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
pub struct ProcessFlags: u32 {
/// Skip any processing unrelated to the file descriptor events passed in.
const SkipNonFd = c_ares_sys::ares_process_flag_t::ARES_PROCESS_FLAG_SKIP_NON_FD as u32;
}
);

/// Type holding a file descriptor and mask of events, used by [`crate::Channel::process_fds()`].
#[repr(transparent)]
pub struct FdEvents(c_ares_sys::ares_fd_events_t);

impl FdEvents {
/// Returns a new `FdEvents`.
pub fn new(socket: Socket, events: FdEventFlags) -> Self {
let events = c_ares_sys::ares_fd_events_t {
fd: socket,
events: events.bits(),
};
FdEvents(events)
}
}
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ mod caa;
mod channel;
mod cname;
mod error;
#[cfg(cares1_34)]
mod events;
mod flags;
mod host;
mod hostent;
Expand Down Expand Up @@ -77,6 +79,8 @@ pub use crate::channel::ServerFailoverOptions;
pub use crate::channel::{Channel, GetSock, GetSockIter, Options};
pub use crate::cname::CNameResults;
pub use crate::error::{Error, Result};
#[cfg(cares1_34)]
pub use crate::events::{FdEventFlags, FdEvents, ProcessFlags};
pub use crate::flags::Flags;
pub use crate::host::HostResults;
pub use crate::hostent::{HostAddressResultsIter, HostAliasResultsIter};
Expand Down

0 comments on commit de50c17

Please sign in to comment.