1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
use crate::behaviour::{ExpiredExternalAddr, FromSwarm, NewExternalAddr};
#[allow(deprecated)]
use crate::IntoConnectionHandler;
use libp2p_core::Multiaddr;
use std::collections::HashSet;

/// The maximum number of local external addresses. When reached any
/// further externally reported addresses are ignored. The behaviour always
/// tracks all its listen addresses.
const MAX_LOCAL_EXTERNAL_ADDRS: usize = 20;

/// Utility struct for tracking the external addresses of a [`Swarm`](crate::Swarm).
#[derive(Debug, Clone)]
pub struct ExternalAddresses {
    addresses: HashSet<Multiaddr>,
    limit: usize,
}

impl Default for ExternalAddresses {
    fn default() -> Self {
        Self {
            addresses: Default::default(),
            limit: MAX_LOCAL_EXTERNAL_ADDRS,
        }
    }
}

impl ExternalAddresses {
    /// Returns an [`Iterator`] over all external addresses.
    pub fn iter(&self) -> impl ExactSizeIterator<Item = &Multiaddr> {
        self.addresses.iter()
    }

    /// Feed a [`FromSwarm`] event to this struct.
    #[allow(deprecated)]
    pub fn on_swarm_event<THandler>(&mut self, event: &FromSwarm<THandler>)
    where
        THandler: IntoConnectionHandler,
    {
        match event {
            FromSwarm::NewExternalAddr(NewExternalAddr { addr, .. }) => {
                if self.addresses.len() < self.limit {
                    self.addresses.insert((*addr).clone());
                }
            }
            FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr, .. }) => {
                self.addresses.remove(addr);
            }
            _ => {}
        }
    }
}