java.lang.Object
net.i2p.util.Clock
net.i2p.router.RouterClock
All Implemented Interfaces:
Timestamper.UpdateListener

public class RouterClockextends Clock
Alternate location for determining the time which takes into account an offset. This offset will ideally be periodically updated so as to serve as the difference between the local computer's current time and the time as known by some reference (such as an NTP synchronized clock).

RouterClock is a subclass of Clock with access to router transports. Configuration permitting, it will block clock offset changes which would increase peer clock skew.

  • Field Details

    • MAX_SLEW

      private static final long MAX_SLEW
      How often we will slew the clock i.e. ppm = 1000000/MAX_SLEW We should be able to slew really fast, this is probably a lot faster than what NTP does 1/50 is 12s in a 10m tunnel lifetime, that should be fine. All of this is @since 0.7.12.
      See Also:
    • DEFAULT_STRATUM

      public static final int DEFAULT_STRATUM
      NTP stratum assumed before any external time source is known.
      See Also:
    • WORST_STRATUM

      private static final int WORST_STRATUM
      Worst NTP stratum accepted.
      See Also:
    • MIN_DELAY_FOR_WORSE_STRATUM

      private static final long MIN_DELAY_FOR_WORSE_STRATUM
      The max NTP Timestamper delay is 30m right now, make this longer than that.
      See Also:
    • _desiredOffset

      private volatile long _desiredOffset
      The clock offset being sought.
    • _lastSlewed

      private volatile long _lastSlewed
      When the clock was last slewed.
    • _lastChanged

      private long _lastChanged
      Use system time for this.
    • _lastStratum

      private int _lastStratum
      The stratum of the last proposal.
    • _lastProposedOffset

      private long _lastProposedOffset
      The offset of the last proposal.
    • _timeStamper

      private final RouterTimestamper _timeStamper
      The timestamper making the proposals.
    • MASSIVE_SHIFT_FORWARD

      private static final long MASSIVE_SHIFT_FORWARD
      If the system clock shifts by this much, call the callback, we probably need a soft restart.
      See Also:
    • MASSIVE_SHIFT_BACKWARD

      private static final long MASSIVE_SHIFT_BACKWARD
      Backward shift that counts as massive.
      See Also:
    • PROP_DISABLE_ADJUSTMENT

      private static final String PROP_DISABLE_ADJUSTMENT
      Testing only - disables clock adjustment when set.
      See Also:
    • _shiftListeners

      private final Set<RouterClock.ClockShiftListener> _shiftListeners
      The listeners for clock shifts.
    • _lastShiftNanos

      private volatile long _lastShiftNanos
      When the clock was last shifted.
  • Constructor Details

    • RouterClock

      public RouterClock(RouterContext context)
      Does not start. Caller MUST call start().
      Parameters:
      context - the router context used to create the timestamper and to resolve clock settings
  • Method Details

    • start

      public void start()
      Start the router clock and its associated timestamper. The timestamper will begin synchronizing with NTP or peer time sources.
    • getTimestamper

      public Timestamper getTimestamper()
      The timestamper used for time synchronization.
      Overrides:
      getTimestamper in class Clock
      Returns:
      the RouterTimestamper instance
    • setOffset

      public void setOffset(long offsetMs, boolean force)
      Specify how far away from the "correct" time the computer is - a positive value means that the system time is slow, while a negative value means the system time is fast.
      Overrides:
      setOffset in class Clock
      Parameters:
      offsetMs - the delta from System.currentTimeMillis() (NOT the delta from now())
      force - if true, bypass all sanity checks
    • setOffset

      private void setOffset(long offsetMs, int stratum)
      The offset with the given stratum.
      Parameters:
      offsetMs - the delta from System.currentTimeMillis() (NOT the delta from now())
      stratum - the stratum of the time source
    • setOffset

      private void setOffset(long offsetMs, boolean force, int stratum)
      The offset, optionally forcing the change.
      Parameters:
      offsetMs - the delta from System.currentTimeMillis() (NOT the delta from now())
      force - whether to bypass sanity checks
      stratum - the stratum of the time source
    • setNow

      public void setNow(long realTime, int stratum)
      The current time, used by the timestamper when synchronizing.
      Specified by:
      setNow in interface Timestamper.UpdateListener
      Overrides:
      setNow in class Clock
      Parameters:
      realTime - the current time from the time source
      stratum - the stratum level
    • now

      public long now()
      Retrieve the current time synchronized with whatever reference clock is in use. Do really simple clock slewing, like NTP but without jitter prevention. Slew the clock toward the desired offset, but only up to a maximum slew rate, and never let the clock go backwards because of slewing.

      Take care to only access the volatile variables once for speed and to avoid having another thread change them

      This is called about a zillion times a second, so we can do the slewing right here rather than in some separate thread to keep it simple. Avoiding backwards clocks when updating in a thread would be hard too.

      Overrides:
      now in class Clock
      Returns:
      the current synchronized time in milliseconds
    • notifyMassive

      private void notifyMassive(long shift)
      Notifies the listeners of a massive shift.
      Parameters:
      shift - the size of the shift, in milliseconds
    • addShiftListener

      public void addShiftListener(RouterClock.ClockShiftListener lsnr)
      Add a listener to be notified of massive system clock shifts. These are shifts of one minute or more.
      Parameters:
      lsnr - the listener to add
    • removeShiftListener

      public void removeShiftListener(RouterClock.ClockShiftListener lsnr)
      Remove a clock shift listener.
      Parameters:
      lsnr - the listener to remove