java.lang.Object
org.klomp.snark.SnarkManager
All Implemented Interfaces:
ClientApp, I2PSocketManager.DisconnectListener, CompleteListener

public class SnarkManagerextends Object implements CompleteListener, ClientApp, I2PSocketManager.DisconnectListener
Central manager for multiple torrent downloads and the I2PSnark application.

This class is the core controller that manages:

  • Multiple torrent instances (Snarks) and their lifecycle
  • Configuration management and persistence
  • Peer coordination and bandwidth management
  • Tracker communication and DHT integration
  • Web interface and user interaction
  • Torrent file monitoring and auto-loading
  • Magnet link handling
  • Comments and metadata management

As a ClientApp, it integrates with the I2P router application framework and can be started, stopped, and monitored through the standard I2P interfaces.

  • Field Details

    • _snarks

      private final Map<String,Snark> _snarks
      Map of (canonical) filename of the .torrent file to Snark instance. This is a CHM so listTorrentFiles() need not be synced, but all adds, deletes, and the DirMonitor should sync on it.
    • _infoHashToSnark

      private final Map<SHA1Hash,Snark> _infoHashToSnark
      Snarks by info hash; synchronize on _snarks.
    • _filteredBaseNameToSnark

      private final Map<String,Snark> _filteredBaseNameToSnark
      Snarks by filtered base name; synchronize on _snarks.
    • _magnets

      private final Set<String> _magnets
      Prevents DirMonitor from deleting torrents that don't have a torrent file yet.
    • _addSnarkLock

      private final Object _addSnarkLock
      Lock keeping concurrent snark adds from duplicating work.
    • _configFile

      private File _configFile
      File holding the global snark config.
    • _configDir

      private File _configDir
      Directory holding the per-torrent config files.
    • _metadataFile

      private File _metadataFile
      File holding the global metadata.
    • _metadata

      private Properties _metadata
      The loaded global metadata.
    • _configLock

      private final Object _configLock
      One lock for all config, files for simplicity.
    • _config

      private Properties _config
      The loaded global config.
    • _context

      private final I2PAppContext _context
      The application context.
    • _contextPath

      private final String _contextPath
      Webapp context path used in links.
    • _contextName

      private final String _contextName
      Display name of the webapp.
    • _log

      private final Log _log
      Logger for this class.
    • _messages

      private final UIMessages _messages
      Translated strings for the web UI.
    • _util

      private final I2PSnarkUtil _util
      Shared utilities and settings for the torrents.
    • _peerCoordinatorSet

      private final PeerCoordinatorSet _peerCoordinatorSet
      Peer coordinators shared between torrents.
    • _connectionAcceptor

      private final ConnectionAcceptor _connectionAcceptor
      Accepts incoming peer connections.
    • _bwManager

      private final BandwidthManager _bwManager
      Shares bandwidth between the torrents.
    • _monitor

      private Thread _monitor
      Thread monitoring the running torrents.
    • _running

      private volatile boolean _running
      True while the manager is running.
    • _stopping

      private volatile boolean _stopping
      True while the manager shuts down.
    • _trackerMap

      private final Map<String,Tracker> _trackerMap
      Trackers by URL.
    • _torrentCreateFilterMap

      private final Map<String, TorrentCreateFilter> _torrentCreateFilterMap
      Torrent create filters by name.
    • _umgr

      private UpdateManager _umgr
      Manager of the torrent update threads.
    • _uhandler

      private UpdateHandler _uhandler
      Thread handling torrent updates.
    • _idleChecker

      private SimpleTimer2.TimedEvent _idleChecker
      Timer stopping idle torrents.
    • MAX_LOOKUP_CONCURRENCY

      private static final int MAX_LOOKUP_CONCURRENCY
      Max concurrent DHT lookup threads (zzzot lookups).
      See Also:
    • LOOKUP_STALE_MS

      static final long LOOKUP_STALE_MS
      Age past which a lookup torrent is swept. Package-visible so the boundary can be pinned by test rather than restated as a literal.
      See Also:
    • LOOKUP_NAME_PREFIX

      private static final String LOOKUP_NAME_PREFIX
      Marker in the display name of a torrent created by a metadata lookup.
      See Also:
    • LOOKUP_PATH_MARKER

      private static final String LOOKUP_PATH_MARKER
      Marker in the storage path of a torrent created by a metadata lookup.
      See Also:
    • _lookupSemaphore

      private final Semaphore _lookupSemaphore
      Caps concurrent magnet and torrent lookups.
    • _lookupCreationTimes

      private final Map<SHA1Hash,Long> _lookupCreationTimes
      Infohash to time (ms) when the lookup was created, for stale cleanup.
    • _staleLookupCleanupRunning

      private volatile boolean _staleLookupCleanupRunning
      True while stale lookups are being cleaned up.
    • _snarkScheduler

      private final ScheduledExecutorService _snarkScheduler
      Snark's own scheduler for periodic chores, deliberately not SimpleTimer2.

      SimpleTimer2 has two worker threads shared by every periodic event in the router, including the stats coalesce sweep. A Snark chore that contends for a lock therefore does not merely delay itself: consuming a worker there stops the coalesce sweep, which silently freezes every RRD graph. That is exactly what a stale-lookup cleanup blocked in SnarkManager did to this router.

      Single-threaded, so overlapping cleanups cannot occur and the existing _staleLookupCleanupRunning guard remains sufficient. The thread is a daemon and is not started until the first task is submitted.

    • _randomizeStartupDelay

      private volatile boolean _randomizeStartupDelay
      True to randomize each torrent's startup delay.
    • _browserApiEnabled

      private volatile boolean _browserApiEnabled
      True to serve the browser API.
    • _browserApiHosts

      private volatile String _browserApiHosts
      Raw comma-separated config value, for the config form.
    • _browserApiHostSet

      private volatile Set<InetAddress> _browserApiHostSet
      Resolved allowed hosts (excluding loopback, which is always allowed).
    • PROP_I2CP_HOST

      public static final String PROP_I2CP_HOST
      I2CP host to connect to the router on.
      See Also:
    • PROP_I2CP_PORT

      public static final String PROP_I2CP_PORT
      I2CP port to connect to the router on.
      See Also:
    • PROP_I2CP_OPTS

      public static final String PROP_I2CP_OPTS
      Extra session options, "name=value" space-separated.
      See Also:
    • PROP_UPLOADERS_TOTAL

      public static final String PROP_UPLOADERS_TOTAL
      Uploader limit summed across all torrents.
      See Also:
    • PROP_UPBW_MAX

      public static final String PROP_UPBW_MAX
      Upload bandwidth cap across all torrents, in KBps.
      See Also:
    • PROP_DOWNBW_MAX

      public static final String PROP_DOWNBW_MAX
      Download bandwidth cap across all torrents, in KBps.
      See Also:
    • PROP_MIN_PIPELINE

      public static final String PROP_MIN_PIPELINE
      Minimum request pipeline depth for outbound requests.
      See Also:
    • PROP_MAX_PIPELINE

      public static final String PROP_MAX_PIPELINE
      Maximum request pipeline depth for outbound requests.
      See Also:
    • PROP_PARTSIZE

      public static final String PROP_PARTSIZE
      Chunk size for outbound piece requests.
      See Also:
    • PROP_MAX_PARTSIZE

      public static final String PROP_MAX_PARTSIZE
      Cap on a single piece request from a peer.
      See Also:
    • PROP_DIR

      public static final String PROP_DIR
      Directory the downloaded torrent data is stored in.
      See Also:
    • PROP_TEMP_DIR

      public static final String PROP_TEMP_DIR
      Configuration key for the staging directory where incomplete files are written until a file's pieces are all downloaded, at which point the file is copied into the data directory. Unset or empty disables the feature.
      See Also:
    • PROP_TORRENT_DIR

      public static final String PROP_TORRENT_DIR
      Configuration key for the directory where .torrent files are stored, separate from the data directory. Unset or empty falls back to the data directory.
      See Also:
    • PROP_META_PREFIX

      private static final String PROP_META_PREFIX
      Config prefix for per-torrent metadata.
      See Also:
    • PROP_META_RUNNING

      static final String PROP_META_RUNNING
      Per-torrent key marking whether the torrent runs at startup; absent means run it.
      See Also:
    • PROP_META_STAMP

      private static final String PROP_META_STAMP
      Metadata key for the last-save time.
      See Also:
    • PROP_META_BASE

      private static final String PROP_META_BASE
      Metadata key for the torrent's data directory.
      See Also:
    • PROP_META_BITFIELD

      private static final String PROP_META_BITFIELD
      Metadata key for the downloaded pieces.
      See Also:
    • PROP_META_PRIORITY

      private static final String PROP_META_PRIORITY
      Metadata key for the file priorities.
      See Also:
    • PROP_META_UPLOADED

      private static final String PROP_META_UPLOADED
      Metadata key for the bytes uploaded.
      See Also:
    • PROP_META_ADDED

      private static final String PROP_META_ADDED
      Metadata key for when the torrent was added.
      See Also:
    • PROP_META_COMPLETED

      private static final String PROP_META_COMPLETED
      Metadata key for when the torrent completed.
      See Also:
    • PROP_META_MAGNET

      private static final String PROP_META_MAGNET
      Metadata key for the magnet URI.
      See Also:
    • PROP_META_MAGNET_DN

      private static final String PROP_META_MAGNET_DN
      Metadata key for the magnet's display name.
      See Also:
    • PROP_META_MAGNET_TR

      private static final String PROP_META_MAGNET_TR
      Metadata key for the magnet's trackers.
      See Also:
    • PROP_META_MAGNET_DIR

      private static final String PROP_META_MAGNET_DIR
      Metadata key for the magnet's target directory.
      See Also:
    • PROP_META_MAGNET_PREFIX

      private static final String PROP_META_MAGNET_PREFIX
      Config prefix for remembered magnet URIs.
      See Also:
    • PROP_META_COMMENTS

      private static final String PROP_META_COMMENTS
      Torrent meta key for comments.
      See Also:
    • PROP_META_ACTIVITY

      private static final String PROP_META_ACTIVITY
      Torrent meta key for activity level.
      See Also:
    • DEPRECATED_PRESERVE_FILE_NAMES

      private static final String DEPRECATED_PRESERVE_FILE_NAMES
      Deprecated per-torrent keys removed in 0.9.71+. preserveFileNames is now global; inOrder was removed entirely. Stripped on load and migration.
      See Also:
    • DEPRECATED_IN_ORDER

      private static final String DEPRECATED_IN_ORDER
      Retired config key for in-order downloading.
      See Also:
    • CONFIG_FILE_SUFFIX

      private static final String CONFIG_FILE_SUFFIX
      Suffix of each torrent's config file.
      See Also:
    • CONFIG_FILE

      public static final String CONFIG_FILE
      Config file name within the config directory; the webapp's name only selects the directory.
      See Also:
    • COMMENT_FILE_SUFFIX

      private static final String COMMENT_FILE_SUFFIX
      Suffix of each torrent's gzipped comments file.
      See Also:
    • METADATA_FILE

      private static final String METADATA_FILE
      Name of the global metadata file.
      See Also:
    • META_PREFIX

      private static final String META_PREFIX
      Prefix of metadata keys inside a config.
      See Also:
    • PROP_FILES_PUBLIC

      public static final String PROP_FILES_PUBLIC
      Whether files in the data directory are world-readable.
      See Also:
    • PROP_PREALLOCATE_FILES

      public static final String PROP_PREALLOCATE_FILES
      Preallocate the storage of new torrents.
      See Also:
    • DEFAULT_PREALLOCATE_FILES

      public static final String DEFAULT_PREALLOCATE_FILES
      true: preallocate new torrents' storage.
      See Also:
    • PROP_SHOULD_PAD_FILES

      public static final String PROP_SHOULD_PAD_FILES
      Add BEP 47 padding files to new torrents.
      See Also:
    • DEFAULT_SHOULD_PAD_FILES

      public static final String DEFAULT_SHOULD_PAD_FILES
      false: leave new torrents unpadded.
      See Also:
    • PROP_BAN_DISCARD_RATIO

      public static final String PROP_BAN_DISCARD_RATIO
      Disconnect peers that cancel most of what they request. On by default; conservative thresholds and a minimum-volume guard protect legitimate peers under congestion.
      See Also:
    • DEFAULT_BAN_DISCARD_RATIO

      public static final String DEFAULT_BAN_DISCARD_RATIO
      true: auto-ban peers with an excessive discard ratio.
      See Also:
    • PROP_BAN_DISCARD_PERIOD

      public static final String PROP_BAN_DISCARD_PERIOD
      Duration of the ban applied to peers with an excessive discard ratio, in minutes.
      See Also:
    • DEFAULT_BAN_DISCARD_PERIOD

      public static final int DEFAULT_BAN_DISCARD_PERIOD
      Discard-ratio bans last an hour.
      See Also:
    • PROP_OLD_AUTO_START

      public static final String PROP_OLD_AUTO_START
      Ancient "i2snark" typo in old configs, migrated to PROP_AUTO_START.
      See Also:
    • PROP_AUTO_START

      public static final String PROP_AUTO_START
      Auto-start saved torrents on startup.
      See Also:
    • DEFAULT_AUTO_START

      private final boolean DEFAULT_AUTO_START
      Whether torrents start on add by default.
    • PROP_STARTUP_DELAY_MIN

      public static final String PROP_STARTUP_DELAY_MIN
      Shortest delay before an auto-started torrent, in minutes.
      See Also:
    • PROP_STARTUP_DELAY_MAX

      public static final String PROP_STARTUP_DELAY_MAX
      Longest delay before an auto-started torrent, in minutes.
      See Also:
    • PROP_REFRESH_DELAY

      public static final String PROP_REFRESH_DELAY
      Seconds between automatic page refreshes.
      See Also:
    • PROP_PAGE_SIZE

      public static final String PROP_PAGE_SIZE
      Torrents listed per page.
      See Also:
    • RC_PROP_THEME

      public static final String RC_PROP_THEME
      Router console property holding the theme shared by all webapps.
      See Also:
    • RC_PROP_UNIVERSAL_THEMING

      public static final String RC_PROP_UNIVERSAL_THEMING
      Router console property applying one theme to all webapps.
      See Also:
    • PROP_THEME

      public static final String PROP_THEME
      Theme I2PSnark uses when universal theming is off.
      See Also:
    • DEFAULT_THEME

      public static final String DEFAULT_THEME
      Theme used until the user picks one.
      See Also:
    • PROP_COLLAPSE_PANELS

      public static final String PROP_COLLAPSE_PANELS
      Start the page panels collapsed.
      See Also:
    • PROP_SHOW_STATUSFILTER

      public static final String PROP_SHOW_STATUSFILTER
      Show the torrents-page status filter.
      See Also:
    • DEFAULT_SHOW_STATUSFILTER

      public static final String DEFAULT_SHOW_STATUSFILTER
      false: hide the status filter.
      See Also:
    • PROP_ENABLE_LIGHTBOX

      public static final String PROP_ENABLE_LIGHTBOX
      Load the image lightbox viewer.
      See Also:
    • DEFAULT_ENABLE_LIGHTBOX

      public static final String DEFAULT_ENABLE_LIGHTBOX
      true: load the lightbox viewer.
      See Also:
    • PROP_ENABLE_ADDCREATE

      public static final String PROP_ENABLE_ADDCREATE
      Keep the add-torrent and create-torrent forms on every page, not just page one.
      See Also:
    • DEFAULT_ENABLE_ADDCREATE

      public static final String DEFAULT_ENABLE_ADDCREATE
      false: show the add/create forms only on page one.
      See Also:
    • PROP_USE_OPENTRACKERS

      private static final String PROP_USE_OPENTRACKERS
      Config property enabling opentracker lists.
      See Also:
    • PROP_OPENTRACKERS

      public static final String PROP_OPENTRACKERS
      Announce URLs of the open trackers, used as backups.
      See Also:
    • PROP_PRIVATETRACKERS

      public static final String PROP_PRIVATETRACKERS
      Announce URLs offered per torrent for private trackers.
      See Also:
    • PROP_USE_DHT

      private static final String PROP_USE_DHT
      Config property enabling DHT lookups.
      See Also:
    • PROP_SMART_SORT

      private static final String PROP_SMART_SORT
      Config property enabling smart piece sorting.
      See Also:
    • PROP_LANG

      private static final String PROP_LANG
      Config property selecting the UI language.
      See Also:
    • PROP_COUNTRY

      private static final String PROP_COUNTRY
      Config property selecting the country.
      See Also:
    • PROP_RATINGS

      private static final String PROP_RATINGS
      Config key enabling ratings display.
      See Also:
    • PROP_COMMENTS

      private static final String PROP_COMMENTS
      Config key enabling comments display.
      See Also:
    • PROP_COMMENTS_NAME

      private static final String PROP_COMMENTS_NAME
      Config key for the comments author name.
      See Also:
    • PROP_MAX_FILES_PER_TORRENT

      public static final String PROP_MAX_FILES_PER_TORRENT
      Ceiling on the number of files one torrent may contain.
      See Also:
    • PROP_API_PREFIX

      private static final String PROP_API_PREFIX
      Config key prefix for API keys.
      See Also:
    • PROP_PRESERVE_FILE_NAMES

      static final String PROP_PRESERVE_FILE_NAMES
      Whether to preserve original file names from the torrent. When false (default), filenames are filtered to remove illegal filesystem characters. When true, original filenames are used but may cause errors on some filesystems; a per-file fallback to safe names occurs with a warning message.
      See Also:
    • PROP_BROWSER_API

      public static final String PROP_BROWSER_API
      Whether the nonce-free browser API (magnet/torrent add) is enabled.
      See Also:
    • PROP_BROWSER_API_HOSTS

      public static final String PROP_BROWSER_API_HOSTS
      Comma-separated hosts (IPs or hostnames) allowed to use the browser API without a nonce, in addition to loopback. Ignored when PROP_BROWSER_API is false.
      See Also:
    • PROP_MAX_MESSAGES

      public static final String PROP_MAX_MESSAGES
      Configured cap on the number of log messages.
      See Also:
    • PROP_VARY_INBOUND_HOPS

      public static final String PROP_VARY_INBOUND_HOPS
      Randomize the hop count of inbound torrent tunnels.
      See Also:
    • PROP_VARY_OUTBOUND_HOPS

      public static final String PROP_VARY_OUTBOUND_HOPS
      Randomize the hop count of outbound torrent tunnels.
      See Also:
    • PROP_MULTI_DEST

      public static final String PROP_MULTI_DEST
      Whether each torrent runs on its own destination.
      See Also:
    • PROP_MULTI_DEST_MAX

      public static final String PROP_MULTI_DEST_MAX
      Maximum number of destinations in multi-dest mode, 0 for one per torrent.
      See Also:
    • PROP_CLIENT_ID

      public static final String PROP_CLIENT_ID
      Client identity spoofing: empty (default) to identify as I2PSnark, "random" to pick a random known client profile per destination per run, or the name of a known client (e.g. "Vuze") to always impersonate it. Applies to the tracker peer ID and User-Agent, the BT handshake peer ID, the BEP 10 extension handshake "v" string, and webseed fetches.
      See Also:
    • PROP_CLIENT_IDS

      public static final String PROP_CLIENT_IDS
      Optional comma-separated subset of client names, see ClientID.profiles(), to choose from when PROP_CLIENT_ID is "random"; unknown names are ignored.
      See Also:
    • PROP_DEST_CYCLE

      public static final String PROP_DEST_CYCLE
      Whether running torrents are periodically stopped and restarted so their destinations rotate to fresh identities, breaking long-lived linkage between the router's IP and the torrents' destinations at trackers and in the DHT. Destinations are ephemeral anyway, changing on every router restart. This extends that to within a run. The cycle is skipped while any torrent is actively downloading, and only the torrents running when the cycle fires are restarted.
      See Also:
    • DEST_CYCLE_INTERVAL

      private static final long DEST_CYCLE_INTERVAL
      Destinations cycle every this long, plus a random jitter.
      See Also:
    • DEST_CYCLE_JITTER

      private static final int DEST_CYCLE_JITTER
      Random jitter added to each destination cycle, so routers do not rotate in lockstep.
      See Also:
    • DEST_CYCLE_RESTART_DELAY

      private static final long DEST_CYCLE_RESTART_DELAY
      Delay after the stop-all before restarting, long enough for the Disconnector to close the old session.
      See Also:
    • PROP_RANDOMIZE_STARTUP

      public static final String PROP_RANDOMIZE_STARTUP
      Stagger batched starts with a random delay, so torrents that start together cannot be correlated by trackers or DHT peers, and tunnel builds are spread out. Disable to start all torrents in a batch immediately.
      See Also:
    • DEFAULT_MULTI_DEST_MAX

      public static final int DEFAULT_MULTI_DEST_MAX
      Default cap on destinations so many torrents share destinations instead of exhausting memory.
      See Also:
    • MAX_MULTI_DEST

      public static final int MAX_MULTI_DEST
      Absolute maximum for the destination cap.
      See Also:
    • MIN_UP_BW

      public static final int MIN_UP_BW
      Lowest upload bandwidth limit the configuration accepts, in KBps.
      See Also:
    • MIN_DOWN_BW

      public static final int MIN_DOWN_BW
      Lowest download bandwidth limit the configuration accepts, in KBps.
      See Also:
    • DEFAULT_MAX_UP_BW

      public static final int DEFAULT_MAX_UP_BW
      Initial upload bandwidth cap across all torrents, in KBps.
      See Also:
    • DEFAULT_MAX_DOWN_BW

      private static final int DEFAULT_MAX_DOWN_BW
      Default download bandwidth cap, in KB/s.
      See Also:
    • DEFAULT_STARTUP_DELAY_MIN

      public static final int DEFAULT_STARTUP_DELAY_MIN
      Initial shortest delay before an auto-started torrent, in minutes.
      See Also:
    • DEFAULT_STARTUP_DELAY_MAX

      public static final int DEFAULT_STARTUP_DELAY_MAX
      Initial longest delay before an auto-started torrent, in minutes.
      See Also:
    • DEFAULT_REFRESH_DELAY_SECS

      public static final int DEFAULT_REFRESH_DELAY_SECS
      Initial seconds between automatic page refreshes.
      See Also:
    • DEFAULT_PAGE_SIZE

      private static final int DEFAULT_PAGE_SIZE
      Default number of torrents per page.
      See Also:
    • DEFAULT_TUNNEL_QUANTITY

      public static final int DEFAULT_TUNNEL_QUANTITY
      Tunnel quantity the default I2CP options ask for, in each direction.
      See Also:
    • MULTI_DEST_STAGGER_MS

      private static final long MULTI_DEST_STAGGER_MS
      Delay between per-destination torrent starts, allowing each destination's tunnels to build.
      See Also:
    • DEFAULT_MAX_FILES_PER_TORRENT

      public static final int DEFAULT_MAX_FILES_PER_TORRENT
      Initial ceiling on the number of files one torrent may contain.
      See Also:
    • CONFIG_DIR_SUFFIX

      public static final String CONFIG_DIR_SUFFIX
      Appended to the old flat config file name to form the config directory name.
      See Also:
    • SUBDIR_PREFIX

      private static final String SUBDIR_PREFIX
      Prefix of the per-torrent data subdirectories.
      See Also:
    • B64

      private static final String B64
      Alphabet used in the subdirectory names.
      See Also:
    • COMMENT_CLEANUP

      private static final Pattern COMMENT_CLEANUP
      Characters stripped from comment text.
    • TORRENT_SUFFIX

      private static final Pattern TORRENT_SUFFIX
      Trailing .torrent suffix stripped from display names.
    • DEFAULT_MAX_MESSAGES

      private static final int DEFAULT_MAX_MESSAGES
      Default messages kept per torrent.
      See Also:
    • DEFAULT_TRACKERS

      private static final String[] DEFAULT_TRACKERS
      "name", "announceURL=websiteURL" pairs '=' in announceURL must be escaped as ,

      Please use host name, not b32 or full dest, in announce URL. Ensure in default hosts.txt. Please use host name, not b32 or full dest, in website URL. Ensure in default hosts.txt.

    • DEFAULT_BACKUP_TRACKER

      public static final String DEFAULT_BACKUP_TRACKER
      URL. This is our equivalent to router.utorrent.com for bootstrap.
      See Also:
    • DEFAULT_OPENTRACKERS

      private static final String DEFAULT_OPENTRACKERS
      URLs, comma-separated. Used for "announce to open trackers also".
      See Also:
    • DEFAULT_TRACKER_ANNOUNCES

      public static final Set<String> DEFAULT_TRACKER_ANNOUNCES
      Default set of tracker announce URLs to use when no torrent trackers are configured.
    • KNOWN_OPENTRACKERS

      static final Set<String> KNOWN_OPENTRACKERS
      Host names for config form.
    • DEFAULT_TORRENT_CREATE_FILTERS

      private static final String[] DEFAULT_TORRENT_CREATE_FILTERS
      Filters blocking torrent creation by default.
    • PROP_TRACKERS

      public static final String PROP_TRACKERS
      Comma delimited list of name=announceURL=baseURL for the trackers to be displayed.
      See Also:
    • PROP_TORRENT_CREATE_FILTERS

      public static final String PROP_TORRENT_CREATE_FILTERS
      Comma delimited list of name=filterPattern for torrent create filters. Deprecated. If detected, filters will be converted to new storage and then this config will be removed.
      See Also:
    • PROP_TORRENT_FILTERS_CONFIG

      public static final String PROP_TORRENT_FILTERS_CONFIG
      Filename for serialized torrent filters config.
      See Also:
    • lastAddedMessageTimestamp

      private long lastAddedMessageTimestamp
      When the last add message arrived.
    • lastAddedMessage

      private String lastAddedMessage
      Text of the last status message added.
    • DATE_FORMAT

      private static final ThreadLocal<DateFormat> DATE_FORMAT
      Date format for recent messages.
    • CONFIG_CACHE_TTL

      private static final long CONFIG_CACHE_TTL
      How long to cache a per-torrent config before reloading, covers manual file edits.
      See Also:
    • _configCache

      private final Map<SHA1Hash, SnarkManager.ConfigCacheEntry> _configCache
      Guarded by _configLock.
    • DISK_USAGE_TTL

      private static final long DISK_USAGE_TTL
      How long to cache the disk usage string, avoids a statfs per render.
      See Also:
    • _diskUsageCheckedAt

      private long _diskUsageCheckedAt
      Last time the disk usage string was computed.
    • _diskUsageCached

      private String _diskUsageCached
      Cached disk usage string.
  • Constructor Details

    • SnarkManager

      public SnarkManager(I2PAppContext ctx)
      For embedded.
      Parameters:
      ctx - the I2P context to run in
    • SnarkManager

      public SnarkManager(I2PAppContext ctx, String ctxPath, String ctxName)
      For webapp.
      Parameters:
      ctx - the I2P context to run in
      ctxPath - generally "/i2psnark"
      ctxName - generally "i2psnark"
  • Method Details

    • multiDestStartDelay

      private void multiDestStartDelay()
      Wait before the next auto-started torrent in a batch when multi-destination mode is on, once per pool, spreading out tunnel builds and decoupling start times from batch order. No wait in single-dest mode, where all torrents share the one session, or when randomize startup delay is disabled.
    • startDelay

      static long startDelay(Random rnd)
      Random delay between auto-started torrents in multi-dest mode, 30-90 seconds.
      Parameters:
      rnd - source of randomness
      Returns:
      delay in milliseconds
    • sleep

      private static void sleep(long ms)
      Sleep, ignoring interruption.
      Parameters:
      ms - delay in milliseconds
    • start

      public void start()
      Caller _must_ call loadConfig(file) before this if setting new values for i2cp host/port or i2psnark.dir.
    • sessionDisconnected

      public void sessionDisconnected()
      DisconnectListener interface.
      Specified by:
      sessionDisconnected in interface I2PSocketManager.DisconnectListener
    • stop

      public void stop()
      Called by the webapp at Jetty shutdown. Stops all torrents. Does not close the tunnel, so the announces have a chance. Fix this so an individual webapp stop will close the tunnel. Runs inline.
    • isStopping

      public boolean isStopping()
      Whether the manager is in the process of stopping.
      Returns:
      true from the moment stop() is entered, false while still running
    • startup

      public void startup()
      ClientApp method. Does nothing. Doesn't matter, we are only registering.
      Specified by:
      startup in interface ClientApp
    • shutdown

      public void shutdown(String[] args)
      ClientApp method. Does nothing. Doesn't matter, we are only registering.
      Specified by:
      shutdown in interface ClientApp
      Parameters:
      args - generally null but could be stopArgs from clients.config
    • getState

      public ClientAppState getState()
      ClientApp method. Doesn't matter, we are only registering.
      Specified by:
      getState in interface ClientApp
      Returns:
      ClientAppState.INITIALIZED, the manager never enters another state
    • getName

      public String getName()
      ClientApp method.
      Specified by:
      getName in interface ClientApp
      Returns:
      "i2psnark", identifying this client app in logs and to the router console
    • getDisplayName

      public String getDisplayName()
      ClientApp method.
      Specified by:
      getDisplayName in interface ClientApp
      Returns:
      the display name
    • util

      public I2PSnarkUtil util()
      The I2PSnarkUtil instance for this manager.
      Returns:
      I2PSnarkUtil instance
    • getRandomizeStartupDelay

      public boolean getRandomizeStartupDelay()
      Whether batched torrent starts are staggered with a random delay, so torrents starting together cannot be correlated, and tunnel builds are spread out.
      Returns:
      true to stagger batched starts (default)
    • shouldDestCycle

      public boolean shouldDestCycle()
      Whether running torrents are periodically restarted with fresh destinations.
      Returns:
      true to cycle destinations (default)
    • getBandwidthListener

      public BandwidthListener getBandwidthListener()
      The bandwidth listener for this manager.
      Specified by:
      getBandwidthListener in interface CompleteListener
      Returns:
      bandwidth listener
    • escapeMessage

      public static String escapeMessage(String message)
      Escape a message for HTML display, preserving intentional '&nbsp;' spacers. Order matters: '&' first so the later entity-escapes of '<' and '>' are not undone, and restore the literal ' ' entries afterwards.
      Parameters:
      message - the raw message text, not null
      Returns:
      the message with HTML metacharacters escaped
    • addMessage

      public void addMessage(String message)
      Use if it does not include a link. Escapes '<' and '>' before queueing.
      Parameters:
      message - text to queue for the messages page
    • addMessageNoEscape

      public void addMessageNoEscape(String message)
      Use if it includes a link. Does not escape '<' and '>' before queueing.
      Parameters:
      message - HTML to queue for the messages page, unescaped
    • addMessageAndPrint

      public void addMessageAndPrint(String message)
      Queue a message and, when running standalone, print it to stdout.
      Parameters:
      message - the message to queue
    • addMessageAndPrint

      public void addMessageAndPrint(String message, String print)
      Queue a message and, when running standalone, print possibly different text to stdout.
      Parameters:
      message - the message to queue
      print - the text to print, or null for no output
    • addMessageNoEscapeAndPrint

      public void addMessageNoEscapeAndPrint(String message)
      Queue a message and, when running standalone, print it to stdout.
      Parameters:
      message - the message to queue
    • addMessageNoEscapeAndPrint

      public void addMessageNoEscapeAndPrint(String message, String print)
      Queue a message and, when running standalone, print possibly different text to stdout.
      Parameters:
      message - the message to queue
      print - the text to print, or null for no output
    • printToConsole

      private void printToConsole(String msg)
      Print a message to stdout when running standalone, replacing any HTML nbsp entities so the console output is readable.
      Parameters:
      msg - the text to print, or null for no output
    • getTime

      public String getTime()
      The current time as bold UTC "dd/MM HH:mm:ss" HTML, prefixed to each queued message.
      Returns:
      the formatted time in bold HTML, not a bare number
    • getMessages

      public List<UIMessages.Message> getMessages()
      The list of recent UI messages for display on the web page.
      Returns:
      list of recent messages
    • clearMessages

      public void clearMessages()
      Discard every queued UI message.
    • clearMessages

      public void clearMessages(int id)
      Clear through this id.
      Parameters:
      id - discard messages up to and including this one
    • areFilesPublic

      public boolean areFilesPublic()
      Whether the files in the data directory are world-readable.
      Returns:
      default false
    • shouldPreallocateFiles

      public boolean shouldPreallocateFiles()
      Whether new torrents preallocate their storage files.
      Returns:
      default true
    • shouldAutoStart

      public boolean shouldAutoStart()
      Whether newly added torrents should be started automatically.
      Specified by:
      shouldAutoStart in interface CompleteListener
      Returns:
      true if newly added torrents should be started automatically
    • isSmartSortEnabled

      public boolean isSmartSortEnabled()
      Whether smart sort is enabled in the web interface.
      Returns:
      default false
    • isCollapsePanelsEnabled

      public boolean isCollapsePanelsEnabled()
      Whether the web interface collapses panels by default.
      Returns:
      default true
    • isShowStatusFilter

      public boolean isShowStatusFilter()
      Whether the status filter bar is shown in the web interface.
      Returns:
      default false
    • isEnableLightbox

      public boolean isEnableLightbox()
      Whether the lightbox is used to display large images in the web interface.
      Returns:
      default true
    • isVaryInboundHops

      public boolean isVaryInboundHops()
      Whether hops are randomly varied for inbound torrent tunnels.
      Returns:
      default false
    • isVaryOutboundHops

      public boolean isVaryOutboundHops()
      Whether hops are randomly varied for outbound torrent tunnels.
      Returns:
      default false
    • getRefreshDelaySeconds

      public int getRefreshDelaySeconds()
      How often the web page refreshes itself.
      Returns:
      -1 for never
    • getMaxFilesPerTorrent

      public int getMaxFilesPerTorrent()
      Maximum number of files a torrent may contain.
      Returns:
      the max files per torrent
    • getMaxLogMessages

      public int getMaxLogMessages()
      Maximum number of messages kept for display on the web page.
      Returns:
      the max log messages
    • getPageSize

      public int getPageSize()
      For GUI.
      Returns:
      the page size
    • getStartupDelayMinutes

      private int getStartupDelayMinutes()
      A random startup delay in minutes, uniformly between the configured minimum and maximum, to avoid correlating auto-starts across routers.
      Returns:
      delay in minutes, 0 when not running inside the router
    • getDataDir

      public File getDataDir()
      The configured torrent data directory.
      Returns:
      the directory, from the config or the webapp name
    • getTorrentDir

      public File getTorrentDir()
      Return the configured torrent file directory, or the data directory if not set. Torrent metadata (.torrent) files are stored here when configured separately from downloaded data.
      Returns:
      the directory for .torrent files
    • getConfigDir

      public File getConfigDir()
      For RPC.
      Returns:
      the config dir
    • migrateConfig

      private File migrateConfig(File oldFile)
      Migrate the old flat config file to the new config dir. Extracts per-torrent zmeta entries into the metadata file and writes the remaining config. Caller must synch.
      Parameters:
      oldFile - the old flat config file to migrate from, may not exist
      Returns:
      the new config directory, non-null
      Throws:
      RuntimeException - on creation fail
    • getConfig

      private Properties getConfig(Snark snark)
      The config for a torrent.
      Parameters:
      snark - the torrent whose config properties are wanted
      Returns:
      non-null, possibly empty
    • getConfig

      private Properties getConfig(byte[] ih)
      The config for a torrent.
      Parameters:
      ih - 20-byte infohash
      Returns:
      non-null, possibly empty
    • metaKey

      private static String metaKey(byte[] ih, String prop)
      Build a metadata key for a torrent property.
      Parameters:
      ih - the 20-byte infohash of the torrent the property belongs to
      prop - the property name to store under that torrent's prefix
      Returns:
      the flat metadata key: META_PREFIX, the hex infohash and prop, joined with dots
    • loadMetadata

      private void loadMetadata()
      Load the metadata file into _metadata. Called once at startup, under _configLock.
    • stripDeprecatedKeys

      private void stripDeprecatedKeys()
      Remove deprecated per-torrent keys from metadata. preserveFileNames is now global; inOrder was removed entirely.
    • saveMetadata

      private void saveMetadata()
      Save the metadata file to disk. Called under _configLock after every mutation.
    • migrateToMetadata

      private void migrateToMetadata()
      Migrate per-torrent config files into the single metadata file. One-time operation at startup: scans sX/ subdirs and flat/grouped files, merges them into _metadata, then deletes the old files.
    • scanForConfigFiles

      private int scanForConfigFiles(File dir, int migrated)
      Recursively scan for .config files and migrate them. Skips the root config dir itself (only scans children).
      Parameters:
      dir - the directory to scan, its subdirectories included
      migrated - count of files migrated so far, threaded through the recursion
      Returns:
      the running total of migrated files, including those found in dir
    • mergeIntoMetadata

      private void mergeIntoMetadata(byte[] ih, Properties props)
      Merge per-torrent properties into _metadata.
      Parameters:
      ih - the 20-byte infohash of the torrent the properties belong to
      props - the per-torrent properties to copy in; the internal infohash key and the deprecated keys are skipped
    • moveCommentFile

      private void moveCommentFile(File configConf, byte[] ih)
      Move a comment file from legacy/subdir location to config dir root.
      Parameters:
      configConf - the legacy config file whose companion comment file is moved
      ih - the 20-byte infohash, unused: the comment name comes from the file name
    • commentFile

      private File commentFile(byte[] ih)
      The comment file for a torrent, stored alongside the config.
      Parameters:
      ih - 20-byte infohash
      Returns:
      the path the comment file would be at, whether or not it exists
    • getSavedComments

      public CommentSet getSavedComments(Snark snark)
      The comments for a torrent.
      Specified by:
      getSavedComments in interface CompleteListener
      Parameters:
      snark - the Snark instance to read the comment set from
      Returns:
      null if none
    • locked_saveComments

      public void locked_saveComments(Snark snark, CommentSet comments)
      Save the comments for a torrent. Caller must synchronize on comments.
      Specified by:
      locked_saveComments in interface CompleteListener
      Parameters:
      snark - the Snark instance whose torrent lock is held
      comments - non-null
    • configFileToInfoHash

      private static SHA1Hash configFileToInfoHash(File file)
      Extract the info hash from a config file name.
      Parameters:
      file - the config file whose name is the hex infohash
      Returns:
      the infohash parsed from the name, null if the name is not 40 hex digits plus the config suffix
    • loadConfig

      public void loadConfig(String filename)
      Load the config from the given file.
      Parameters:
      filename - null to set initial defaults
    • locked_loadConfig

      private void locked_loadConfig(String filename)
      Load the config from the given file. Caller must hold _configLock.
      Parameters:
      filename - null to set initial defaults
    • getUniversalTheming

      public boolean getUniversalTheming()
      Whether themes are applied across all applications.
      Returns:
      the universal theming
    • getTheme

      public String getTheme()
      The current theme for this web interface.
      Returns:
      String -- the current theme
    • getThemes

      public String[] getThemes()
      All themes available for this web interface.
      Returns:
      String[] -- Array of all the themes found, non-null, unsorted
    • getBWLimit

      private boolean getBWLimit()
      Call from DirMonitor since loadConfig(String) is called before router I2CP is up. We also use this as a test that the router is there for standalone.
      Returns:
      true if we got a response from the router
    • updateConfig

      private void updateConfig()
      Re-reads the config file if it changed on disk.
    • rereadConfig

      private void rereadConfig()
      Re-reads the entire config file from disk and activates any settings that differ from the applied ones, so edits to i2psnark.config take effect without a restart. Called by the directory monitor on its periodic scan. Changed values are re-applied through the same updateConfig() path used at startup. Settings removed from the file keep their current value.
    • parseShouldPadFiles

      static boolean parseShouldPadFiles(Properties props)
      Parses the PROP_SHOULD_PAD_FILES value from the given properties, applying the default when absent or unparsable.
      Parameters:
      props - the config properties
      Returns:
      whether BEP 47 padding files are added to new torrents
    • getTempDirProp

      private String getTempDirProp()
      Reads the PROP_TEMP_DIR property, trimming whitespace and stripping surrounding double quotes (so the value may contain spaces). An unset, blank, or quoted-empty value disables the staging feature.
      Returns:
      the staging directory, or null if disabled
    • cleanTempDirProp

      private static String cleanTempDirProp(String s)
      Trims whitespace and strips surrounding double quotes, so the value may contain spaces. An unset, blank, or quoted-empty value disables the staging feature.
      Parameters:
      s - the raw configured value, may be null or blank
      Returns:
      the staging directory, or null if disabled
    • validateTempDir

      private String validateTempDir(String tempDir)
      Validates the staging directory: creates it if missing, checks write permission, and warns (returning null) when it is unusable.
      Parameters:
      tempDir - the raw configured value, or null
      Returns:
      the cleaned usable staging directory, or null if disabled or unusable
    • validateTorrentDir

      private String validateTorrentDir(String torrentDir)
      Checks a torrent's target directory is usable.
      Parameters:
      torrentDir - the directory to check
      Returns:
      the error to show, null if the directory is fine
    • getInt

      private int getInt(String prop, int defaultVal)
      Reads an int from the config.
      Parameters:
      prop - the property to read
      defaultVal - the value when unset or malformed
      Returns:
      the configured value
    • parseMaxDest

      private static int parseMaxDest(String s)
      Parse the destination cap, clamping invalid and out-of-range values to zero, which restores one destination per torrent.
      Parameters:
      s - the raw property value, or null
      Returns:
      a value in [0, MAX_MULTI_DEST]
    • updateConfig

      public void updateConfig(String dataDir, boolean filesPublic, boolean autoStart, String refreshDelay, String startDelayMin, String startDelayMax, String pageSize, String i2cpHost, String i2cpPort, String i2cpOpts, String upLimit, String upBW, String downBW, boolean useOpenTrackers, boolean useDHT, String theme, String lang, boolean enableRatings, boolean enableComments, String commentName, boolean collapsePanels, boolean showStatusFilter, boolean enableLightbox, boolean enableAddCreate, boolean enableVaryInboundHops, boolean enableVaryOutboundHops, boolean multiDest, String multiDestMax, boolean randomizeStartup, String apiTarget, String apiKey, String maxFiles, boolean preallocateFiles, String tempDir, String torrentDir, boolean preserveFileNames)
      All params may be null or need trimming.
      Parameters:
      dataDir - absolute path for the data directory, or null to leave it alone; changing it stops and removes every non-magnet torrent
      filesPublic - true to make new data directory files world-readable
      autoStart - true to auto-start saved torrents
      refreshDelay - seconds between page refreshes, negative to disable, or null to leave it alone
      startDelayMin - shortest delay before an auto-started torrent in minutes, or null to leave it alone
      startDelayMax - longest delay before an auto-started torrent in minutes, swapped with the minimum if lower, or null to leave it alone
      pageSize - torrents listed per page, 5 or more, zero or less for all, or null to leave it alone
      i2cpHost - I2CP host to connect to, or null to keep the current one
      i2cpPort - I2CP port to connect to, or null to keep the current one
      i2cpOpts - space-separated "name=value" session options, not null
      upLimit - uploader limit summed across all torrents, or null to leave it alone
      upBW - upload bandwidth cap in KBps, or null to leave it alone
      downBW - download bandwidth cap in KBps, or null to leave it alone
      useOpenTrackers - true to announce to the open trackers as backups
      useDHT - true to participate in the DHT
      theme - theme name to use when universal theming is off, or null to leave it alone
      lang - standalone language as "lang_COUNTRY", ignored in router context, or null to leave it alone
      enableRatings - true to collect and show peer ratings
      enableComments - true to fetch and show peer comments
      commentName - author name for our own comments, or null to clear it
      collapsePanels - true to start the page panels collapsed
      showStatusFilter - true to show the torrents-page filter bar
      enableLightbox - true to load the image lightbox viewer
      enableAddCreate - true to keep the add/create forms on every page
      enableVaryInboundHops - true to randomize the inbound tunnel hop count
      enableVaryOutboundHops - true to randomize the outbound tunnel hop count
      multiDest - true to give each torrent a destination of its own
      multiDestMax - destination cap in multi-dest mode, zero for one per torrent, or null to leave it alone
      randomizeStartup - true to stagger batched torrent starts
      apiTarget - API target base path, honored only alongside a non-empty apiKey
      apiKey - API key, honored only alongside a non-empty apiTarget
      maxFiles - ceiling on the files one torrent may contain, at least 1, or null to leave it alone
      preallocateFiles - true to preallocate storage for new torrents
      tempDir - staging directory for incomplete files, or null to disable staging
      torrentDir - directory for .torrent files, or null to reset to the data directory
      preserveFileNames - true to keep the torrent's own file names
    • locked_updateConfig

      private void locked_updateConfig(String dataDir, boolean filesPublic, boolean autoStart, String refreshDelay, String startDelayMin, String startDelayMax, String pageSize, String i2cpHost, String i2cpPort, String i2cpOpts, String upLimit, String upBW, String downBW, boolean useOpenTrackers, boolean useDHT, String theme, String lang, boolean enableRatings, boolean enableComments, String commentName, boolean collapsePanels, boolean showStatusFilter, boolean enableLightbox, boolean enableAddCreate, boolean enableVaryInboundHops, boolean enableVaryOutboundHops, boolean multiDest, String multiDestMax, boolean randomizeStartup, String apiTarget, String apiKey, String maxFiles, boolean preallocateFiles, String tempDir, String torrentDir, boolean preserveFileNames)
      Applies the settings form under the config lock.
      Parameters:
      dataDir - the new data directory
      filesPublic - true to serve files publicly
      autoStart - true to start torrents on add
      refreshDelay - the UI refresh delay
      startDelayMin - the shortest startup delay
      startDelayMax - the longest startup delay
      pageSize - the torrents per page
      i2cpHost - the I2CP host
      i2cpPort - the I2CP port
      i2cpOpts - the I2CP options
      upLimit - the max uploaders
      upBW - the upload bandwidth cap
      downBW - the download bandwidth cap
      useOpenTrackers - true to use opentracker lists
      useDHT - true to use DHT
      theme - the UI theme
      lang - the UI language
      enableRatings - true to show ratings
      enableComments - true to show comments
      commentName - the poster name
      collapsePanels - true to start panels collapsed
      showStatusFilter - true to show the status filter
      enableLightbox - true to enable the lightbox
      enableAddCreate - true to enable add and create
      enableVaryInboundHops - true to vary inbound hop counts
      enableVaryOutboundHops - true to vary outbound hop counts
      multiDest - true to allow multiple destinations
      multiDestMax - the destination cap
      randomizeStartup - true to randomize startup delays
      apiTarget - the browser API target
      apiKey - the browser API key
      maxFiles - the file listing cap
      preallocateFiles - true to preallocate space
      tempDir - the temporary download directory
      torrentDir - the torrent directory
      preserveFileNames - true to keep original file names
    • getPrivateTrackers

      public List<String> getPrivateTrackers()
      The configured private tracker list.
      Returns:
      non-null, fixed size, may be empty or unmodifiable
    • browserApiEnabled

      public boolean browserApiEnabled()
      Whether the nonce-free browser API for adding torrents is enabled.
      Returns:
      whether the browser api is enabled
    • getBrowserApiHosts

      public String getBrowserApiHosts()
      The raw comma-separated browser API allowed hosts config, for the config form.
      Returns:
      non-null, may be empty
    • setBrowserApi

      public void setBrowserApi(boolean enable, String hosts)
      Set and persist the browser API enable flag and allowed hosts list. The change takes effect immediately; no restart required.
      Parameters:
      enable - whether the browser API is enabled at all
      hosts - comma-separated hostnames or IPs, may be null/empty
    • setAPI

      public void setAPI(String target, String key)
      Set and persist the API key for remote access, mirroring the apiKey/apiTarget handling in updateConfig. Empty key clears nothing (existing behavior).
      Parameters:
      target - the API target base path
      key - the API key
    • isBrowserApiHost

      public boolean isBrowserApiHost(String host)
      Whether the given remote address may use the browser API without a nonce. Loopback is always allowed; otherwise the host must be listed in the PROP_BROWSER_API_HOSTS config. Does not check the enable flag.
      Parameters:
      host - remote address string from the request
      Returns:
      true for loopback, or for a host resolving to PROP_BROWSER_API_HOSTS; false for an unresolvable or unlisted address
    • resolveBrowserApiHosts

      public static Set<InetAddress> resolveBrowserApiHosts(String hosts)
      Parse a comma-separated host list into resolved addresses. Unresolvable or malformed entries are skipped; loopback entries are redundant (always allowed) and skipped.
      Parameters:
      hosts - comma-separated hostnames or IPs, may be null
      Returns:
      non-null set of resolved addresses, may be empty
    • isLoopbackHost

      public static boolean isLoopbackHost(String host)
      IPv4 loopback (127/8), IPv6 loopback, and "localhost".
      Parameters:
      host - remote address string from the request
      Returns:
      whether the host is a loopback address
    • saveOpenTrackers

      public void saveOpenTrackers(List<String> ot)
      Save the given open tracker list.
      Parameters:
      ot - null to restore default
    • savePrivateTrackers

      public void savePrivateTrackers(List<String> pt)
      Save the given private tracker list.
      Parameters:
      pt - null ok, default is none
    • getListConfig

      private List<String> getListConfig(String prop, String dflt)
      Deserialize the given list property from the config.
      Parameters:
      prop - the config property holding a comma-separated list
      dflt - default or null
      Returns:
      the split values, non-null and fixed size, empty if neither the property nor the default is set
    • setListConfig

      private String setListConfig(String prop, List<String> values)
      Serialize the given list into the config for the given property, does NOT save it.
      Parameters:
      prop - the config property to write to, removed when values is empty
      values - may be null or empty
      Returns:
      the comma-separated config string, non-null
    • saveConfig

      public void saveConfig()
      Write the config to the config file, queueing a message on failure.
    • listTorrentFiles

      public Set<String> listTorrentFiles()
      Canonical .torrent filenames that we are dealing with. An unsynchronized copy.
      Returns:
      the filenames, a copy that may change under the caller
    • getTorrent

      public Snark getTorrent(String filename)
      Grab the torrent given the (canonical) filename of the .torrent file.
      Parameters:
      filename - canonical .torrent filename
      Returns:
      Snark or null
    • getTorrents

      public Collection<Snark> getTorrents()
      Snapshot of the loaded torrents as an unmodifiable collection.
      Returns:
      a live unmodifiable view of the loaded torrents, empty if none are loaded
    • getTorrentByBaseName

      public Snark getTorrentByBaseName(String filename)
      Grab the torrent given the base name of the storage.
      Parameters:
      filename - must be the filtered name, which may be different than the metainfo's name
      Returns:
      Snark or null
    • getTorrentByInfoHash

      public Snark getTorrentByInfoHash(byte[] infohash)
      Grab the torrent given the info hash.
      Parameters:
      infohash - the torrent's info hash
      Returns:
      Snark or null
    • putSnark

      private void putSnark(String torrentFile, Snark snark)
      Add the snark. Caller must sync on _snarks.
      Parameters:
      torrentFile - the torrent file path used as the map key
      snark - the torrent to register under that path, its infohash and its storage base name
    • removeSnark

      private void removeSnark(Snark snark)
      Remove the snark. Caller must sync on _snarks.
      Parameters:
      snark - the torrent to drop from the name, infohash and base-name maps
    • removeSnark

      private Snark removeSnark(String torrentFile)
      Remove the snark. Caller must sync on _snarks.
      Parameters:
      torrentFile - the path the snark was registered under
      Returns:
      the removed Snark or null
    • disableTorrentFile

      private void disableTorrentFile(String torrentFile)
      Rename the torrent file to add a .BAD suffix, log messages.
      Parameters:
      torrentFile - the bad torrent file to delete, or rename with a .BAD suffix
    • addTorrent

      private boolean addTorrent(String filename, File baseFile, boolean dontAutoStart)
      Caller must verify this torrent is not already added.
      Parameters:
      filename - the absolute path to save the metainfo to, generally ending in ".torrent"
      baseFile - may be null, if so look in dataDir
      dontAutoStart - must be false, AND running=true or null in metadata, to start
      Returns:
      true if the torrent is now loaded, false if the metainfo file is unreadable or a torrent with that name is already running
      Throws:
      RuntimeException - if the storage for the torrent cannot be created
    • addTorrent

      private boolean addTorrent(String filename, File baseFile, boolean dontAutoStart, File dataDir)
      Caller must verify this torrent is not already added.
      Parameters:
      filename - the absolute path to save the metainfo to, generally ending in ".torrent"
      baseFile - may be null, if so look in dataDir
      dontAutoStart - must be false, AND running=true or null in metadata, to start
      dataDir - must exist, or null to default to snark data directory
      Returns:
      true if the torrent is now loaded, false if the metainfo file is unreadable or a torrent with that name is already running
      Throws:
      RuntimeException - if the storage for the torrent cannot be created
    • addMagnet

      public void addMagnet(String name, byte[] ih, String trackerURL, boolean updateStatus)
      Add a torrent with the info hash alone (magnet / maggot).
      Parameters:
      name - hex or b32 name from the magnet link
      ih - 20 byte info hash
      trackerURL - may be null
      updateStatus - should we save this magnet to metadata, to persist it across restarts, in case we don't get the metadata before shutdown?
      Throws:
      RuntimeException - if the data location for the magnet cannot be created
    • addMagnet

      public void addMagnet(String name, byte[] ih, String trackerURL, boolean updateStatus, File dataDir)
      Add a torrent with the info hash alone (magnet / maggot).
      Parameters:
      name - hex or b32 name from the magnet link
      ih - 20 byte info hash
      trackerURL - may be null
      updateStatus - should we save this magnet to metadata, to persist it across restarts, in case we don't get the metadata before shutdown?
      dataDir - must exist, or null to default to snark data directory
      Throws:
      RuntimeException - if the data location for the magnet cannot be created
    • addMagnet

      public Snark addMagnet(String name, byte[] ih, String trackerURL, boolean updateStatus, boolean autoStart, File dataDir, CompleteListener listener)
      Add a torrent with the info hash alone (magnet / maggot) External use is for UpdateRunner.
      Parameters:
      name - hex or b32 name from the magnet link
      ih - 20 byte info hash
      trackerURL - may be null
      updateStatus - should we save this magnet to metadata, to persist it across restarts, in case we don't get the metadata before shutdown?
      autoStart - true to start fetching right away
      dataDir - must exist, or null to default to snark data directory
      listener - to intercept callbacks, should pass through to this
      Returns:
      the new Snark or null on failure
      Throws:
      RuntimeException - if the data location for the magnet cannot be created
    • deleteMagnet

      public void deleteMagnet(Snark snark)
      Stop and delete a torrent running in magnet mode.
      Parameters:
      snark - a torrent with a fake file name ("Magnet xxxx")
    • lookupTorrentName

      public String lookupTorrentName(byte[] infoHash, long timeoutMs)
      Self-contained DHT lookup for torrent name without persisting torrent data. Creates a temporary magnet in a temp directory under the I2P temp dir, waits for metadata via DHT, extracts the torrent name, then deletes the magnet and temp directory. Does not store the .torrent file in the snark data directory and does not persist magnet status. If the infohash is already running as a user torrent, its name is returned directly without creating a lookup torrent or deleting the existing one.

      This is intended for lightweight trackers (e.g. zzzot) that need only the torrent name for display (hashlist) and do not want to store metadata or pre-allocate data files. The lookup torrent is stored in $I2P_TEMP/zzzot-lookup-<random> and deleted when resolved or on timeout.

      Parameters:
      infoHash - 20-byte infohash
      timeoutMs - max time to wait for metadata (e.g. 60_000 for 1 min, 3_600_000 for 60 min)
      Returns:
      torrent name (MetaInfo.getName()) or null if not found/timeout/interrupted
    • lookupTorrentName

      public String lookupTorrentName(String hex, long timeoutMs)
      Hex string overload for convenience.
      Parameters:
      hex - 40-char hex infohash (case-insensitive)
      timeoutMs - max time to wait for metadata (e.g. 60_000 for 1 min, 3_600_000 for 60 min)
      Returns:
      name or null
    • lookupTorrentInfo

      public SnarkManager.TorrentInfo lookupTorrentInfo(byte[] infoHash, long timeoutMs)
      Self-contained DHT lookup for torrent name and size without persisting torrent data. Same semantics as lookupTorrentName(byte[], long) but also returns the combined size of data files (excludes BEP47 padding) via MetaInfo.getDataLength(). This is the value zzzot hashlist should display alongside the name.
      Parameters:
      infoHash - 20-byte infohash
      timeoutMs - max wait as for lookupTorrentName
      Returns:
      TorrentInfo with name and size, or null if not found/timeout
    • lookupTorrentInfo

      public SnarkManager.TorrentInfo lookupTorrentInfo(String hex, long timeoutMs)
      Parameters:
      hex - 40-character hex infohash
      timeoutMs - max wait as for lookupTorrentInfo
      Returns:
      TorrentInfo with name and size, or null if not found/timeout
    • scheduleStaleLookupCleanup

      private void scheduleStaleLookupCleanup()
      Schedule a one-shot cleanup of stale lookup torrents (if not already scheduled). Scans _snarks for lookup-* torrents that have been running longer than LOOKUP_STALE_MS and removes them. They will be resubmitted by the caller (zzzot) on the next request.
    • isLookupTorrent

      static boolean isLookupTorrent(String name, String basePath)
      Is this one of our own metadata-lookup torrents, as opposed to a user's?

      Pure decision, separated from cleanupStaleLookupTorrents() so it can be pinned by test: the sweep deletes torrents, and the only thing standing between a user's download and that deletion is this identification.

      Parameters:
      name - display name, or null if it could not be read
      basePath - storage base path, or null if unknown or not yet resolved
      Returns:
      true if this is a lookup torrent
    • isStaleLookup

      static boolean isStaleLookup(String name, String basePath, long createdAt, long now)
      Should this lookup torrent be swept now?
      Parameters:
      name - display name, or null if it could not be read
      basePath - storage base path, or null if unknown
      createdAt - when the lookup was created, in ms
      now - current wall-clock ms
      Returns:
      true if it is one of ours and older than LOOKUP_STALE_MS
    • cleanupStaleLookupTorrents

      private void cleanupStaleLookupTorrents()
      Removes torrents left by abandoned magnet lookups.
    • addDownloader

      public void addDownloader(Snark torrent)
      Add and start a FetchAndAdd task. Remove it with deleteMagnet(Snark).
      Parameters:
      torrent - must be instanceof FetchAndAdd
      Throws:
      RuntimeException - if the downloader cannot reach I2P
    • addTorrent

      public boolean addTorrent(MetaInfo metainfo, BitField bitfield, String filename, File baseFile, boolean dontAutoStart) throws IOException
      Add a torrent from a MetaInfo. Save the MetaInfo data to filename. Serialized on the add lock to prevent interference from the DirMonitor. This verifies that a torrent with this infohash is not already added. This may take a LONG time to create or check the storage, so the global snarks lock is only held for the duplicate checks.

      Called from servlet. This is only for the 'create torrent' form.

      Parameters:
      metainfo - the metainfo for the torrent
      bitfield - the current completion status of the torrent, or null
      filename - the absolute path to save the metainfo to, generally ending in ".torrent", which is also the name of the torrent Must be a filesystem-safe name. If null, will generate a name from the metainfo.
      baseFile - may be null, if so look in rootDataDir
      dontAutoStart - true to add the torrent without starting it
      Returns:
      true if the torrent is now loaded, false if the metainfo could not be saved
      Throws:
      RuntimeException - if the storage for the torrent cannot be created
      IOException - declared for API compatibility; a write failure is reported as a queued message and a false return
    • copyAndAddTorrent

      public boolean copyAndAddTorrent(File fromfile, String filename, File dataDir) throws IOException
      Add a torrent from a file not in the torrent directory. Copy the file to filename. Holds the snarks lock to prevent interference from the DirMonitor. Caller must verify this torrent is not already added. This may take a LONG time to create or check the storage.
      Parameters:
      fromfile - where the file is now, presumably in a temp directory somewhere
      filename - the absolute path to save the metainfo to, generally ending in ".torrent", which is also the name of the torrent Must be a filesystem-safe name.
      dataDir - must exist, or null to default to snark data directory
      Returns:
      true if the file was copied and the torrent added
      Throws:
      RuntimeException - if the newly added torrent cannot be started; Snark.fatal(String) logs the failure and reports it to the CompleteListener before throwing
      IOException - declared for API compatibility; a copy failure is reported as a queued message and a false return
    • locked_writeMetaInfo

      private static void locked_writeMetaInfo(MetaInfo metainfo, String filename, boolean areFilesPublic) throws IOException
      Write the metainfo to the file, caller must hold the snarks lock to prevent interference from the DirMonitor.
      Parameters:
      metainfo - The metainfo for the torrent
      filename - The absolute path to save the metainfo to, generally ending in ".torrent". Must be a filesystem-safe name.
      areFilesPublic - true to write with the normal umask permissions, false to restrict the file with SecureFileOutputStream
      Throws:
      IOException - if the file already exists or the write fails
    • getSavedTorrentTime

      public long getSavedTorrentTime(Snark snark)
      Timestamp for a torrent from the metadata file. A Snark.CompleteListener method.
      Specified by:
      getSavedTorrentTime in interface CompleteListener
      Parameters:
      snark - the Snark instance holding the stored timestamp
      Returns:
      the saved torrent time in milliseconds
    • getSavedTorrentBitField

      public BitField getSavedTorrentBitField(Snark snark)
      Saved bitfield for a torrent from the metadata file. Convert "." to a full bitfield. A Snark.CompleteListener method.
      Specified by:
      getSavedTorrentBitField in interface CompleteListener
      Parameters:
      snark - the Snark instance holding the stored bitfield
      Returns:
      the saved torrent bit field
    • loadSavedFilePriorities

      public void loadSavedFilePriorities(Snark snark)
      Saved priorities for a torrent from the metadata file.
      Parameters:
      snark - the torrent to load the per-file priorities into
    • getSavedBaseFile

      private File getSavedBaseFile(byte[] ih)
      Base location for a torrent from the metadata file.
      Parameters:
      ih - the 20-byte infohash of the torrent
      Returns:
      the saved base location, null if not stored, and it need not exist
    • getSavedUploaded

      public long getSavedUploaded(Snark snark)
      Setting for a torrent from the metadata file.
      Specified by:
      getSavedUploaded in interface CompleteListener
      Parameters:
      snark - the torrent whose saved upload total is wanted
      Returns:
      total bytes uploaded, 0 if not found
    • getSavedAddedAndCompleted

      public long[] getSavedAddedAndCompleted(Snark snark)
      Setting for a torrent from the metadata file.
      Parameters:
      snark - the torrent to read the times of
      Returns:
      non-null, rv[0] is added time or 0; rv[1] is completed time or 0
    • getSavedCommentsEnabled

      public boolean getSavedCommentsEnabled(Snark snark)
      Setting for comments enabled from the metadata file. Caller must first check global I2PSnarkUtil.commentsEnabled() Default true.
      Parameters:
      snark - the torrent to read the setting of
      Returns:
      the saved comments enabled
    • setSavedCommentsEnabled

      public void setSavedCommentsEnabled(Snark snark, boolean yes)
      Setting for comments enabled in the metadata file.
      Parameters:
      snark - the torrent to record the setting for
      yes - the setting to store
    • saveTorrentStatus

      public void saveTorrentStatus(Snark snark)
      Save the completion status of a torrent and other data in the metadata file. Does nothing for magnets.
      Parameters:
      snark - the torrent to record
    • saveTorrentStatus

      private void saveTorrentStatus(Snark snark, Boolean comments)
      Save the completion status of a torrent and other data in the metadata file. Does nothing for magnets.
      Parameters:
      snark - the torrent to save; a magnet, with no metainfo or storage, is skipped
      comments - null for no change
    • saveTorrentStatus

      private void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities, File base, long uploaded, long activity, boolean stopped, Boolean comments)
      Save the completion status of a torrent and the current time in the metadata file. The time is a standard long converted to string. The status is either a bitfield converted to Base64 or "." for a completed torrent to save space in the metadata file and in memory.
      Parameters:
      metainfo - non-null
      bitfield - non-null
      priorities - may be null
      base - may be null
      uploaded - total bytes uploaded, stored as the torrent's upload total
      activity - last activity time in ms since the epoch, 0 leaves it unset
      stopped - true records the torrent as not running, so it is not restarted
      comments - null for no change
    • locked_saveTorrentStatus

      private void locked_saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities, File base, long uploaded, long activity, boolean stopped, Boolean comments)
      Writes one torrent's progress into its config.
      Parameters:
      metainfo - the torrent's metadata
      bitfield - the downloaded pieces
      priorities - the file priorities
      base - the torrent's data directory
      uploaded - the bytes uploaded
      activity - the last activity time
      stopped - true if the torrent is stopped
      comments - true if comments were fetched
    • locked_saveTorrentStatus

      private void locked_saveTorrentStatus(byte[] ih, Properties config)
      Save per-torrent config to the single metadata file.
      Parameters:
      ih - the 20-byte infohash whose metadata entries are replaced
      config - the properties to store, without the per-torrent prefix
    • removeTorrentStatus

      private void removeTorrentStatus(Snark snark)
      Remove the status of a torrent from the metadata file.
      Parameters:
      snark - the torrent whose metadata entries and comment file are dropped
    • cleanupTorrentStatus

      private void cleanupTorrentStatus()
      Remove metadata entries for torrents no longer loaded. Run once at startup.
    • saveMagnetStatus

      public void saveMagnetStatus(byte[] ih, String dir, String trackerURL, String dn)
      Just remember we have it. Stores the magnet info in the metadata file so we can remember the directory, tracker, etc.
      Parameters:
      ih - the magnet's info hash, which keys the stored marker
      dir - may be null
      trackerURL - may be null
      dn - may be null
    • removeMagnetStatus

      public void removeMagnetStatus(byte[] ih)
      Remove the magnet marker from the config.
      Parameters:
      ih - the magnet's info hash, whose marker to remove
    • countRealFiles

      static int countRealFiles(List<List<String>> files)
      Count the files in a metainfo file list for the max files per torrent check, excluding BEP 47 padding files (.pad) and parse-renamed padding (_pad); a padded torrent must not be rejected because of its synthetic zero files. Padding is only recognized at the top level, matching the BEP 47 layout and Storage's create-side handling.
      Parameters:
      files - from MetaInfo.getFiles(), may be null
      Returns:
      the number of non-padding files
    • validateTorrent

      private String validateTorrent(MetaInfo info)
      Does not really delete on failure, that's the caller's responsibility. Warning - does not validate announce URL - use TrackerClient.isValidAnnounce(String).
      Parameters:
      info - the parsed metainfo to check against the configured limits
      Returns:
      failure message or null on success
    • stopTorrent

      public Snark stopTorrent(String filename, boolean shouldRemove)
      Stop the torrent, leaving it on the list of torrents unless told to remove it. If shouldRemove is true, removes the torrent's metadata entries also.
      Parameters:
      filename - canonical .torrent filename of the torrent to stop
      shouldRemove - true to drop the torrent from the list and delete its metadata
      Returns:
      the stopped torrent, or null if no torrent has that filename
    • stopTorrent

      public void stopTorrent(Snark torrent, boolean shouldRemove)
      Stop the torrent, leaving it on the list of torrents unless told to remove it. If shouldRemove is true, removes the torrent's metadata entries also.
      Parameters:
      torrent - the torrent to stop, may be null
      shouldRemove - true to drop the torrent from the list and delete its metadata
    • stopTorrent

      public void stopTorrent(Snark torrent)
      Stop the torrent only, leaving it on the list of torrents.
      Parameters:
      torrent - the torrent to stop, may be null
    • removeTorrent

      public void removeTorrent(String filename)
      Stop the torrent and delete the torrent file itself, but leaving the data behind. Removes saved metadata entries also. Holds the snarks lock to prevent interference from the DirMonitor.
      Parameters:
      filename - canonical .torrent filename of the torrent to remove
    • getStorageSpace

      private void getStorageSpace(File dir)
      Logs the free space of a directory in human units.
      Parameters:
      dir - the directory to measure
    • checkTempDirSpace

      private void checkTempDirSpace(File dir)
      Checks free space on the partition containing the staging (temp) directory and warns when it is low. Incomplete files are written there, so a full temp partition stalls all downloads.
      Parameters:
      dir - the staging directory
    • torrentComplete

      public void torrentComplete(Snark snark)
      A Snark.CompleteListener method.
      Specified by:
      torrentComplete in interface CompleteListener
      Parameters:
      snark - the Snark instance that completed
    • updateStatus

      public void updateStatus(Snark snark)
      A Snark.CompleteListener method.
      Specified by:
      updateStatus in interface CompleteListener
      Parameters:
      snark - the Snark instance to update status for
    • gotMetaInfo

      public String gotMetaInfo(Snark snark)
      We transitioned from magnet mode, we have now initialized our metainfo and storage. The listener should now call getMetaInfo() and save the data to disk. A Snark.CompleteListener method.
      Specified by:
      gotMetaInfo in interface CompleteListener
      Parameters:
      snark - the Snark instance that just initialized its metainfo and storage
      Returns:
      the new name for the torrent or null on error
    • fatal

      public void fatal(Snark snark, String error)
      A Snark.CompleteListener method.
      Specified by:
      fatal in interface CompleteListener
      Parameters:
      snark - the Snark instance that stopped
      error - the description of the failure, already localized for display
    • addMessage

      public void addMessage(Snark snark, String message)
      A Snark.CompleteListener method.
      Specified by:
      addMessage in interface CompleteListener
      Parameters:
      snark - the Snark instance raising the message
      message - the text to show in the torrent UI, already localized
    • gotPiece

      public void gotPiece(Snark snark)
      A Snark.CompleteListener method.
      Specified by:
      gotPiece in interface CompleteListener
      Parameters:
      snark - the Snark instance that downloaded the piece
    • linkify

      private String linkify(Snark snark)
      An HTML link to the file if complete and a single file, to the directory if not complete or not a single file, or simply the unlinkified name of the snark if a magnet.
      Parameters:
      snark - the torrent to link to
      Returns:
      the HTML link, or the escaped base name alone for a magnet or a torrent without metainfo or storage
    • getSnarkName

      private String getSnarkName(Snark snark)
      Returns the Snark name with URL-encoded spaces replaced by regular spaces. This method is intended for use when sending the Snark name to a terminal log (standalone).
      Parameters:
      snark - The Snark object to retrieve the name from.
      Returns:
      The Snark name suitable for display in a terminal log.
    • addMagnets

      private void addMagnets(boolean autostart)
      Add all magnets from the config file.
      Parameters:
      autostart - true to start each magnet as it is added, in randomized pool order with start delays, false to only add them
    • monitorTorrents

      private List<Snark> monitorTorrents(File dir)
      Add torrents found in the given directory. Caller must synchronize on _snarks, and must keep the critical section short - the returned batch is started by the caller AFTER releasing the lock, since starting staggers pools with long sleeps.
      Parameters:
      dir - the directory scanned for .torrent files
      Returns:
      the newly added torrents; empty if none were added, or null if a fatal error aborted the pass
    • _t

      private String _t(String s)
      Translate the given string.
      Parameters:
      s - the English text to look up in the I2PSnark bundle
      Returns:
      the localized text from the bundle
    • _t

      private String _t(String s, Object o)
      Translate the given string with one substitution.
      Parameters:
      s - the text to translate, containing a {0} placeholder; single quotes must be doubled
      o - the substitution for {0}, not itself translated
      Returns:
      the localized text with {0} replaced by o
    • _t

      private String _t(String s, Object o, Object o2)
      Translate the given string with two substitutions.
      Parameters:
      s - the text to translate, containing {0} and {1} placeholders; single quotes must be doubled
      o - the substitution for {0}, not itself translated
      o2 - the substitution for {1}, not itself translated
      Returns:
      the localized text with {0} and {1} replaced
    • getTrackerMap

      public Map<String,Tracker> getTrackerMap()
      Unsorted map of name to Tracker object Modifiable, not a copy.
      Returns:
      the tracker map
    • getTorrentCreateFilterMap

      public Map<String, TorrentCreateFilter> getTorrentCreateFilterMap()
      Unsorted map of name to TorrentCreateFilter object Modifiable, not a copy.
      Returns:
      the torrent create filter map
    • getCreateFilterCount

      public int getCreateFilterCount()
      Returns the current number of configured file filters.
      Returns:
      the create filter count
    • getTrackers

      public Collection<Tracker> getTrackers()
      Unsorted, do not modify.
      Returns:
      the configured trackers, a live view of the tracker map
    • getTorrentCreateFilterStrings

      public Collection<TorrentCreateFilter> getTorrentCreateFilterStrings()
      Unsorted, do not modify.
      Returns:
      the torrent create filter strings
    • getSortedTrackers

      public List<Tracker> getSortedTrackers()
      Sorted copy.
      Returns:
      the sorted trackers
    • getSortedTorrentCreateFilterStrings

      public List<TorrentCreateFilter> getSortedTorrentCreateFilterStrings()
      Sorted copy.
      Returns:
      the sorted torrent create filter strings
    • hasModifiedTrackers

      public boolean hasModifiedTrackers()
      Has the default tracker list been modified?
      Returns:
      whether modified trackers is present
    • initTrackerMap

      private void initTrackerMap()
      Builds the shared tracker map from the config.
    • convertFiltersToNewConfig

      private void convertFiltersToNewConfig()
      Convert old filter settings to the new config.
    • initTorrentCreateFilterMap

      private void initTorrentCreateFilterMap()
      Load the torrent-create filter map.
    • setDefaultTrackerMap

      public void setDefaultTrackerMap()
      Replace the tracker map with the built-in defaults, clearing the config key.
    • setDefaultTorrentCreateFilterMap

      public void setDefaultTorrentCreateFilterMap()
      Replace the torrent create filter map with the built-in defaults and persist it.
    • setDefaultTrackerMap

      private void setDefaultTrackerMap(boolean save)
      Restore the default tracker map.
      Parameters:
      save - true to save the config, and only if a custom tracker list was set
    • setDefaultTorrentCreateFilterMap

      private void setDefaultTorrentCreateFilterMap(boolean save)
      Restore the default torrent-create filter map.
      Parameters:
      save - true to write the restored filters to the config
    • saveTrackerMap

      public void saveTrackerMap()
      Write the tracker map to the config and save it.
    • saveTorrentCreateFilterMap

      public void saveTorrentCreateFilterMap()
      Serialize the torrent create filter map to its config file.
    • startTorrent

      public void startTorrent(byte[] infoHash)
      If not connected, thread it, otherwise inline.
      Parameters:
      infoHash - info hash of the torrent to start
      Throws:
      RuntimeException - if the torrent cannot be started; Snark.fatal(String) logs the failure and reports it to the CompleteListener before throwing
    • startTorrent

      public void startTorrent(Snark snark)
      If not connected, thread it, otherwise inline.
      Parameters:
      snark - the stopped torrent to start
      Throws:
      RuntimeException - if the torrent cannot be started; Snark.fatal(String) logs the failure and reports it to the CompleteListener before throwing
    • startAllTorrents

      public void startAllTorrents()
      Always thread it.
    • startStoppedTorrents

      public void startStoppedTorrents(List<Snark> batch)
      Start all currently-stopped torrents of the given batch in the background using the same pool-aware staggering and parallel pool startup as startBatch(List). Returns immediately so the caller's request thread is never blocked by tunnel builds. Torrents that are not stopped are ignored, so a repeated invocation while a previous batch is still starting is naturally a no-op.
      Parameters:
      batch - the candidate torrents
    • startAll

      private void startAll()
      Starts every stopped torrent, staggering the tunnel builds when pools share a destination.
    • previouslyRunning

      private List<Snark> previouslyRunning(List<Snark> batch)
      Filters a candidate start batch down to the torrents that were running when last saved. A torrent whose per-torrent config has no PROP_META_RUNNING entry counts as previously running, matching the auto-start default; one explicitly saved as stopped stays stopped. Used by the startup auto-start paths, where torrents are first loaded without starting them (so pool-mates can batch together) and must then be filtered by their persisted prior status before starting.
      Parameters:
      batch - candidate torrents, non-null
      Returns:
      the subset that should be auto-started
    • wasPreviouslyRunning

      static boolean wasPreviouslyRunning(Properties config)
      Returns true if the torrent's persisted config indicates it was running when last saved. A missing entry counts as previously running, matching the auto-start default; an explicitly false entry means it was stopped.
      Parameters:
      config - the torrent's persisted properties
      Returns:
      true if the torrent should be auto-started
    • startBatch

      private boolean startBatch(List<Snark> batch)
      Start a batch of torrents, keeping pool-mates together. All torrents in the batch are already known when this is called, so the destinations can be computed up front: pool-mates are started back-to-back, and only the first torrent of each subsequent pool waits, letting that destination's tunnels build before the next pool's torrents start. The pool start order is randomized so one destination doesn't grab all the early torrents. In single-dest mode the batch order is randomized with no delay between torrents.
      Parameters:
      batch - the torrents to start
      Returns:
      false if the I2CP connection could not be established, so the caller knows the batch was left for a later pass
    • stopTorrent

      private int stopTorrent(Snark snark, int count, boolean finalShutdown)
      Stop one torrent, notifying trackers per finalShutdown, and adding the "stopping all" message on the first stop.
      Parameters:
      snark - the torrent to stop
      count - number of torrents stopped so far
      finalShutdown - if true, notify trackers immediately
      Returns:
      the incremented count
    • stopAllTorrents

      public void stopAllTorrents(boolean finalShutdown)
      Stop all running torrents, and close the tunnel after a delay to allow for announces. If called at router shutdown via Jetty shutdown hook -> webapp destroy() -> stop(), the tunnel won't actually be closed as the SimpleTimer2 is already shutdown or will be soon, so we delay a few seconds inline.
      Parameters:
      finalShutdown - if true, sleep at the end if any torrents were running
    • cycleDestinations

      private void cycleDestinations()
      Restart all running torrents on fresh destinations: stop them all, which destroys their sessions and schedules the Disconnector to close the main session too, then restart only the torrents that were running when the cycle fired, once the old session is gone. Skipped while any torrent is actively downloading, and when the router is already stopping.
    • recheckTorrent

      public void recheckTorrent(Snark snark)
      Threaded. Torrent must be stopped.
      Parameters:
      snark - the stopped torrent to recheck
    • getDiskUsage

      public String getDiskUsage()
      The cached disk usage string for display.
      Returns:
      the disk usage