meta.rs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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, 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, .. } => {
  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 {
  68. false
  69. }
  70. }
  71. }
  72. }
  73. pub(crate) fn neighbor_missing(&mut self, timestamp: Instant, neighbor: IpAddress) {
  74. net_trace!("{}: neighbor {} missing, silencing until t+{}",
  75. self.handle, neighbor, Self::DISCOVERY_SILENT_TIME);
  76. self.neighbor_state = NeighborState::Waiting {
  77. neighbor, silent_until: timestamp + Self::DISCOVERY_SILENT_TIME
  78. };
  79. }
  80. }