java.lang.Object
net.i2p.router.JobImpl
net.i2p.router.networkdb.kademlia.StoreJob
All Implemented Interfaces:
Job
Direct Known Subclasses:
FloodfillStoreJob

abstract class StoreJobextends JobImpl
Abstract base class for network database store operations.

Handles the process of storing database entries (RouterInfo or LeaseSet) to floodfill peers with configurable parallelization, redundancy, and timeout handling. Supports both direct and tunnel-based delivery with garlic encryption for client data.

All store operations through this class request a reply to confirm successful delivery. Unused directly - see FloodfillStoreJob for the concrete implementation.

  • Field Details

    • _log

      protected final Log _log
      Logger for this class.
    • _facade

      private final KademliaNetworkDatabaseFacade _facade
      Reference to the network database facade.
    • _state

      protected final StoreState _state
      Current state of the store operation.
    • _onSuccess

      private final Job _onSuccess
      Job to run on successful store.
    • _onFailure

      private final Job _onFailure
      Job to run on failed store.
    • _timeoutMs

      private final long _timeoutMs
      Timeout in milliseconds for the store operation.
    • _expiration

      private final long _expiration
      Expiration time for the store operation.
    • _peerSelector

      private final PeerSelector _peerSelector
      Peer selector for choosing floodfill participants.
    • _connectChecker

      private final ConnectChecker _connectChecker
      Checks if we can connect to a peer directly.
    • _connectMask

      private final int _connectMask
      Bitmask for connection types we can use (IPv4, IPv6, etc.).
    • PARALLELIZATION

      private static final int PARALLELIZATION
      Lookups sent at a time.
      See Also:
    • REDUNDANCY

      private static final int REDUNDANCY
      Peers the data should end up stored on.
      See Also:
    • STORE_PRIORITY

      private static final int STORE_PRIORITY
      Priority of this router's own netdb store.
      See Also:
    • MAX_PEERS_SENT

      private static final int MAX_PEERS_SENT
      Most peers one store job sends to in total.
      See Also:
    • RESEND_DELAY

      private static final int RESEND_DELAY
      Pause before the next batch of sends: 1 second.
      See Also:
    • MAX_DIRECT_EXPIRATION

      private static final int MAX_DIRECT_EXPIRATION
      Limit expiration for direct sends.
      See Also:
    • MIN_STORE_VERSION

      public static final String MIN_STORE_VERSION
      Short ECIES tunnel build messages (1.5.0).
      See Also:
    • MIN_STORE_LS2_VERSION

      public static final String MIN_STORE_LS2_VERSION
      Minimum version for LS2 stores.
      See Also:
    • MIN_STORE_ENCLS2_VERSION

      public static final String MIN_STORE_ENCLS2_VERSION
      Was supported in 38, but they're now sigtype 11 which wasn't added until 39.
      See Also:
  • Constructor Details

    • StoreJob

      public StoreJob(RouterContext context, KademliaNetworkDatabaseFacade facade, Hash key, DatabaseEntry data, Job onSuccess, Job onFailure, long timeoutMs)
      Send a data structure to the floodfills.
      Parameters:
      context - the router context
      facade - the network database facade
      key - the hash the data is to be stored under
      data - the data to store
      onSuccess - job to run on success
      onFailure - job to run on failure
      timeoutMs - timeout in milliseconds
    • StoreJob

      public StoreJob(RouterContext context, KademliaNetworkDatabaseFacade facade, Hash key, DatabaseEntry data, Job onSuccess, Job onFailure, long timeoutMs, Set<Hash> toSkip)
      Send a data structure to the floodfills, skipping certain peers.
      Parameters:
      context - the router context
      facade - the network database facade
      key - the hash the data is to be stored under
      data - the data to store
      onSuccess - job to run on success
      onFailure - job to run on failure
      timeoutMs - timeout in milliseconds
      toSkip - set of peer hashes of people we don't want to send the data to (e.g. we already know they have it). This can be null.
  • Method Details

    • getName

      public String getName()
      Name of this job for logging and debugging.
      Returns:
      job name
    • runJob

      public void runJob()
      Execute the job to start sending to the next batch of peers.
    • isExpired

      private boolean isExpired()
      Check if the store operation has expired.
      Returns:
      true if the operation has timed out
    • sendNext

      private void sendNext()
      Send the key to the next batch of peers.

      Synchronized to enforce parallelization limits and prevent dups.

    • getParallelization

      protected int getParallelization()
      Maximum number of parallel store operations. Note: Overridden in Floodfill Search Job.
      Returns:
      number of messages to send simultaneously
    • getRedundancy

      protected int getRedundancy()
      Required redundancy level for successful store. Note: Overridden in Floodfill Search Job.
      Returns:
      number of peers that must receive the data
    • continueSending

      private void continueSending()
      Send a series of searches to the next available peers as selected by the routing table, but making sure no more than PARALLELIZATION are outstanding at any time

      Caller should synchronize to enforce parallelization limits and prevent dups.

    • getClosestFloodfillRouters

      private List<Hash> getClosestFloodfillRouters(Hash key, int numClosest, Set<Hash> alreadyChecked)
      Find the closest floodfill routers to a given key.
      Parameters:
      key - the target hash to find routers near
      numClosest - how many routers to return
      alreadyChecked - set of router hashes to skip
      Returns:
      list of closest floodfill router hashes, empty if there are no KBuckets
    • sendStore

      private void sendStore(RouterInfo router, int responseTime)
      Send a store message directly to a peer.
      Parameters:
      router - the floodfill to send the store message to
      responseTime - timeout for the response in milliseconds
    • sendStore

      private void sendStore(DatabaseStoreMessage msg, RouterInfo peer, long expiration)
      Send a store message to a peer via the appropriate delivery method.
      Parameters:
      msg - the database store message to send
      peer - the router to send to
      expiration - when the message expires
    • sendDirect

      private void sendDirect(DatabaseStoreMessage msg, RouterInfo peer, long expiration)
      Send a store message directly to a peer with direct reply.
      Parameters:
      msg - the database store message to send
      peer - the router to send to
      expiration - when the message expires
    • sendStoreThroughExploratory

      private void sendStoreThroughExploratory(DatabaseStoreMessage msg, RouterInfo peer, long expiration)
      Send it out through an exploratory tunnel, with the reply to come back through an exploratory tunnel. There is no garlic encryption added.
      Parameters:
      msg - the store message to send
      peer - the remote peer to store at
      expiration - when the message expires
    • sendStoreThroughClient

      private void sendStoreThroughClient(DatabaseStoreMessage msg, RouterInfo peer, long expiration)
      Send a leaseset store message out the client tunnel, with the reply to come back through a client tunnel. Stores are garlic encrypted to hide the identity from the OBEP.

      This makes it harder for an exploratory OBEP or IBGW to correlate it with one or more destinations. Since we are publishing the leaseset, it's easy to find out that an IB tunnel belongs to this dest, and it isn't much harder to do the same for an OB tunnel.

      As a side benefit, client tunnels should be faster and more reliable than exploratory tunnels.

      Parameters:
      msg - must contain a leaseset
      peer - the remote peer to store at
      expiration - when the message expires
    • pickReplyTunnel

      private Lease pickReplyTunnel(LeaseSet ls, int attempts, Hash to)
      Pick a reply tunnel from a LeaseSet for the store response.
      Parameters:
      ls - the LeaseSet containing available tunnels
      attempts - number of previous attempts made
      to - the target hash for closest selection
      Returns:
      the selected lease
      Throws:
      IllegalStateException - if no leases are available
    • sendWrappedStoreThroughExploratory

      private void sendWrappedStoreThroughExploratory(DatabaseStoreMessage msg, RouterInfo peer, long expiration)
      Send a leaseset store message out an exploratory tunnel, with the reply to come back through a exploratory tunnel. Stores are garlic encrypted to hide the identity from the OBEP.

      Only for Meta LS2, for now.

      Parameters:
      msg - must contain a leaseset
      peer - the remote peer to store at
      expiration - when the message expires
    • shouldStoreTo

      static boolean shouldStoreTo(RouterInfo ri)
      Is it new enough?
      Parameters:
      ri - the router info to check
      Returns:
      true if the router is new enough
    • shouldStoreLS2To

      static boolean shouldStoreLS2To(RouterInfo ri)
      Is it new enough?
      Parameters:
      ri - the router info to check
      Returns:
      true if the router supports LS2
    • shouldStoreEncLS2To

      static boolean shouldStoreEncLS2To(RouterInfo ri)
      Is it new enough?
      Parameters:
      ri - the router info to check
      Returns:
      true if the router supports encrypted LS2
    • succeed

      protected void succeed()
      Handle successful completion of the store operation.

      Called when the required redundancy level is reached.

    • fail

      protected void fail()
      Handle failed completion of the store operation.

      Called when the store operation has exhausted all options.