meta.rs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. use wire::IpAddress;
  2. use super::{SocketHandle, PollAt};
  3. use time::{Duration, Instant};
  4. /// Neighbor dependency.
  5. ///
  6. /// This enum tracks whether the socket should be polled based on the neighbor it is
  7. /// going to send packets to.
  8. #[derive(Debug)]
  9. enum NeighborState {
  10. /// Socket can be polled immediately.
  11. Active,
  12. /// Socket should not be polled until either `silent_until` passes or `neighbor` appears
  13. /// in the neighbor cache.
  14. Waiting {
  15. neighbor: IpAddress,
  16. silent_until: Instant,
  17. }
  18. }
  19. impl Default for NeighborState {
  20. fn default() -> Self {
  21. NeighborState::Active
  22. }
  23. }
  24. /// Network socket metadata.
  25. ///
  26. /// This includes things that only external (to the socket, that is) code
  27. /// is interested in, but which are more conveniently stored inside the socket itself.
  28. #[derive(Debug, Default)]
  29. pub struct Meta {
  30. /// Handle of this socket within its enclosing `SocketSet`.
  31. /// Mainly useful for debug output.
  32. pub(crate) handle: SocketHandle,
  33. /// See [NeighborState](struct.NeighborState.html).
  34. neighbor_state: NeighborState,
  35. }
  36. impl Meta {
  37. /// Minimum delay between neighbor discovery requests for this particular socket,
  38. /// in milliseconds.
  39. ///
  40. /// See also `iface::NeighborCache::SILENT_TIME`.
  41. pub(crate) const DISCOVERY_SILENT_TIME: Duration = Duration { millis: 3_000 };
  42. pub(crate) fn poll_at<F>(&self, socket_poll_at: PollAt, has_neighbor: F) -> PollAt
  43. where F: Fn(IpAddress) -> bool
  44. {
  45. match self.neighbor_state {
  46. NeighborState::Active =>
  47. socket_poll_at,
  48. NeighborState::Waiting { neighbor, .. }
  49. if has_neighbor(neighbor) =>
  50. socket_poll_at,
  51. NeighborState::Waiting { silent_until, .. } =>
  52. PollAt::Time(silent_until)
  53. }
  54. }
  55. pub(crate) fn egress_permitted<F>(&mut self, timestamp: Instant, has_neighbor: F) -> bool
  56. where F: Fn(IpAddress) -> bool
  57. {
  58. match self.neighbor_state {
  59. NeighborState::Active =>
  60. true,
  61. NeighborState::Waiting { neighbor, silent_until } => {
  62. if has_neighbor(neighbor) {
  63. net_trace!("{}: neighbor {} discovered, unsilencing",
  64. self.handle, neighbor);
  65. self.neighbor_state = NeighborState::Active;
  66. true
  67. } else if timestamp > silent_until {
  68. net_trace!("{}: neighbor {} silence timer expired, rediscovering", self.handle, neighbor);
  69. true
  70. } else {
  71. false
  72. }
  73. }
  74. }
  75. }
  76. pub(crate) fn neighbor_missing(&mut self, timestamp: Instant, neighbor: IpAddress) {
  77. net_trace!("{}: neighbor {} missing, silencing until t+{}",
  78. self.handle, neighbor, Self::DISCOVERY_SILENT_TIME);
  79. self.neighbor_state = NeighborState::Waiting {
  80. neighbor, silent_until: timestamp + Self::DISCOVERY_SILENT_TIME
  81. };
  82. }
  83. }