diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a627ccf..9f95cb4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 8.4.0 (24 May 2024) + +- cares 1.29.0 + ## 8.3.0 (23 February 2024) - cares 1.27.0 diff --git a/Cargo.toml b/Cargo.toml index 6f3b4aa2..bb740e77 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "c-ares-resolver" license = "MIT" -version = "8.3.0" +version = "8.4.0" authors = ["David Hotham"] description = """ An asynchronous DNS resolver, backed by c-ares. @@ -21,8 +21,8 @@ include = [ ] [dependencies] -c-ares = { version = "9.0.0", default-features = false } -c-ares-sys = { version = "9.0.0", default-features = false } +c-ares = { version = "9.1.0", default-features = false } +c-ares-sys = { version = "9.2.0", default-features = false } futures-channel = "0.3.9" polling = "3.1.0" diff --git a/build.rs b/build.rs index e66e171f..2f52e609 100644 --- a/build.rs +++ b/build.rs @@ -33,5 +33,10 @@ fn main() { if version >= 0x1_17_00 { println!("cargo:rustc-cfg=cares1_23"); } + + println!("cargo::rustc-check-cfg=cfg(cares1_29)"); + if version >= 0x1_1d_00 { + println!("cargo:rustc-cfg=cares1_29"); + } } } diff --git a/src/blockingresolver.rs b/src/blockingresolver.rs index b6a1c0f1..c7db3085 100644 --- a/src/blockingresolver.rs +++ b/src/blockingresolver.rs @@ -4,6 +4,10 @@ use crate::error::Error; use crate::host::HostResults; use crate::nameinfo::NameInfoResult; use crate::resolver::{Options, Resolver}; + +#[cfg(cares1_29)] +use c_ares::ServerStateFlags; + use std::sync::mpsc; /// A blocking DNS resolver. @@ -81,6 +85,22 @@ impl BlockingResolver { Ok(self) } + /// Set a callback function to be invoked whenever a query on the channel completes. + /// + /// `callback(server, success, flags)` will be called when a query completes. + /// + /// - `server` indicates the DNS server that was used for the query. + /// - `success` indicates whether the query succeeded or not. + /// - `flags` is a bitmask of flags describing various aspects of the query. + #[cfg(cares1_29)] + pub fn set_server_state_callback(&self, callback: F) -> &Self + where + F: FnMut(&str, bool, ServerStateFlags) + Send + 'static, + { + self.inner.set_server_state_callback(callback); + self + } + /// Look up the A records associated with `name`. pub fn query_a(&self, name: &str) -> c_ares::Result { blockify!(self.inner, query_a, name) diff --git a/src/futureresolver.rs b/src/futureresolver.rs index a6e2eb0c..945cee8a 100644 --- a/src/futureresolver.rs +++ b/src/futureresolver.rs @@ -9,6 +9,9 @@ use crate::host::HostResults; use crate::nameinfo::NameInfoResult; use crate::resolver::{Options, Resolver}; +#[cfg(cares1_29)] +use c_ares::ServerStateFlags; + /// The type of future returned by methods on the `FutureResolver`. #[must_use] pub struct CAresFuture { @@ -127,6 +130,22 @@ impl FutureResolver { Ok(self) } + /// Set a callback function to be invoked whenever a query on the channel completes. + /// + /// `callback(server, success, flags)` will be called when a query completes. + /// + /// - `server` indicates the DNS server that was used for the query. + /// - `success` indicates whether the query succeeded or not. + /// - `flags` is a bitmask of flags describing various aspects of the query. + #[cfg(cares1_29)] + pub fn set_server_state_callback(&self, callback: F) -> &Self + where + F: FnMut(&str, bool, ServerStateFlags) + Send + 'static, + { + self.inner.set_server_state_callback(callback); + self + } + /// Look up the A records associated with `name`. pub fn query_a(&self, name: &str) -> CAresFuture { futurize!(self.inner, query_a, name) diff --git a/src/lib.rs b/src/lib.rs index 9a6dff28..577d4ec6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,22 +3,22 @@ //! This crate provides three resolver types - the `Resolver`, the `FutureResolver`, and the //! `BlockingResolver`: //! -//! * The `Resolver` is the thinnest wrapper around the underlying `c-ares` library. It returns -//! answers via callbacks. The other resolvers are built on top of this. +//! - The `Resolver` is the thinnest wrapper around the underlying `c-ares` library. It returns +//! answers via callbacks. The other resolvers are built on top of this. //! -//! * The `FutureResolver` returns answers as `std::future::Future`s. +//! - The `FutureResolver` returns answers as `std::future::Future`s. //! -//! * The `BlockingResolver` isn't asynchronous at all - as the name suggests, it blocks until the -//! lookup completes. +//! - The `BlockingResolver` isn't asynchronous at all - as the name suggests, it blocks until the +//! lookup completes. //! //! On all resolvers: //! -//! - methods like `query_xxx` correspond to the `c-ares` function `ares_query`, which "initiates -//! a single-question DNS query". +//! - methods like `query_xxx` correspond to the `c-ares` function `ares_query`, which "initiates +//! a single-question DNS query". //! -//! - methods like `search_xxx` correspond to the `c-ares` function `ares_search`, which -//! "initiates a series of single-question DNS queries ... using the channel's search domains as -//! well as a host alias file given by the HOSTALIAS environment variable". +//! - methods like `search_xxx` correspond to the `c-ares` function `ares_search`, which +//! "initiates a series of single-question DNS queries ... using the channel's search domains as +//! well as a host alias file given by the HOSTALIAS environment variable". //! //! See [`c-ares` documentation](https://c-ares.org/docs.html) for more details. //! diff --git a/src/resolver.rs b/src/resolver.rs index 44223b5e..02a0c9de 100644 --- a/src/resolver.rs +++ b/src/resolver.rs @@ -4,6 +4,9 @@ use std::sync::{Arc, Mutex}; use crate::error::Error; use crate::eventloop::{EventLoop, EventLoopStopper}; +#[cfg(cares1_29)] +use c_ares::{ServerFailoverOptions, ServerStateFlags}; + /// Used to configure the behaviour of the resolver. #[derive(Default)] pub struct Options { @@ -150,6 +153,26 @@ impl Options { self.inner.set_query_cache_max_ttl(qcache_max_ttl); self } + + /// Set server failover options. + /// + /// When a DNS server fails to respond to a query, c-ares will deprioritize the server. On + /// subsequent queries, servers with fewer consecutive failures will be selected in preference. + /// However, in order to detect when such a server has recovered, c-ares will occasionally + /// retry failed servers. [`cares::ServerFailoverOptions`] contains options to control this + /// behaviour. + /// + /// If this option is not specified then c-ares will use a retry chance of 10% and a minimum + /// delay of 5 seconds. + #[cfg(cares1_29)] + pub fn set_server_failover_options( + &mut self, + server_failover_options: &ServerFailoverOptions, + ) -> &mut Self { + self.inner + .set_server_failover_options(server_failover_options); + self + } } /// An asynchronous DNS resolver, which returns results via callbacks. @@ -229,6 +252,25 @@ impl Resolver { Ok(self) } + /// Set a callback function to be invoked whenever a query on the channel completes. + /// + /// `callback(server, success, flags)` will be called when a query completes. + /// + /// - `server` indicates the DNS server that was used for the query. + /// - `success` indicates whether the query succeeded or not. + /// - `flags` is a bitmask of flags describing various aspects of the query. + #[cfg(cares1_29)] + pub fn set_server_state_callback(&self, callback: F) -> &Self + where + F: FnMut(&str, bool, ServerStateFlags) + Send + 'static, + { + self.ares_channel + .lock() + .unwrap() + .set_server_state_callback(callback); + self + } + /// Look up the A records associated with `name`. /// /// On completion, `handler` is called with the result.