java.lang.Object
net.i2p.router.BanLogger
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 Summary
FieldsModifier and TypeFieldDescriptionprivate AtomicIntegerBans recorded by this instance.private RouterContextThe router context.private final ThreadLocal<DateFormat> Per-thread formatter for the record dates.private LogLogger for the ban messages.private FileFile the ban records are written to.private longWhen this instance started recording.private final ObjectLock for writing the log file.private static final StringPrefix of the archived ban log names.private static final intArchives kept by default.private static booleanTrue once the old global log was archived.private static booleanTrue once the file header was written.private static booleanTrue once the log file was opened.private static final StringDirectory holding the ban logs.private static final StringName of the current ban log file.private static final PatternSplits a ban record on the pipe separators.private static final StringConfig key for the archive count kept.private static BanLoggerThe single instance of the logger.private static PrintWriterWriter for the current ban log file.Constructor Summary
ConstructorsConstructorDescriptionNo-arg constructor for deferred initialization.BanLogger(RouterContext context) Constructor with context for immediate initialization.Method Summary
Modifier and TypeMethodDescriptionprivate voidArchive an existing log file from a previous session.voidArchive the current log when closing.private voidClean up old archives, keeping only the configured maximum.voidclose()Close the log writer and archive if there are entries.private voidfetchRouterInfo(Hash hash, String reason, long durationMs) Schedule an async network lookup for a RouterInfo that was not locally cached when the ban was logged.voidflush()Flush the log writer.private static StringformatDuration(long durationMs) Format duration in milliseconds to human-readable string.private StringCapabilities string from RouterInfo for the given hash.private StringgetCountry(String ipPort) Country code from IP using GeoIP.private StringHostname or ASN org name from IP using the local ASN database.static BanLoggerThe singleton instance of BanLogger.private StringgetIPFromContext(Hash hash, RouterContext context) IP address from banlist for the given hash.private StringgetIPFromRouterInfo(RouterInfo router) Extract IP address and port from RouterInfo.The log file path.private StringgetVersion(Hash hash) Version string from RouterInfo for the given hash.private booleanhasActiveBan(String ip) Check if an IP already has an active ban in sessionbans.txt.voidinitialize(RouterContext context) Initialize the logger.static booleanCheck if the logger is initialized.voidLog a ban by IP only (ignores hash).voidLog a ban by hash with IP address.voidlogBan(Hash hash, String ip, String reason, long durationMs, RouterInfo ri) Log a ban withRouterInfofor direct caps extraction.voidlogBan(Hash hash, RouterContext context, String reason, long durationMs) Log a ban by hash withRouterContext(IP will be looked up from banlist).voidlogBanForever(String ip, String reason) Log a permanent ban by IP only.voidlogBanForever(Hash hash, String ip, String reason) Log a permanent ban (forever).voidlogBanForever(Hash hash, String ip, String reason, RouterInfo ri) Log a permanent ban with RouterInfo for direct caps extraction.voidlogBanForever(Hash hash, RouterContext context, String reason) Log a permanent ban with RouterContext.voidlogBanIPOnly(String ip, String reason, long durationMs) Log a ban by IP only (no router hash available).private voidLog the router start time.private voidInitialize the log file writer.private static longparseDuration(String durationStr, long now) Parse duration string to expiration timestamp.static voidshutdown()Shutdown the ban logger — close the writer and release resources.private static StringExtract the bare IP (strip port) from an "ip:port" or "[ipv6]:port" string.private voidwriteLog(String hashStr, String ip, String reason, String durationStr, String caps, String version, String country, String host) Internal method to write the log entry.
Field Details
_context
The router context._log
Logger for the ban messages._logFile
File the ban records are written to._dateFormat
Per-thread formatter for the record dates._banCount
Bans recorded by this instance._startTime
private long _startTimeWhen this instance started recording._writeLock
Lock for writing the log file.self
The single instance of the logger.LOG_DIR
LOG_FILENAME
Name of the current ban log file.- See Also:
ARCHIVE_PREFIX
Prefix of the archived ban log names.- See Also:
PROP_MAX_ARCHIVES
Config key for the archive count kept.- See Also:
PIPE_SPLIT
Splits a ban record on the pipe separators.DEFAULT_MAX_ARCHIVES
private static final int DEFAULT_MAX_ARCHIVESArchives kept by default.- See Also:
writer
Writer for the current ban log file.initialized
private static volatile boolean initializedTrue once the log file was opened.globalArchiveDone
private static volatile boolean globalArchiveDoneTrue once the old global log was archived.headerWritten
private static volatile boolean headerWrittenTrue once the file header was written.
Constructor Details
BanLogger
public BanLogger()No-arg constructor for deferred initialization.BanLogger
Constructor with context for immediate initialization.- Parameters:
context- the router context
Method Details
initialize
Initialize the logger. Safe to call multiple times.- Parameters:
context- the router context
hasActiveBan
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
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
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 bandurationMs- Ban duration in milliseconds, or 0 for permanent
logBan
Log a ban withRouterInfofor 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 bandurationMs- Ban duration in milliseconds, or 0 for permanentri- RouterInfo to extract capabilities from (may be null)
logBan
logBanIPOnly
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 bandurationMs- Ban duration in milliseconds, or 0 for permanent
logBanForever
logBanForever
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 banri- RouterInfo to extract capabilities from (may be null)
logBanForever
logBan
Log a ban by hash withRouterContext(IP will be looked up from banlist).- Parameters:
hash- Router hash (may be null)context- Router context for IP lookupreason- Reason for the bandurationMs- Ban duration in milliseconds, or 0 for permanent
logBanForever
Log a permanent ban with RouterContext.- Parameters:
hash- Router hash (may be null)context- Router context for IP lookupreason- Reason for the ban
getCaps
getVersion
stripPort
getCountry
getHost
getIPFromContext
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
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 bandurationMs- ban length in milliseconds; zero or less logs it as FOREVER
getIPFromRouterInfo
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 banip- the banned address with port, "UNKNOWN" when it is not knownreason- the ban reason as shown in the console, HTML markup is strippeddurationStr- the ban duration already formatted, "FOREVER" for a permanent bancaps- the router's capabilities string, null or empty leaves the field blankversion- the router's version string, null or empty leaves the field blankcountry- the two-letter country code of the IP, null or empty leaves it blankhost- the hostname or ASN organisation of the IP, null or empty leaves it blank
formatDuration
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
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 expirednow- 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
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.