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
This commit is contained in:
@ -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,7 +90,9 @@ public class I2PSnarkUtil {
|
||||
public boolean configured() { return _configured; }
|
||||
|
||||
public void setI2CPConfig(String i2cpHost, int i2cpPort, Map opts) {
|
||||
if (i2cpHost != null)
|
||||
_i2cpHost = i2cpHost;
|
||||
if (i2cpPort > 0)
|
||||
_i2cpPort = i2cpPort;
|
||||
if (opts != null)
|
||||
_opts.putAll(opts);
|
||||
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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,10 +120,12 @@ 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();
|
||||
if (filename != null) {
|
||||
_configFile = filename;
|
||||
File cfg = new File(filename);
|
||||
if (cfg.exists()) {
|
||||
try {
|
||||
@ -126,6 +134,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
_log.error("Error loading I2PSnark config '" + filename + "'", ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
// now add sane defaults
|
||||
if (!_config.containsKey(PROP_I2CP_HOST))
|
||||
_config.setProperty(PROP_I2CP_HOST, "localhost");
|
||||
|
@ -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 {
|
||||
|
Reference in New Issue
Block a user