pub fn update(&mut self, change: MetaAddrChange) -> Option<MetaAddr> {
        let previous = self.get(&change.addr());

        let _guard = self.span.enter();

        let instant_now = Instant::now();
        let chrono_now = Utc::now();

        let updated = change.apply_to_meta_addr(previous);

        trace!(
            ?change,
            ?updated,
            ?previous,
            total_peers = self.by_addr.len(),
            recent_peers = self.recently_live_peers(chrono_now).count(),
        );

        if let Some(updated) = updated {
            // Ignore invalid outbound addresses.
            // (Inbound connections can be monitored via Zebra's metrics.)
            if !updated.address_is_valid_for_outbound() {
                return None;
            }

            // Ignore invalid outbound services and other info,
            // but only if the peer has never been attempted.
            //
            // Otherwise, if we got the info directly from the peer,
            // store it in the address book, so we know not to reconnect.
            //
            // TODO: delete peers with invalid info when they get too old (#1873)
            if !updated.last_known_info_is_valid_for_outbound()
                && updated.last_connection_state.is_never_attempted()
            {
                return None;
            }

            self.by_addr.insert(updated.addr, updated);

            // Security: Limit the number of peers in the address book.
            //
            // We only delete outdated peers when we have too many peers.
            // If we deleted them as soon as they became too old,
            // then other peers could re-insert them into the address book.
            // And we would start connecting to those outdated peers again,
            // ignoring the age limit in [`MetaAddr::is_probably_reachable`].
            while self.by_addr.len() > self.addr_limit {
                let surplus_peer = self
                    .peers()
                    .next_back()
                    .expect("just checked there is at least one peer");

                self.by_addr.remove(&surplus_peer.addr);
            }

            assert!(self.len() <= self.addr_limit);

            std::mem::drop(_guard);
            self.update_metrics(instant_now, chrono_now);
        }

        updated
    }
/// Apply `change` to the address book, returning the updated `MetaAddr`,
/// if the change was valid.
///
/// # Correctness
///
/// All changes should go through `update`, so that the address book
/// only contains valid outbound addresses.
///
/// Change addresses must be canonical `SocketAddr`s. This makes sure that
/// each address book entry has a unique IP address.
///
/// # Security
///
/// This function must apply every attempted, responded, and failed change
/// to the address book. This prevents rapid reconnections to the same peer.
///
/// As an exception, this function can ignore all changes for specific
/// [`SocketAddr`]s. Ignored addresses will never be used to connect to
/// peers.
Apply `change` to the address book, returning the updated `MetaAddr`,
if the change was valid.
Apply ` change ` to the address book returning the updated ` MetaAddr ` if the change was valid .
pub fn update(&mut self, change: MetaAddrChange) -> Option<MetaAddr> {
        let previous = self.get(&change.addr());
        let _guard = self.span.enter();
        let instant_now = Instant::now();
        let chrono_now = Utc::now();
        let updated = change.apply_to_meta_addr(previous);
        trace!(
            ?change,
            ?updated,
            ?previous,
            total_peers = self.by_addr.len(),
            recent_peers = self.recently_live_peers(chrono_now).count(),
        );
        if let Some(updated) = updated {
            // Ignore invalid outbound addresses.
            // (Inbound connections can be monitored via Zebra's metrics.)
            if !updated.address_is_valid_for_outbound() {
                return None;
            }
            // Ignore invalid outbound services and other info,
            // but only if the peer has never been attempted.
            //
            // Otherwise, if we got the info directly from the peer,
            // store it in the address book, so we know not to reconnect.
            //
            // TODO: delete peers with invalid info when they get too old (#1873)
            if !updated.last_known_info_is_valid_for_outbound()
                && updated.last_connection_state.is_never_attempted()
            {
                return None;
            }
            self.by_addr.insert(updated.addr, updated);
            // Security: Limit the number of peers in the address book.
            //
            // We only delete outdated peers when we have too many peers.
            // If we deleted them as soon as they became too old,
            // then other peers could re-insert them into the address book.
            // And we would start connecting to those outdated peers again,
            // ignoring the age limit in [`MetaAddr::is_probably_reachable`].
            while self.by_addr.len() > self.addr_limit {
                let surplus_peer = self
                    .peers()
                    .next_back()
                    .expect("just checked there is at least one peer");
                self.by_addr.remove(&surplus_peer.addr);
            }
            assert!(self.len() <= self.addr_limit);
            std::mem::drop(_guard);
            self.update_metrics(instant_now, chrono_now);
        }
        updated
    }
pub fn update ( & mut self , change : MetaAddrChange ) -> Option < MetaAddr > { let previous = self . get ( & change . addr ( ) ) ; let _guard = self . span . enter ( ) ; let instant_now = Instant :: now ( ) ; let chrono_now = Utc :: now ( ) ; let updated = change . apply_to_meta_addr ( previous ) ; trace ! ( change updated previous total_peers self by_addr len ( ) recent_peers self recently_live_peers ( chrono_now ) count ( ) ) ; if let Some ( updated ) = updated { // Ignore invalid outbound addresses. // (Inbound connections can be monitored via Zebra's metrics.) if ! updated . address_is_valid_for_outbound ( ) { return None ; } // Ignore invalid outbound services and other info, // but only if the peer has never been attempted. // // Otherwise, if we got the info directly from the peer, // store it in the address book, so we know not to reconnect. // // TODO: delete peers with invalid info when they get too old (#1873) if ! updated . last_known_info_is_valid_for_outbound ( ) && updated . last_connection_state . is_never_attempted ( ) { return None ; } self . by_addr . insert ( updated . addr , updated ) ; // Security: Limit the number of peers in the address book. // // We only delete outdated peers when we have too many peers. // If we deleted them as soon as they became too old, // then other peers could re-insert them into the address book. // And we would start connecting to those outdated peers again, // ignoring the age limit in [`MetaAddr::is_probably_reachable`]. while self . by_addr . len ( ) > self . addr_limit { let surplus_peer = self . peers ( ) . next_back ( ) . expect ( " " ) ; self . by_addr . remove ( & surplus_peer . addr ) ; } assert ! ( self len ( ) self addr_limit ) ; std :: mem :: drop ( _guard ) ; self . update_metrics ( instant_now , chrono_now ) ; } updated }
Apply `change` to the address book, returning the updated `MetaAddr`,
if the change was valid.
Apply ` change ` to the address book returning the updated ` MetaAddr ` if the change was valid .
&mut self
change
MetaAddrChange
correctness
All changes should go through `update`, so that the address book
only contains valid outbound addresses.

Change addresses must be canonical `SocketAddr`s. This makes sure that
each address book entry has a unique IP address.
All changes should go through ` update ` so that the address book only contains valid outbound addresses . Change addresses must be canonical ` SocketAddr ` s . This makes sure that each address book entry has a unique IP address .
security
This function must apply every attempted, responded, and failed change
to the address book. This prevents rapid reconnections to the same peer.

As an exception, this function can ignore all changes for specific
[`SocketAddr`]s. Ignored addresses will never be used to connect to
peers.
This function must apply every attempted responded and failed change to the address book . This prevents rapid reconnections to the same peer . As an exception this function can ignore all changes for specific [ ` SocketAddr ` ] s . Ignored addresses will never be used to connect to peers .