- All Implemented Interfaces:
Service
- Direct Known Subclasses:
FloodfillNetworkDatabaseFacade
Provides core network database functionality using Kademlia DHT for peer discovery, routing table management, and data storage/lookup operations. Never instantiated directly; see FloodfillNetworkDatabaseFacade.
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate classJob to process batched LeaseSet republishes.private classJob to asynchronously purge all routers from NetDb matching enabled ban rules.private static classJob to refresh client LeaseSets periodically.Field Summary
Modifier and TypeFieldDescriptionprivate final ConcurrentHashMap<Hash, AtomicInteger> Count of active outbound iterative-search queries per floodfill peer; incremented when a query is dispatched, decremented when it completes or fails.private BanLoggerBan logger.Pending set for batch deduplication — a hash is in this set iff it is in the batch queue or being processed.private final ConcurrentLinkedQueue<Hash> Queue for batching LeaseSet republishes within a 15-second window.private final BlindCacheBlind cache.Cached set of blocked countries - lazily initialized.private static booleanThe cached block-my-country flag.private static StringThe cached minimum allowed version.private static StringThe cached own country.private static longThe cached republish threshold.private static RouterContextThe context of the cached settings.private static longWhen the cached settings were refreshed.private final ConcurrentHashMap<Hash, Long> Map of remote destination Hash to last access time for LeaseSets we're using as a client.protected final RouterContext_context.private StringWhere the data store is pushing the data.private final HashDB ID.private DataStoreData store.private final JobExpire leases job.private final JobExpire routers job.private StartExplorersJobClock independent time of when we started up.Hash objects that we should search on (to fill up a bucket, not to get data).private booleanInitialized flag.private KBucketSet<Hash> Kbucket set.private longTrack last batch processing time to ensure 15-second window.private longWhen was the last time an exploration found something new?private longLast RI publish time.protected final LogClass logger.private NegativeLookupCacheNegative cache.protected final intNetwork identifier.protected final PeerSelector_peerSelector.private final ConcurrentMap<Hash, Set<RepublishLeaseSetJob>> Map of Hash to RepublishLeaseSetJob for leases we're already managing.private final ConcurrentHashMap<Hash, Long> Tracks recently-queried floodfill peers across all concurrent searches to avoid hammering the same floodfill.Singleton job to refresh client LeaseSets - only one instance exists.private final ReseedCheckerReseed checker.Peers stored in the netdb but not yet in the routing buckets, awaiting direct-contact evidence before insertion (verify-before-add).private static final longDelay in ms between processing batches of netdb entries.private static final longBatched LeaseSet republishing constants.private static final intKad K — routers kept per distance class.private static final PatternPattern.compile.private static final longInterval for refreshing the cached settings.static StringCurrent minor version identifier for net DB format.private static final StringDefault comma-separated list of blocked countries.static final StringDefault database directory name.static longFor 15 minutes after startup, don't fail db entries so that if we were offline for a while, we'll have a chance of finding some live peers with the previous references.private static final longGrace period, in ms, a locally-published LeaseSet's lease dates may already be past before validateLeaseSetExpiry() rejects it.private static final longDelay in ms before starting explore jobs.(package private) static final intMax bucket entries sharing one IP group — eclipse/Sybil resistance, mirrors kubo's table.go limits.(package private) static final intMax entries across all buckets sharing one IP group.private static final intKademlia top-level split factor (B).private final ObjectLock object for netdb access.private final AtomicIntegerCounter for lookups.private static final longInterval between local leaseset refreshes.private static final intMaximum number of entries per batch.private static final intMax concurrent outbound IterativeSearch queries per floodfill peer.(package private) static final intMaximum number of peers to place in the queue to explore.(package private) static final intIntroducer slots per transport address.private static final longDon't let leaseSets go too far into the future.private static final longMaximum future time in ms for meta leases.private static final intWe want FNDF.PUBLISH_TIMEOUT and RepublishLeaseSetJob.REPUBLISH_LEASESET_TIMEOUT to be greater than MAX_PER_PEER_TIMEOUT * TIMEOUT_MULTIPLIER by a factor of at least 3 or 4, to allow at least that many peers to be attempted for a store.private static final intSmallest allowed period.protected static final intIf we have less than this many routers left, don't drop any more, even if they're failing or doing bad stuff.(package private) static final intReseed if below this.static final StringLowest peer version that may be selected for a KBucket probe.static final StringLowest peer version whose LeaseSets we will store and serve.private static final longTime to lease expiry, in ms, below which a tracked client LeaseSet is refreshed proactively instead of waiting for the next access.private static final StringConfig property to block countries by IP.static final StringConfig property for blocking own-country peers.(package private) static final StringProperty: Kademlia bucket size (K), read once at startup.static final StringConfig property for database directory.private static final StringIntroducer relay tag option prefix ("itag0".."itag4"); required in every slot.static final StringConfig property for IP country override.(package private) static final StringProperty: minimum router version for exploration.(package private) static final StringProperty: adjusted RouterInfo expiration time in ms.(package private) static final StringProperty: delay before validating routers in ms.private static final longDelay in ms before publishing.protected static final longLong enough to give us time to start up, but less than 20m, when we start accepting tunnels and could be an IBGW.private static final booleanDon't probe or broadcast data, just respond and search when explicitly needed.private static final long[]Rate limits for netdb operations.private static final longCooldown before a floodfill can be queried again in ms.private static final longLimits for accepting a dbStore of a router, unless we don't know anyone or just started up -- seevalidate(RouterInfo)below.private static final longRouterInfo expiration time in ms for floodfill peers.private static final longRouterInfo expiration time in ms for introduced peers.private static final longMinimum RouterInfo expiration time in ms.private static final longShort RouterInfo expiration time in ms for non-floodfill.private static final intMultiplier for Kademlia RPC timeout calculation.(package private) static final intMax peers held awaiting direct-contact verification.(package private) static final longDrop a pending peer from the verification queue after this long; it is still in the netdb, it just stops being a bucket candidate until it proves itself.Constructor Summary
ConstructorsConstructorDescriptionKademliaNetworkDatabaseFacade(RouterContext context, Hash dbid) Initializes the Kademlia-based network database facade.Method Summary
Modifier and TypeMethodDescriptionprivate StringConsole translation for the debug page strings.voidaccessLeaseSet(Hash key) Record access to a LeaseSet for refresh tracking.(package private) booleanaddContact(Hash key) Policy entry point for peers learned from search replies, where no RouterInfo is in hand yet: direct-contact gate only.private voidaddContact(Hash key, RouterInfo routerInfo) Insert a newly-stored peer into the routing buckets, gated on two local-only checks (no wire-format change): verify-before-add — a peer merely named in someone else's DatabaseSearchReply has never answered us, so it waits in_unverifiedPeersuntil direct-contact evidence arrives (a reply, a successful send, or an established session).private booleanallowPolicyBan(Hash key) Whether policy bans (country/XG/LU/capability) may be applied to this router during resolution.private booleanbanInvalidNTCPAddresses(RouterInfo routerInfo, long now, String caps, String routerId) Checks for invalid NTCP2 addresses in the given RouterInfo and bans the router if any are found.protected BlindCacheReturns the blind data cache used by this database.(package private) static intbucketSize(RouterContext context) Bucket size (K) from the property, clamped to what KBucketSet accepts.(package private) static StringbuildBucketTable(List<String[]> rows, int capacity, java.util.function.Function<String, String> entryRenderer, java.util.function.Function<String, String> tr) Build the bucket table from the rows ofKBucketSet.getDebugBucketRows(): bucket index, XOR-distance bit range, entry count as a details/summary disclosure whose expanded content is the entry hashes rendered by the given function, and fill as a percentage of capacity.private booleancancelActiveRepublishJob(Hash hash) Cancel any queued RepublishLeaseSetJob for the given hash.private StringcheckAddressesAndIntroducers(RouterInfo routerInfo, String caps, String routerId, boolean isUs, boolean dontFail) Checks if the router has no valid addresses or introducers and has been published too long ago.private booleancheckCountryBlocking(RouterInfo routerInfo, String caps, String routerId, Hash h) Checks if the given router should be blocked due to country restrictions.private StringcheckExpirationBasedDrop(RouterInfo routerInfo, boolean upLongEnough, long adjustedExpiration, long now, String caps, String routerId, boolean isUs) Checks if the router has expired based on configured expiration time.private StringcheckExpiredLeaseSet(Hash key, LeaseSet leaseSet, long earliest, long latest, long now, String idShort) Reject a LeaseSet whose timestamps are outdated (stale).private voidcheckForHashCollision(LeaseSet rv, LeaseSet leaseSet, boolean force) Reject a store whose LeaseSet hash collides with an existing LeaseSet for a different destination.private StringcheckFutureExpiration(LeaseSet leaseSet, int type, long latest, long now, String idShort) Reject a LeaseSet that expires too far into the future, to handle clock skew issues.private StringcheckFutureRouterInfo(RouterInfo routerInfo, long now, String caps, String routerId, Hash h, boolean isUs) Checks if the given router info was published in the future and bans it if so.private voidcheckLeaseSetSigType(Hash h, LeaseSet ls) Reject LeaseSets with unsupported signature types; negative-cache the destination permanently.private booleancheckLU(RouterInfo routerInfo, String caps, String routerId, Hash h) Ban LU (low bandwidth) routers unconditionally for 1 hour.private voidcheckRouterInfoSigType(Hash h, RouterInfo ri) Reject RouterInfos with unsupported signature types; ban until restart.private StringcheckRouterVersion(RouterInfo routerInfo, String caps, String routerId, Hash h) Checks if the given router is running a version older than the minimum allowed.private StringcheckShortExpiration(RouterInfo routerInfo, String caps, String routerId, boolean isUs) Why the router's short expiration is disqualifying, or null.private StringcheckStaleRouterInfo(RouterInfo routerInfo, boolean upLongEnough, int existing, String routerId, boolean isUs) Whether an otherwise-acceptable RouterInfo has aged pastcomputeAdjustedExpiration(int)and should now be dropped.private booleancheckXG(RouterInfo routerInfo, String caps, String routerId, Hash h) Whether the router should be XG-banned: an X-tier (unlimited bandwidth) router advertising the G (no tunnels) capability.voidclearNegativeCache(Hash key) Clear any transient (non-permanent) negative-cache entry for the given key so the nextlookupLeaseSet(Hash, Job, Job, long)performs a real search instead of aborting instantly.private longcomputeAdjustedExpiration(int existingRouters) Computes the expiration time for a RouterInfo based on current network conditions.private booleancontainsCapability(RouterInfo ri, char capability) Whether the router advertises the given capability.private voidcopyStoreMetadata(LeaseSet rv, LeaseSet leaseSet) Copy the received-by / received-as-reply / received-as-published metadata flags from the incoming LeaseSet onto the stored copy, without re-storing the entry.protected voidUnused, see override.protected PeerSelectorCreates a peer selector for the network database.(package private) voiddecrementActiveFloodfillQuery(Hash floodfill) Decrement the active outbound query count for a floodfill peer.(package private) booleandropAfterLookupFailed(Hash peer) Final remove for a router info.private StringdropSlowRouter(RouterInfo routerInfo, long now, int existing, String caps, String routerId) Checks if the given router should be dropped due to being a slow tier (K, L, or M) and outdated.(package private) static StringentryLinks(String keys, java.util.function.Function<String, String> entryRenderer) Entry hashes rendered through the given function, sorted for stable display.voidFinal remove for a leaseset.(package private) voidfailPermanently(Destination dest) Negative cache until restart.findNearestRouters(Hash key, int maxNumRouters, Set<Hash> peersToIgnore) The routers closest to that key in response to a remote lookup.Hashes for all known routers.All cached BlindData.BlindData for the given key.Blocked countries, parsed once from the property and cached.LeaseSets published by this router's clients.(package private) DataStoreThe data store.(package private) StringgetDbDir()For the main DB only.long[]Debug overview stats: total keys, bucket count, per-bucket capacity and fullest bucket size, as {keys, buckets, capacity, fullest}.Keys to explore.LeaseSets stored in the floodfill database.(package private) KBucketSet<Hash> KBucketSet for the main DB.protected intSize of the KBucketSet.intThis is only used by StatisticsManager to publish the count if we are floodfill.intThis used to return the number of routers that were in both the kbuckets AND the data store, which was fine when the kbuckets held everything.(package private) longTime of the last explore run.longTime of the last successful RI publication.All known LeaseSets for display.private LeaseSetgetLocalLeaseSet(Hash key) Read a current LeaseSet from this facade's store only.private KademliaNetworkDatabaseFacadeMain (router) NetDb facade, or null if unavailable.Returns the main database's peer selector.intgetPeerTimeout(Hash peer) How long to wait for one peer's reply, scaled from its profile.private longProactive republish threshold from config or default (3 minutes).LeaseSets published to the network.private StringgetRouterId(RouterInfo routerInfo) Generates a short identifier for a router based on its hash.RouterInfos stored in the database.intNumber of RouterInfo files stored on disk, if usingPersistentDataStore.LeaseSets not published to the network.(package private) intThe pending-verification queue size, for tests and the debug console.Snapshot of the pending-verification queue, for the probe cycle to target.private voidhandleBanlistAndRemove(RouterInfo ri, Hash key, Job onFailedLookupJob) Banlist a router for one hour as an unreachable low-bandwidth peer older thanMIN_VERSION, then drop it from the data store, the routing buckets and the unverified queue.private voidhandleBlindStore(EncryptedLeaseSet encls, LeaseSet leaseSet) After storing, handle the blind data bookkeeping: an encrypted LeaseSet we have now decrypted is stored under its own key, and a blinded-when-published LeaseSet marks its destination as blinded.private voidhandleCustomCapabilityBan(RouterInfo ri, Hash key, Job onFailedLookupJob) Handle banning a router that matches custom capability ban patterns, for four hours.private voidhandleHostileBlocklist(RouterInfo _ri, Hash key, Job onFailedLookupJob) Drop the RouterInfo of a router tagged hostile on the Banlist, without extending or adding a ban.private voidhandleIntroducerBan(RouterInfo ri, Hash key, Job onFailedLookupJob) Handle banning a router that advertises more introducers on one address than the SSU2 spec allows.private voidhandleInvalidRouterInfoBan(RouterInfo ri, Hash key, String reason, Job onFailedLookupJob) Handle banning a RouterInfo that breaks one of the RouterInfo validation rules - fabricated version, impossible publication date, or contradictory reachability flags.private voidA local client whose LS is not published to the network (i2cp.dontPublishLeaseSet, e.g.private voidhandlePermanentBlocklist(RouterInfo _ri, Hash key, Job onFailedLookupJob) Drop the RouterInfo of a router already on the permanent blocklist; no new ban entry is written, the existing one stands.(package private) booleanhasActiveRepublishJob(Hash hash) Check if an active republish job exists for the given destination.(package private) booleanhasDirectContact(Hash peer) Have we ever heard from this peer directly, as opposed to merely being told about it? An established session or a profile with a received message or successful send counts.(package private) static booleanhasDirectContact(PeerProfile prof) Direct-contact test on profile evidence only: heard-from or successful-send, never heard-about (that only means someone mentioned them).(package private) intincrementActiveFloodfillQuery(Hash floodfill) Increment the active outbound query count for a floodfill peer.(package private) StringThe ban reason if this RouterInfo fails one of the RouterInfo validation rules - a version above every released version, an impossible publication date, or both the reachable and the unreachable flag at once - or null if it passes.(package private) static StringinvalidRouterInfoBanReason(RouterInfo ri, boolean banVersion, boolean banPubDate, boolean banCaps) The validation rule a RouterInfo breaks, given which of the three rules are switched on.(package private) booleanipDiversityAllows(Hash key, RouterInfo routerInfo) Would adding this peer to its bucket exceed the per-bucket or global IP-group caps? Peers with no literal-IP address are unconstrained.(package private) static LongipGroup(byte[] ip) IP group key: /16 for IPv4, /48 for IPv6, packed into a long with a family marker bit so the two families never collide.ipGroups(RouterInfo ri) The distinct IP groups of a router's literal-IP addresses.booleanCheck if the database is a client DB.(package private) booleanisFloodfillOverloaded(Hash floodfill) Check if a floodfill peer already has too many active outbound queries from this router.private booleanWhether the router is shutting down gracefully.private booleanisHostileBlocklisted(Hash key) Whether the router is on the hostile blocklist.booleanChecks whether the network database has been fully initialized.private booleanisLocalDestination(Hash key) Whether the key is one of our own destinations.(package private) booleanisNegativeCached(Hash key) Is the key in the negative lookup cache?booleanIs it permanently negative cached?static booleanUtility to determine if a is newer than b.private booleanWhether the router is on the permanent blocklist.(package private) booleanisRecentlyQueried(Hash peer) Check if a floodfill peer was queried recently (within cooldown period).private booleanisRouterXG(RouterInfo routerInfo, boolean isUs) Determines whether the given router qualifies as an XG router that should be blocked.private booleanisUptimeLongEnough(long uptime) Checks if the router's uptime is long enough to begin validating other routers.private static StringlogName(NamingService ns, Hash key) Best-effort display name for a tracked LeaseSet in logs: the registered hostname when available, otherwise a truncated base32.protected voidlookupBeforeDropping(Hash peer, RouterInfo info) Don't use directly - see F.N.D.F.voidlookupDestination(Hash key, Job onFinishedJob, long timeoutMs, Hash fromLocalDest) Lookup using the client's tunnels Succeeds even if LS validation and store fails due to unsupported sig type, expired, etc.Destination stored locally, or null.(package private) voidlookupFailed(Hash key) Increment in the negative lookup cache.voidlookupLeaseSet(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs) Look up a LeaseSet, locally first.voidlookupLeaseSet(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs, Hash fromLocalDest) Lookup using the client's tunnels UselookupDestination(Hash, Job, long, Hash)if you don't need the LS or don't need it validated.LeaseSet stored locally.voidlookupLeaseSetRemotely(Hash key, Hash fromLocalDest) Unconditionally lookup using the client's tunnels, with no jobs.voidlookupLeaseSetRemotely(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs, Hash fromLocalDest) Unconditionally lookup using the client's tunnels.lookupLocally(Hash key) Validated entry stored locally.Not for use without validation.(package private) RouterInfolookupRIUnvalidated(Hash key) Look up a peer's RouterInfo without running the fullvalidate(RouterInfo)ban cascade.voidlookupRouterInfo(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs) Look up a RouterInfo, resolving over the network when not cached locally.This will return immediately with the result or null.voidlookupRouterInfoRemote(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs) Look up a RouterInfo by hash, performing a network search if not locally cached.(package private) voidlookupTimeout(Hash key) Pure-timeout search failure (no peer replied).(package private) voidmarkQueried(Hash peer) Mark a floodfill peer as recently queried.private voidmirrorToMainFacade(LeaseSet localLeaseSet) A locally-published LeaseSet legitimately occupies both the client facade (where the client pushed it) and the floodfill facade (where the router console and the network look it up).booleanpeekNegativeCached(Hash key) Negative-cache check without recording an abort stat.Turns a base64 hash into the standard router-info reference (flag, netdb link, bandwidth) for the bucket entry lists.private booleanproactivelyRefreshIfExpiring(Hash key, long now, NamingService ns) Refresh a tracked LeaseSet early when it is about to expire.private voidprocessStoreFailure(Hash h, DatabaseEntry entry) If the validate fails, call this to determine if it was because of unsupported crypto.(package private) intMove pending peers that have earned direct-contact evidence into the routing buckets, and drop those that waited too long.private voidEvict oldest tracked entries to cap map size.voidPublishes a local LeaseSet to the network: stores it in this facade and, for a client facade, also in the floodfill facade, then schedules republishing.voidpublish(RouterInfo localRouterInfo) Stores to local db only.voidTrigger a retroactive purge sweep of the NetDb.voidqueueForExploration(Collection<Hash> keys) Queue keys for exploration.private voidqueueUnverified(Hash key) Queue a peer for later bucket promotion once it proves itself, sweeping expired entries when the queue is full.private voidRefresh client lease sets.private static voidRefresh the cached configuration from properties at most once per CONFIG_REFRESH_MS, or immediately when the context changes.private voidrefreshLocalLeaseSetIfExpiring(Hash key, long now) Nudge the inbound pool to re-publish our own LeaseSet when a client is actively using it and the earliest lease is inside the proactive window.(package private) booleanRegister a new job for tracking.booleanFor console ConfigKeyringHelper.voidremoveFromExploreKeys(Collection<Hash> toRemove) Remove keys from the exploration set.private voidremoveFromNetDb(Hash key) Remove a router from the NetDb without banning it.voidRemove a LeaseSet from refresh tracking.(package private) voidremovePublishingJob(Hash hash, RepublishLeaseSetJob job) Remove a specific job from the tracking set.voidremoveRouterInfo(Hash key) Remove a RouterInfo from the local netdb.voidrenderStatusHTML(Writer out) Render the KBucket summary and a per-bucket table.voidrescan()Rescan the netdb directory for new RouterInfo files.Reseed checker, or null for a client DB.private voidresolveBlindData(EncryptedLeaseSet encls, LeaseSet leaseSet) Resolve blind data for an encrypted LeaseSet so validate() can verify the signature, setting the secret before the destination.(package private) voidRecord the current time as the last successful RI publication.voidNotify the netDB that the routing key changed at midnight UTC.private voidscheduleRepublish(Hash hash) Queues the LeaseSet for future republishing.(package private) abstract SearchJobBegin a kademlia-style iterative search for the key, which can take up to timeoutMs and will fire the appropriate jobs on success or timeout (or if the search completes without any match).(package private) abstract SearchJobsearch(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs, boolean isLease, Hash fromLocalDest) Search using the client's tunnels; seesearch(Hash, Job, Job, long, boolean).(package private) voidsearchComplete(Hash key) The search for the given key is no longer active.(package private) abstract voidsendStore(Hash key, DatabaseEntry ds, Job onSuccess, Job onFailure, long sendTimeout, Set<Hash> toIgnore) See implementation in FNDF.voidBlindData to put in the cache.(package private) voidsetLastExploreNewDate(long when) Time of the last explore run.private booleansharesIPGroup(Set<Long> groups, Hash peer) Does this bucket entry share an IP group with any of the given groups?(package private) static booleanshouldAcceptLeaseSet(LeaseSet stored, LeaseSet incoming, long now) Determine whether an incoming LeaseSet may replace the currently stored copy.private booleanshouldBanlistBasedOnCountry(RouterInfo _ri, Hash key) Should we banlist this router based on country restrictions? Checks if: - we are in strict country mode and router is in same country - blockMyCountry is enabled - router is in our country (strict country mode).private booleanDetermine whether the given router should be banlisted based on custom capability patterns configured by the user.private booleanDetermine whether the given router should be banlisted for advertising more introducers on one transport address than the SSU2 spec allows.private booleanDetermine whether the given router should be banlisted due to being: - an unreachable L-tier router (CAPABILITY_BW12),private booleanDetermine whether the given router should be banlisted due to being an XG router that is neither reachable nor unreachable and the XG banlist option is enabled.(package private) static booleanshouldFailLocalWithoutRemoteSearch(boolean isClientDb, boolean isLocalDest) Whether a client sub-NetDb local miss for a destination this router hosts must fail immediately instead of starting a network search.(package private) static booleanshouldFallbackLocalLookupToMain(boolean isClientDb, boolean isLocalDest, boolean foundLocally) Whether a client sub-NetDb local miss should be re-checked in the main NetDb.private booleanDetermines whether validation should be skipped based on initialization status or dummy communication system.voidshutdown()Shut down the NetDB and all its jobs.private static StringsigTypeDescription(KeyCertificate kc, SigType type) Human-readable signature type for log messages.voidstartup()Open the backing store, build the KBuckets, and prime the negative cache and the recurring expiry, refresh, and exploration jobs.(package private) voidstopPublishing(Hash target) Stops publishing the given LeaseSet.Store the LeaseSet without persisting it to disk.Store the leaseSet.store(Hash key, RouterInfo routerInfo) Store the routerInfo.(package private) RouterInfostore(Hash key, RouterInfo routerInfo, boolean persist) Store the routerInfo.private voidstoreLocalLeaseSetCopy(LeaseSet localLeaseSet) Store the local copy, forcing overwrite; propagate IAE to the caller.(package private) static StringstripStoreWrapper(String message) Strip the "Invalid NetDbStore attempt" wrapper from a store rejection message, keeping the capability flags and the Router [id] the console renders as a link.(package private) static booleanWhether any single transport address advertises more introducers than the SSU2 spec allows.toString()Name this netdb for use in log messages.voidUnpublish a LeaseSet from the network database.Validates whether the given LeaseSet is acceptable as valid and current based on current known parameters.private Stringvalidate(Hash key, RouterInfo routerInfo) Determine whether this routerInfo will be accepted as valid and current given what we know now.(package private) Stringvalidate(RouterInfo routerInfo) Determine whether this routerInfo will be accepted as valid and current given what we know now.private StringvalidateKeyMatch(Hash key, LeaseSet leaseSet) Check that the key matches the LeaseSet hash.private voidvalidateLeaseSetExpiry(LeaseSet leaseSet) Reject a LeaseSet whose leases are already in the past, allowingEXPIRY_GRACE_PERIODof slack for clock skew.private StringvalidateSignature(Hash key, LeaseSet leaseSet, String leaseBase32) Verify the LeaseSet's cryptographic signature validity.Methods inherited from class NetworkDatabaseFacade
floodfillEnabled, storeModifier and TypeMethodDescriptionbooleanFor convenience, so users don't have to cast to FNDF, and unit tests using Dummy NDF will work.store(Hash key, DatabaseEntry entry) Store a DatabaseEntry in the network database.
Field Details
COMMA_SPLIT
Pattern.compile._log
Class logger._banLogger
Ban logger._kb
Kbucket set._ds
Data store._dbDir
Where the data store is pushing the data._exploreKeys
UNVERIFIED_MAX
static final int UNVERIFIED_MAXMax peers held awaiting direct-contact verification. @since 0.9.71+.- See Also:
UNVERIFIED_MAX_AGE
static final long UNVERIFIED_MAX_AGEDrop a pending peer from the verification queue after this long; it is still in the netdb, it just stops being a bucket candidate until it proves itself. @since 0.9.71+.- See Also:
IP_GROUP_BUCKET_LIMIT
static final int IP_GROUP_BUCKET_LIMITMax bucket entries sharing one IP group — eclipse/Sybil resistance, mirrors kubo's table.go limits. @since 0.9.71+.- See Also:
IP_GROUP_GLOBAL_LIMIT
static final int IP_GROUP_GLOBAL_LIMITMax entries across all buckets sharing one IP group. @since 0.9.71+.- See Also:
_unverifiedPeers
Peers stored in the netdb but not yet in the routing buckets, awaiting direct-contact evidence before insertion (verify-before-add). Filled byaddContact(Hash, RouterInfo), drained bypromoteUnverifiedPeers()and the probe cycle. Capped atUNVERIFIED_MAX, entries older thanUNVERIFIED_MAX_AGEare dropped. Hash -> time queued._initialized
private boolean _initializedInitialized flag._exploreJob
Clock independent time of when we started up._lastExploreNew
private long _lastExploreNewWhen was the last time an exploration found something new?_peerSelector
_peerSelector._context
_context._reseedChecker
Reseed checker._lastRIPublishTime
private volatile long _lastRIPublishTimeLast RI publish time._negativeCache
Negative cache._networkID
protected final int _networkIDNetwork identifier._blindCache
Blind cache._dbid
DB ID._elj
Expire leases job._erj
Expire routers job.PROP_MIN_ROUTER_VERSION
Property: minimum router version for exploration.- See Also:
PROP_BLOCK_MY_COUNTRY
Config property for blocking own-country peers.- See Also:
PROP_IP_COUNTRY
Config property for IP country override.- See Also:
PROP_BLOCK_COUNTRIES
Config property to block countries by IP.- See Also:
DEFAULT_BLOCK_COUNTRIES
Default comma-separated list of blocked countries.- See Also:
MIN_ROUTER_VERSION
Lowest peer version that may be selected for a KBucket probe.- See Also:
MIN_VERSION
Lowest peer version whose LeaseSets we will store and serve.- See Also:
MAX_INTRO_SLOTS
static final int MAX_INTRO_SLOTSIntroducer slots per transport address. Mirrors UDPAddress.MAX_INTRODUCERS, which is package-private in the transport package - the same deliberate duplication IntroducerLookupJob already carries.- See Also:
PROP_INTRO_TAG_PREFIX
Introducer relay tag option prefix ("itag0".."itag4"); required in every slot.- See Also:
CURRENT_VERSION
Current minor version identifier for net DB format.kbInitLock
Lock object for netdb access.knownLeaseSetsCount
Counter for lookups._publishingLeaseSets
Map of Hash to RepublishLeaseSetJob for leases we're already managing. Multiple jobs may be queued per destination; new jobs replace old ones._batchRepublishQueue
Queue for batching LeaseSet republishes within a 15-second window. This reduces job queue pressure by consolidating multiple republish jobs into one._batchRepublishPending
Pending set for batch deduplication — a hash is in this set iff it is in the batch queue or being processed. Prevents duplicate entries under rapidpublish(LeaseSet)calls._lastBatchProcessTime
private volatile long _lastBatchProcessTimeTrack last batch processing time to ensure 15-second window.BATCH_WINDOW_MS
private static final long BATCH_WINDOW_MSBatched LeaseSet republishing constants.- See Also:
BATCH_PROCESS_DELAY
private static final long BATCH_PROCESS_DELAYDelay in ms between processing batches of netdb entries.- See Also:
MAX_BATCH_SIZE
private static final int MAX_BATCH_SIZEMaximum number of entries per batch.- See Also:
LOCAL_LEASESET_REFRESH_INTERVAL
private static final long LOCAL_LEASESET_REFRESH_INTERVALInterval between local leaseset refreshes.- See Also:
_refreshClientLeaseSetsJob
Singleton job to refresh client LeaseSets - only one instance exists._clientLeaseSetAccessTime
Map of remote destination Hash to last access time for LeaseSets we're using as a client. Used to refresh remote LeaseSets we're actively accessing and remove after 150s inactivity._activeFloodfillQueries
Count of active outbound iterative-search queries per floodfill peer; incremented when a query is dispatched, decremented when it completes or fails._recentlyQueriedFloodfills
Tracks recently-queried floodfill peers across all concurrent searches to avoid hammering the same floodfill. Entries expire after 60s.RECENTLY_QUERIED_COOLDOWN
private static final long RECENTLY_QUERIED_COOLDOWNCooldown before a floodfill can be queried again in ms.- See Also:
_blockedCountries
DONT_FAIL_PERIOD
public static long DONT_FAIL_PERIODFor 15 minutes after startup, don't fail db entries so that if we were offline for a while, we'll have a chance of finding some live peers with the previous references.QUIET
private static final boolean QUIETDon't probe or broadcast data, just respond and search when explicitly needed.- See Also:
PROP_DB_DIR
Config property for database directory.- See Also:
DEFAULT_DB_DIR
Default database directory name.- See Also:
MIN_RESEED
MIN_REMAINING_ROUTERS
protected static final int MIN_REMAINING_ROUTERSIf we have less than this many routers left, don't drop any more, even if they're failing or doing bad stuff. As of 0.9.4, this equals the min for reseeding, so dropping stops at the point where a reseed is forced.- See Also:
ROUTER_INFO_EXPIRATION
private static final long ROUTER_INFO_EXPIRATIONLimits for accepting a dbStore of a router, unless we don't know anyone or just started up -- seevalidate(RouterInfo)below.- See Also:
ROUTER_INFO_EXPIRATION_MIN
private static final long ROUTER_INFO_EXPIRATION_MINMinimum RouterInfo expiration time in ms.- See Also:
ROUTER_INFO_EXPIRATION_SHORT
private static final long ROUTER_INFO_EXPIRATION_SHORTShort RouterInfo expiration time in ms for non-floodfill.- See Also:
ROUTER_INFO_EXPIRATION_FLOODFILL
private static final long ROUTER_INFO_EXPIRATION_FLOODFILLRouterInfo expiration time in ms for floodfill peers.- See Also:
_cfgCtx
The context of the cached settings._cfgRefreshed
private static volatile long _cfgRefreshedWhen the cached settings were refreshed._cachedProactiveRepublishThreshold
private static volatile long _cachedProactiveRepublishThresholdThe cached republish threshold._cachedBlockMyCountry
private static volatile boolean _cachedBlockMyCountryThe cached block-my-country flag._cachedMyCountry
The cached own country._cachedMinVersionAllowed
The cached minimum allowed version.CONFIG_REFRESH_MS
private static final long CONFIG_REFRESH_MSInterval for refreshing the cached settings.- See Also:
ROUTER_INFO_EXPIRATION_INTRODUCED
private static final long ROUTER_INFO_EXPIRATION_INTRODUCEDRouterInfo expiration time in ms for introduced peers.- See Also:
PROP_ROUTER_INFO_EXPIRATION_ADJUSTED
Property: adjusted RouterInfo expiration time in ms.- See Also:
PROP_VALIDATE_ROUTERS_AFTER
Property: delay before validating routers in ms.- See Also:
EXPLORE_JOB_DELAY
private static final long EXPLORE_JOB_DELAYDelay in ms before starting explore jobs.- See Also:
MAX_LEASE_FUTURE
private static final long MAX_LEASE_FUTUREDon't let leaseSets go too far into the future.- See Also:
MAX_META_LEASE_FUTURE
private static final long MAX_META_LEASE_FUTUREMaximum future time in ms for meta leases.- See Also:
PUBLISH_JOB_DELAY
protected static final long PUBLISH_JOB_DELAYLong enough to give us time to start up, but less than 20m, when we start accepting tunnels and could be an IBGW. Actually, we need this soon if we are a new router or other routers have forgotten about us, else we can't build IB exploratory tunnels. Unused.- See Also:
MAX_EXPLORE_QUEUE
static final int MAX_EXPLORE_QUEUEMaximum number of peers to place in the queue to explore.- See Also:
BUCKET_SIZE_DEFAULT
private static final int BUCKET_SIZE_DEFAULTKad K — routers kept per distance class. With 256 single-bit leaf buckets this caps routing knowledge at 256 x 64 = 16,384 routers. Was 500 in the old implementation, but that was with B ~= -8.- See Also:
PROP_BUCKET_SIZE
Property: Kademlia bucket size (K), read once at startup.- See Also:
KAD_B
RATES
private static final long[] RATESRate limits for netdb operations.MAX_CONCURRENT_PER_FLOODFILL
private static final int MAX_CONCURRENT_PER_FLOODFILLMax concurrent outbound IterativeSearch queries per floodfill peer. Above this we'll pick a different floodfill to distribute load.- See Also:
PUBLISH_DELAY
EXPIRY_GRACE_PERIOD
private static final long EXPIRY_GRACE_PERIODGrace period, in ms, a locally-published LeaseSet's lease dates may already be past before validateLeaseSetExpiry() rejects it.- See Also:
MIN_PER_PEER_TIMEOUT
MAX_PER_PEER_TIMEOUT
private static final int MAX_PER_PEER_TIMEOUTWe want FNDF.PUBLISH_TIMEOUT and RepublishLeaseSetJob.REPUBLISH_LEASESET_TIMEOUT to be greater than MAX_PER_PEER_TIMEOUT * TIMEOUT_MULTIPLIER by a factor of at least 3 or 4, to allow at least that many peers to be attempted for a store.- See Also:
TIMEOUT_MULTIPLIER
private static final int TIMEOUT_MULTIPLIERMultiplier for Kademlia RPC timeout calculation.- See Also:
PROACTIVE_REFRESH_THRESHOLD
private static final long PROACTIVE_REFRESH_THRESHOLDTime to lease expiry, in ms, below which a tracked client LeaseSet is refreshed proactively instead of waiting for the next access. Only applies to the client NetDB, not the main NetDB. Each refresh cycle removes LeaseSets not accessed in 150s, re-fetches every tracked LeaseSet, and refreshes early when expiry is nearer than this value.- See Also:
Constructor Details
KademliaNetworkDatabaseFacade
Initializes the Kademlia-based network database facade.- Parameters:
context- the router contextdbid- the unique identifier for this network database
Method Details
searchComplete
The search for the given key is no longer active.- Parameters:
key- the key whose search is complete
refreshConfig
Refresh the cached configuration from properties at most once per CONFIG_REFRESH_MS, or immediately when the context changes. Benign race: duplicate refreshes are idempotent writes.- Parameters:
ctx- router context whose properties are read into the cache
bucketSize
Bucket size (K) from the property, clamped to what KBucketSet accepts.- Parameters:
context- the router context to read the property from- Returns:
- the bucket size, at least 5
isInitialized
public boolean isInitialized()Checks whether the network database has been fully initialized.- Overrides:
isInitializedin classNetworkDatabaseFacade- Returns:
- true if the database is initialized and ready for use, false otherwise
createPeerSelector
Creates a peer selector for the network database. Only applicable for the main database.- Returns:
- a new PeerSelector instance
- Throws:
IllegalStateException- if called on a client database
getPeerSelector
Returns the main database's peer selector.- Returns:
- the PeerSelector instance, or null if this is a client database
reseedChecker
Reseed checker, or null for a client DB.- Overrides:
reseedCheckerin classNetworkDatabaseFacade- Returns:
- the reseed checker
blindCache
Returns the blind data cache used by this database.We still always use a single blind cache in the main Db(for now), see issue #421 on i2pgit.org/i2p-hackers/i2p.i2p for details. This checks if we're the main DB already and returns our blind cache if we are. If not, it looks up the main Db and gets it.
- Returns:
- the BlindCache instance, never null
getKBuckets
KBucketSet<Hash> getKBuckets()KBucketSet for the main DB.- Returns:
- the main DB's KBucketSet. Client DBs do not have their own.
getDataStore
DataStore getDataStore()The data store.- Returns:
- the backing store used to look up and store kademlia data
getLastExploreNewDate
long getLastExploreNewDate()Time of the last explore run.- Returns:
- the last explore new date
setLastExploreNewDate
void setLastExploreNewDate(long when) Time of the last explore run.- Parameters:
when- the new date
getExploreKeys
removeFromExploreKeys
Remove keys from the exploration set.- Parameters:
toRemove- keys to remove
queueForExploration
Queue keys for exploration.- Parameters:
keys- keys to queue
shutdown
public void shutdown()Shut down the NetDB and all its jobs.rescan
public void rescan()Rescan the netdb directory for new RouterInfo files.- Overrides:
rescanin classNetworkDatabaseFacade
getDbDir
isClientDb
public boolean isClientDb()Check if the database is a client DB.- Returns:
- true if the database is a client DB, false otherwise
startup
public void startup()Open the backing store, build the KBuckets, and prime the negative cache and the recurring expiry, refresh, and exploration jobs. Called once by the router at startup.- Throws:
RuntimeException- if the on-disk store cannot be opened
createHandlers
protected void createHandlers()Unused, see override.findNearestRouters
The routers closest to that key in response to a remote lookup. Only used by ../HDLMJ Set MAY INCLUDE our own router - add to peersToIgnore if you don't want.- Specified by:
findNearestRoutersin classNetworkDatabaseFacade- Parameters:
key- the real key, NOT the routing keymaxNumRouters- The maximum number of routers to returnpeersToIgnore- can be null- Returns:
- set of router hashes closest to the key
isRecentlyQueried
Check if a floodfill peer was queried recently (within cooldown period).- Parameters:
peer- the floodfill peer- Returns:
- true if the peer was queried within the last 60s
markQueried
Mark a floodfill peer as recently queried. Other searches will avoid this peer for the cooldown period.- Parameters:
peer- the floodfill peer
incrementActiveFloodfillQuery
Increment the active outbound query count for a floodfill peer. Call when sendQuery() dispatches a DatabaseLookupMessage to this peer.- Parameters:
floodfill- the floodfill peer- Returns:
- the new count
decrementActiveFloodfillQuery
Decrement the active outbound query count for a floodfill peer. Call when the search for this peer completes, fails, or times out.- Parameters:
floodfill- the floodfill peer
isFloodfillOverloaded
Check if a floodfill peer already has too many active outbound queries from this router. Spreads the load across available floodfills so no single peer is saturated.- Parameters:
floodfill- the floodfill peer- Returns:
- true if the peer should be skipped for now
getAllRouters
Hashes for all known routers.- Specified by:
getAllRoutersin classNetworkDatabaseFacade- Returns:
- set of router hashes
getKnownRouters
public int getKnownRouters()This used to return the number of routers that were in both the kbuckets AND the data store, which was fine when the kbuckets held everything. But now that is probably not what you want. Just return the count in the data store.- Overrides:
getKnownRoutersin classNetworkDatabaseFacade- Returns:
- 0 if this is a client DB
getKnownLeaseSets
public int getKnownLeaseSets()This is only used by StatisticsManager to publish the count if we are floodfill. So to hide a clue that a popular eepsite is hosted on a floodfill router, only count leasesets that are "received as published", as of 0.7.14.- Overrides:
getKnownLeaseSetsin classNetworkDatabaseFacade- Returns:
- the known lease sets
getKBucketSetSize
protected int getKBucketSetSize()Size of the KBucketSet. The KBucketSet contains RIs only.- Returns:
- the number of RIs in the KBucketSet, or 0 before it is built
getBlindData
BlindData for the given key.- Overrides:
getBlindDatain classNetworkDatabaseFacade- Parameters:
spk- unblinded key- Returns:
- BlindData or null
setBlindData
BlindData to put in the cache.- Overrides:
setBlindDatain classNetworkDatabaseFacade- Parameters:
bd- new BlindData to put in the cache
getBlindData
All cached BlindData.- Overrides:
getBlindDatain classNetworkDatabaseFacade- Returns:
- every BlindData held in the blind cache
removeBlindData
For console ConfigKeyringHelper.- Overrides:
removeBlindDatain classNetworkDatabaseFacade- Parameters:
spk- the unblinded public key- Returns:
- true if removed
routingKeyChanged
public void routingKeyChanged()Notify the netDB that the routing key changed at midnight UTC.- Overrides:
routingKeyChangedin classNetworkDatabaseFacade
lookupLocally
Validated entry stored locally.- Specified by:
lookupLocallyin classNetworkDatabaseFacade- Parameters:
key- the hash of the RouterInfo or LeaseSet to look up- Returns:
- RouterInfo, LeaseSet, or null, validated
lookupLocallyWithoutValidation
Not for use without validation.- Specified by:
lookupLocallyWithoutValidationin classNetworkDatabaseFacade- Parameters:
key- the hash of the RouterInfo or LeaseSet to look up- Returns:
- RouterInfo, LeaseSet, or null, NOT validated
lookupLeaseSet
Look up a LeaseSet, locally first.Searches remotely if the LeaseSet is not held locally, is not negative-cached, and is not a local destination this router hosts.
- Specified by:
lookupLeaseSetin classNetworkDatabaseFacade- Parameters:
key- the LeaseSet keyonFindJob- run if the LeaseSet is found locally or in the search, may be nullonFailedLookupJob- run if the lookup cannot be attempted or fails, may be nulltimeoutMs- how long to wait for the search before failing
lookupLeaseSet
public void lookupLeaseSet(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs, Hash fromLocalDest) Lookup using the client's tunnels UselookupDestination(Hash, Job, long, Hash)if you don't need the LS or don't need it validated.A negative-cached key is not searched again: the failure job is run instead. A client sub-NetDb local miss for a destination this router hosts also fails without a search, since only the main NetDb holds such a LeaseSet.
- Specified by:
lookupLeaseSetin classNetworkDatabaseFacade- Parameters:
key- the LeaseSet keyonFindJob- run if the LeaseSet is found locally or in the search, may be nullonFailedLookupJob- run if the router is uninitialized, the key is negative-cached, or the search fails, may be nulltimeoutMs- how long to wait for the search before failingfromLocalDest- use these tunnels for the lookup, or null for exploratory
shouldFailLocalWithoutRemoteSearch
static boolean shouldFailLocalWithoutRemoteSearch(boolean isClientDb, boolean isLocalDest) Whether a client sub-NetDb local miss for a destination this router hosts must fail immediately instead of starting a network search. Locally-published LeaseSets live in the main NetDb (mirrored on publish); querying floodfills for our own key is always wasted work and the client sub-Db path has no reply routing for that search.- Parameters:
isClientDb- true when this facade is a client sub-NetDbisLocalDest- true when the key is a destination hosted on this router- Returns:
- true to fail without a remote search
shouldFallbackLocalLookupToMain
static boolean shouldFallbackLocalLookupToMain(boolean isClientDb, boolean isLocalDest, boolean foundLocally) Whether a client sub-NetDb local miss should be re-checked in the main NetDb. Only for destinations we host; remote keys must stay isolated in the caller's sub-NetDb.- Parameters:
isClientDb- true when this facade is a client sub-NetDbisLocalDest- true when the key is a destination hosted on this routerfoundLocally- true when this facade already held a current LeaseSet- Returns:
- true to consult the main NetDb
isLocalDestination
Whether the key is one of our own destinations.- Parameters:
key- destination hash to test, null returns false- Returns:
- true if the key is a destination currently registered locally
getMainFacade
Main (router) NetDb facade, or null if unavailable.- Returns:
- the main facade, or null
lookupLeaseSetRemotely
Unconditionally lookup using the client's tunnels, with no jobs. No local lookup and no LeaseSet validation. Use this to refresh a LeaseSet before expiration.The one check that does apply is the negative cache: a negative-cached key returns without searching, since a recent search already established that the key is unresolvable. Nothing is sent to the caller if the router is uninitialized.
- Specified by:
lookupLeaseSetRemotelyin classNetworkDatabaseFacade- Parameters:
key- the LeaseSet keyfromLocalDest- use these tunnels for the lookup, or null for exploratory
lookupLeaseSetRemotely
public void lookupLeaseSetRemotely(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs, Hash fromLocalDest) Unconditionally lookup using the client's tunnels.Same negative-cache suppression as the two-argument overload: a negative-cached key is not searched again and the failure job is run instead. Nothing is searched if the router is uninitialized.
- Specified by:
lookupLeaseSetRemotelyin classNetworkDatabaseFacade- Parameters:
key- the LeaseSet keyonFindJob- run if the LeaseSet is found, may be nullonFailedLookupJob- run if the router is uninitialized, the key is negative-cached, or the search fails, may be nulltimeoutMs- how long to wait for the search before failingfromLocalDest- use these tunnels for the lookup, or null for exploratory
lookupLeaseSetLocally
LeaseSet stored locally.- Specified by:
lookupLeaseSetLocallyin classNetworkDatabaseFacade- Parameters:
key- the destination hash whose LeaseSet is sought- Returns:
- the LeaseSet or null
getLocalLeaseSet
accessLeaseSet
Record access to a LeaseSet for refresh tracking. Call this when actively using a LeaseSet (tunnel build, outbound message). Tracks all remote destinations, hostname or not, tunnel pool or not - b32/hash-only services (SAM, BOB, anonymous browsing) need refreshing too, and getOutboundPool() is keyed by local client hash, so it can never be used to gate remote destinations. Do NOT call for HostChecker lookups.- Specified by:
accessLeaseSetin classNetworkDatabaseFacade- Parameters:
key- the destination hash of the LeaseSet that was used
refreshLocalLeaseSetIfExpiring
Nudge the inbound pool to re-publish our own LeaseSet when a client is actively using it and the earliest lease is inside the proactive window. No-op without a stored LeaseSet or when the earliest lease still has ample remaining life.- Parameters:
key- local destination hashnow- current router time (ms)
removeLeaseSetFromTracking
Remove a LeaseSet from refresh tracking. Call this after HostChecker completes to avoid unnecessary refreshes.- Specified by:
removeLeaseSetFromTrackingin classNetworkDatabaseFacade- Parameters:
key- the destination hash of the LeaseSet to stop tracking
lookupDestination
Lookup using the client's tunnels Succeeds even if LS validation and store fails due to unsupported sig type, expired, etc.Note that there are not separate success and fail jobs. Caller must call
lookupDestinationLocally(Hash)in the job to determine success.The finished job is also run, without any search, if the router is uninitialized or the key is negative-cached.
- Specified by:
lookupDestinationin classNetworkDatabaseFacade- Parameters:
key- the destination keyonFinishedJob- run when the lookup finishes, may not be nulltimeoutMs- how long to wait for the search before finishingfromLocalDest- use these tunnels for the lookup, or null for exploratory
lookupDestinationLocally
Destination stored locally, or null.- Specified by:
lookupDestinationLocallyin classNetworkDatabaseFacade- Parameters:
key- the destination hash to look up- Returns:
- the Destination or null
containsCapability
Whether the router advertises the given capability.- Parameters:
ri- router whose capability string is examinedcapability- one of the Router.CAPABILITY_* characters, e.g. 'G'- Returns:
- true if that character appears in the capability string
lookupRouterInfo
Look up a RouterInfo, resolving over the network when not cached locally.Screening (country/capability bans, blocklists) applies only to an entry we actually hold; a screened-out entry fails the callback instead of succeeding. A cache miss always starts a real search: data-plane callers (transit next-hop resolution in BuildHandler and TunnelParticipant, tunnel receivers, message distributors) depend on this actually finding the peer, and an instant fail here turns every next-hop miss into a rejected join or a silently dropped message. Negatively-cached keys short-circuit inside IterativeSearchJob, so repeated searches for known-dead peers stay cheap.
- Specified by:
lookupRouterInfoin classNetworkDatabaseFacade- Parameters:
key- the router hash whose RouterInfo is soughtonFindJob- job to run on successonFailedLookupJob- job to run on failuretimeoutMs- timeout in milliseconds
lookupRouterInfoRemote
Look up a RouterInfo by hash, performing a network search if not locally cached. UnlikelookupRouterInfo(Hash, Job, Job, long)which calls onFailedLookupJob immediately for unknown routers, this method schedules an IterativeSearchJob when the RI is absent from the local netdb. The caller should provide a timeoutMs shorter than the acceptable delay (typical: 8-15 seconds).The onFindJob fires when the RI is available locally (either it was already present or the search completed). The onFailedLookupJob fires on search timeout or failure.
Caller must clean up via
removeRouterInfo(Hash)after extracting the needed data.- Parameters:
key- the Router hash to look uponFindJob- run when RI is local (may be null)onFailedLookupJob- run on lookup failure (may be null)timeoutMs- max wait in ms (bounded internally by the adaptive lookup cap)
shouldBanlistBasedOnCountry
Should we banlist this router based on country restrictions? Checks if: - we are in strict country mode and router is in same country - blockMyCountry is enabled - router is in our country (strict country mode).- Parameters:
_ri- router info under consideration, not consulted by the testkey- router hash, used to look up strict-country membership- Returns:
- true if the peer's country makes it banlistable
shouldBanlistXG
Determine whether the given router should be banlisted due to being an XG router that is neither reachable nor unreachable and the XG banlist option is enabled.- Parameters:
ri- the router info to evaluate- Returns:
- true if the router matches the XG banlist criteria
shouldBanlistLU
Determine whether the given router should be banlisted due to being: - an unreachable L-tier router (CAPABILITY_BW12),This is typically used to filter out low-performing routers.
- Parameters:
ri- the router info to evaluate- Returns:
- true if the router matches the LU banlist criteria
tooManyIntroducers
Whether any single transport address advertises more introducers than the SSU2 spec allows. Every introducer slot carries a relay tag, so a tag at or beyond the cap means the peer wrote more slots than it may. Checked per address, not in total: a dual-stack router may legitimately carry the cap once on v4 and again on v6, and the console flattens both lists.- Parameters:
addrs- the router's transport addresses, may be null or empty- Returns:
- true if one address declares more than
MAX_INTRO_SLOTSintroducers
shouldBanlistIntroducers
Determine whether the given router should be banlisted for advertising more introducers on one transport address than the SSU2 spec allows. Out-of-spec introducer counts are used by scanners to inflate netdb storage and by modified clients to hide behind relay churn.- Parameters:
ri- the router info to evaluate- Returns:
- true if the router matches the introducer-cap ban criteria
invalidRouterInfoBanReason
The ban reason if this RouterInfo fails one of the RouterInfo validation rules - a version above every released version, an impossible publication date, or both the reachable and the unreachable flag at once - or null if it passes. Each rule has its own toggle on /configban. The reason strings match what the transport handshakes record, so a peer is penalised identically however we learn of it.- Parameters:
ri- the router info to evaluate- Returns:
- the ban reason for the first rule it breaks, or null if it breaks none
invalidRouterInfoBanReason
static String invalidRouterInfoBanReason(RouterInfo ri, boolean banVersion, boolean banPubDate, boolean banCaps) The validation rule a RouterInfo breaks, given which of the three rules are switched on. The self-router check and the toggle reads stay with the caller; this is the pure part, so the rule ordering and the reason strings can be tested without a router context.- Parameters:
ri- the router info to evaluate, may be nullbanVersion- whether the fabricated-version rule is enabledbanPubDate- whether the impossible-publication-date rule is enabledbanCaps- whether the contradictory-reachability rule is enabled- Returns:
- the reason for the first rule broken, or null if none
shouldBanlistByCapability
Determine whether the given router should be banlisted based on custom capability patterns configured by the user.- Parameters:
ri- the router info to evaluate- Returns:
- true if the router matches any custom capability ban pattern
allowPolicyBan
Whether policy bans (country/XG/LU/capability) may be applied to this router during resolution. Controlled byrouter.banlist.banNextHop: when false, peers we are not directly connected to - transit next-hop candidates and client tunnel endpoints heard from the network - are exempt, so transit and client traffic never banlist a peer merely because it appeared as a resolution target. Security screening (permanent/hostile blocklists) is unaffected.- Parameters:
key- the router being resolved- Returns:
- true if policy bans may fire for this lookup
handleCustomCapabilityBan
Handle banning a router that matches custom capability ban patterns, for four hours.- Parameters:
ri- router info to ban, source of the IP:port in the ban logkey- router hash to banlist and drop from the netdbonFailedLookupJob- queued to fail the pending lookup, or null
handleIntroducerBan
Handle banning a router that advertises more introducers on one address than the SSU2 spec allows. Same four-hour term the SSU2 handshake ban uses, so a peer is penalised identically however we learn of it.- Parameters:
ri- router info to ban, source of the IP:port in the ban logkey- router hash to banlist and drop from the netdbonFailedLookupJob- job to requeue if the lookup is abandoned, or null
handleInvalidRouterInfoBan
private void handleInvalidRouterInfoBan(RouterInfo ri, Hash key, String reason, Job onFailedLookupJob) Handle banning a RouterInfo that breaks one of the RouterInfo validation rules - fabricated version, impossible publication date, or contradictory reachability flags. Same 24-hour term the transport handshakes use for the same rule, so a peer is penalised identically however we learn of it.- Parameters:
ri- the offending router infokey- the router hashreason- the rule it broke, frominvalidRouterInfoBanReason(RouterInfo)onFailedLookupJob- job to requeue a lookup that resolved to this router, or null
removeRouterInfo
Remove a RouterInfo from the local netdb. No-op if the key is not present or is not a RouterInfo. Safe to call on any hash — non-RouterInfo entries are left untouched.- Parameters:
key- the Router hash to remove
removeFromNetDb
Remove a router from the NetDb without banning it. Used internally by the purge sweep and handleBanlistAndRemove.- Parameters:
key- router hash to drop, null is a no-op
purgeMatchingRouters
public void purgeMatchingRouters()Trigger a retroactive purge sweep of the NetDb. Bans and removes all routers matching enabled LU/XG/custom-cap bans. Only call this on config change, not on startup or disable.- Overrides:
purgeMatchingRoutersin classNetworkDatabaseFacade
isPermanentlyBlocklisted
Whether the router is on the permanent blocklist.- Parameters:
key- router hash to look for in the Banlist- Returns:
- true if the Banlist holds the key with no expiry
isHostileBlocklisted
Whether the router is on the hostile blocklist.- Parameters:
key- router hash to look for in the Banlist- Returns:
- true if the Banlist holds the key as hostile
handleBanlistAndRemove
Banlist a router for one hour as an unreachable low-bandwidth peer older thanMIN_VERSION, then drop it from the data store, the routing buckets and the unverified queue.- Parameters:
ri- router info being banned, source of the IP:port in the logkey- router hash to banlist and drop from the netdbonFailedLookupJob- requeued as the lookup's failure, or null
handlePermanentBlocklist
Drop the RouterInfo of a router already on the permanent blocklist; no new ban entry is written, the existing one stands.- Parameters:
_ri- router info being dropped, not consultedkey- router hash removed from the netdb and the routing tablesonFailedLookupJob- requeued as the lookup's failure, or null
handleHostileBlocklist
Drop the RouterInfo of a router tagged hostile on the Banlist, without extending or adding a ban.- Parameters:
_ri- router info being dropped, not consultedkey- router hash removed from the netdb and the routing tablesonFailedLookupJob- queued to fail the pending lookup, or null
lookupRouterInfoLocally
This will return immediately with the result or null. However, this may still fire off a lookup if the RI is present but expired (and will return null). This may result in deadlocks. For true local only, uselookupLocallyWithoutValidation(Hash).- Specified by:
lookupRouterInfoLocallyin classNetworkDatabaseFacade- Parameters:
key- the router hash whose RouterInfo is sought- Returns:
- null always for client dbs
getProactiveRepublishThreshold
private long getProactiveRepublishThreshold()Proactive republish threshold from config or default (3 minutes). If a lease is expiring within this threshold, it gets republished immediately. Tunable viai2p.netdb.proactiveRepublishThreshold(default: 180000).- Returns:
- the proactive republish threshold
publish
Publishes a local LeaseSet to the network: stores it in this facade and, for a client facade, also in the floodfill facade, then schedules republishing. LeaseSet expiry dates are validated first (not expired before publish).- Specified by:
publishin classNetworkDatabaseFacade- Parameters:
localLeaseSet- the LeaseSet to publish- Throws:
IllegalArgumentException- if the LeaseSet is invalid or expired
storeLocalLeaseSetCopy
Store the local copy, forcing overwrite; propagate IAE to the caller.- Parameters:
localLeaseSet- the LeaseSet a local client just published- Throws:
IllegalArgumentException- if storing it fails validation
handleNonPublishedLeaseSet
A local client whose LS is not published to the network (i2cp.dontPublishLeaseSet, e.g. HTTP proxy) still needs the local copy re-minted while it is active. Client leases last ~6 min but tunnels rotate on a ~10-min cycle, so without a republish schedule the local LeaseSet shows expired in the netdb for minutes at a time.- Parameters:
hash- destination hash of a client we host but do not publish
isGracefulExitShutdown
private boolean isGracefulExitShutdown()Whether the router is shutting down gracefully.- Returns:
- true if a graceful shutdown with defined exit codes is in progress
mirrorToMainFacade
A locally-published LeaseSet legitimately occupies both the client facade (where the client pushed it) and the floodfill facade (where the router console and the network look it up). Storing the copy into the floodfill facade here makes hosted services retrievable immediately, without waiting for the network to flood the LeaseSet back to us. The NetDbRenderer dedups the two facades' entries on the netdb page.- Parameters:
localLeaseSet- copy to place in the main (floodfill) facade
validateLeaseSetExpiry
Reject a LeaseSet whose leases are already in the past, allowingEXPIRY_GRACE_PERIODof slack for clock skew.- Parameters:
leaseSet- the locally-published LeaseSet about to be stored- Throws:
IllegalArgumentException- if either lease date is more than the grace period in the past
scheduleRepublish
Queues the LeaseSet for future republishing. First publications are queued immediately; subsequent republishes are batched within a 15-second window to reduce job queue pressure.Proactively starts republishing 3 minutes before lease expiration to ensure network propagation has ample time before the lease expires.
- Parameters:
hash- destination hash of the LeaseSet to republish
cancelActiveRepublishJob
Cancel any queued RepublishLeaseSetJob for the given hash. This ensures that the next fresh run picks up the latest LeaseSet rather than using one that was stale when the job was queued.- Parameters:
hash- destination hash whose queued republish job is withdrawn- Returns:
- true if a job was cancelled, false if none existed
removePublishingJob
Remove a specific job from the tracking set.- Parameters:
hash- the destination hashjob- the job to remove
hasActiveRepublishJob
Check if an active republish job exists for the given destination.- Parameters:
hash- the destination hash- Returns:
- true if active
registerPublishingJob
Register a new job for tracking. Skips registration if a job is already active.- Parameters:
job- the job to register- Returns:
- true if job was registered, false if one was already active
stopPublishing
Stops publishing the given LeaseSet.- Parameters:
target- hash to stop publishing
publish
Stores to local db only. Overridden in FNDF to actually send to the floodfills.- Specified by:
publishin classNetworkDatabaseFacade- Parameters:
localRouterInfo- the RouterInfo to publish- Throws:
IllegalArgumentException- if the local router info is invalid or if this is a client DB
routerInfoPublishSuccessful
void routerInfoPublishSuccessful()Record the current time as the last successful RI publication.getLastRouterInfoPublishTime
public long getLastRouterInfoPublishTime()Time of the last successful RI publication.- Overrides:
getLastRouterInfoPublishTimein classNetworkDatabaseFacade- Returns:
- ms since the epoch of the last successful publication, 0 if never
validate
Validates whether the given LeaseSet is acceptable as valid and current based on current known parameters.This method performs several checks including:
- Verifying the key matches the LeaseSet destination.
- Validating the LeaseSet's cryptographic signature.
- Checking if the LeaseSet is too old (expired).
- Checking if the LeaseSet expires too far in the future.
Note: Unlike RouterInfos, this validation is only done once at storage time. Afterward,
LeaseSet.isCurrent()should be used to check currency.- Parameters:
key- the expected key (destination hash) for this LeaseSetleaseSet- the LeaseSet instance to validate- Returns:
- a descriptive reason why the LeaseSet is invalid or expired, or
nullif the LeaseSet is valid - Throws:
UnsupportedCryptoException- if the LeaseSet uses an unsupported cryptographic type/signature
validateKeyMatch
validateSignature
private String validateSignature(Hash key, LeaseSet leaseSet, String leaseBase32) throws UnsupportedCryptoException Verify the LeaseSet's cryptographic signature validity.- Parameters:
key- the expected key (destination hash) for this LeaseSetleaseSet- the LeaseSet instance to validateleaseBase32- base32 of the LeaseSet hash, for logging- Returns:
- a descriptive reason why the signature is invalid, or null
- Throws:
UnsupportedCryptoException- if the signature type is unsupported
checkExpiredLeaseSet
private String checkExpiredLeaseSet(Hash key, LeaseSet leaseSet, long earliest, long latest, long now, String idShort) Reject a LeaseSet whose timestamps are outdated (stale).- Parameters:
key- the expected key (destination hash) for this LeaseSetleaseSet- the LeaseSet instance to validateearliest- earliest relevant datelatest- latest relevant datenow- current time in ms, from the router clockidShort- shortened destination ID for logs and messages- Returns:
- a descriptive reason why the LeaseSet is expired, or null
checkFutureExpiration
private String checkFutureExpiration(LeaseSet leaseSet, int type, long latest, long now, String idShort) Reject a LeaseSet that expires too far into the future, to handle clock skew issues.- Parameters:
leaseSet- the LeaseSet instance to validatetype- the LeaseSet typelatest- latest relevant datenow- current time in ms, from the router clockidShort- shortened destination ID for logs and messages- Returns:
- a descriptive reason why the LeaseSet is rejected, or null
store
Store the LeaseSet without persisting it to disk.- Specified by:
storein classNetworkDatabaseFacade- Parameters:
key- the LeaseSet keyleaseSet- the LeaseSet to store- Returns:
- the previous entry for the key, or null
- Throws:
IllegalArgumentException- if the LeaseSet is not valid
store
Store the leaseSet.If the store fails due to unsupported crypto, it will negative cache the hash until restart.
- Parameters:
key- the hash keyleaseSet- the leaseSet to storeforce- always store even if not newer- Returns:
- previous entry or null
- Throws:
IllegalArgumentException- if the leaseSet is not validUnsupportedCryptoException- if that's why it failed.
copyStoreMetadata
checkForHashCollision
Reject a store whose LeaseSet hash collides with an existing LeaseSet for a different destination.- Parameters:
rv- the stored copy, or nullleaseSet- the incoming LeaseSetforce- if true, skip the collision check- Throws:
IllegalArgumentException- on a hash collision
resolveBlindData
Resolve blind data for an encrypted LeaseSet so validate() can verify the signature, setting the secret before the destination.- Parameters:
encls- the encrypted LeaseSetleaseSet- the incoming LeaseSet, for the signing key
handleBlindStore
After storing, handle the blind data bookkeeping: an encrypted LeaseSet we have now decrypted is stored under its own key, and a blinded-when-published LeaseSet marks its destination as blinded.- Parameters:
encls- the encrypted LeaseSet, or nullleaseSet- the stored LeaseSet
isNewer
shouldAcceptLeaseSet
Determine whether an incoming LeaseSet may replace the currently stored copy.The anti-clobber rule: a strictly-newer incoming copy always replaces the stored copy; an equal- or older-dated incoming copy is rejected so a late echo or duplicate cannot clobber fresher data (see
isNewer(LeaseSet, LeaseSet)).Exception: when the stored copy has lapsed - its latest lease ends within
Router.CLOCK_FUDGE_FACTORofnow- the stored copy carries no reachability value, so any incoming copy (still validated by the caller beforestore(Hash, LeaseSet)) is accepted to restore service. Without this, a hidden service that re-publishes the same LeaseSet2 generation (unchanged publish date) can never refresh a lapsed local copy, leaving the destination unreachable until the service happens to generate a brand-new LeaseSet2.- Parameters:
stored- the currently stored copy, non-nullincoming- the incoming copy, non-nullnow- the current time in ms- Returns:
- true if the incoming copy should replace the stored copy
validate
Determine whether this routerInfo will be accepted as valid and current given what we know now. Call this only on first store, to check the key and signature once.If the store fails due to unsupported crypto, it will banlist the router hash until restart and then throw UnsupportedCryptoException.
- Parameters:
key- hash the entry is stored under, compared against the RouterInfo's own identity hashrouterInfo- the RouterInfo about to be stored- Returns:
- reason why the entry is not valid, or null if it is valid
- Throws:
UnsupportedCryptoException- if that's why it failed.IllegalArgumentException
validate
Determine whether this routerInfo will be accepted as valid and current given what we know now.Call this before each use, to check expiration.
- Parameters:
routerInfo- the router info to validate- Returns:
- reason why the entry is not valid, or null if it is valid
- Throws:
IllegalArgumentException
shouldSkipValidation
private boolean shouldSkipValidation()Determines whether validation should be skipped based on initialization status or dummy communication system.- Returns:
- true if validation should be skipped, false otherwise
getRouterId
Generates a short identifier for a router based on its hash.- Parameters:
routerInfo- the RouterInfo to extract the ID from- Returns:
- the first 6 characters of the base64-encoded router hash
banInvalidNTCPAddresses
private boolean banInvalidNTCPAddresses(RouterInfo routerInfo, long now, String caps, String routerId) Checks for invalid NTCP2 addresses in the given RouterInfo and bans the router if any are found.- Parameters:
routerInfo- the RouterInfo to validatenow- current timestamp in millisecondscaps- the capabilities string of the routerrouterId- the short ID of the router- Returns:
- true if the router has invalid NTCP addresses and was banned, false otherwise
isUptimeLongEnough
private boolean isUptimeLongEnough(long uptime) Checks if the router's uptime is long enough to begin validating other routers.The minimum uptime is determined by the property "
router.validateRoutersAfter" (in minutes), or defaults to 20 minutes.- Parameters:
uptime- how long the router has been up, in milliseconds- Returns:
- true if the uptime is sufficient, false otherwise
computeAdjustedExpiration
private long computeAdjustedExpiration(int existingRouters) Computes the expiration time for a RouterInfo based on current network conditions.The expiration time can be customized via the "
router.expireRouterInfo" property (in hours), or defaults based on the number of existing routers or whether this is a floodfill.- Parameters:
existingRouters- the number of routers currently stored on disk- Returns:
- the adjusted expiration time in milliseconds
checkCountryBlocking
Checks if the given router should be blocked due to country restrictions.This includes: - Strict country mode - Hidden mode - Configuration-based country bans - XG router bans.
- Parameters:
routerInfo- the RouterInfo to evaluatecaps- the capabilities string of the routerrouterId- the short ID of the routerh- the Hash of the router- Returns:
- true if the router should be blocked, false otherwise
checkXG
Whether the router should be XG-banned: an X-tier (unlimited bandwidth) router advertising the G (no tunnels) capability. The ban is one hour.- Parameters:
routerInfo- router under validation, source of the IP:port loggedcaps- capability string, checked for 'f' to label the ban logrouterId- truncated base64 hash, used only in the log lineh- router hash the ban is written against- Returns:
- true if the router is an XG router, banlisted here or already
checkLU
Ban LU (low bandwidth) routers unconditionally for 1 hour. These routers flood the network with no meaningful bandwidth contribution.- Parameters:
routerInfo- router under validation, source of the IP:port loggedcaps- capability string, null means no ban is possiblerouterId- truncated base64 hash, used only in the log lineh- router hash the ban is written against- Returns:
- true if the router is a low-tier unreachable peer
isRouterXG
Determines whether the given router qualifies as an XG router that should be blocked.An XG router is defined as: - Has the G capability (no tunnels) - Has the X (unlimited bandwidth) capability.
- Parameters:
routerInfo- the RouterInfo to evaluateisUs- true if the router is the local router- Returns:
- true if the router is an XG router and should be blocked
checkFutureRouterInfo
private String checkFutureRouterInfo(RouterInfo routerInfo, long now, String caps, String routerId, Hash h, boolean isUs) Checks if the given router info was published in the future and bans it if so.- Parameters:
routerInfo- the RouterInfo to evaluatenow- current timestamp in millisecondscaps- the capabilities string of the routerrouterId- the short ID of the routerh- the Hash of the routerisUs- true if the router is the local router- Returns:
- a descriptive string if the router is from the future, null otherwise
checkRouterVersion
Checks if the given router is running a version older than the minimum allowed.If so, it bans the router until restart.
- Parameters:
routerInfo- the RouterInfo to evaluatecaps- the capabilities string of the routerrouterId- the short ID of the routerh- the Hash of the router- Returns:
- a descriptive string if the router is too old, null otherwise
dropSlowRouter
private String dropSlowRouter(RouterInfo routerInfo, long now, int existing, String caps, String routerId) Checks if the given router should be dropped due to being a slow tier (K, L, or M) and outdated.- Parameters:
routerInfo- the RouterInfo to evaluatenow- current timestamp in millisecondsexisting- number of routers currently stored on diskcaps- the capabilities string of the routerrouterId- the short ID of the router- Returns:
- a descriptive string if the router should be dropped, null otherwise
lookupRIUnvalidated
Look up a peer's RouterInfo without running the fullvalidate(RouterInfo)ban cascade.lookupLocallyWithoutValidation(Hash)returns any database entry, so the entry type is checked here;lookupRouterInfoLocally(Hash)would have done that plus the validation. Callers must only use the result where a validating lookup would answer the same question — presence, or a predicate over the peer's own immutable RouterInfo fields.- Parameters:
key- the peer hash- Returns:
- the RouterInfo, or null if this peer is not held as a RouterInfo
checkAddressesAndIntroducers
private String checkAddressesAndIntroducers(RouterInfo routerInfo, String caps, String routerId, boolean isUs, boolean dontFail) Checks if the router has no valid addresses or introducers and has been published too long ago.Only applies once the router is past the 54 minute "introduced" window and while still inside the startup grace period (
dontFail) is skipped, so a fresh router is never dropped on this check.- Parameters:
routerInfo- the RouterInfo to evaluatecaps- the capabilities string of the routerrouterId- the short ID of the routerisUs- true if the router is the local routerdontFail- whether to skip failure checks- Returns:
- a descriptive string if the router should be dropped, null otherwise
checkExpirationBasedDrop
private String checkExpirationBasedDrop(RouterInfo routerInfo, boolean upLongEnough, long adjustedExpiration, long now, String caps, String routerId, boolean isUs) Checks if the router has expired based on configured expiration time.- Parameters:
routerInfo- the RouterInfo to evaluateupLongEnough- true if the local router has been up long enoughadjustedExpiration- the computed expiration time in millisecondsnow- current timestamp in millisecondscaps- the capabilities string of the routerrouterId- the short ID of the routerisUs- true if the router is the local router- Returns:
- a descriptive string if the router should be dropped, null otherwise
checkShortExpiration
private String checkShortExpiration(RouterInfo routerInfo, String caps, String routerId, boolean isUs) Why the router's short expiration is disqualifying, or null. Once a RouterInfo is older thanROUTER_INFO_EXPIRATION_SHORT, an SSU-only peer with no introducers, or one unreachable on every transport, is dropped.- Parameters:
routerInfo- router to check, null returns nullcaps- capability string, used only to build the reason textrouterId- truncated base64 hash, used only in the reason textisUs- true to exempt our own RouterInfo from being dropped- Returns:
- reason to drop the entry, or null to keep it
checkStaleRouterInfo
private String checkStaleRouterInfo(RouterInfo routerInfo, boolean upLongEnough, int existing, String routerId, boolean isUs) Whether an otherwise-acceptable RouterInfo has aged pastcomputeAdjustedExpiration(int)and should now be dropped.This is the last-resort stale-entry policy, applied after the address, introducer, expiration-property, and short-expiration checks. It only runs once the local router has been up long enough (
isUptimeLongEnough(long)) and never for the local router, and it is suppressed while fewer thanMIN_REMAINING_ROUTERSrouters are stored on disk, so a thinning network does not drop down to nothing. Capabilities are not consulted here;checkAddressesAndIntroducers(RouterInfo, String, String, boolean, boolean)is the check for missing transports.- Parameters:
routerInfo- the RouterInfo to evaluateupLongEnough- true if the local router has been up long enoughexisting- the number of routers currently stored on diskrouterId- the short ID of the routerisUs- true if the router is the local router- Returns:
- a descriptive string if the router should be dropped, null otherwise
store
Store the routerInfo.If the store fails due to unsupported crypto, it will banlist the router hash until restart and then throw UnsupportedCrytpoException.
- Specified by:
storein classNetworkDatabaseFacade- Parameters:
key- the hash keyrouterInfo- the router info to store- Returns:
- previous entry or null
- Throws:
IllegalArgumentException- if the routerInfo is not validUnsupportedCryptoException- if that's why it failed.
store
Store the routerInfo.If the store fails due to unsupported crypto, it will banlist the router hash until restart and then throw UnsupportedCrytpoException.
- Parameters:
key- the hash keyrouterInfo- the router info to storepersist- whether to persist to disk- Returns:
- previous entry or null
- Throws:
IllegalArgumentException- if the routerInfo is not validUnsupportedCryptoException- if that's why it failed.
stripStoreWrapper
Strip the "Invalid NetDbStore attempt" wrapper from a store rejection message, keeping the capability flags and the Router [id] the console renders as a link.- Parameters:
message- the rejection message, may be null- Returns:
- the bare rejection detail, for log output
addContact
Insert a newly-stored peer into the routing buckets, gated on two local-only checks (no wire-format change):- verify-before-add — a peer merely named in someone else's DatabaseSearchReply has never answered us, so it waits in
_unverifiedPeersuntil direct-contact evidence arrives (a reply, a successful send, or an established session). This is the main dead-peer contamination vector for the routing table. - IP diversity — cap how many entries of one IP group (a /16 for IPv4, a /48 for IPv6) one bucket and the whole table will hold, so a single entity cannot eclipse our routing table.
- Parameters:
key- the peer hashrouterInfo- the peer's RouterInfo (for its addresses)
- verify-before-add — a peer merely named in someone else's DatabaseSearchReply has never answered us, so it waits in
addContact
Policy entry point for peers learned from search replies, where no RouterInfo is in hand yet: direct-contact gate only. The diversity check runs when the RI lands viastore(Hash, LeaseSet). Rejected peers are queued and probed/promoted by the ProbeStalePeerJob cycle.- Parameters:
key- the peer hash- Returns:
- true if the peer was inserted into its bucket now
queueUnverified
Queue a peer for later bucket promotion once it proves itself, sweeping expired entries when the queue is full.- Parameters:
key- peer hash to hold pending direct-contact evidence
hasDirectContact
Have we ever heard from this peer directly, as opposed to merely being told about it? An established session or a profile with a received message or successful send counts.- Parameters:
peer- the peer hash, non-null- Returns:
- true if the peer has answered us at some point
hasDirectContact
Direct-contact test on profile evidence only: heard-from or successful-send, never heard-about (that only means someone mentioned them). Null-safe.- Parameters:
prof- the peer's profile or null- Returns:
- true if the profile shows direct contact
promoteUnverifiedPeers
int promoteUnverifiedPeers()Move pending peers that have earned direct-contact evidence into the routing buckets, and drop those that waited too long. Called byProbeStalePeerJobeach cycle, which also probes the pending peers so live ones earn evidence quickly.- Returns:
- number promoted into buckets
getUnverifiedPeerCount
int getUnverifiedPeerCount()The pending-verification queue size, for tests and the debug console.- Returns:
- zero or more
getUnverifiedPeersSnapshot
ipDiversityAllows
Would adding this peer to its bucket exceed the per-bucket or global IP-group caps? Peers with no literal-IP address are unconstrained.- Parameters:
key- the peer hashrouterInfo- the peer's RouterInfo- Returns:
- true if the diversity policy allows the add
ipGroups
The distinct IP groups of a router's literal-IP addresses. Package private for testing.- Parameters:
ri- router whose literal-IP addresses are grouped- Returns:
- non-null set of group keys, empty if no literal IPs
ipGroup
IP group key: /16 for IPv4, /48 for IPv6, packed into a long with a family marker bit so the two families never collide. Hostnames (getIP() null) have no group.- Parameters:
ip- 4- or 16-byte address, or null- Returns:
- the group key, or null if not a literal IP
processStoreFailure
If the validate fails, call this to determine if it was because of unsupported crypto.If so, this will banlist-forever the router hash or permanently negative cache the dest hash, and then throw the exception. Otherwise it does nothing.
- Parameters:
h- hash the failed store was attempted underentry- the entry that failed validation, RouterInfo or LeaseSet- Throws:
UnsupportedCryptoException- if that's why it failed.
checkLeaseSetSigType
Reject LeaseSets with unsupported signature types; negative-cache the destination permanently.- Parameters:
h- destination hash the store was attempted under, log-onlyls- LeaseSet whose key certificate names the signature type- Throws:
UnsupportedCryptoException- if the sig type is unavailable or RSA
checkRouterInfoSigType
Reject RouterInfos with unsupported signature types; ban until restart.- Parameters:
h- router hash the permanent ban is written againstri- RouterInfo that failed signature validation- Throws:
UnsupportedCryptoException- if the sig type is unavailable
sigTypeDescription
Human-readable signature type for log messages.- Parameters:
kc- key certificate whose sig type code is the fallback texttype- resolved signature type, null when it is not recognized- Returns:
- the sig type name, or the raw type code when unnamed
fail
Final remove for a leaseset. For a router info, will look up in the network before dropping.- Specified by:
failin classNetworkDatabaseFacade- Parameters:
dbEntry- the key of the entry to fail
lookupBeforeDropping
Don't use directly - see F.N.D.F. override.- Parameters:
peer- the router hash to drop after the lookup failureinfo- the router info
dropAfterLookupFailed
Final remove for a router info. Do NOT use for leasesets.- Parameters:
peer- the peer hash- Returns:
- true if logged
unpublish
Description copied from class:NetworkDatabaseFacadeUnpublish a LeaseSet from the network database.- Specified by:
unpublishin classNetworkDatabaseFacade- Parameters:
localLeaseSet- the LeaseSet to unpublish
search
abstract SearchJob search(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs, boolean isLease) Begin a kademlia-style iterative search for the key, which can take up to timeoutMs and will fire the appropriate jobs on success or timeout (or if the search completes without any match).Abstract because only a concrete facade knows how to reach floodfills;
FloodfillNetworkDatabaseFacadeimplements this with IterativeSearchJob. Data-plane callers such aslookupRouterInfo(Hash, Job, Job, long)route transit traffic through here, so there is deliberately no base fallback: a facade that cannot search must say so at compile time.- Parameters:
key- the hash to search foronFindJob- job on findonFailedLookupJob- job on failuretimeoutMs- timeout in msisLease- whether searching for lease- Returns:
- implementation-defined; results are delivered via the callbacks
search
abstract SearchJob search(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs, boolean isLease, Hash fromLocalDest) Search using the client's tunnels; seesearch(Hash, Job, Job, long, boolean).- Parameters:
key- the hash to search foronFindJob- job on findonFailedLookupJob- job on failuretimeoutMs- timeout in msisLease- whether searching for leasefromLocalDest- use these tunnels for the lookup, or null for exploratory- Returns:
- implementation-defined; results are delivered via the callbacks
getLeases
Description copied from class:NetworkDatabaseFacadeAll known LeaseSets for display.- Overrides:
getLeasesin classNetworkDatabaseFacade- Returns:
- set of LeaseSets, or empty
getClientLeases
LeaseSets published by this router's clients.- Overrides:
getClientLeasesin classNetworkDatabaseFacade- Returns:
- the local LeaseSets, or null before the database is initialized
getPublishedLeases
LeaseSets published to the network.- Overrides:
getPublishedLeasesin classNetworkDatabaseFacade- Returns:
- the local LeaseSets that shouldPublishLeaseSet approves, or null before the database is initialized
getUnpublishedLeases
LeaseSets not published to the network.- Overrides:
getUnpublishedLeasesin classNetworkDatabaseFacade- Returns:
- the local LeaseSets that shouldPublishLeaseSet rejects, or null before the database is initialized
getFloodfillLeases
LeaseSets stored in the floodfill database.- Overrides:
getFloodfillLeasesin classNetworkDatabaseFacade- Returns:
- the stored LeaseSets, or null before the database is initialized
getRouters
RouterInfos stored in the database.- Overrides:
getRoutersin classNetworkDatabaseFacade- Returns:
- the stored RouterInfos, empty in client mode, or null before the database is initialized
getPeerTimeout
How long to wait for one peer's reply, scaled from its profile.- Parameters:
peer- the router hash whose profile sets the timeout; must not be null- Returns:
- the timeout in ms, 7500-45000; 45000 when there is no profile data
sendStore
abstract void sendStore(Hash key, DatabaseEntry ds, Job onSuccess, Job onFailure, long sendTimeout, Set<Hash> toIgnore) See implementation in FNDF.- Parameters:
key- the DatabaseEntry hashds- the database entryonSuccess- may be null; called on reply-based store success (not used for wide-flood-only RI path)onFailure- may be null; called when no floodfill peers are available or reply-based store failssendTimeout- timeout in ms for the reply-based FloodfillStoreJob pathtoIgnore- may be null, if non-null, all attempted and skipped targets will be added as of 0.9.53; passed through to FloodfillStoreJob (unused for wide-flood-only RI path)
lookupFailed
Increment in the negative lookup cache.- Parameters:
key- for Destinations or RouterIdentities
lookupTimeout
Pure-timeout search failure (no peer replied). Higher negative-cache threshold thanlookupFailed(Hash).- Parameters:
key- the key that timed out
isNegativeCached
Is the key in the negative lookup cache?- Parameters:
key- for Destinations or RouterIdentities- Returns:
- true if cached
peekNegativeCached
Negative-cache check without recording an abort stat. Used by callers that need to branch on cache state before deciding cooldown/stats, so a single send path does not double-countnetDb.negativeCache.- Parameters:
key- the key to check- Returns:
- true if the key is negatively cached (transient or permanent)
clearNegativeCache
Clear any transient (non-permanent) negative-cache entry for the given key so the nextlookupLeaseSet(Hash, Job, Job, long)performs a real search instead of aborting instantly. Permanent negatives (failPermanently(Destination)) are left intact. Used by the outbound client message path to re-probe a destination whose LeaseSet was valid recently but is undergoing a transient gap.- Parameters:
key- the destination hash
failPermanently
Negative cache until restart.- Parameters:
dest- the Destination to remember as unreachable until restart
isNegativeCachedForever
Is it permanently negative cached?- Overrides:
isNegativeCachedForeverin classNetworkDatabaseFacade- Parameters:
key- only for Destinations; for RouterIdentities, see Banlist- Returns:
- whether negative cached forever
renderStatusHTML
Render the KBucket summary and a per-bucket table. Writes nothing before startup(). The individual keys are not listed; they carry no diagnostic value and made the page unreadable.- Specified by:
renderStatusHTMLin interfaceService- Overrides:
renderStatusHTMLin classNetworkDatabaseFacade- Parameters:
out- where to write the HTML- Throws:
IOException- on write errors
peerRenderer
_t
buildBucketTable
static String buildBucketTable(List<String[]> rows, int capacity, java.util.function.Function<String, String> entryRenderer, java.util.function.Function<String, String> tr) Build the bucket table from the rows ofKBucketSet.getDebugBucketRows(): bucket index, XOR-distance bit range, entry count as a details/summary disclosure whose expanded content is the entry hashes rendered by the given function, and fill as a percentage of capacity. Package-visible for testing.- Parameters:
rows- the bucket rowscapacity- the per-bucket capacity, greater than zeroentryRenderer- renders each entry hash as htmltr- translates a label, identity in tests- Returns:
- the table html, never null
entryLinks
Entry hashes rendered through the given function, sorted for stable display.- Parameters:
keys- comma-separated base64 hashes, may be emptyentryRenderer- renders each hash as html- Returns:
- the entries html, or an em-dash if there are no keys
getDebugStats
public long[] getDebugStats()Debug overview stats: total keys, bucket count, per-bucket capacity and fullest bucket size, as {keys, buckets, capacity, fullest}. Null where the facade has no kademlia buckets. Reads the live bucket set under its read lock.- Overrides:
getDebugStatsin classNetworkDatabaseFacade- Returns:
- the stats, or null
toString
getBlockedCountries
getStoredRouterInfoCount
public int getStoredRouterInfoCount()Number of RouterInfo files stored on disk, if usingPersistentDataStore.- Returns:
- number of RIs on disk, or 0 if not using persistent storage
refreshClientLeaseSets
private void refreshClientLeaseSets()Refresh client lease sets.pruneLeaseSetTracking
private void pruneLeaseSetTracking()Evict oldest tracked entries to cap map size.proactivelyRefreshIfExpiring
Refresh a tracked LeaseSet early when it is about to expire. Always uses client tunnels for client subDb refresh.- Parameters:
key- destination hash of the tracked LeaseSetnow- current router time in ms, compared with the lease expiryns- naming service used only to name the entry in the log- Returns:
- true if the proactive refresh was triggered
logName
Best-effort display name for a tracked LeaseSet in logs: the registered hostname when available, otherwise a truncated base32. Never gates refresh.- Parameters:
ns- naming service to reverse-lookup, may be nullkey- LeaseSet hash to name, used for the base32 fallback- Returns:
- the registered hostname, or the hash as [8 base32 chars]