java.lang.Object
net.i2p.router.BanLogger

public class BanLoggerextends Object
Dedicated logger for all ban events. Writes to sessionbans.txt in the router's data directory.

This allows analysis of ban patterns without parsing router.log.

  • Field Details

    • _context

      private RouterContext _context
      The router context.
    • _log

      private Log _log
      Logger for the ban messages.
    • _logFile

      private File _logFile
      File the ban records are written to.
    • _dateFormat

      private final ThreadLocal<DateFormat> _dateFormat
      Per-thread formatter for the record dates.
    • _banCount

      private AtomicInteger _banCount
      Bans recorded by this instance.
    • _startTime

      private long _startTime
      When this instance started recording.
    • _writeLock

      private final Object _writeLock
      Lock for writing the log file.
    • self

      private static BanLogger self
      The single instance of the logger.
    • LOG_DIR

      private static final String LOG_DIR
      Directory holding the ban logs.
      See Also:
    • LOG_FILENAME

      private static final String LOG_FILENAME
      Name of the current ban log file.
      See Also:
    • ARCHIVE_PREFIX

      private static final String ARCHIVE_PREFIX
      Prefix of the archived ban log names.
      See Also:
    • PROP_MAX_ARCHIVES

      private static final String PROP_MAX_ARCHIVES
      Config key for the archive count kept.
      See Also:
    • PIPE_SPLIT

      private static final Pattern PIPE_SPLIT
      Splits a ban record on the pipe separators.
    • DEFAULT_MAX_ARCHIVES

      private static final int DEFAULT_MAX_ARCHIVES
      Archives kept by default.
      See Also:
    • writer

      private static volatile PrintWriter writer
      Writer for the current ban log file.
    • initialized

      private static volatile boolean initialized
      True once the log file was opened.
    • globalArchiveDone

      private static volatile boolean globalArchiveDone
      True once the old global log was archived.
    • headerWritten

      private static volatile boolean headerWritten
      True once the file header was written.
  • Constructor Details

    • BanLogger

      public BanLogger()
      No-arg constructor for deferred initialization.
    • BanLogger

      public BanLogger(RouterContext context)
      Constructor with context for immediate initialization.
      Parameters:
      context - the router context
  • Method Details

    • initialize

      public void initialize(RouterContext context)
      Initialize the logger. Safe to call multiple times.
      Parameters:
      context - the router context
    • hasActiveBan

      private boolean hasActiveBan(String ip)
      Check if an IP already has an active ban in sessionbans.txt.
      Parameters:
      ip - the address to search for, without a port; null is never banned
      Returns:
      true if a hash-less ban line for this IP has not expired yet
    • isInitialized

      public static boolean isInitialized()
      Check if the logger is initialized.
      Returns:
      true if initialized
    • getInstance

      public static BanLogger getInstance()
      The singleton instance of BanLogger. May return null if not initialized yet.
      Returns:
      the singleton instance, or null if not initialized
    • archiveExisting

      private void archiveExisting()
      Archive an existing log file from a previous session. Called during initialization before opening a new writer.
    • archiveIfNeeded

      public void archiveIfNeeded()
      Archive the current log when closing. Uses the router start time to timestamp the archive.
    • cleanupOldArchives

      private void cleanupOldArchives()
      Clean up old archives, keeping only the configured maximum.
    • logStartTime

      private void logStartTime()
      Log the router start time.
    • openWriter

      private void openWriter()
      Initialize the log file writer.
    • logBan

      public void logBan(Hash hash, String ip, String reason, long durationMs)
      Log a ban by hash with IP address.
      Parameters:
      hash - Router hash (may be null)
      ip - IP address with port (format: "1.2.3.4:5678" or "ipv6:port")
      reason - Reason for the ban
      durationMs - Ban duration in milliseconds, or 0 for permanent
    • logBan

      public void logBan(Hash hash, String ip, String reason, long durationMs, RouterInfo ri)
      Log a ban with RouterInfo for direct caps extraction. Prefer this when the RouterInfo is available at the callsite, to avoid a NetDB lookup that may fail if the RI was never stored.
      Parameters:
      hash - Router hash (may be null)
      ip - IP address with port (format: "1.2.3.4:5678" or "ipv6:port")
      reason - Reason for the ban
      durationMs - Ban duration in milliseconds, or 0 for permanent
      ri - RouterInfo to extract capabilities from (may be null)
    • logBan

      public void logBan(String ip, String reason, long durationMs)
      Log a ban by IP only (ignores hash).
      Parameters:
      ip - IP address with port (format: "1.2.3.4:5678" or "ipv6:port")
      reason - Reason for the ban
      durationMs - Ban duration in milliseconds, or 0 for permanent
    • logBanIPOnly

      public void logBanIPOnly(String ip, String reason, long durationMs)
      Log a ban by IP only (no router hash available). Uses "UNKNOWN" for the hash column.
      Parameters:
      ip - IP address with port (format: "1.2.3.4:5678" or "ipv6:port")
      reason - Reason for the ban
      durationMs - Ban duration in milliseconds, or 0 for permanent
    • logBanForever

      public void logBanForever(Hash hash, String ip, String reason)
      Log a permanent ban (forever).
      Parameters:
      hash - Router hash (may be null)
      ip - IP address with port (format: "1.2.3.4:5678" or "ipv6:port")
      reason - Reason for the ban
    • logBanForever

      public void logBanForever(Hash hash, String ip, String reason, RouterInfo ri)
      Log a permanent ban with RouterInfo for direct caps extraction.
      Parameters:
      hash - Router hash (may be null)
      ip - IP address with port (format: "1.2.3.4:5678" or "ipv6:port")
      reason - Reason for the ban
      ri - RouterInfo to extract capabilities from (may be null)
    • logBanForever

      public void logBanForever(String ip, String reason)
      Log a permanent ban by IP only.
      Parameters:
      ip - IP address with port (format: "1.2.3.4:5678" or "ipv6:port")
      reason - Reason for the ban
    • logBan

      public void logBan(Hash hash, RouterContext context, String reason, long durationMs)
      Log a ban by hash with RouterContext (IP will be looked up from banlist).
      Parameters:
      hash - Router hash (may be null)
      context - Router context for IP lookup
      reason - Reason for the ban
      durationMs - Ban duration in milliseconds, or 0 for permanent
    • logBanForever

      public void logBanForever(Hash hash, RouterContext context, String reason)
      Log a permanent ban with RouterContext.
      Parameters:
      hash - Router hash (may be null)
      context - Router context for IP lookup
      reason - Reason for the ban
    • getCaps

      private String getCaps(Hash hash)
      Capabilities string from RouterInfo for the given hash.
      Parameters:
      hash - the router to look up in the local NetDb, null yields an empty string
      Returns:
      caps string or empty string
    • getVersion

      private String getVersion(Hash hash)
      Version string from RouterInfo for the given hash.
      Parameters:
      hash - the router whose version is looked up in the local NetDb, null yields an empty string
      Returns:
      version string or empty string
    • stripPort

      private static String stripPort(String ipPort)
      Extract the bare IP (strip port) from an "ip:port" or "[ipv6]:port" string.
      Parameters:
      ipPort - the address and port as stored in the ban log
      Returns:
      the address without its port, or null for null, empty or "UNKNOWN" input
    • getCountry

      private String getCountry(String ipPort)
      Country code from IP using GeoIP.
      Parameters:
      ipPort - the banned address with port; the port is stripped before the lookup
      Returns:
      country code or empty string
    • getHost

      private String getHost(String ipPort)
      Hostname or ASN org name from IP using the local ASN database. Non-blocking — uses cached results or fast local MMDB lookup.
      Parameters:
      ipPort - the banned address with port; the port is stripped before the lookup
      Returns:
      hostname/ASN or empty string
    • getIPFromContext

      private String getIPFromContext(Hash hash, RouterContext context)
      IP address from banlist for the given hash.
      Parameters:
      hash - the router to look up, null yields "UNKNOWN"
      context - the context whose NetDb is searched, unused when the hash is null
      Returns:
      the router's address with port, or "UNKNOWN" if the hash is null or the router is not cached locally
    • fetchRouterInfo

      private void fetchRouterInfo(Hash hash, String reason, long durationMs)
      Schedule an async network lookup for a RouterInfo that was not locally cached when the ban was logged. When the lookup completes, write a second line to sessionbans.txt with the actual IP, caps, and version, then evict the RouterInfo from the netdb (we only fetched it for logging).

      This is a best-effort operation: silently keep the basic entry on failure.

      Parameters:
      hash - Router hash (non-null)
      reason - reason from the ban
      durationMs - ban length in milliseconds; zero or less logs it as FOREVER
    • getIPFromRouterInfo

      private String getIPFromRouterInfo(RouterInfo router)
      Extract IP address and port from RouterInfo.
      Parameters:
      router - the router whose first address with a host is used, null yields an empty string
      Returns:
      the address as "host:port", with an IPv6 host in brackets, or an empty string when no address has a host
    • writeLog

      private void writeLog(String hashStr, String ip, String reason, String durationStr, String caps, String version, String country, String host)
      Internal method to write the log entry. Skips logging if this IP already has an active ban in sessionbans.txt, or if this hash is already banlisted.
      Parameters:
      hashStr - the router's base64 hash, or "UNKNOWN" for an IP-only ban
      ip - the banned address with port, "UNKNOWN" when it is not known
      reason - the ban reason as shown in the console, HTML markup is stripped
      durationStr - the ban duration already formatted, "FOREVER" for a permanent ban
      caps - the router's capabilities string, null or empty leaves the field blank
      version - the router's version string, null or empty leaves the field blank
      country - the two-letter country code of the IP, null or empty leaves it blank
      host - the hostname or ASN organisation of the IP, null or empty leaves it blank
    • formatDuration

      private static String formatDuration(long durationMs)
      Format duration in milliseconds to human-readable string.
      Parameters:
      durationMs - the ban length in milliseconds, 0 or less means permanent
      Returns:
      the length with a unit suffix of ms, m, h or d, or "FOREVER" for a permanent ban
    • parseDuration

      private static long parseDuration(String durationStr, long now)
      Parse duration string to expiration timestamp.
      Parameters:
      durationStr - the duration as written in the log: "FOREVER", or a number with an optional ms, m, h or d suffix; null or empty means already expired
      now - the current time in milliseconds, added to the parsed length
      Returns:
      the expiry time in milliseconds, Long.MAX_VALUE for a permanent ban, or now when the string is empty or cannot be parsed
    • getLogFile

      public File getLogFile()
      The log file path.
      Returns:
      the log file
    • shutdown

      public static void shutdown()
      Shutdown the ban logger — close the writer and release resources. Safe to call multiple times.
    • flush

      public void flush()
      Flush the log writer.
    • close

      public void close()
      Close the log writer and archive if there are entries.