mdns: update if-watch to 3.0.0 (#3096)

This commit is contained in:
João Oliveira
2022-11-18 01:12:23 +00:00
committed by GitHub
parent 7803524a76
commit 08510dd523
12 changed files with 173 additions and 111 deletions

View File

@@ -24,9 +24,9 @@ mod timer;
use self::iface::InterfaceState;
use crate::behaviour::{socket::AsyncSocket, timer::Builder};
use crate::MdnsConfig;
use crate::Config;
use futures::Stream;
use if_watch::{IfEvent, IfWatcher};
use if_watch::IfEvent;
use libp2p_core::{Multiaddr, PeerId};
use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm};
use libp2p_swarm::{
@@ -36,32 +36,80 @@ use smallvec::SmallVec;
use std::collections::hash_map::{Entry, HashMap};
use std::{cmp, fmt, io, net::IpAddr, pin::Pin, task::Context, task::Poll, time::Instant};
/// An abstraction to allow for compatibility with various async runtimes.
pub trait Provider: 'static {
/// The Async Socket type.
type Socket: AsyncSocket;
/// The Async Timer type.
type Timer: Builder + Stream;
/// The IfWatcher type.
type Watcher: Stream<Item = std::io::Result<IfEvent>> + fmt::Debug + Unpin;
/// Create a new instance of the `IfWatcher` type.
fn new_watcher() -> Result<Self::Watcher, std::io::Error>;
}
/// The type of a [`Behaviour`] using the `async-io` implementation.
#[cfg(feature = "async-io")]
use crate::behaviour::{socket::asio::AsyncUdpSocket, timer::asio::AsyncTimer};
pub mod async_io {
use super::Provider;
use crate::behaviour::{socket::asio::AsyncUdpSocket, timer::asio::AsyncTimer};
use if_watch::smol::IfWatcher;
/// The type of a [`GenMdns`] using the `async-io` implementation.
#[cfg(feature = "async-io")]
pub type Mdns = GenMdns<AsyncUdpSocket, AsyncTimer>;
#[doc(hidden)]
pub enum AsyncIo {}
impl Provider for AsyncIo {
type Socket = AsyncUdpSocket;
type Timer = AsyncTimer;
type Watcher = IfWatcher;
fn new_watcher() -> Result<Self::Watcher, std::io::Error> {
IfWatcher::new()
}
}
pub type Behaviour = super::Behaviour<AsyncIo>;
}
/// The type of a [`Behaviour`] using the `tokio` implementation.
#[cfg(feature = "tokio")]
use crate::behaviour::{socket::tokio::TokioUdpSocket, timer::tokio::TokioTimer};
pub mod tokio {
use super::Provider;
use crate::behaviour::{socket::tokio::TokioUdpSocket, timer::tokio::TokioTimer};
use if_watch::tokio::IfWatcher;
/// The type of a [`GenMdns`] using the `tokio` implementation.
#[cfg(feature = "tokio")]
pub type TokioMdns = GenMdns<TokioUdpSocket, TokioTimer>;
#[doc(hidden)]
pub enum Tokio {}
impl Provider for Tokio {
type Socket = TokioUdpSocket;
type Timer = TokioTimer;
type Watcher = IfWatcher;
fn new_watcher() -> Result<Self::Watcher, std::io::Error> {
IfWatcher::new()
}
}
pub type Behaviour = super::Behaviour<Tokio>;
}
/// A `NetworkBehaviour` for mDNS. Automatically discovers peers on the local network and adds
/// them to the topology.
#[derive(Debug)]
pub struct GenMdns<S, T> {
pub struct Behaviour<P>
where
P: Provider,
{
/// InterfaceState config.
config: MdnsConfig,
config: Config,
/// Iface watcher.
if_watch: IfWatcher,
if_watch: P::Watcher,
/// Mdns interface states.
iface_states: HashMap<IpAddr, InterfaceState<S, T>>,
iface_states: HashMap<IpAddr, InterfaceState<P::Socket, P::Timer>>,
/// List of nodes that we have discovered, the address, and when their TTL expires.
///
@@ -72,19 +120,18 @@ pub struct GenMdns<S, T> {
/// Future that fires when the TTL of at least one node in `discovered_nodes` expires.
///
/// `None` if `discovered_nodes` is empty.
closest_expiration: Option<T>,
closest_expiration: Option<P::Timer>,
}
impl<S, T> GenMdns<S, T>
impl<P> Behaviour<P>
where
T: Builder,
P: Provider,
{
/// Builds a new `Mdns` behaviour.
pub fn new(config: MdnsConfig) -> io::Result<Self> {
let if_watch = if_watch::IfWatcher::new()?;
pub fn new(config: Config) -> io::Result<Self> {
Ok(Self {
config,
if_watch,
if_watch: P::new_watcher()?,
iface_states: Default::default(),
discovered_nodes: Default::default(),
closest_expiration: Default::default(),
@@ -109,17 +156,16 @@ where
*expires = now;
}
}
self.closest_expiration = Some(T::at(now));
self.closest_expiration = Some(P::Timer::at(now));
}
}
impl<S, T> NetworkBehaviour for GenMdns<S, T>
impl<P> NetworkBehaviour for Behaviour<P>
where
T: Builder + Stream,
S: AsyncSocket,
P: Provider,
{
type ConnectionHandler = dummy::ConnectionHandler;
type OutEvent = MdnsEvent;
type OutEvent = Event;
fn new_handler(&mut self) -> Self::ConnectionHandler {
dummy::ConnectionHandler
@@ -226,7 +272,7 @@ where
}
}
if !discovered.is_empty() {
let event = MdnsEvent::Discovered(DiscoveredAddrsIter {
let event = Event::Discovered(DiscoveredAddrsIter {
inner: discovered.into_iter(),
});
return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event));
@@ -245,13 +291,13 @@ where
true
});
if !expired.is_empty() {
let event = MdnsEvent::Expired(ExpiredAddrsIter {
let event = Event::Expired(ExpiredAddrsIter {
inner: expired.into_iter(),
});
return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event));
}
if let Some(closest_expiration) = closest_expiration {
let mut timer = T::at(closest_expiration);
let mut timer = P::Timer::at(closest_expiration);
let _ = Pin::new(&mut timer).poll_next(cx);
self.closest_expiration = Some(timer);
@@ -262,7 +308,7 @@ where
/// Event that can be produced by the `Mdns` behaviour.
#[derive(Debug)]
pub enum MdnsEvent {
pub enum Event {
/// Discovered nodes through mDNS.
Discovered(DiscoveredAddrsIter),

View File

@@ -24,7 +24,7 @@ mod query;
use self::dns::{build_query, build_query_response, build_service_discovery_response};
use self::query::MdnsPacket;
use crate::behaviour::{socket::AsyncSocket, timer::Builder};
use crate::MdnsConfig;
use crate::Config;
use libp2p_core::{Multiaddr, PeerId};
use libp2p_swarm::PollParameters;
use socket2::{Domain, Socket, Type};
@@ -74,7 +74,7 @@ where
T: Builder + futures::Stream,
{
/// Builds a new [`InterfaceState`].
pub fn new(addr: IpAddr, config: MdnsConfig) -> io::Result<Self> {
pub fn new(addr: IpAddr, config: Config) -> io::Result<Self> {
log::info!("creating instance on iface {}", addr);
let recv_socket = match addr {
IpAddr::V4(addr) => {

View File

@@ -38,14 +38,33 @@
use std::net::{Ipv4Addr, Ipv6Addr};
use std::time::Duration;
#[deprecated(
since = "0.42.0",
note = "Use re-exports that omit `Mdns` prefix, i.e. `libp2p::mdns::Config`"
)]
pub type MdnsConfig = Config;
#[deprecated(
since = "0.42.0",
note = "Use re-exports that omit `Mdns` prefix, i.e. `libp2p::mdns::Event`"
)]
pub type MdnsEvent = Event;
#[deprecated(
since = "0.42.0",
note = "Use the async-io prefixed `Mdns`, i.e. `libp2p::mdns::async_io::Mdns`"
)]
#[cfg(feature = "async-io")]
pub type Mdns = async_io::Behaviour;
mod behaviour;
pub use crate::behaviour::{GenMdns, MdnsEvent};
pub use crate::behaviour::{Behaviour, Event};
#[cfg(feature = "async-io")]
pub use crate::behaviour::Mdns;
pub use crate::behaviour::async_io;
#[cfg(feature = "tokio")]
pub use crate::behaviour::TokioMdns;
pub use crate::behaviour::tokio;
/// The DNS service name for all libp2p peers used to query for addresses.
const SERVICE_NAME: &[u8] = b"_p2p._udp.local";
@@ -61,7 +80,7 @@ pub const IPV6_MDNS_MULTICAST_ADDRESS: Ipv6Addr = Ipv6Addr::new(0xFF02, 0, 0, 0,
/// Configuration for mDNS.
#[derive(Debug, Clone)]
pub struct MdnsConfig {
pub struct Config {
/// TTL to use for mdns records.
pub ttl: Duration,
/// Interval at which to poll the network for new peers. This isn't
@@ -74,7 +93,7 @@ pub struct MdnsConfig {
pub enable_ipv6: bool,
}
impl Default for MdnsConfig {
impl Default for Config {
fn default() -> Self {
Self {
ttl: Duration::from_secs(6 * 60),