- All Implemented Interfaces:
ClientApp, I2PSocketManager.DisconnectListener, CompleteListener
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.
Nested Class Summary
Modifier and TypeClassDescriptionprivate static classA cached per-torrent config.private classPeriodically cycle destinations: stop all running torrents and restart them so their sessions - and with them their destinations - are recreated fresh.private classRestart the torrents that were running when the cycle fired, once the stop-all's Disconnector has closed the old session, so the new session - and with it the new destinations - is created on start.private classThis callsmonitorTorrents(File)once a minute.private classDisconnects the I2P tunnel when the router shuts down.private static classCompare ignoring case, current locale.private static classCompare ignoring case, current locale.private classStart the torrents of one pool on its own thread, so each pool's session and tunnel builds proceed in parallel with the other pools.private classPeriodically re-registers the app with the update manager.private static classOnly used in app context.private classRechecks one torrent in a background thread.private classUse null constructor param for all.static classResult of a DHT metadata lookup — name plus combined size of data files.Field Summary
Modifier and TypeFieldDescriptionprivate final ObjectLock keeping concurrent snark adds from duplicating work.private booleanTrue to serve the browser API.private StringRaw comma-separated config value, for the config form.private Set<InetAddress> Resolved allowed hosts (excluding loopback, which is always allowed).private final BandwidthManagerShares bandwidth between the torrents.private PropertiesThe loaded global config.private final Map<SHA1Hash, SnarkManager.ConfigCacheEntry> Guarded by _configLock.private FileDirectory holding the per-torrent config files.private FileFile holding the global snark config.private final ObjectOne lock for all config, files for simplicity.private final ConnectionAcceptorAccepts incoming peer connections.private final I2PAppContextThe application context.private final StringDisplay name of the webapp.private final StringWebapp context path used in links.private StringCached disk usage string.private longLast time the disk usage string was computed.Snarks by filtered base name; synchronize on _snarks.private SimpleTimer2.TimedEventTimer stopping idle torrents.Snarks by info hash; synchronize on _snarks.private final LogLogger for this class.Infohash to time (ms) when the lookup was created, for stale cleanup.private final SemaphoreCaps concurrent magnet and torrent lookups.Prevents DirMonitor from deleting torrents that don't have a torrent file yet.private final UIMessagesTranslated strings for the web UI.private PropertiesThe loaded global metadata.private FileFile holding the global metadata.private ThreadThread monitoring the running torrents.private final PeerCoordinatorSetPeer coordinators shared between torrents.private booleanTrue to randomize each torrent's startup delay.private booleanTrue while the manager is running.Map of (canonical) filename of the .torrent file to Snark instance.private final ScheduledExecutorServiceSnark's own scheduler for periodic chores, deliberately notSimpleTimer2.private booleanTrue while stale lookups are being cleaned up.private booleanTrue while the manager shuts down.private final Map<String, TorrentCreateFilter> Torrent create filters by name.Trackers by URL.private UpdateHandlerThread handling torrent updates.private UpdateManagerManager of the torrent update threads.private final I2PSnarkUtilShared utilities and settings for the torrents.private static final StringAlphabet used in the subdirectory names.private static final PatternCharacters stripped from comment text.private static final StringSuffix of each torrent's gzipped comments file.private static final longHow long to cache a per-torrent config before reloading, covers manual file edits.static final StringAppended to the old flat config file name to form the config directory name.static final StringConfig file name within the config directory; the webapp's name only selects the directory.private static final StringSuffix of each torrent's config file.private static final ThreadLocal<DateFormat> Date format for recent messages.private final booleanWhether torrents start on add by default.static final StringURL.static final intDiscard-ratio bans last an hour.static final Stringtrue: auto-ban peers with an excessive discard ratio.static final Stringfalse: show the add/create forms only on page one.static final Stringtrue: load the lightbox viewer.private static final intDefault download bandwidth cap, in KB/s.static final intInitial ceiling on the number of files one torrent may contain.private static final intDefault messages kept per torrent.static final intInitial upload bandwidth cap across all torrents, in KBps.static final intDefault cap on destinations so many torrents share destinations instead of exhausting memory.private static final StringURLs, comma-separated.private static final intDefault number of torrents per page.static final Stringtrue: preallocate new torrents' storage.static final intInitial seconds between automatic page refreshes.static final Stringfalse: leave new torrents unpadded.static final Stringfalse: hide the status filter.static final intInitial longest delay before an auto-started torrent, in minutes.static final intInitial shortest delay before an auto-started torrent, in minutes.static final StringTheme used until the user picks one.private static final String[]Filters blocking torrent creation by default.Default set of tracker announce URLs to use when no torrent trackers are configured.private static final String[]"name", "announceURL=websiteURL" pairs '=' in announceURL must be escaped as ,static final intTunnel quantity the default I2CP options ask for, in each direction.private static final StringRetired config key for in-order downloading.private static final StringDeprecated per-torrent keys removed in 0.9.71+.private static final longDestinations cycle every this long, plus a random jitter.private static final intRandom jitter added to each destination cycle, so routers do not rotate in lockstep.private static final longDelay after the stop-all before restarting, long enough for the Disconnector to close the old session.private static final longHow long to cache the disk usage string, avoids a statfs per render.Host names for config form.private StringText of the last status message added.private longWhen the last add message arrived.private static final StringMarker in the display name of a torrent created by a metadata lookup.private static final StringMarker in the storage path of a torrent created by a metadata lookup.(package private) static final longAge past which a lookup torrent is swept.private static final intMax concurrent DHT lookup threads (zzzot lookups).static final intAbsolute maximum for the destination cap.private static final StringPrefix of metadata keys inside a config.private static final StringName of the global metadata file.static final intLowest download bandwidth limit the configuration accepts, in KBps.static final intLowest upload bandwidth limit the configuration accepts, in KBps.private static final longDelay between per-destination torrent starts, allowing each destination's tunnels to build.private static final StringConfig key prefix for API keys.static final StringAuto-start saved torrents on startup.static final StringDuration of the ban applied to peers with an excessive discard ratio, in minutes.static final StringDisconnect peers that cancel most of what they request.static final StringWhether the nonce-free browser API (magnet/torrent add) is enabled.static final StringComma-separated hosts (IPs or hostnames) allowed to use the browser API without a nonce, in addition to loopback.static final StringClient 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.static final StringOptional comma-separated subset of client names, seeClientID.profiles(), to choose from whenPROP_CLIENT_IDis "random"; unknown names are ignored.static final StringStart the page panels collapsed.private static final StringConfig key enabling comments display.private static final StringConfig key for the comments author name.private static final StringConfig property selecting the country.static final StringWhether 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.static final StringDirectory the downloaded torrent data is stored in.static final StringDownload bandwidth cap across all torrents, in KBps.static final StringKeep the add-torrent and create-torrent forms on every page, not just page one.static final StringLoad the image lightbox viewer.static final StringWhether files in the data directory are world-readable.static final StringI2CP host to connect to the router on.static final StringExtra session options, "name=value" space-separated.static final StringI2CP port to connect to the router on.private static final StringConfig property selecting the UI language.static final StringCeiling on the number of files one torrent may contain.static final StringConfigured cap on the number of log messages.static final StringCap on a single piece request from a peer.static final StringMaximum request pipeline depth for outbound requests.private static final StringTorrent meta key for activity level.private static final StringMetadata key for when the torrent was added.private static final StringMetadata key for the torrent's data directory.private static final StringMetadata key for the downloaded pieces.private static final StringTorrent meta key for comments.private static final StringMetadata key for when the torrent completed.private static final StringMetadata key for the magnet URI.private static final StringMetadata key for the magnet's target directory.private static final StringMetadata key for the magnet's display name.private static final StringConfig prefix for remembered magnet URIs.private static final StringMetadata key for the magnet's trackers.private static final StringConfig prefix for per-torrent metadata.private static final StringMetadata key for the file priorities.(package private) static final StringPer-torrent key marking whether the torrent runs at startup; absent means run it.private static final StringMetadata key for the last-save time.private static final StringMetadata key for the bytes uploaded.static final StringMinimum request pipeline depth for outbound requests.static final StringWhether each torrent runs on its own destination.static final StringMaximum number of destinations in multi-dest mode, 0 for one per torrent.static final StringAncient "i2snark" typo in old configs, migrated toPROP_AUTO_START.static final StringAnnounce URLs of the open trackers, used as backups.static final StringTorrents listed per page.static final StringChunk size for outbound piece requests.static final StringPreallocate the storage of new torrents.(package private) static final StringWhether to preserve original file names from the torrent.static final StringAnnounce URLs offered per torrent for private trackers.static final StringStagger 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.private static final StringConfig key enabling ratings display.static final StringSeconds between automatic page refreshes.static final StringAdd BEP 47 padding files to new torrents.static final StringShow the torrents-page status filter.private static final StringConfig property enabling smart piece sorting.static final StringLongest delay before an auto-started torrent, in minutes.static final StringShortest delay before an auto-started torrent, in minutes.static final StringConfiguration 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.static final StringTheme I2PSnark uses when universal theming is off.static final StringComma delimited list of name=filterPattern for torrent create filters.static final StringConfiguration key for the directory where .torrent files are stored, separate from the data directory.static final StringFilename for serialized torrent filters config.static final StringComma delimited list of name=announceURL=baseURL for the trackers to be displayed.static final StringUpload bandwidth cap across all torrents, in KBps.static final StringUploader limit summed across all torrents.private static final StringConfig property enabling DHT lookups.private static final StringConfig property enabling opentracker lists.static final StringRandomize the hop count of inbound torrent tunnels.static final StringRandomize the hop count of outbound torrent tunnels.static final StringRouter console property holding the theme shared by all webapps.static final StringRouter console property applying one theme to all webapps.private static final StringPrefix of the per-torrent data subdirectories.private static final PatternTrailing .torrent suffix stripped from display names.Constructor Summary
ConstructorsConstructorDescriptionFor embedded.SnarkManager(I2PAppContext ctx, String ctxPath, String ctxName) For webapp.Method Summary
Modifier and TypeMethodDescriptionprivate StringTranslate the given string.private StringTranslate the given string with one substitution.private StringTranslate the given string with two substitutions.voidaddDownloader(Snark torrent) Add and start a FetchAndAdd task.voidAdd a torrent with the info hash alone (magnet / maggot).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.voidAdd a torrent with the info hash alone (magnet / maggot).private voidaddMagnets(boolean autostart) Add all magnets from the config file.voidaddMessage(String message) Use if it does not include a link.voidaddMessage(Snark snark, String message) A Snark.CompleteListener method.voidaddMessageAndPrint(String message) Queue a message and, when running standalone, print it to stdout.voidaddMessageAndPrint(String message, String print) Queue a message and, when running standalone, print possibly different text to stdout.voidaddMessageNoEscape(String message) Use if it includes a link.voidaddMessageNoEscapeAndPrint(String message) Queue a message and, when running standalone, print it to stdout.voidaddMessageNoEscapeAndPrint(String message, String print) Queue a message and, when running standalone, print possibly different text to stdout.private booleanaddTorrent(String filename, File baseFile, boolean dontAutoStart) Caller must verify this torrent is not already added.private booleanaddTorrent(String filename, File baseFile, boolean dontAutoStart, File dataDir) Caller must verify this torrent is not already added.booleanaddTorrent(MetaInfo metainfo, BitField bitfield, String filename, File baseFile, boolean dontAutoStart) Add a torrent from a MetaInfo.booleanWhether the files in the data directory are world-readable.booleanWhether the nonce-free browser API for adding torrents is enabled.private voidcheckTempDirSpace(File dir) Checks free space on the partition containing the staging (temp) directory and warns when it is low.private static StringTrims whitespace and strips surrounding double quotes, so the value may contain spaces.private voidRemoves torrents left by abandoned magnet lookups.private voidRemove metadata entries for torrents no longer loaded.voidDiscard every queued UI message.voidclearMessages(int id) Clear through this id.private FilecommentFile(byte[] ih) The comment file for a torrent, stored alongside the config.private static SHA1HashconfigFileToInfoHash(File file) Extract the info hash from a config file name.private voidConvert old filter settings to the new config.booleancopyAndAddTorrent(File fromfile, String filename, File dataDir) Add a torrent from a file not in the torrent directory.(package private) static intcountRealFiles(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.private voidRestart 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.voiddeleteMagnet(Snark snark) Stop and delete a torrent running in magnet mode.private voiddisableTorrentFile(String torrentFile) Rename the torrent file to add a .BAD suffix, log messages.static StringescapeMessage(String message) Escape a message for HTML display, preserving intentional ' ' spacers.voidA Snark.CompleteListener method.The bandwidth listener for this manager.The raw comma-separated browser API allowed hosts config, for the config form.private booleanCall from DirMonitor sinceloadConfig(String)is called before router I2CP is up.private PropertiesgetConfig(byte[] ih) The config for a torrent.private PropertiesThe config for a torrent.For RPC.intReturns the current number of configured file filters.The configured torrent data directory.The cached disk usage string for display.ClientApp method.private intReads an int from the config.getListConfig(String prop, String dflt) Deserialize the given list property from the config.intMaximum number of files a torrent may contain.intMaximum number of messages kept for display on the web page.The list of recent UI messages for display on the web page.getName()ClientApp method.intFor GUI.The configured private tracker list.booleanWhether batched torrent starts are staggered with a random delay, so torrents starting together cannot be correlated, and tunnel builds are spread out.intHow often the web page refreshes itself.long[]getSavedAddedAndCompleted(Snark snark) Setting for a torrent from the metadata file.private FilegetSavedBaseFile(byte[] ih) Base location for a torrent from the metadata file.getSavedComments(Snark snark) The comments for a torrent.booleangetSavedCommentsEnabled(Snark snark) Setting for comments enabled from the metadata file.getSavedTorrentBitField(Snark snark) Saved bitfield for a torrent from the metadata file.longgetSavedTorrentTime(Snark snark) Timestamp for a torrent from the metadata file.longgetSavedUploaded(Snark snark) Setting for a torrent from the metadata file.private StringgetSnarkName(Snark snark) Returns the Snark name with URL-encoded spaces replaced by regular spaces.Sorted copy.Sorted copy.private intA random startup delay in minutes, uniformly between the configured minimum and maximum, to avoid correlating auto-starts across routers.getState()ClientApp method.private voidgetStorageSpace(File dir) Logs the free space of a directory in human units.private StringReads thePROP_TEMP_DIRproperty, trimming whitespace and stripping surrounding double quotes (so the value may contain spaces).getTheme()The current theme for this web interface.String[]All themes available for this web interface.getTime()The current time as bold UTC "dd/MM HH:mm:ss" HTML, prefixed to each queued message.getTorrent(String filename) Grab the torrent given the (canonical) filename of the .torrent file.getTorrentByBaseName(String filename) Grab the torrent given the base name of the storage.getTorrentByInfoHash(byte[] infohash) Grab the torrent given the info hash.Unsorted map of name to TorrentCreateFilter object Modifiable, not a copy.Unsorted, do not modify.Return the configured torrent file directory, or the data directory if not set.Snapshot of the loaded torrents as an unmodifiable collection.Unsorted map of name to Tracker object Modifiable, not a copy.Unsorted, do not modify.booleanWhether themes are applied across all applications.gotMetaInfo(Snark snark) We transitioned from magnet mode, we have now initialized our metainfo and storage.voidA Snark.CompleteListener method.booleanHas the default tracker list been modified?private voidLoad the torrent-create filter map.private voidBuilds the shared tracker map from the config.booleanisBrowserApiHost(String host) Whether the given remote address may use the browser API without a nonce.booleanWhether the web interface collapses panels by default.booleanWhether the lightbox is used to display large images in the web interface.(package private) static booleanisLookupTorrent(String name, String basePath) Is this one of our own metadata-lookup torrents, as opposed to a user's?static booleanisLoopbackHost(String host) IPv4 loopback (127/8), IPv6 loopback, and "localhost".booleanWhether the status filter bar is shown in the web interface.booleanWhether smart sort is enabled in the web interface.(package private) static booleanisStaleLookup(String name, String basePath, long createdAt, long now) Should this lookup torrent be swept now?booleanWhether the manager is in the process of stopping.booleanWhether hops are randomly varied for inbound torrent tunnels.booleanWhether hops are randomly varied for outbound torrent tunnels.private StringAn 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.Canonical .torrent filenames that we are dealing with.voidloadConfig(String filename) Load the config from the given file.private voidLoad the metadata file into _metadata.voidloadSavedFilePriorities(Snark snark) Saved priorities for a torrent from the metadata file.private voidlocked_loadConfig(String filename) Load the config from the given file.voidlocked_saveComments(Snark snark, CommentSet comments) Save the comments for a torrent.private voidlocked_saveTorrentStatus(byte[] ih, Properties config) Save per-torrent config to the single metadata file.private voidlocked_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.private voidlocked_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.private static voidlocked_writeMetaInfo(MetaInfo metainfo, String filename, boolean areFilesPublic) Write the metainfo to the file, caller must hold the snarks lock to prevent interference from the DirMonitor.lookupTorrentInfo(byte[] infoHash, long timeoutMs) Self-contained DHT lookup for torrent name and size without persisting torrent data.lookupTorrentInfo(String hex, long timeoutMs) Hex overload forlookupTorrentInfo(byte[], long).lookupTorrentName(byte[] infoHash, long timeoutMs) Self-contained DHT lookup for torrent name without persisting torrent data.lookupTorrentName(String hex, long timeoutMs) Hex string overload for convenience.private voidmergeIntoMetadata(byte[] ih, Properties props) Merge per-torrent properties into _metadata.private static StringBuild a metadata key for a torrent property.private FilemigrateConfig(File oldFile) Migrate the old flat config file to the new config dir.private voidMigrate per-torrent config files into the single metadata file.monitorTorrents(File dir) Add torrents found in the given directory.private voidmoveCommentFile(File configConf, byte[] ih) Move a comment file from legacy/subdir location to config dir root.private voidWait 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.private static intParse the destination cap, clamping invalid and out-of-range values to zero, which restores one destination per torrent.(package private) static booleanparseShouldPadFiles(Properties props) Parses thePROP_SHOULD_PAD_FILESvalue from the given properties, applying the default when absent or unparsable.previouslyRunning(List<Snark> batch) Filters a candidate start batch down to the torrents that were running when last saved.private voidprintToConsole(String msg) Print a message to stdout when running standalone, replacing any HTML nbsp entities so the console output is readable.private voidAdd the snark.voidrecheckTorrent(Snark snark) Threaded.voidremoveMagnetStatus(byte[] ih) Remove the magnet marker from the config.private SnarkremoveSnark(String torrentFile) Remove the snark.private voidremoveSnark(Snark snark) Remove the snark.voidremoveTorrent(String filename) Stop the torrent and delete the torrent file itself, but leaving the data behind.private voidremoveTorrentStatus(Snark snark) Remove the status of a torrent from the metadata file.private voidRe-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.static Set<InetAddress> resolveBrowserApiHosts(String hosts) Parse a comma-separated host list into resolved addresses.voidWrite the config to the config file, queueing a message on failure.voidsaveMagnetStatus(byte[] ih, String dir, String trackerURL, String dn) Just remember we have it.private voidSave the metadata file to disk.voidsaveOpenTrackers(List<String> ot) Save the given open tracker list.voidSave the given private tracker list.voidSerialize the torrent create filter map to its config file.private voidsaveTorrentStatus(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.voidsaveTorrentStatus(Snark snark) Save the completion status of a torrent and other data in the metadata file.private voidsaveTorrentStatus(Snark snark, Boolean comments) Save the completion status of a torrent and other data in the metadata file.voidWrite the tracker map to the config and save it.private intscanForConfigFiles(File dir, int migrated) Recursively scan for .config files and migrate them.private voidSchedule a one-shot cleanup of stale lookup torrents (if not already scheduled).voidDisconnectListener interface.voidSet and persist the API key for remote access, mirroring the apiKey/apiTarget handling in updateConfig.voidsetBrowserApi(boolean enable, String hosts) Set and persist the browser API enable flag and allowed hosts list.voidReplace the torrent create filter map with the built-in defaults and persist it.private voidsetDefaultTorrentCreateFilterMap(boolean save) Restore the default torrent-create filter map.voidReplace the tracker map with the built-in defaults, clearing the config key.private voidsetDefaultTrackerMap(boolean save) Restore the default tracker map.private StringsetListConfig(String prop, List<String> values) Serialize the given list into the config for the given property, does NOT save it.voidsetSavedCommentsEnabled(Snark snark, boolean yes) Setting for comments enabled in the metadata file.booleanWhether newly added torrents should be started automatically.booleanWhether running torrents are periodically restarted with fresh destinations.booleanWhether new torrents preallocate their storage files.voidClientApp method.private static voidsleep(long ms) Sleep, ignoring interruption.voidstart()Caller _must_ call loadConfig(file) before this if setting new values for i2cp host/port or i2psnark.dir.private voidstartAll()Starts every stopped torrent, staggering the tunnel builds when pools share a destination.voidAlways thread it.private booleanstartBatch(List<Snark> batch) Start a batch of torrents, keeping pool-mates together.(package private) static longstartDelay(Random rnd) Random delay between auto-started torrents in multi-dest mode, 30-90 seconds.voidstartStoppedTorrents(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 asstartBatch(List).voidstartTorrent(byte[] infoHash) If not connected, thread it, otherwise inline.voidstartTorrent(Snark snark) If not connected, thread it, otherwise inline.voidstartup()ClientApp method.voidstop()Called by the webapp at Jetty shutdown.voidstopAllTorrents(boolean finalShutdown) Stop all running torrents, and close the tunnel after a delay to allow for announces.stopTorrent(String filename, boolean shouldRemove) Stop the torrent, leaving it on the list of torrents unless told to remove it.voidstopTorrent(Snark torrent) Stop the torrent only, leaving it on the list of torrents.voidstopTorrent(Snark torrent, boolean shouldRemove) Stop the torrent, leaving it on the list of torrents unless told to remove it.private intstopTorrent(Snark snark, int count, boolean finalShutdown) Stop one torrent, notifying trackers per finalShutdown, and adding the "stopping all" message on the first stop.private voidRemove deprecated per-torrent keys from metadata.voidtorrentComplete(Snark snark) A Snark.CompleteListener method.private voidRe-reads the config file if it changed on disk.voidupdateConfig(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.voidupdateStatus(Snark snark) A Snark.CompleteListener method.util()The I2PSnarkUtil instance for this manager.private StringvalidateTempDir(String tempDir) Validates the staging directory: creates it if missing, checks write permission, and warns (returning null) when it is unusable.private StringvalidateTorrent(MetaInfo info) Does not really delete on failure, that's the caller's responsibility.private StringvalidateTorrentDir(String torrentDir) Checks a torrent's target directory is usable.(package private) static booleanwasPreviouslyRunning(Properties config) Returns true if the torrent's persisted config indicates it was running when last saved.
Field Details
_snarks
Map of (canonical) filename of the .torrent file to Snark instance. This is a CHM solistTorrentFiles()need not be synced, but all adds, deletes, and the DirMonitor should sync on it._infoHashToSnark
_filteredBaseNameToSnark
_magnets
_addSnarkLock
Lock keeping concurrent snark adds from duplicating work._configFile
File holding the global snark config._configDir
Directory holding the per-torrent config files._metadataFile
File holding the global metadata._metadata
The loaded global metadata._configLock
One lock for all config, files for simplicity._config
The loaded global config._context
The application context._contextPath
Webapp context path used in links._contextName
Display name of the webapp._log
Logger for this class._messages
Translated strings for the web UI._util
Shared utilities and settings for the torrents._peerCoordinatorSet
Peer coordinators shared between torrents._connectionAcceptor
Accepts incoming peer connections._bwManager
Shares bandwidth between the torrents._monitor
Thread monitoring the running torrents._running
private volatile boolean _runningTrue while the manager is running._stopping
private volatile boolean _stoppingTrue while the manager shuts down._trackerMap
_torrentCreateFilterMap
Torrent create filters by name._umgr
Manager of the torrent update threads._uhandler
Thread handling torrent updates._idleChecker
Timer stopping idle torrents.MAX_LOOKUP_CONCURRENCY
private static final int MAX_LOOKUP_CONCURRENCYMax concurrent DHT lookup threads (zzzot lookups).- See Also:
LOOKUP_STALE_MS
static final long LOOKUP_STALE_MSAge 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
Marker in the display name of a torrent created by a metadata lookup.- See Also:
LOOKUP_PATH_MARKER
Marker in the storage path of a torrent created by a metadata lookup.- See Also:
_lookupSemaphore
Caps concurrent magnet and torrent lookups._lookupCreationTimes
_staleLookupCleanupRunning
private volatile boolean _staleLookupCleanupRunningTrue while stale lookups are being cleaned up._snarkScheduler
Snark's own scheduler for periodic chores, deliberately notSimpleTimer2.SimpleTimer2has 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 inSnarkManagerdid to this router.Single-threaded, so overlapping cleanups cannot occur and the existing
_staleLookupCleanupRunningguard remains sufficient. The thread is a daemon and is not started until the first task is submitted._randomizeStartupDelay
private volatile boolean _randomizeStartupDelayTrue to randomize each torrent's startup delay._browserApiEnabled
private volatile boolean _browserApiEnabledTrue to serve the browser API._browserApiHosts
Raw comma-separated config value, for the config form._browserApiHostSet
Resolved allowed hosts (excluding loopback, which is always allowed).PROP_I2CP_HOST
I2CP host to connect to the router on.- See Also:
PROP_I2CP_PORT
I2CP port to connect to the router on.- See Also:
PROP_I2CP_OPTS
Extra session options, "name=value" space-separated.- See Also:
PROP_UPLOADERS_TOTAL
Uploader limit summed across all torrents.- See Also:
PROP_UPBW_MAX
Upload bandwidth cap across all torrents, in KBps.- See Also:
PROP_DOWNBW_MAX
Download bandwidth cap across all torrents, in KBps.- See Also:
PROP_MIN_PIPELINE
Minimum request pipeline depth for outbound requests.- See Also:
PROP_MAX_PIPELINE
Maximum request pipeline depth for outbound requests.- See Also:
PROP_PARTSIZE
Chunk size for outbound piece requests.- See Also:
PROP_MAX_PARTSIZE
Cap on a single piece request from a peer.- See Also:
PROP_DIR
Directory the downloaded torrent data is stored in.- See Also:
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
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
Config prefix for per-torrent metadata.- See Also:
PROP_META_RUNNING
Per-torrent key marking whether the torrent runs at startup; absent means run it.- See Also:
PROP_META_STAMP
Metadata key for the last-save time.- See Also:
PROP_META_BASE
Metadata key for the torrent's data directory.- See Also:
PROP_META_BITFIELD
Metadata key for the downloaded pieces.- See Also:
PROP_META_PRIORITY
Metadata key for the file priorities.- See Also:
PROP_META_UPLOADED
Metadata key for the bytes uploaded.- See Also:
PROP_META_ADDED
Metadata key for when the torrent was added.- See Also:
PROP_META_COMPLETED
Metadata key for when the torrent completed.- See Also:
PROP_META_MAGNET
Metadata key for the magnet URI.- See Also:
PROP_META_MAGNET_DN
Metadata key for the magnet's display name.- See Also:
PROP_META_MAGNET_TR
Metadata key for the magnet's trackers.- See Also:
PROP_META_MAGNET_DIR
Metadata key for the magnet's target directory.- See Also:
PROP_META_MAGNET_PREFIX
Config prefix for remembered magnet URIs.- See Also:
PROP_META_COMMENTS
Torrent meta key for comments.- See Also:
PROP_META_ACTIVITY
Torrent meta key for activity level.- See Also:
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
Retired config key for in-order downloading.- See Also:
CONFIG_FILE_SUFFIX
Suffix of each torrent's config file.- See Also:
CONFIG_FILE
Config file name within the config directory; the webapp's name only selects the directory.- See Also:
COMMENT_FILE_SUFFIX
Suffix of each torrent's gzipped comments file.- See Also:
METADATA_FILE
Name of the global metadata file.- See Also:
META_PREFIX
Prefix of metadata keys inside a config.- See Also:
PROP_FILES_PUBLIC
Whether files in the data directory are world-readable.- See Also:
PROP_PREALLOCATE_FILES
Preallocate the storage of new torrents.- See Also:
DEFAULT_PREALLOCATE_FILES
true: preallocate new torrents' storage.- See Also:
PROP_SHOULD_PAD_FILES
Add BEP 47 padding files to new torrents.- See Also:
DEFAULT_SHOULD_PAD_FILES
false: leave new torrents unpadded.- See Also:
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
true: auto-ban peers with an excessive discard ratio.- See Also:
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_PERIODDiscard-ratio bans last an hour.- See Also:
PROP_OLD_AUTO_START
Ancient "i2snark" typo in old configs, migrated toPROP_AUTO_START.- See Also:
PROP_AUTO_START
Auto-start saved torrents on startup.- See Also:
DEFAULT_AUTO_START
private final boolean DEFAULT_AUTO_STARTWhether torrents start on add by default.PROP_STARTUP_DELAY_MIN
Shortest delay before an auto-started torrent, in minutes.- See Also:
PROP_STARTUP_DELAY_MAX
Longest delay before an auto-started torrent, in minutes.- See Also:
PROP_REFRESH_DELAY
Seconds between automatic page refreshes.- See Also:
PROP_PAGE_SIZE
RC_PROP_THEME
Router console property holding the theme shared by all webapps.- See Also:
RC_PROP_UNIVERSAL_THEMING
Router console property applying one theme to all webapps.- See Also:
PROP_THEME
Theme I2PSnark uses when universal theming is off.- See Also:
DEFAULT_THEME
Theme used until the user picks one.- See Also:
PROP_COLLAPSE_PANELS
Start the page panels collapsed.- See Also:
PROP_SHOW_STATUSFILTER
Show the torrents-page status filter.- See Also:
DEFAULT_SHOW_STATUSFILTER
false: hide the status filter.- See Also:
PROP_ENABLE_LIGHTBOX
Load the image lightbox viewer.- See Also:
DEFAULT_ENABLE_LIGHTBOX
true: load the lightbox viewer.- See Also:
PROP_ENABLE_ADDCREATE
Keep the add-torrent and create-torrent forms on every page, not just page one.- See Also:
DEFAULT_ENABLE_ADDCREATE
false: show the add/create forms only on page one.- See Also:
PROP_USE_OPENTRACKERS
Config property enabling opentracker lists.- See Also:
PROP_OPENTRACKERS
Announce URLs of the open trackers, used as backups.- See Also:
PROP_PRIVATETRACKERS
Announce URLs offered per torrent for private trackers.- See Also:
PROP_USE_DHT
Config property enabling DHT lookups.- See Also:
PROP_SMART_SORT
Config property enabling smart piece sorting.- See Also:
PROP_LANG
Config property selecting the UI language.- See Also:
PROP_COUNTRY
Config property selecting the country.- See Also:
PROP_RATINGS
Config key enabling ratings display.- See Also:
PROP_COMMENTS
Config key enabling comments display.- See Also:
PROP_COMMENTS_NAME
Config key for the comments author name.- See Also:
PROP_MAX_FILES_PER_TORRENT
Ceiling on the number of files one torrent may contain.- See Also:
PROP_API_PREFIX
Config key prefix for API keys.- See Also:
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
Whether the nonce-free browser API (magnet/torrent add) is enabled.- See Also:
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
Configured cap on the number of log messages.- See Also:
PROP_VARY_INBOUND_HOPS
Randomize the hop count of inbound torrent tunnels.- See Also:
PROP_VARY_OUTBOUND_HOPS
Randomize the hop count of outbound torrent tunnels.- See Also:
PROP_MULTI_DEST
Whether each torrent runs on its own destination.- See Also:
PROP_MULTI_DEST_MAX
Maximum number of destinations in multi-dest mode, 0 for one per torrent.- See Also:
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
Optional comma-separated subset of client names, seeClientID.profiles(), to choose from whenPROP_CLIENT_IDis "random"; unknown names are ignored.- See Also:
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_INTERVALDestinations cycle every this long, plus a random jitter.- See Also:
DEST_CYCLE_JITTER
private static final int DEST_CYCLE_JITTERRandom 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_DELAYDelay after the stop-all before restarting, long enough for the Disconnector to close the old session.- See Also:
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_MAXDefault cap on destinations so many torrents share destinations instead of exhausting memory.- See Also:
MAX_MULTI_DEST
public static final int MAX_MULTI_DESTAbsolute maximum for the destination cap.- See Also:
MIN_UP_BW
public static final int MIN_UP_BWLowest upload bandwidth limit the configuration accepts, in KBps.- See Also:
MIN_DOWN_BW
public static final int MIN_DOWN_BWLowest download bandwidth limit the configuration accepts, in KBps.- See Also:
DEFAULT_MAX_UP_BW
public static final int DEFAULT_MAX_UP_BWInitial upload bandwidth cap across all torrents, in KBps.- See Also:
DEFAULT_MAX_DOWN_BW
private static final int DEFAULT_MAX_DOWN_BWDefault download bandwidth cap, in KB/s.- See Also:
DEFAULT_STARTUP_DELAY_MIN
public static final int DEFAULT_STARTUP_DELAY_MINInitial shortest delay before an auto-started torrent, in minutes.- See Also:
DEFAULT_STARTUP_DELAY_MAX
public static final int DEFAULT_STARTUP_DELAY_MAXInitial longest delay before an auto-started torrent, in minutes.- See Also:
DEFAULT_REFRESH_DELAY_SECS
public static final int DEFAULT_REFRESH_DELAY_SECSInitial seconds between automatic page refreshes.- See Also:
DEFAULT_PAGE_SIZE
private static final int DEFAULT_PAGE_SIZEDefault number of torrents per page.- See Also:
DEFAULT_TUNNEL_QUANTITY
public static final int DEFAULT_TUNNEL_QUANTITYTunnel quantity the default I2CP options ask for, in each direction.- See Also:
MULTI_DEST_STAGGER_MS
private static final long MULTI_DEST_STAGGER_MSDelay 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_TORRENTInitial ceiling on the number of files one torrent may contain.- See Also:
CONFIG_DIR_SUFFIX
Appended to the old flat config file name to form the config directory name.- See Also:
SUBDIR_PREFIX
Prefix of the per-torrent data subdirectories.- See Also:
B64
Alphabet used in the subdirectory names.- See Also:
COMMENT_CLEANUP
Characters stripped from comment text.TORRENT_SUFFIX
Trailing .torrent suffix stripped from display names.DEFAULT_MAX_MESSAGES
private static final int DEFAULT_MAX_MESSAGESDefault messages kept per torrent.- See Also:
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
URL. This is our equivalent torouter.utorrent.comfor bootstrap.- See Also:
DEFAULT_OPENTRACKERS
URLs, comma-separated. Used for "announce to open trackers also".- See Also:
DEFAULT_TRACKER_ANNOUNCES
KNOWN_OPENTRACKERS
DEFAULT_TORRENT_CREATE_FILTERS
Filters blocking torrent creation by default.PROP_TRACKERS
Comma delimited list of name=announceURL=baseURL for the trackers to be displayed.- See Also:
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
Filename for serialized torrent filters config.- See Also:
lastAddedMessageTimestamp
private long lastAddedMessageTimestampWhen the last add message arrived.lastAddedMessage
Text of the last status message added.DATE_FORMAT
Date format for recent messages.CONFIG_CACHE_TTL
private static final long CONFIG_CACHE_TTLHow long to cache a per-torrent config before reloading, covers manual file edits.- See Also:
_configCache
Guarded by _configLock.DISK_USAGE_TTL
private static final long DISK_USAGE_TTLHow long to cache the disk usage string, avoids a statfs per render.- See Also:
_diskUsageCheckedAt
private long _diskUsageCheckedAtLast time the disk usage string was computed._diskUsageCached
Cached disk usage string.
Constructor Details
SnarkManager
SnarkManager
For webapp.- Parameters:
ctx- the I2P context to run inctxPath- 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
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:
sessionDisconnectedin interfaceI2PSocketManager.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
shutdown
getState
ClientApp method. Doesn't matter, we are only registering.getName
getDisplayName
ClientApp method.- Specified by:
getDisplayNamein interfaceClientApp- Returns:
- the display name
util
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
The bandwidth listener for this manager.- Specified by:
getBandwidthListenerin interfaceCompleteListener- Returns:
- bandwidth listener
escapeMessage
Escape a message for HTML display, preserving intentional ' ' 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
Use if it does not include a link. Escapes '<' and '>' before queueing.- Parameters:
message- text to queue for the messages page
addMessageNoEscape
Use if it includes a link. Does not escape '<' and '>' before queueing.- Parameters:
message- HTML to queue for the messages page, unescaped
addMessageAndPrint
Queue a message and, when running standalone, print it to stdout.- Parameters:
message- the message to queue
addMessageAndPrint
addMessageNoEscapeAndPrint
Queue a message and, when running standalone, print it to stdout.- Parameters:
message- the message to queue
addMessageNoEscapeAndPrint
printToConsole
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
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
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:
shouldAutoStartin interfaceCompleteListener- 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
The configured torrent data directory.- Returns:
- the directory, from the config or the webapp name
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
migrateConfig
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
The config for a torrent.- Parameters:
snark- the torrent whose config properties are wanted- Returns:
- non-null, possibly empty
getConfig
The config for a torrent.- Parameters:
ih- 20-byte infohash- Returns:
- non-null, possibly empty
metaKey
Build a metadata key for a torrent property.- Parameters:
ih- the 20-byte infohash of the torrent the property belongs toprop- 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
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 includedmigrated- count of files migrated so far, threaded through the recursion- Returns:
- the running total of migrated files, including those found in dir
mergeIntoMetadata
Merge per-torrent properties into _metadata.- Parameters:
ih- the 20-byte infohash of the torrent the properties belong toprops- the per-torrent properties to copy in; the internal infohash key and the deprecated keys are skipped
moveCommentFile
Move a comment file from legacy/subdir location to config dir root.- Parameters:
configConf- the legacy config file whose companion comment file is movedih- the 20-byte infohash, unused: the comment name comes from the file name
commentFile
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
The comments for a torrent.- Specified by:
getSavedCommentsin interfaceCompleteListener- Parameters:
snark- the Snark instance to read the comment set from- Returns:
- null if none
locked_saveComments
Save the comments for a torrent. Caller must synchronize on comments.- Specified by:
locked_saveCommentsin interfaceCompleteListener- Parameters:
snark- the Snark instance whose torrent lock is heldcomments- non-null
configFileToInfoHash
loadConfig
Load the config from the given file.- Parameters:
filename- null to set initial defaults
locked_loadConfig
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
The current theme for this web interface.- Returns:
- String -- the current theme
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 sinceloadConfig(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 sameupdateConfig()path used at startup. Settings removed from the file keep their current value.parseShouldPadFiles
Parses thePROP_SHOULD_PAD_FILESvalue 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
Reads thePROP_TEMP_DIRproperty, 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
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
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
getInt
Reads an int from the config.- Parameters:
prop- the property to readdefaultVal- the value when unset or malformed- Returns:
- the configured value
parseMaxDest
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 torrentfilesPublic- true to make new data directory files world-readableautoStart- true to auto-start saved torrentsrefreshDelay- seconds between page refreshes, negative to disable, or null to leave it alonestartDelayMin- shortest delay before an auto-started torrent in minutes, or null to leave it alonestartDelayMax- longest delay before an auto-started torrent in minutes, swapped with the minimum if lower, or null to leave it alonepageSize- torrents listed per page, 5 or more, zero or less for all, or null to leave it alonei2cpHost- I2CP host to connect to, or null to keep the current onei2cpPort- I2CP port to connect to, or null to keep the current onei2cpOpts- space-separated "name=value" session options, not nullupLimit- uploader limit summed across all torrents, or null to leave it aloneupBW- upload bandwidth cap in KBps, or null to leave it alonedownBW- download bandwidth cap in KBps, or null to leave it aloneuseOpenTrackers- true to announce to the open trackers as backupsuseDHT- true to participate in the DHTtheme- theme name to use when universal theming is off, or null to leave it alonelang- standalone language as "lang_COUNTRY", ignored in router context, or null to leave it aloneenableRatings- true to collect and show peer ratingsenableComments- true to fetch and show peer commentscommentName- author name for our own comments, or null to clear itcollapsePanels- true to start the page panels collapsedshowStatusFilter- true to show the torrents-page filter barenableLightbox- true to load the image lightbox viewerenableAddCreate- true to keep the add/create forms on every pageenableVaryInboundHops- true to randomize the inbound tunnel hop countenableVaryOutboundHops- true to randomize the outbound tunnel hop countmultiDest- true to give each torrent a destination of its ownmultiDestMax- destination cap in multi-dest mode, zero for one per torrent, or null to leave it alonerandomizeStartup- true to stagger batched torrent startsapiTarget- API target base path, honored only alongside a non-empty apiKeyapiKey- API key, honored only alongside a non-empty apiTargetmaxFiles- ceiling on the files one torrent may contain, at least 1, or null to leave it alonepreallocateFiles- true to preallocate storage for new torrentstempDir- staging directory for incomplete files, or null to disable stagingtorrentDir- directory for .torrent files, or null to reset to the data directorypreserveFileNames- 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 directoryfilesPublic- true to serve files publiclyautoStart- true to start torrents on addrefreshDelay- the UI refresh delaystartDelayMin- the shortest startup delaystartDelayMax- the longest startup delaypageSize- the torrents per pagei2cpHost- the I2CP hosti2cpPort- the I2CP porti2cpOpts- the I2CP optionsupLimit- the max uploadersupBW- the upload bandwidth capdownBW- the download bandwidth capuseOpenTrackers- true to use opentracker listsuseDHT- true to use DHTtheme- the UI themelang- the UI languageenableRatings- true to show ratingsenableComments- true to show commentscommentName- the poster namecollapsePanels- true to start panels collapsedshowStatusFilter- true to show the status filterenableLightbox- true to enable the lightboxenableAddCreate- true to enable add and createenableVaryInboundHops- true to vary inbound hop countsenableVaryOutboundHops- true to vary outbound hop countsmultiDest- true to allow multiple destinationsmultiDestMax- the destination caprandomizeStartup- true to randomize startup delaysapiTarget- the browser API targetapiKey- the browser API keymaxFiles- the file listing cappreallocateFiles- true to preallocate spacetempDir- the temporary download directorytorrentDir- the torrent directorypreserveFileNames- true to keep original file names
getPrivateTrackers
browserApiEnabled
public boolean browserApiEnabled()Whether the nonce-free browser API for adding torrents is enabled.- Returns:
- whether the browser api is enabled
getBrowserApiHosts
The raw comma-separated browser API allowed hosts config, for the config form.- Returns:
- non-null, may be empty
setBrowserApi
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 allhosts- comma-separated hostnames or IPs, may be null/empty
setAPI
isBrowserApiHost
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
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
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
savePrivateTrackers
getListConfig
Deserialize the given list property from the config.- Parameters:
prop- the config property holding a comma-separated listdflt- default or null- Returns:
- the split values, non-null and fixed size, empty if neither the property nor the default is set
setListConfig
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 emptyvalues- 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
getTorrent
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
getTorrentByInfoHash
Grab the torrent given the info hash.- Parameters:
infohash- the torrent's info hash- Returns:
- Snark or null
putSnark
removeSnark
Remove the snark. Caller must sync on _snarks.- Parameters:
snark- the torrent to drop from the name, infohash and base-name maps
removeSnark
disableTorrentFile
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
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 dataDirdontAutoStart- 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
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 dataDirdontAutoStart- must be false, AND running=true or null in metadata, to startdataDir- 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
Add a torrent with the info hash alone (magnet / maggot).- Parameters:
name- hex or b32 name from the magnet linkih- 20 byte info hashtrackerURL- may be nullupdateStatus- 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 linkih- 20 byte info hashtrackerURL- may be nullupdateStatus- 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 linkih- 20 byte info hashtrackerURL- may be nullupdateStatus- 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 awaydataDir- must exist, or null to default to snark data directorylistener- 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
Stop and delete a torrent running in magnet mode.- Parameters:
snark- a torrent with a fake file name ("Magnet xxxx")
lookupTorrentName
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 infohashtimeoutMs- 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
lookupTorrentInfo
Self-contained DHT lookup for torrent name and size without persisting torrent data. Same semantics aslookupTorrentName(byte[], long)but also returns the combined size of data files (excludes BEP47 padding) viaMetaInfo.getDataLength(). This is the value zzzot hashlist should display alongside the name.- Parameters:
infoHash- 20-byte infohashtimeoutMs- max wait as forlookupTorrentName- Returns:
TorrentInfowith name and size, or null if not found/timeout
lookupTorrentInfo
Hex overload forlookupTorrentInfo(byte[], long).- Parameters:
hex- 40-character hex infohashtimeoutMs- max wait as forlookupTorrentInfo- Returns:
TorrentInfowith 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 thanLOOKUP_STALE_MSand removes them. They will be resubmitted by the caller (zzzot) on the next request.isLookupTorrent
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 readbasePath- storage base path, or null if unknown or not yet resolved- Returns:
- true if this is a lookup torrent
isStaleLookup
Should this lookup torrent be swept now?- Parameters:
name- display name, or null if it could not be readbasePath- storage base path, or null if unknowncreatedAt- when the lookup was created, in msnow- 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
Add and start a FetchAndAdd task. Remove it withdeleteMagnet(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 torrentbitfield- the current completion status of the torrent, or nullfilename- 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 rootDataDirdontAutoStart- 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 createdIOException- declared for API compatibility; a write failure is reported as a queued message and a false return
copyAndAddTorrent
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 somewherefilename- 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 throwingIOException- 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 torrentfilename- 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
Timestamp for a torrent from the metadata file. A Snark.CompleteListener method.- Specified by:
getSavedTorrentTimein interfaceCompleteListener- Parameters:
snark- the Snark instance holding the stored timestamp- Returns:
- the saved torrent time in milliseconds
getSavedTorrentBitField
Saved bitfield for a torrent from the metadata file. Convert "." to a full bitfield. A Snark.CompleteListener method.- Specified by:
getSavedTorrentBitFieldin interfaceCompleteListener- Parameters:
snark- the Snark instance holding the stored bitfield- Returns:
- the saved torrent bit field
loadSavedFilePriorities
Saved priorities for a torrent from the metadata file.- Parameters:
snark- the torrent to load the per-file priorities into
getSavedBaseFile
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
Setting for a torrent from the metadata file.- Specified by:
getSavedUploadedin interfaceCompleteListener- Parameters:
snark- the torrent whose saved upload total is wanted- Returns:
- total bytes uploaded, 0 if not found
getSavedAddedAndCompleted
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
Setting for comments enabled from the metadata file. Caller must first check globalI2PSnarkUtil.commentsEnabled()Default true.- Parameters:
snark- the torrent to read the setting of- Returns:
- the saved comments enabled
setSavedCommentsEnabled
Setting for comments enabled in the metadata file.- Parameters:
snark- the torrent to record the setting foryes- the setting to store
saveTorrentStatus
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
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-nullbitfield- non-nullpriorities- may be nullbase- may be nulluploaded- total bytes uploaded, stored as the torrent's upload totalactivity- last activity time in ms since the epoch, 0 leaves it unsetstopped- true records the torrent as not running, so it is not restartedcomments- 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 metadatabitfield- the downloaded piecespriorities- the file prioritiesbase- the torrent's data directoryuploaded- the bytes uploadedactivity- the last activity timestopped- true if the torrent is stoppedcomments- true if comments were fetched
locked_saveTorrentStatus
Save per-torrent config to the single metadata file.- Parameters:
ih- the 20-byte infohash whose metadata entries are replacedconfig- the properties to store, without the per-torrent prefix
removeTorrentStatus
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
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 markerdir- may be nulltrackerURL- may be nulldn- 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
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- fromMetaInfo.getFiles(), may be null- Returns:
- the number of non-padding files
validateTorrent
Does not really delete on failure, that's the caller's responsibility. Warning - does not validate announce URL - useTrackerClient.isValidAnnounce(String).- Parameters:
info- the parsed metainfo to check against the configured limits- Returns:
- failure message or null on success
stopTorrent
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 stopshouldRemove- 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
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 nullshouldRemove- true to drop the torrent from the list and delete its metadata
stopTorrent
Stop the torrent only, leaving it on the list of torrents.- Parameters:
torrent- the torrent to stop, may be null
removeTorrent
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
Logs the free space of a directory in human units.- Parameters:
dir- the directory to measure
checkTempDirSpace
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
A Snark.CompleteListener method.- Specified by:
torrentCompletein interfaceCompleteListener- Parameters:
snark- the Snark instance that completed
updateStatus
A Snark.CompleteListener method.- Specified by:
updateStatusin interfaceCompleteListener- Parameters:
snark- the Snark instance to update status for
gotMetaInfo
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:
gotMetaInfoin interfaceCompleteListener- Parameters:
snark- the Snark instance that just initialized its metainfo and storage- Returns:
- the new name for the torrent or null on error
fatal
A Snark.CompleteListener method.- Specified by:
fatalin interfaceCompleteListener- Parameters:
snark- the Snark instance that stoppederror- the description of the failure, already localized for display
addMessage
A Snark.CompleteListener method.- Specified by:
addMessagein interfaceCompleteListener- Parameters:
snark- the Snark instance raising the messagemessage- the text to show in the torrent UI, already localized
gotPiece
A Snark.CompleteListener method.- Specified by:
gotPiecein interfaceCompleteListener- Parameters:
snark- the Snark instance that downloaded the piece
linkify
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
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
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
_t
_t
Translate the given string with two substitutions.- Parameters:
s- the text to translate, containing {0} and {1} placeholders; single quotes must be doubledo- the substitution for {0}, not itself translatedo2- the substitution for {1}, not itself translated- Returns:
- the localized text with {0} and {1} replaced
getTrackerMap
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
Unsorted, do not modify.- Returns:
- the configured trackers, a live view of the tracker map
getTorrentCreateFilterStrings
Unsorted, do not modify.- Returns:
- the torrent create filter strings
getSortedTrackers
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
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
Start all currently-stopped torrents of the given batch in the background using the same pool-aware staggering and parallel pool startup asstartBatch(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
Filters a candidate start batch down to the torrents that were running when last saved. A torrent whose per-torrent config has noPROP_META_RUNNINGentry 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
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
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
Stop one torrent, notifying trackers per finalShutdown, and adding the "stopping all" message on the first stop.- Parameters:
snark- the torrent to stopcount- number of torrents stopped so farfinalShutdown- 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
Threaded. Torrent must be stopped.- Parameters:
snark- the stopped torrent to recheck
getDiskUsage