java.lang.Object
net.i2p.client.impl.HandlerImpl
net.i2p.client.impl.RequestLeaseSetMessageHandler
All Implemented Interfaces:
I2CPMessageHandler
Direct Known Subclasses:
RequestVariableLeaseSetMessageHandler

class RequestLeaseSetMessageHandlerextends HandlerImpl
Handle I2CP RequestLeaseSetMessage from the router by granting all leases, using the specified expiration time for each lease.
  • Field Details

    • _existingLeaseSets

      private final Map<Destination, RequestLeaseSetMessageHandler.LeaseInfo> _existingLeaseSets
      The lease sets already published, by destination.
    • _ls2Type

      protected volatile int _ls2Type
      _ls2Type.
    • PROP_LS_ENCRYPT

      private static final String PROP_LS_ENCRYPT
      Config key enabling lease set encryption.
      See Also:
    • PROP_LS_KEY

      private static final String PROP_LS_KEY
      Config key of the lease set encryption key.
      See Also:
    • PROP_LS_PK

      private static final String PROP_LS_PK
      Config key of the lease set private key.
      See Also:
    • PROP_LS_SPK

      private static final String PROP_LS_SPK
      Config key of the lease set signing key.
      See Also:
    • PROP_LS_TYPE

      public static final String PROP_LS_TYPE
      PROP_LS_TYPE — used for LS2.
      See Also:
    • PROP_LS_ENCTYPE

      private static final String PROP_LS_ENCTYPE
      Config key of the lease set encryption type.
      See Also:
    • PROP_SECRET

      private static final String PROP_SECRET
      Config key of the destination's secret code.
      See Also:
    • PROP_AUTH_TYPE

      private static final String PROP_AUTH_TYPE
      Config key of the destination's auth type.
      See Also:
    • PROP_PRIV_KEY

      private static final String PROP_PRIV_KEY
      Config key of the destination's private key.
      See Also:
    • PROP_DH

      private static final String PROP_DH
      Config key of the client's DH crypto settings.
      See Also:
    • PROP_PSK

      private static final String PROP_PSK
      Config key of the client's pre shared key.
      See Also:
    • PREFER_NEW_ENC

      private static final boolean PREFER_NEW_ENC
      True to prefer the new style lease set encryption.
      See Also:
    • MIN_LS2_LEASE_TTL_MS

      static final long MIN_LS2_LEASE_TTL_MS
      Minimum remaining lifetime required on a lease end relative to the LS2 published timestamp so LeaseSet2.writeHeader() does not reject the set with "LeaseSet expired".
      See Also:
    • MAX_TRANSIENT_SIGN_RETRIES

      static final int MAX_TRANSIENT_SIGN_RETRIES
      Maximum prompt re-runs of a request after a transient signing failure. Each re-run rebuilds the set with fresh timestamps, so a clock-skewed or stale request heals within seconds instead of waiting out the router's 60-second check timeout.
      See Also:
    • TRANSIENT_SIGN_RETRY_DELAY_MS

      static final long TRANSIENT_SIGN_RETRY_DELAY_MS
      Delay before a transient signing failure is re-run, in ms.
      See Also:
  • Constructor Details

    • RequestLeaseSetMessageHandler

      public RequestLeaseSetMessageHandler(I2PAppContext context)
      Registers the handler for the standard request-lease-set message type.
      Parameters:
      context - the client context the handler runs in, passed to the superclass for logging and session lookup
    • RequestLeaseSetMessageHandler

      protected RequestLeaseSetMessageHandler(I2PAppContext context, int messageType)
      For extension.
      Parameters:
      context - the client context the handler runs in, passed to the superclass for logging and session lookup
      messageType - the I2CP message type to register for, so subclasses can claim a different request message
  • Method Details

    • requiresLS2

      protected boolean requiresLS2(I2PSessionImpl session)
      Do we send a LeaseSet or a LeaseSet2? As of 0.9.69, always use LS2 unless the router doesn't support it

      Side effect: sets _ls2Type.

      Parameters:
      session - the session whose LeaseSet2 preference is consulted, and which is torn down when that preference cannot be parsed
      Returns:
      true if LS2 should be used
    • handleMessage

      public void handleMessage(I2CPMessage message, I2PSessionImpl session)
      Handle an incoming I2CP message.
      Parameters:
      message - the inbound I2CP request naming the destination whose LeaseSet should be published
      session - the session that sent the request and that the resulting LeaseSet is published for
    • handleMessage

      protected void handleMessage(I2CPMessage message, I2PSessionImpl session, int attempt)
      Handle an incoming I2CP message, tracking how many prompt re-runs a transient signing failure has already scheduled for this request.
      Parameters:
      message - the request from the router
      session - the session the request is for
      attempt - number of transient sign retries already performed
    • ensurePositiveLs2Expiry

      static long ensurePositiveLs2Expiry(long leaseEnd, long published, long now)
      Floor a requested lease end so it remains strictly after both the LS2 published timestamp (second resolution) and the current time, leaving at least MIN_LS2_LEASE_TTL_MS of validity. Without this, a stale or skewed end time makes LeaseSet2.writeHeader() throw "LeaseSet expired", and a floor measured only from a stale published stamp would hand out an already-expired set when the clock has moved on by sign time.
      Parameters:
      leaseEnd - absolute lease end from the router request
      published - LS2 published timestamp, or 0 for LS1 / unset
      now - current time when the floor is computed; the later of published and now sets the margin, so delay between publishing and signing does not shrink it
      Returns:
      leaseEnd if already safely after both instants, else max(published, now) + 1s
    • isSignable

      static boolean isSignable(LeaseSet leaseSet)
      Whether a LeaseSet can be signed. An empty set leaves LeaseSet2._expires at 0 and always fails writeHeader, except for a pre-decryption EncryptedLeaseSet: its leases are only visible after decryption, so an ELS2 with a non-zero expiry is signable even though getLeaseCount() reports 0.
      Parameters:
      leaseSet - candidate set, may be null
      Returns:
      true if the set can be signed
    • validateLeaseSetRequest

      static String validateLeaseSetRequest(int endpoints, Date endDate)
      Validate a fixed-length LeaseSet request before any state is mutated. An empty request leaves LeaseSet2._expires at 0 and writeHeader would throw "LeaseSet expired"; more than LeaseSet.MAX_LEASES endpoints overflow addLease()'s cap and throw mid-build; a missing end date (0 on the wire) would NPE at msg.getEndDate().getTime(). One clear error keeps the publish floor and clock untouched on every reject.
      Parameters:
      endpoints - number of endpoints in the request
      endDate - requested end date, null when absent on the wire
      Returns:
      the error to propagate, or null if the request is valid
    • validateEndpointCount

      static String validateEndpointCount(int endpoints)
      Validate an endpoint count for the variable-length handler. The same empty and over-capacity rules apply, but the variable message carries no end date to check.
      Parameters:
      endpoints - number of endpoints in the request
      Returns:
      the error to propagate, or null if the count is valid
    • signLeaseSet

      protected boolean signLeaseSet(LeaseSet leaseSet, boolean isLS2, I2PSessionImpl session)
      Finish creating and signing the new LeaseSet and submitting it to the router. Reuses cached private keys when available, generates new keys otherwise, and handles offline signatures. Failures during signing are propagated to the session; transient expiry errors do not destroy the session so the router can retry with a fresh lease end time.
      Parameters:
      leaseSet - the unsigned LeaseSet with leases already added
      isLS2 - true for LS2, false for LS1
      session - the I2CP session requesting the LeaseSet
      Returns:
      true if the LeaseSet was signed and handed to the session, false if it was rejected or signing failed; callers use this to advance the monotonic publish floor only on success
    • signLeaseSet

      protected boolean signLeaseSet(LeaseSet leaseSet, boolean isLS2, I2PSessionImpl session, I2CPMessage message, int attempt)
      Finish creating and signing the new LeaseSet and submitting it to the router, with the originating request attached so a transient signing failure can schedule a prompt re-run instead of leaving the router to wait out its 60-second check timeout.
      Parameters:
      leaseSet - the unsigned LeaseSet with leases already added
      isLS2 - true for LS2, false for LS1
      session - the I2CP session requesting the LeaseSet
      message - the request that produced this set, or null when the caller cannot supply it (no transient retry is scheduled then)
      attempt - number of prompt re-runs already performed for this request
      Returns:
      true if the LeaseSet was signed and handed to the session, false if it was rejected or signing failed
    • isTransientSignFailure

      static boolean isTransientSignFailure(String reason)
      Is a signing failure transient — a stale or clock-skewed request the caller can fix with fresh data — rather than a permanent key or configuration error?
      Parameters:
      reason - the DataFormatException message, or null
      Returns:
      true for expiry and empty-request rejections that a prompt re-run of the request can resolve
    • scheduleSignRetry

      void scheduleSignRetry(I2CPMessage message, I2PSessionImpl session, int attempt)
      Schedule a prompt re-run of a request whose signing failed transiently. Without this, no CreateLeaseSet is sent and the router waits out its 60-second CheckLeaseRequestStatus before retrying. The re-run rebuilds the set against the current clock, so a skewed published stamp or stale lease end is corrected on the next attempt; attempts are bounded and the router's check timeout remains the fallback once they are exhausted.
      Parameters:
      message - the request to re-run
      session - the session the request is for
      attempt - the attempt number just completed (0 for the first)
    • removeLeaseSet

      public void removeLeaseSet(Destination dest)
      Remove the cached lease info for the given destination. Called on session destroy to prevent unbounded map growth and timely release of private key material.
      Parameters:
      dest - the destination whose cached lease info and private keys are to be dropped
    • keyPrefix

      private static String keyPrefix(String b64)
      First 6 chars of a base64 key string, for logging without leaking key material.
      Parameters:
      b64 - the base64-encoded key string
      Returns:
      its first 6 chars, or the whole string if shorter
    • parsePrivateKeys

      private void parsePrivateKeys(String spkl, List<PrivateKey> privKeys, List<EncType> allowedTypes)
      Non-null [type:]b64[,[type:]b64]...
      Parameters:
      spkl - non-null [type:]b64[,[type:]b64]...
      privKeys - the list the parsed keys are appended to; entries that fail to parse are logged and skipped
      allowedTypes - list of allowed encryption types