java.lang.Object
net.i2p.router.web.helpers.HostCheckStatus

public class HostCheckStatusextends Object
Whether each site in the Sites of Interest listing is still worth showing.

A site can fail in two independent ways, so two sources are consulted.

Addressbook membership. The router resolves names through BlockfileNamingService, backed by hostsdb.blockfile - the live addressbook, which is much larger than the hosts.txt shipped at install and accumulates entries beyond it. A site the naming service cannot resolve cannot be reached by name, so it is not shown. Membership is therefore asked of NamingService rather than read from any file: hosts.txt is only the seed the database was built from and says nothing about what is live.

Probe status. The addressbook checker periodically probes the sites it knows and appends the outcome to addressbook/hosts_check.txt, one CSV row per probe:

 # Format: timestamp,host,reachable,category,responseTime,leaseSetTypes
 1791429608769,exil3.i2p,y,forum,34765,[6,4]

A site in the addressbook whose latest probe failed is hidden and reappears when a later probe succeeds. A site in the addressbook that has not been probed yet is shown: absence of a result is not evidence of failure, so a cold cache must not empty the page.

Only the host column and the reachable flag are read. The trailing field contains commas of its own ([6,4]); that is harmless because the fields of interest come first and the split is positional.

Probe results are cached for one ping interval, since they cannot change any faster than the checker refreshes them.

  • Field Details

    • STATUS_DIR

      static final String STATUS_DIR
      Directory under the router dir holding the addressbook's own state.
      See Also:
    • STATUS_FILE

      static final String STATUS_FILE
      The probe results, written by the addressbook host checker.
      See Also:
    • BLACKLIST_FILE

      static final String BLACKLIST_FILE
      Hostnames the operator has blacklisted, maintained by susidns/addressbook.
      See Also:
    • CONFIG_FILE

      static final String CONFIG_FILE
      Where the ping interval is configured.
      See Also:
    • PROP_PING_INTERVAL

      static final String PROP_PING_INTERVAL
      Key naming the ping interval in CONFIG_FILE.
      See Also:
    • DEFAULT_INTERVAL_MS

      static final long DEFAULT_INTERVAL_MS
      Used when the config is absent or unparseable. Matches the checker's own default.
      See Also:
    • REACHABLE_YES

      static final String REACHABLE_YES
      The reachable flag as the checker writes it.
      See Also:
    • REACHABLE_NO

      static final String REACHABLE_NO
      The unreachable flag as the checker writes it.
      See Also:
    • MIN_FIELDS

      private static final int MIN_FIELDS
      Rows carry at least timestamp, host and reachable.
      See Also:
    • FIELD_HOST

      private static final int FIELD_HOST
      Field index of the host in a results line.
      See Also:
    • FIELD_REACHABLE

      private static final int FIELD_REACHABLE
      Field index of the reachable flag in a results line.
      See Also:
    • MAX_LINE

      private static final int MAX_LINE
      Longest results line read, in bytes.
      See Also:
    • _cachedDir

      private static File _cachedDir
      Directory the cached results were read from.
    • _probed

      private static Map<String,Boolean> _probed
      Reachability results, by host.
    • _blacklisted

      private static Set<String> _blacklisted
      Hosts excluded from the checks.
    • _loadedAt

      private static long _loadedAt
      Time the cached results were read.
    • _ttl

      private static long _ttl
      Age past which the cached results are refreshed.
  • Constructor Details

    • HostCheckStatus

      public HostCheckStatus()
      Constructor. Every read below resolves the status directory from the router context on the spot, so a bare instance holds no state.
  • Method Details

    • probed

      public static Map<String,Boolean> probed(File routerDir)
      The probe results, cached for the current ping interval.

      Callers rendering a whole list should fetch once and use isDown(String, boolean, Map) per entry, rather than re-reading per entry.

      Parameters:
      routerDir - the router's working directory
      Returns:
      host to reachable flag; empty if the results file could not be read, which judges nothing rather than judging everything
    • blacklisted

      public static Set<String> blacklisted(File routerDir)
      Hostnames the operator has blacklisted, cached on the same cycle as the probe results.

      This is the susidns/addressbook blacklist, one lowercased hostname per line. It is not the router's Banlist, which is a separate peer-hash mechanism with expiry: the two answer different questions, and a hostname can be blacklisted here without the router ever refusing that peer.

      Parameters:
      routerDir - the router's working directory
      Returns:
      the blacklisted hostnames, empty if the file could not be read
    • refresh

      private static void refresh(File routerDir)
      Reload both files if the cache has expired.

      They are refreshed together on purpose: the checker rewrites both, so they have the same cadence, and one timestamp for the pair means a page render can never mix a fresh blacklist with stale probe results. Freshness is keyed on the timestamp rather than on whether the files were found, so a missing file does not make every request re-read.

      Parameters:
      routerDir - the router's working directory
    • isDown

      public static boolean isDown(String host, boolean inAddressbook, Map<String,Boolean> probed)
      Whether a site should be hidden from the listing.

      A site is hidden when it is not in the addressbook at all, or when its latest probe failed. A site in the addressbook with no probe result is shown, because untested is not the same as down.

      Parameters:
      host - hostname, already lowercased
      inAddressbook - whether the naming service resolves the host
      probed - result of probed(File)
      Returns:
      true if the link should not be shown
    • isBlacklisted

      public static boolean isBlacklisted(String host, Set<String> blacklist)
      Whether a hostname is blacklisted.

      A blacklisted host is never offered as a link, whatever the probe results say. That is a stronger rule than "down": the operator has said they do not want it reached, so a successful probe does not earn it a place back.

      Parameters:
      host - lowercase host, as returned by hostFromUrl(String)
      blacklist - result of blacklisted(File)
      Returns:
      true if the host is blacklisted
    • parseBlacklistLine

      public static void parseBlacklistLine(String line, Set<String> out)
      Record one entry of the blacklist, which is a bare hostname per line.

      Comments and blank lines are skipped and the name is lowercased, so the file stays usable if it is ever hand-edited. A line carrying anything other than a hostname is ignored rather than stored, since a malformed entry must not silently blank a link.

      Parameters:
      line - one line from the blacklist
      out - receives the hostname
    • hostFromUrl

      public static String hostFromUrl(String url)
      Extract the host from a link's URL.

      Strips the scheme, any path, any port, and lowercases the result. Returns null when there is no host to extract, which is also the signal that the link is not a site the addressbook could ever hold.

      Parameters:
      url - the configured URL
      Returns:
      the lowercase host, or null
    • isI2pHost

      public static boolean isI2pHost(String host)
      Whether a host is one the addressbook can hold, i.e. an I2P name.

      Links to clearnet or to the console's own paths are always shown; only .i2p names can be judged down.

      A .b32.i2p name is deliberately included: it is an I2P name, and the naming service resolves it. It is left in scope even though resolving one can reach the network, because the listing is not expected to contain them.

      Parameters:
      host - lowercase host, as returned by hostFromUrl(String)
      Returns:
      true if the host is an I2P name
    • parseProbeLine

      public static void parseProbeLine(String line, Map<String,Boolean> out)
      Record one row of the results file.

      Comments and blank lines are skipped, as is any row whose reachable flag is neither y nor n, so a half-written row cannot be mistaken for a verdict and hide a working site. Hosts are lowercased so lookups need not worry about case. Later rows win, which is what lets a recovered site come back.

      Parameters:
      line - one line from the results file
      out - receives host to reachable
    • parseInterval

      public static long parseInterval(String value)
      Convert a configured ping interval to milliseconds.

      Follows the checker's own convention: a trailing M means minutes, anything else means hours. The config in use reads pingInterval=1, which means one hour rather than one minute.

      Parameters:
      value - the raw config value
      Returns:
      the interval in milliseconds, or DEFAULT_INTERVAL_MS if unusable
    • readProbed

      private static Map<String,Boolean> readProbed(File routerDir)
      Read the probe results.
      Parameters:
      routerDir - the router's working directory
      Returns:
      host to reachable, or null if the file could not be read
    • readBlacklist

      private static Set<String> readBlacklist(File routerDir)
      Read the susidns/addressbook blacklist.
      Parameters:
      routerDir - the router's working directory
      Returns:
      the blacklisted hostnames, or null if the file could not be read
    • readInterval

      private static long readInterval(File routerDir)
      Read the configured ping interval.
      Parameters:
      routerDir - the router's working directory
      Returns:
      the interval in milliseconds, defaulting if unreadable
    • clearCache

      static void clearCache()
      Drop the cache. For tests, and for reacting to a configuration change.