java.lang.Object
net.i2p.router.networkdb.kademlia.PeerSelector
net.i2p.router.networkdb.kademlia.FloodfillPeerSelector

public class FloodfillPeerSelectorextends PeerSelector
This is where we implement semi-Kademlia with the floodfills, by selecting floodfills closest to a given key for searches and stores.

Warning - most methods taking a key as an argument require the routing key, not the original key.

  • Constructor Details

    • FloodfillPeerSelector

      public FloodfillPeerSelector(RouterContext ctx, KademliaNetworkDatabaseFacade facade)
      Binds the facade and prepares the ban logger.
      Parameters:
      ctx - the router context
      facade - the network database to select peers from
  • Method Details

    • selectNearestExplicit

      List<Hash> selectNearestExplicit(Hash key, int maxNumRouters, Set<Hash> peersToIgnore, KBucketSet<Hash> kbuckets)
      Pick out peers with the floodfill capacity set, returning them first, but then after they're complete, sort via kademlia.

      Walks the kbuckets with a FloodfillSelectionCollector, which gathers floodfill peers in groups (good floodfills first, then bad, then non-floodfills sorted by Kademlia distance to the key).

      Does not prefer the floodfill peers that are directly connected. List will not include our own hash. Returns new list, may be modified.

      Specified by:
      selectNearestExplicit in class PeerSelector
      Parameters:
      key - the ROUTING key (NOT the original key)
      maxNumRouters - the most hashes to return, zero or less meaning no limit
      peersToIgnore - can be null
      kbuckets - the routing table to select from
      Returns:
      List of Hash for the peers selected
    • selectFloodfillParticipants

      List<Hash> selectFloodfillParticipants(KBucketSet<Hash> kbuckets)
      List will not include our own hash. List is not sorted and not shuffled. Returns new list, may be modified.
      Parameters:
      kbuckets - unused, retained for signature compatibility; null is accepted
      Returns:
      all floodfills not banlisted forever.
    • selectFloodfillParticipants

      List<Hash> selectFloodfillParticipants(Set<Hash> toIgnore, KBucketSet<Hash> _kbuckets)
      List MAY INCLUDE our own hash. List is not sorted and not shuffled. Returns new list, may be modified.
      Parameters:
      toIgnore - can be null
      _kbuckets - unused, retained for signature compatibility; null is accepted
      Returns:
      all floodfills not banlisted forever and not flagged unreachable.
    • selectFloodfillParticipants

      List<Hash> selectFloodfillParticipants(Hash key, int maxNumRouters, KBucketSet<Hash> kbuckets)
      Sort the floodfills. The challenge here is to keep the good ones at the front and the bad ones at the back. If they are all good or bad, searches and stores won't work well.

      List will not include our own hash. Returns new list, may be modified. Sorted by closest to the key if > maxNumRouters, otherwise not. The list is in 3 groups - sorted by routing key within each group. Group 1: No store or lookup failure in a long time, and lookup fail rate no more than 1.5 * average Group 2: No store or lookup failure in a little while or success newer than failure Group 3: All others.

      Parameters:
      key - the ROUTING key (NOT the original key)
      maxNumRouters - max to return
      kbuckets - unused, retained for signature compatibility; null is accepted
      Returns:
      floodfills closest to the key that are not banlisted forever
    • selectFloodfillParticipants

      List<Hash> selectFloodfillParticipants(Hash key, int howMany, Set<Hash> toIgnore, KBucketSet<Hash> kbuckets)
      See above for description List will not include our own hash Returns new list, may be modified.
      Parameters:
      key - the ROUTING key (NOT the original key)
      howMany - the maximum number of peers to return
      toIgnore - can be null
      kbuckets - unused, retained for signature compatibility; null is accepted
      Returns:
      the selected peers, ordered best first, never null
    • maskedIPKey

      static long maskedIPKey(byte[] ip, int mask)
      Compact long fingerprint of a masked IP, replacing the per-candidate String construction (one StringBuilder plus up to 2*mask heap chars) that the historic MaskedIPSet.maskedIP() did per address on the selection hot path. Semantics match MaskedIPSet: the first mask bytes are matched, and an IPv6 address doubles the match width (8 bytes for mask=2, i.e. /64).

      Bit layout: bit 63 is an IPv6 marker (the analog of MaskedIPSet's ':' vs '.' delimiter, so the two families can never collide); the masked bytes' nibbles then occupy bits 59 downward. The largest supported packed key is 15 nibbles (60 bits) below the marker, i.e. IPv4 mask 4 or IPv6 mask 3.

      Parameters:
      ip - an IPv4 (4-byte) or IPv6 (16-byte) address
      mask - 1-4, the number of leading bytes to match
      Returns:
      the packed fingerprint; equal keys mean "same masked subnet"
      Throws:
      IllegalArgumentException - if the packed key would exceed 60 bits (IPv6 with mask 4), which no caller uses
    • addSameIPFingerprint

      static boolean addSameIPFingerprint(Set<Long> maskedIPs, Set<Integer> ports, Set<String> families, RouterContext ctx, Hash peer, RouterInfo pinfo, int mask)
      Fingerprint a candidate peer into the exclusion accumulators, adding compact masked-IP keys, ports, and the claimed family option. One call replaces the per-candidate MaskedIPSet construction (and its per-address toString churn) of the historic selection loop.

      Returns whether any added key collided with a previously seen peer; this is the definition of "same IP" used to push a peer to the BAD tier. The three spaces (masked IP, port, family) are kept separate so, just like MaskedIPSet's '.' / 'p' / 'x' prefixes, a cross-space collision can never occur.

      Parameters:
      maskedIPs - accumulator of packed masked-IP keys, mutated on add
      ports - accumulator of router ports, mutated on add
      families - accumulator of family option values, mutated on add
      ctx - used to resolve the peer's communicate-address
      peer - the candidate's hash
      pinfo - the candidate RouterInfo (validated, never null here)
      mask - byte count for maskedIPKey(byte[], int)
      Returns:
      true if at least one key was already present
    • classifyFloodfillPeerForDisplay

      public FloodfillPeerSelector.PeerClass classifyFloodfillPeerForDisplay(Hash entry, RouterInfo info, long now)
      Classify a floodfill peer for display purposes. Uses the same logic as the internal selection classifier but without same-IP tracking.
      Parameters:
      entry - the peer hash
      info - the peer's RouterInfo, may be null
      now - current time in milliseconds
      Returns:
      GOOD, OK, or BAD
    • selectNearest

      List<Hash> selectNearest(Hash key, int maxNumRouters, Set<Hash> peersToIgnore, KBucketSet<Hash> kbuckets)
      Floodfill peers only. Used only by HandleDatabaseLookupMessageJob to populate the DSRM. UNLESS peersToIgnore contains Hash.FAKE_HASH (all zeros), in which case this is an exploratory lookup, and the response should not include floodfills. List MAY INCLUDE our own router - add to peersToIgnore if you don't want.
      Specified by:
      selectNearest in class PeerSelector
      Parameters:
      key - the original key (NOT the routing key)
      maxNumRouters - the most hashes to return, zero or less meaning no limit
      peersToIgnore - can be null
      kbuckets - the routing table to select from
      Returns:
      List of Hash for the peers selected, ordered