123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- use crate::socket::{PollAt, SocketHandle};
- use crate::time::{Duration, Instant};
- use crate::wire::IpAddress;
- /// Neighbor dependency.
- ///
- /// This enum tracks whether the socket should be polled based on the neighbor it is
- /// going to send packets to.
- #[derive(Debug)]
- #[cfg_attr(feature = "defmt", derive(defmt::Format))]
- enum NeighborState {
- /// Socket can be polled immediately.
- Active,
- /// Socket should not be polled until either `silent_until` passes or `neighbor` appears
- /// in the neighbor cache.
- Waiting {
- neighbor: IpAddress,
- silent_until: Instant,
- },
- }
- impl Default for NeighborState {
- fn default() -> Self {
- NeighborState::Active
- }
- }
- /// Network socket metadata.
- ///
- /// This includes things that only external (to the socket, that is) code
- /// is interested in, but which are more conveniently stored inside the socket itself.
- #[derive(Debug, Default)]
- #[cfg_attr(feature = "defmt", derive(defmt::Format))]
- pub struct Meta {
- /// Handle of this socket within its enclosing `SocketSet`.
- /// Mainly useful for debug output.
- pub(crate) handle: SocketHandle,
- /// See [NeighborState](struct.NeighborState.html).
- neighbor_state: NeighborState,
- }
- impl Meta {
- /// Minimum delay between neighbor discovery requests for this particular socket,
- /// in milliseconds.
- ///
- /// See also `iface::NeighborCache::SILENT_TIME`.
- pub(crate) const DISCOVERY_SILENT_TIME: Duration = Duration::from_millis(3_000);
- pub(crate) fn poll_at<F>(&self, socket_poll_at: PollAt, has_neighbor: F) -> PollAt
- where
- F: Fn(IpAddress) -> bool,
- {
- match self.neighbor_state {
- NeighborState::Active => socket_poll_at,
- NeighborState::Waiting { neighbor, .. } if has_neighbor(neighbor) => socket_poll_at,
- NeighborState::Waiting { silent_until, .. } => PollAt::Time(silent_until),
- }
- }
- pub(crate) fn egress_permitted<F>(&mut self, timestamp: Instant, has_neighbor: F) -> bool
- where
- F: Fn(IpAddress) -> bool,
- {
- match self.neighbor_state {
- NeighborState::Active => true,
- NeighborState::Waiting {
- neighbor,
- silent_until,
- } => {
- if has_neighbor(neighbor) {
- net_trace!(
- "{}: neighbor {} discovered, unsilencing",
- self.handle,
- neighbor
- );
- self.neighbor_state = NeighborState::Active;
- true
- } else if timestamp >= silent_until {
- net_trace!(
- "{}: neighbor {} silence timer expired, rediscovering",
- self.handle,
- neighbor
- );
- true
- } else {
- false
- }
- }
- }
- }
- pub(crate) fn neighbor_missing(&mut self, timestamp: Instant, neighbor: IpAddress) {
- net_trace!(
- "{}: neighbor {} missing, silencing until t+{}",
- self.handle,
- neighbor,
- Self::DISCOVERY_SILENT_TIME
- );
- self.neighbor_state = NeighborState::Waiting {
- neighbor,
- silent_until: timestamp + Self::DISCOVERY_SILENT_TIME,
- };
- }
- }
|