From 0ff816742550269b3316edf6a7df8112d95a8b79 Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Tue, 18 Nov 2008 02:18:23 +0000 Subject: [PATCH] i2psnark: - Don't create SnarkManager instance until first call, so it doesn't create the i2psnark dir, read the config, etc., for single Snark instances. - Don't read i2psnark.config twice; fix setting i2psnark.dir - More Snark constructor changes for calling from router - Make max connections per torrent configurable --- .../src/org/klomp/snark/I2PSnarkUtil.java | 15 +++++++- .../src/org/klomp/snark/PeerCoordinator.java | 9 ++--- .../java/src/org/klomp/snark/Snark.java | 38 +++++++++++++++++-- .../src/org/klomp/snark/SnarkManager.java | 29 +++++++++----- .../org/klomp/snark/web/I2PSnarkServlet.java | 1 + 5 files changed, 71 insertions(+), 21 deletions(-) diff --git a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java index bdfc056efd..7b674b0a05 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java +++ b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java @@ -47,12 +47,14 @@ public class I2PSnarkUtil { private Set _shitlist; private int _maxUploaders; private int _maxUpBW; + private int _maxConnections; public static final String PROP_USE_OPENTRACKERS = "i2psnark.useOpentrackers"; public static final boolean DEFAULT_USE_OPENTRACKERS = true; public static final String PROP_OPENTRACKERS = "i2psnark.opentrackers"; public static final String DEFAULT_OPENTRACKERS = "http://tracker.welterde.i2p/a"; public static final int DEFAULT_MAX_UP_BW = 8; //KBps + public static final int MAX_CONNECTIONS = 16; // per torrent public I2PSnarkUtil(I2PAppContext ctx) { _context = ctx; @@ -64,6 +66,7 @@ public class I2PSnarkUtil { _configured = false; _maxUploaders = Snark.MAX_TOTAL_UPLOADERS; _maxUpBW = DEFAULT_MAX_UP_BW; + _maxConnections = MAX_CONNECTIONS; } /** @@ -87,8 +90,10 @@ public class I2PSnarkUtil { public boolean configured() { return _configured; } public void setI2CPConfig(String i2cpHost, int i2cpPort, Map opts) { - _i2cpHost = i2cpHost; - _i2cpPort = i2cpPort; + if (i2cpHost != null) + _i2cpHost = i2cpHost; + if (i2cpPort > 0) + _i2cpPort = i2cpPort; if (opts != null) _opts.putAll(opts); _configured = true; @@ -104,6 +109,11 @@ public class I2PSnarkUtil { _configured = true; } + public void setMaxConnections(int limit) { + _maxConnections = limit; + _configured = true; + } + public String getI2CPHost() { return _i2cpHost; } public int getI2CPPort() { return _i2cpPort; } public Map getI2CPOptions() { return _opts; } @@ -112,6 +122,7 @@ public class I2PSnarkUtil { public boolean getEepProxySet() { return _shouldProxy; } public int getMaxUploaders() { return _maxUploaders; } public int getMaxUpBW() { return _maxUpBW; } + public int getMaxConnections() { return _maxConnections; } /** * Connect to the router, if we aren't already diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java b/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java index b54cbdafa4..ba5597e591 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java @@ -44,7 +44,6 @@ public class PeerCoordinator implements PeerListener // package local for access by CheckDownLoadersTask final static long CHECK_PERIOD = 40*1000; // 40 seconds - final static int MAX_CONNECTIONS = 16; final static int MAX_UPLOADERS = 6; // Approximation of the number of current uploaders. @@ -237,7 +236,7 @@ public class PeerCoordinator implements PeerListener { synchronized(peers) { - return !halted && peers.size() < MAX_CONNECTIONS; + return !halted && peers.size() < _util.getMaxConnections(); } } @@ -295,7 +294,7 @@ public class PeerCoordinator implements PeerListener peer.disconnect(false); // Don't deregister this connection/peer. } // This is already checked in addPeer() but we could have gone over the limit since then - else if (peers.size() >= MAX_CONNECTIONS) + else if (peers.size() >= _util.getMaxConnections()) { if (_log.shouldLog(Log.WARN)) _log.warn("Already at MAX_CONNECTIONS in connected() with peer: " + peer); @@ -351,7 +350,7 @@ public class PeerCoordinator implements PeerListener peersize = peers.size(); // This isn't a strict limit, as we may have several pending connections; // thus there is an additional check in connected() - need_more = (!peer.isConnected()) && peersize < MAX_CONNECTIONS; + need_more = (!peer.isConnected()) && peersize < _util.getMaxConnections(); // Check if we already have this peer before we build the connection Peer old = peerIDInList(peer.getPeerID(), peers); need_more = need_more && ((old == null) || (old.getInactiveTime() > 8*60*1000)); @@ -379,7 +378,7 @@ public class PeerCoordinator implements PeerListener if (peer.isConnected()) _log.info("Add peer already connected: " + peer); else - _log.info("Connections: " + peersize + "/" + MAX_CONNECTIONS + _log.info("Connections: " + peersize + "/" + _util.getMaxConnections() + " not accepting extra peer: " + peer); } return false; diff --git a/apps/i2psnark/java/src/org/klomp/snark/Snark.java b/apps/i2psnark/java/src/org/klomp/snark/Snark.java index fdb334d3d3..f10ef41d33 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/Snark.java +++ b/apps/i2psnark/java/src/org/klomp/snark/Snark.java @@ -28,6 +28,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Properties; import java.util.Random; import java.util.StringTokenizer; @@ -35,6 +36,7 @@ import java.util.Timer; import java.util.TimerTask; import net.i2p.I2PAppContext; +import net.i2p.router.client.ClientManagerFacadeImpl; import net.i2p.client.streaming.I2PServerSocket; import net.i2p.data.Destination; import net.i2p.util.I2PThread; @@ -235,6 +237,7 @@ public class Snark } } + public static final String PROP_MAX_CONNECTIONS = "i2psnark.maxConnections"; public String torrent; public MetaInfo meta; public Storage storage; @@ -254,10 +257,35 @@ public class Snark this(util, torrent, ip, user_port, slistener, clistener, null, null, null, true, "."); } - /** single torrent */ - Snark(I2PAppContext ctx, String torrent, String ip, int user_port, - StorageListener slistener, CoordinatorListener clistener) { - this(new I2PSnarkUtil(ctx), torrent, ip, user_port, slistener, clistener, null, null, null, true, "."); + /** single torrent - via router */ + public Snark(I2PAppContext ctx, Properties opts, String torrent, + StorageListener slistener, boolean start, String rootDir) { + this(new I2PSnarkUtil(ctx), torrent, null, -1, slistener, null, null, null, null, false, rootDir); + String host = opts.getProperty(ClientManagerFacadeImpl.PROP_CLIENT_HOST); + int port = 0; + String s = opts.getProperty(ClientManagerFacadeImpl.PROP_CLIENT_PORT); + if (s != null) { + try { + port = Integer.parseInt(s); + } catch (NumberFormatException nfe) {} + } + _util.setI2CPConfig(host, port, opts); + s = opts.getProperty(SnarkManager.PROP_UPBW_MAX); + if (s != null) { + try { + int v = Integer.parseInt(s); + _util.setMaxUpBW(v); + } catch (NumberFormatException nfe) {} + } + s = opts.getProperty(PROP_MAX_CONNECTIONS); + if (s != null) { + try { + int v = Integer.parseInt(s); + _util.setMaxConnections(v); + } catch (NumberFormatException nfe) {} + } + if (start) + this.startTorrent(); } /** multitorrent */ @@ -523,6 +551,8 @@ public class Snark } if (pc != null && _peerCoordinatorSet != null) _peerCoordinatorSet.remove(pc); + if (_peerCoordinatorSet == null) + _util.disconnect(); } static Snark parseArguments(String[] args) diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index 6ae2be6dd5..4b531f6064 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -32,7 +32,7 @@ public class SnarkManager implements Snark.CompleteListener { /** map of (canonical) filename to Snark instance (unsynchronized) */ private Map _snarks; private Object _addSnarkLock; - private String _configFile; + private String _configFile = "i2psnark.config"; private Properties _config; private I2PAppContext _context; private Log _log; @@ -67,9 +67,15 @@ public class SnarkManager implements Snark.CompleteListener { _log = _context.logManager().getLog(SnarkManager.class); _messages = new ArrayList(16); _util = new I2PSnarkUtil(_context); + loadConfig(null); + } + + /** Caller _must_ call loadConfig(file) before this if setting new values + * for i2cp host/port or i2psnark.dir + */ + public void start() { _peerCoordinatorSet = new PeerCoordinatorSet(); _connectionAcceptor = new ConnectionAcceptor(_util); - loadConfig("i2psnark.config"); int minutes = getStartupDelayMinutes(); _messages.add("Adding torrents in " + minutes + (minutes == 1 ? " minute" : " minutes")); I2PAppThread monitor = new I2PAppThread(new DirMonitor(), "Snark DirMonitor"); @@ -114,17 +120,20 @@ public class SnarkManager implements Snark.CompleteListener { return new File(dir); } + /** null to set initial defaults */ public void loadConfig(String filename) { - _configFile = filename; if (_config == null) _config = new Properties(); - File cfg = new File(filename); - if (cfg.exists()) { - try { - DataHelper.loadProps(_config, cfg); - } catch (IOException ioe) { - _log.error("Error loading I2PSnark config '" + filename + "'", ioe); - } + if (filename != null) { + _configFile = filename; + File cfg = new File(filename); + if (cfg.exists()) { + try { + DataHelper.loadProps(_config, cfg); + } catch (IOException ioe) { + _log.error("Error loading I2PSnark config '" + filename + "'", ioe); + } + } } // now add sane defaults if (!_config.containsKey(PROP_I2CP_HOST)) diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index c4baa45cd2..e276ccd88f 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -55,6 +55,7 @@ public class I2PSnarkServlet extends HttpServlet { if ( (configFile == null) || (configFile.trim().length() <= 0) ) configFile = "i2psnark.config"; _manager.loadConfig(configFile); + _manager.start(); } public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { -- GitLab