i2psnark:
- Remove static instances of I2PSnarkUtil, ConnectionAcceptor, and PeerCoordinatorSet - Convert static classes in Snark to listeners - Fix Snark to work in single torrent mode again - Should now work with multiple single Snarks
This commit is contained in:
@ -36,17 +36,16 @@ import net.i2p.util.Log;
|
|||||||
*/
|
*/
|
||||||
public class ConnectionAcceptor implements Runnable
|
public class ConnectionAcceptor implements Runnable
|
||||||
{
|
{
|
||||||
private static final ConnectionAcceptor _instance = new ConnectionAcceptor();
|
|
||||||
public static final ConnectionAcceptor instance() { return _instance; }
|
|
||||||
private Log _log = new Log(ConnectionAcceptor.class);
|
private Log _log = new Log(ConnectionAcceptor.class);
|
||||||
private I2PServerSocket serverSocket;
|
private I2PServerSocket serverSocket;
|
||||||
private PeerAcceptor peeracceptor;
|
private PeerAcceptor peeracceptor;
|
||||||
private Thread thread;
|
private Thread thread;
|
||||||
|
private I2PSnarkUtil _util;
|
||||||
|
|
||||||
private boolean stop;
|
private boolean stop;
|
||||||
private boolean socketChanged;
|
private boolean socketChanged;
|
||||||
|
|
||||||
private ConnectionAcceptor() {}
|
public ConnectionAcceptor(I2PSnarkUtil util) { _util = util; }
|
||||||
|
|
||||||
public synchronized void startAccepting(PeerCoordinatorSet set, I2PServerSocket socket) {
|
public synchronized void startAccepting(PeerCoordinatorSet set, I2PServerSocket socket) {
|
||||||
if (serverSocket != socket) {
|
if (serverSocket != socket) {
|
||||||
@ -63,11 +62,12 @@ public class ConnectionAcceptor implements Runnable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConnectionAcceptor(I2PServerSocket serverSocket,
|
public ConnectionAcceptor(I2PSnarkUtil util, I2PServerSocket serverSocket,
|
||||||
PeerAcceptor peeracceptor)
|
PeerAcceptor peeracceptor)
|
||||||
{
|
{
|
||||||
this.serverSocket = serverSocket;
|
this.serverSocket = serverSocket;
|
||||||
this.peeracceptor = peeracceptor;
|
this.peeracceptor = peeracceptor;
|
||||||
|
_util = util;
|
||||||
|
|
||||||
socketChanged = false;
|
socketChanged = false;
|
||||||
stop = false;
|
stop = false;
|
||||||
@ -78,7 +78,7 @@ public class ConnectionAcceptor implements Runnable
|
|||||||
|
|
||||||
public void halt()
|
public void halt()
|
||||||
{
|
{
|
||||||
if (true) throw new RuntimeException("wtf");
|
if (stop) return;
|
||||||
stop = true;
|
stop = true;
|
||||||
|
|
||||||
I2PServerSocket ss = serverSocket;
|
I2PServerSocket ss = serverSocket;
|
||||||
@ -95,7 +95,7 @@ public class ConnectionAcceptor implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void restart() {
|
public void restart() {
|
||||||
serverSocket = I2PSnarkUtil.instance().getServerSocket();
|
serverSocket = _util.getServerSocket();
|
||||||
socketChanged = true;
|
socketChanged = true;
|
||||||
Thread t = thread;
|
Thread t = thread;
|
||||||
if (t != null)
|
if (t != null)
|
||||||
@ -116,7 +116,7 @@ public class ConnectionAcceptor implements Runnable
|
|||||||
socketChanged = false;
|
socketChanged = false;
|
||||||
}
|
}
|
||||||
while ( (serverSocket == null) && (!stop)) {
|
while ( (serverSocket == null) && (!stop)) {
|
||||||
serverSocket = I2PSnarkUtil.instance().getServerSocket();
|
serverSocket = _util.getServerSocket();
|
||||||
if (serverSocket == null)
|
if (serverSocket == null)
|
||||||
try { Thread.sleep(10*1000); } catch (InterruptedException ie) {}
|
try { Thread.sleep(10*1000); } catch (InterruptedException ie) {}
|
||||||
}
|
}
|
||||||
@ -129,7 +129,7 @@ public class ConnectionAcceptor implements Runnable
|
|||||||
if (socketChanged) {
|
if (socketChanged) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
I2PServerSocket ss = I2PSnarkUtil.instance().getServerSocket();
|
I2PServerSocket ss = _util.getServerSocket();
|
||||||
if (ss != serverSocket) {
|
if (ss != serverSocket) {
|
||||||
serverSocket = ss;
|
serverSocket = ss;
|
||||||
socketChanged = true;
|
socketChanged = true;
|
||||||
@ -143,13 +143,13 @@ public class ConnectionAcceptor implements Runnable
|
|||||||
catch (I2PException ioe)
|
catch (I2PException ioe)
|
||||||
{
|
{
|
||||||
if (!socketChanged) {
|
if (!socketChanged) {
|
||||||
Snark.debug("Error while accepting: " + ioe, Snark.ERROR);
|
_util.debug("Error while accepting: " + ioe, Snark.ERROR);
|
||||||
stop = true;
|
stop = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException ioe)
|
catch (IOException ioe)
|
||||||
{
|
{
|
||||||
Snark.debug("Error while accepting: " + ioe, Snark.ERROR);
|
_util.debug("Error while accepting: " + ioe, Snark.ERROR);
|
||||||
stop = true;
|
stop = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,7 +161,6 @@ public class ConnectionAcceptor implements Runnable
|
|||||||
}
|
}
|
||||||
catch (I2PException ignored) { }
|
catch (I2PException ignored) { }
|
||||||
|
|
||||||
throw new RuntimeException("wtf");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Handler implements Runnable {
|
private class Handler implements Runnable {
|
||||||
|
@ -30,4 +30,8 @@ public interface CoordinatorListener
|
|||||||
* Called when the PeerCoordinator notices a change in the state of a peer.
|
* Called when the PeerCoordinator notices a change in the state of a peer.
|
||||||
*/
|
*/
|
||||||
void peerChange(PeerCoordinator coordinator, Peer peer);
|
void peerChange(PeerCoordinator coordinator, Peer peer);
|
||||||
|
|
||||||
|
public boolean overUploadLimit(int uploaders);
|
||||||
|
public boolean overUpBWLimit();
|
||||||
|
public boolean overUpBWLimit(long total);
|
||||||
}
|
}
|
||||||
|
@ -28,12 +28,13 @@ import net.i2p.util.SimpleTimer;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* I2P specific helpers for I2PSnark
|
* I2P specific helpers for I2PSnark
|
||||||
|
* We use this class as a sort of context for i2psnark
|
||||||
|
* so we can run multiple instances of single Snarks
|
||||||
|
* (but not multiple SnarkManagers, it is still static)
|
||||||
*/
|
*/
|
||||||
public class I2PSnarkUtil {
|
public class I2PSnarkUtil {
|
||||||
private I2PAppContext _context;
|
private I2PAppContext _context;
|
||||||
private Log _log;
|
private Log _log;
|
||||||
private static I2PSnarkUtil _instance = new I2PSnarkUtil();
|
|
||||||
public static I2PSnarkUtil instance() { return _instance; }
|
|
||||||
|
|
||||||
private boolean _shouldProxy;
|
private boolean _shouldProxy;
|
||||||
private String _proxyHost;
|
private String _proxyHost;
|
||||||
@ -53,8 +54,8 @@ public class I2PSnarkUtil {
|
|||||||
public static final String DEFAULT_OPENTRACKERS = "http://tracker.welterde.i2p/a";
|
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 DEFAULT_MAX_UP_BW = 8; //KBps
|
||||||
|
|
||||||
private I2PSnarkUtil() {
|
public I2PSnarkUtil(I2PAppContext ctx) {
|
||||||
_context = I2PAppContext.getGlobalContext();
|
_context = ctx;
|
||||||
_log = _context.logManager().getLog(Snark.class);
|
_log = _context.logManager().getLog(Snark.class);
|
||||||
_opts = new HashMap();
|
_opts = new HashMap();
|
||||||
setProxy("127.0.0.1", 4444);
|
setProxy("127.0.0.1", 4444);
|
||||||
@ -233,6 +234,28 @@ public class I2PSnarkUtil {
|
|||||||
}
|
}
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Base64 only - static (no naming service) */
|
||||||
|
static Destination getDestinationFromBase64(String ip) {
|
||||||
|
if (ip == null) return null;
|
||||||
|
if (ip.endsWith(".i2p")) {
|
||||||
|
if (ip.length() < 520)
|
||||||
|
return null;
|
||||||
|
try {
|
||||||
|
return new Destination(ip.substring(0, ip.length()-4)); // sans .i2p
|
||||||
|
} catch (DataFormatException dfe) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
return new Destination(ip);
|
||||||
|
} catch (DataFormatException dfe) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Base64 Hash or Hash.i2p or name.i2p using naming service */
|
||||||
Destination getDestination(String ip) {
|
Destination getDestination(String ip) {
|
||||||
if (ip == null) return null;
|
if (ip == null) return null;
|
||||||
if (ip.endsWith(".i2p")) {
|
if (ip.endsWith(".i2p")) {
|
||||||
@ -308,6 +331,9 @@ public class I2PSnarkUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** hook between snark's logger and an i2p log */
|
/** hook between snark's logger and an i2p log */
|
||||||
|
void debug(String msg, int snarkDebugLevel) {
|
||||||
|
debug(msg, snarkDebugLevel, null);
|
||||||
|
}
|
||||||
void debug(String msg, int snarkDebugLevel, Throwable t) {
|
void debug(String msg, int snarkDebugLevel, Throwable t) {
|
||||||
if (t instanceof OutOfMemoryError) {
|
if (t instanceof OutOfMemoryError) {
|
||||||
try { Thread.sleep(100); } catch (InterruptedException ie) {}
|
try { Thread.sleep(100); } catch (InterruptedException ie) {}
|
||||||
|
@ -173,7 +173,7 @@ public class Peer implements Comparable
|
|||||||
* If the given BitField is non-null it is send to the peer as first
|
* If the given BitField is non-null it is send to the peer as first
|
||||||
* message.
|
* message.
|
||||||
*/
|
*/
|
||||||
public void runConnection(PeerListener listener, BitField bitfield)
|
public void runConnection(I2PSnarkUtil util, PeerListener listener, BitField bitfield)
|
||||||
{
|
{
|
||||||
if (state != null)
|
if (state != null)
|
||||||
throw new IllegalStateException("Peer already started");
|
throw new IllegalStateException("Peer already started");
|
||||||
@ -184,7 +184,7 @@ public class Peer implements Comparable
|
|||||||
// Do we need to handshake?
|
// Do we need to handshake?
|
||||||
if (din == null)
|
if (din == null)
|
||||||
{
|
{
|
||||||
sock = I2PSnarkUtil.instance().connect(peerID);
|
sock = util.connect(peerID);
|
||||||
_log.debug("Connected to " + peerID + ": " + sock);
|
_log.debug("Connected to " + peerID + ": " + sock);
|
||||||
if ((sock == null) || (sock.isClosed())) {
|
if ((sock == null) || (sock.isClosed())) {
|
||||||
throw new IOException("Unable to reach " + peerID);
|
throw new IOException("Unable to reach " + peerID);
|
||||||
|
@ -35,9 +35,11 @@ class PeerCheckerTask extends TimerTask
|
|||||||
private static final long KILOPERSECOND = 1024*(PeerCoordinator.CHECK_PERIOD/1000);
|
private static final long KILOPERSECOND = 1024*(PeerCoordinator.CHECK_PERIOD/1000);
|
||||||
|
|
||||||
private final PeerCoordinator coordinator;
|
private final PeerCoordinator coordinator;
|
||||||
|
public I2PSnarkUtil _util;
|
||||||
|
|
||||||
PeerCheckerTask(PeerCoordinator coordinator)
|
PeerCheckerTask(I2PSnarkUtil util, PeerCoordinator coordinator)
|
||||||
{
|
{
|
||||||
|
_util = util;
|
||||||
this.coordinator = coordinator;
|
this.coordinator = coordinator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,8 +104,8 @@ class PeerCheckerTask extends TimerTask
|
|||||||
peer.setRateHistory(upload, download);
|
peer.setRateHistory(upload, download);
|
||||||
peer.resetCounters();
|
peer.resetCounters();
|
||||||
|
|
||||||
Snark.debug(peer + ":", Snark.DEBUG);
|
_util.debug(peer + ":", Snark.DEBUG);
|
||||||
Snark.debug(" ul: " + upload/KILOPERSECOND
|
_util.debug(" ul: " + upload/KILOPERSECOND
|
||||||
+ " dl: " + download/KILOPERSECOND
|
+ " dl: " + download/KILOPERSECOND
|
||||||
+ " i: " + peer.isInterested()
|
+ " i: " + peer.isInterested()
|
||||||
+ " I: " + peer.isInteresting()
|
+ " I: " + peer.isInteresting()
|
||||||
@ -129,7 +131,7 @@ class PeerCheckerTask extends TimerTask
|
|||||||
// Check if it still wants pieces from us.
|
// Check if it still wants pieces from us.
|
||||||
if (!peer.isInterested())
|
if (!peer.isInterested())
|
||||||
{
|
{
|
||||||
Snark.debug("Choke uninterested peer: " + peer,
|
_util.debug("Choke uninterested peer: " + peer,
|
||||||
Snark.INFO);
|
Snark.INFO);
|
||||||
peer.setChoking(true);
|
peer.setChoking(true);
|
||||||
uploaders--;
|
uploaders--;
|
||||||
@ -141,7 +143,7 @@ class PeerCheckerTask extends TimerTask
|
|||||||
}
|
}
|
||||||
else if (overBWLimitChoke)
|
else if (overBWLimitChoke)
|
||||||
{
|
{
|
||||||
Snark.debug("BW limit (" + upload + "/" + uploaded + "), choke peer: " + peer,
|
_util.debug("BW limit (" + upload + "/" + uploaded + "), choke peer: " + peer,
|
||||||
Snark.INFO);
|
Snark.INFO);
|
||||||
peer.setChoking(true);
|
peer.setChoking(true);
|
||||||
uploaders--;
|
uploaders--;
|
||||||
@ -155,7 +157,7 @@ class PeerCheckerTask extends TimerTask
|
|||||||
else if (peer.isInteresting() && peer.isChoked())
|
else if (peer.isInteresting() && peer.isChoked())
|
||||||
{
|
{
|
||||||
// If they are choking us make someone else a downloader
|
// If they are choking us make someone else a downloader
|
||||||
Snark.debug("Choke choking peer: " + peer, Snark.DEBUG);
|
_util.debug("Choke choking peer: " + peer, Snark.DEBUG);
|
||||||
peer.setChoking(true);
|
peer.setChoking(true);
|
||||||
uploaders--;
|
uploaders--;
|
||||||
coordinator.uploaders--;
|
coordinator.uploaders--;
|
||||||
@ -168,7 +170,7 @@ class PeerCheckerTask extends TimerTask
|
|||||||
else if (!peer.isInteresting() && !coordinator.completed())
|
else if (!peer.isInteresting() && !coordinator.completed())
|
||||||
{
|
{
|
||||||
// If they aren't interesting make someone else a downloader
|
// If they aren't interesting make someone else a downloader
|
||||||
Snark.debug("Choke uninteresting peer: " + peer, Snark.DEBUG);
|
_util.debug("Choke uninteresting peer: " + peer, Snark.DEBUG);
|
||||||
peer.setChoking(true);
|
peer.setChoking(true);
|
||||||
uploaders--;
|
uploaders--;
|
||||||
coordinator.uploaders--;
|
coordinator.uploaders--;
|
||||||
@ -183,7 +185,7 @@ class PeerCheckerTask extends TimerTask
|
|||||||
&& download == 0)
|
&& download == 0)
|
||||||
{
|
{
|
||||||
// We are downloading but didn't receive anything...
|
// We are downloading but didn't receive anything...
|
||||||
Snark.debug("Choke downloader that doesn't deliver:"
|
_util.debug("Choke downloader that doesn't deliver:"
|
||||||
+ peer, Snark.DEBUG);
|
+ peer, Snark.DEBUG);
|
||||||
peer.setChoking(true);
|
peer.setChoking(true);
|
||||||
uploaders--;
|
uploaders--;
|
||||||
@ -222,7 +224,7 @@ class PeerCheckerTask extends TimerTask
|
|||||||
|| uploaders > uploadLimit)
|
|| uploaders > uploadLimit)
|
||||||
&& worstDownloader != null)
|
&& worstDownloader != null)
|
||||||
{
|
{
|
||||||
Snark.debug("Choke worst downloader: " + worstDownloader,
|
_util.debug("Choke worst downloader: " + worstDownloader,
|
||||||
Snark.DEBUG);
|
Snark.DEBUG);
|
||||||
|
|
||||||
worstDownloader.setChoking(true);
|
worstDownloader.setChoking(true);
|
||||||
|
@ -77,13 +77,15 @@ public class PeerCoordinator implements PeerListener
|
|||||||
private boolean halted = false;
|
private boolean halted = false;
|
||||||
|
|
||||||
private final CoordinatorListener listener;
|
private final CoordinatorListener listener;
|
||||||
|
public I2PSnarkUtil _util;
|
||||||
|
|
||||||
public String trackerProblems = null;
|
public String trackerProblems = null;
|
||||||
public int trackerSeenPeers = 0;
|
public int trackerSeenPeers = 0;
|
||||||
|
|
||||||
public PeerCoordinator(byte[] id, MetaInfo metainfo, Storage storage,
|
public PeerCoordinator(I2PSnarkUtil util, byte[] id, MetaInfo metainfo, Storage storage,
|
||||||
CoordinatorListener listener, Snark torrent)
|
CoordinatorListener listener, Snark torrent)
|
||||||
{
|
{
|
||||||
|
_util = util;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.metainfo = metainfo;
|
this.metainfo = metainfo;
|
||||||
this.storage = storage;
|
this.storage = storage;
|
||||||
@ -96,7 +98,7 @@ public class PeerCoordinator implements PeerListener
|
|||||||
// Randomize the first start time so multiple tasks are spread out,
|
// Randomize the first start time so multiple tasks are spread out,
|
||||||
// this will help the behavior with global limits
|
// this will help the behavior with global limits
|
||||||
Random r = new Random();
|
Random r = new Random();
|
||||||
timer.schedule(new PeerCheckerTask(this), (CHECK_PERIOD / 2) + r.nextInt((int) CHECK_PERIOD), CHECK_PERIOD);
|
timer.schedule(new PeerCheckerTask(_util, this), (CHECK_PERIOD / 2) + r.nextInt((int) CHECK_PERIOD), CHECK_PERIOD);
|
||||||
}
|
}
|
||||||
|
|
||||||
// only called externally from Storage after the double-check fails
|
// only called externally from Storage after the double-check fails
|
||||||
@ -366,7 +368,7 @@ public class PeerCoordinator implements PeerListener
|
|||||||
{
|
{
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
peer.runConnection(listener, bitfield);
|
peer.runConnection(_util, listener, bitfield);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
String threadName = peer.toString();
|
String threadName = peer.toString();
|
||||||
@ -846,7 +848,7 @@ public class PeerCoordinator implements PeerListener
|
|||||||
*/
|
*/
|
||||||
public int allowedUploaders()
|
public int allowedUploaders()
|
||||||
{
|
{
|
||||||
if (Snark.overUploadLimit(uploaders)) {
|
if (listener != null && listener.overUploadLimit(uploaders)) {
|
||||||
// if (_log.shouldLog(Log.DEBUG))
|
// if (_log.shouldLog(Log.DEBUG))
|
||||||
// _log.debug("Over limit, uploaders was: " + uploaders);
|
// _log.debug("Over limit, uploaders was: " + uploaders);
|
||||||
return uploaders - 1;
|
return uploaders - 1;
|
||||||
@ -858,12 +860,16 @@ public class PeerCoordinator implements PeerListener
|
|||||||
|
|
||||||
public boolean overUpBWLimit()
|
public boolean overUpBWLimit()
|
||||||
{
|
{
|
||||||
return Snark.overUpBWLimit();
|
if (listener != null)
|
||||||
|
return listener.overUpBWLimit();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean overUpBWLimit(long total)
|
public boolean overUpBWLimit(long total)
|
||||||
{
|
{
|
||||||
return Snark.overUpBWLimit(total * 1000 / CHECK_PERIOD);
|
if (listener != null)
|
||||||
|
return listener.overUpBWLimit(total * 1000 / CHECK_PERIOD);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,11 +12,9 @@ import java.util.Set;
|
|||||||
* from it there too)
|
* from it there too)
|
||||||
*/
|
*/
|
||||||
public class PeerCoordinatorSet {
|
public class PeerCoordinatorSet {
|
||||||
private static final PeerCoordinatorSet _instance = new PeerCoordinatorSet();
|
|
||||||
public static final PeerCoordinatorSet instance() { return _instance; }
|
|
||||||
private Set _coordinators;
|
private Set _coordinators;
|
||||||
|
|
||||||
private PeerCoordinatorSet() {
|
public PeerCoordinatorSet() {
|
||||||
_coordinators = new HashSet();
|
_coordinators = new HashSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ public class PeerID implements Comparable
|
|||||||
bevalue = (BEValue)m.get("ip");
|
bevalue = (BEValue)m.get("ip");
|
||||||
if (bevalue == null)
|
if (bevalue == null)
|
||||||
throw new InvalidBEncodingException("ip missing");
|
throw new InvalidBEncodingException("ip missing");
|
||||||
address = I2PSnarkUtil.instance().getDestination(bevalue.getString());
|
address = I2PSnarkUtil.getDestinationFromBase64(bevalue.getString());
|
||||||
if (address == null)
|
if (address == null)
|
||||||
throw new InvalidBEncodingException("Invalid destination [" + bevalue.getString() + "]");
|
throw new InvalidBEncodingException("Invalid destination [" + bevalue.getString() + "]");
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ import java.util.StringTokenizer;
|
|||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
import net.i2p.I2PAppContext;
|
||||||
import net.i2p.client.streaming.I2PServerSocket;
|
import net.i2p.client.streaming.I2PServerSocket;
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
import net.i2p.util.I2PThread;
|
import net.i2p.util.I2PThread;
|
||||||
@ -102,7 +103,7 @@ public class Snark
|
|||||||
public void outOfMemory(OutOfMemoryError err) {
|
public void outOfMemory(OutOfMemoryError err) {
|
||||||
try {
|
try {
|
||||||
err.printStackTrace();
|
err.printStackTrace();
|
||||||
I2PSnarkUtil.instance().debug("OOM in the snark", Snark.ERROR, err);
|
System.out.println("OOM in the snark" + err);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
System.out.println("OOM in the OOM");
|
System.out.println("OOM in the OOM");
|
||||||
}
|
}
|
||||||
@ -225,7 +226,7 @@ public class Snark
|
|||||||
}
|
}
|
||||||
catch(IOException ioe)
|
catch(IOException ioe)
|
||||||
{
|
{
|
||||||
debug("ERROR while reading stdin: " + ioe, ERROR);
|
System.out.println("ERROR while reading stdin: " + ioe);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explicit shutdown.
|
// Explicit shutdown.
|
||||||
@ -244,22 +245,34 @@ public class Snark
|
|||||||
public CompleteListener completeListener;
|
public CompleteListener completeListener;
|
||||||
public boolean stopped;
|
public boolean stopped;
|
||||||
byte[] id;
|
byte[] id;
|
||||||
|
public I2PSnarkUtil _util;
|
||||||
|
private PeerCoordinatorSet _peerCoordinatorSet;
|
||||||
|
|
||||||
Snark(String torrent, String ip, int user_port,
|
/** from main() via parseArguments() single torrent */
|
||||||
|
Snark(I2PSnarkUtil util, String torrent, String ip, int user_port,
|
||||||
StorageListener slistener, CoordinatorListener clistener) {
|
StorageListener slistener, CoordinatorListener clistener) {
|
||||||
this(torrent, ip, user_port, slistener, clistener, null, true, ".");
|
this(util, torrent, ip, user_port, slistener, clistener, null, null, null, true, ".");
|
||||||
}
|
}
|
||||||
public Snark(String torrent, String ip, int user_port,
|
|
||||||
|
/** 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, ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** multitorrent */
|
||||||
|
public Snark(I2PSnarkUtil util, String torrent, String ip, int user_port,
|
||||||
StorageListener slistener, CoordinatorListener clistener,
|
StorageListener slistener, CoordinatorListener clistener,
|
||||||
CompleteListener complistener, boolean start, String rootDir)
|
CompleteListener complistener, PeerCoordinatorSet peerCoordinatorSet,
|
||||||
|
ConnectionAcceptor connectionAcceptor, boolean start, String rootDir)
|
||||||
{
|
{
|
||||||
if (slistener == null)
|
if (slistener == null)
|
||||||
slistener = this;
|
slistener = this;
|
||||||
|
|
||||||
//if (clistener == null)
|
|
||||||
// clistener = this;
|
|
||||||
|
|
||||||
completeListener = complistener;
|
completeListener = complistener;
|
||||||
|
_util = util;
|
||||||
|
_peerCoordinatorSet = peerCoordinatorSet;
|
||||||
|
acceptor = connectionAcceptor;
|
||||||
|
|
||||||
this.torrent = torrent;
|
this.torrent = torrent;
|
||||||
this.rootDataDir = rootDir;
|
this.rootDataDir = rootDir;
|
||||||
@ -292,7 +305,7 @@ public class Snark
|
|||||||
while (i < 20)
|
while (i < 20)
|
||||||
id[i++] = (byte)random.nextInt(256);
|
id[i++] = (byte)random.nextInt(256);
|
||||||
|
|
||||||
Snark.debug("My peer id: " + PeerID.idencode(id), Snark.INFO);
|
debug("My peer id: " + PeerID.idencode(id), Snark.INFO);
|
||||||
|
|
||||||
int port;
|
int port;
|
||||||
IOException lastException = null;
|
IOException lastException = null;
|
||||||
@ -301,9 +314,9 @@ public class Snark
|
|||||||
* If we are starting,
|
* If we are starting,
|
||||||
* startTorrent() will force a connect.
|
* startTorrent() will force a connect.
|
||||||
*
|
*
|
||||||
boolean ok = I2PSnarkUtil.instance().connect();
|
boolean ok = util.connect();
|
||||||
if (!ok) fatal("Unable to connect to I2P");
|
if (!ok) fatal("Unable to connect to I2P");
|
||||||
I2PServerSocket serversocket = I2PSnarkUtil.instance().getServerSocket();
|
I2PServerSocket serversocket = util.getServerSocket();
|
||||||
if (serversocket == null)
|
if (serversocket == null)
|
||||||
fatal("Unable to listen for I2P connections");
|
fatal("Unable to listen for I2P connections");
|
||||||
else {
|
else {
|
||||||
@ -324,7 +337,7 @@ public class Snark
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
activity = "Getting torrent";
|
activity = "Getting torrent";
|
||||||
File torrentFile = I2PSnarkUtil.instance().get(torrent, 3);
|
File torrentFile = _util.get(torrent, 3);
|
||||||
if (torrentFile == null) {
|
if (torrentFile == null) {
|
||||||
fatal("Unable to fetch " + torrent);
|
fatal("Unable to fetch " + torrent);
|
||||||
if (false) return; // never reached - fatal(..) throws
|
if (false) return; // never reached - fatal(..) throws
|
||||||
@ -348,7 +361,7 @@ public class Snark
|
|||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
// Try to create a new metainfo file
|
// Try to create a new metainfo file
|
||||||
Snark.debug
|
debug
|
||||||
("Trying to create metainfo torrent for '" + torrent + "'",
|
("Trying to create metainfo torrent for '" + torrent + "'",
|
||||||
NOTICE);
|
NOTICE);
|
||||||
try
|
try
|
||||||
@ -381,7 +394,7 @@ public class Snark
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
activity = "Checking storage";
|
activity = "Checking storage";
|
||||||
storage = new Storage(meta, slistener);
|
storage = new Storage(_util, meta, slistener);
|
||||||
if (completeListener != null) {
|
if (completeListener != null) {
|
||||||
storage.check(rootDataDir,
|
storage.check(rootDataDir,
|
||||||
completeListener.getSavedTorrentTime(this),
|
completeListener.getSavedTorrentTime(this),
|
||||||
@ -422,10 +435,10 @@ public class Snark
|
|||||||
* Start up contacting peers and querying the tracker
|
* Start up contacting peers and querying the tracker
|
||||||
*/
|
*/
|
||||||
public void startTorrent() {
|
public void startTorrent() {
|
||||||
boolean ok = I2PSnarkUtil.instance().connect();
|
boolean ok = _util.connect();
|
||||||
if (!ok) fatal("Unable to connect to I2P");
|
if (!ok) fatal("Unable to connect to I2P");
|
||||||
if (coordinator == null) {
|
if (coordinator == null) {
|
||||||
I2PServerSocket serversocket = I2PSnarkUtil.instance().getServerSocket();
|
I2PServerSocket serversocket = _util.getServerSocket();
|
||||||
if (serversocket == null)
|
if (serversocket == null)
|
||||||
fatal("Unable to listen for I2P connections");
|
fatal("Unable to listen for I2P connections");
|
||||||
else {
|
else {
|
||||||
@ -434,12 +447,20 @@ public class Snark
|
|||||||
}
|
}
|
||||||
debug("Starting PeerCoordinator, ConnectionAcceptor, and TrackerClient", NOTICE);
|
debug("Starting PeerCoordinator, ConnectionAcceptor, and TrackerClient", NOTICE);
|
||||||
activity = "Collecting pieces";
|
activity = "Collecting pieces";
|
||||||
coordinator = new PeerCoordinator(id, meta, storage, this, this);
|
coordinator = new PeerCoordinator(_util, id, meta, storage, this, this);
|
||||||
PeerCoordinatorSet set = PeerCoordinatorSet.instance();
|
if (_peerCoordinatorSet != null) {
|
||||||
set.add(coordinator);
|
// multitorrent
|
||||||
ConnectionAcceptor acceptor = ConnectionAcceptor.instance();
|
_peerCoordinatorSet.add(coordinator);
|
||||||
acceptor.startAccepting(set, serversocket);
|
if (acceptor != null) {
|
||||||
trackerclient = new TrackerClient(meta, coordinator);
|
acceptor.startAccepting(_peerCoordinatorSet, serversocket);
|
||||||
|
} else {
|
||||||
|
// error
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// single torrent
|
||||||
|
acceptor = new ConnectionAcceptor(_util, serversocket, new PeerAcceptor(coordinator));
|
||||||
|
}
|
||||||
|
trackerclient = new TrackerClient(_util, meta, coordinator);
|
||||||
}
|
}
|
||||||
|
|
||||||
stopped = false;
|
stopped = false;
|
||||||
@ -447,11 +468,12 @@ public class Snark
|
|||||||
if (coordinator.halted()) {
|
if (coordinator.halted()) {
|
||||||
// ok, we have already started and stopped, but the coordinator seems a bit annoying to
|
// ok, we have already started and stopped, but the coordinator seems a bit annoying to
|
||||||
// restart safely, so lets build a new one to replace the old
|
// restart safely, so lets build a new one to replace the old
|
||||||
PeerCoordinatorSet set = PeerCoordinatorSet.instance();
|
if (_peerCoordinatorSet != null)
|
||||||
set.remove(coordinator);
|
_peerCoordinatorSet.remove(coordinator);
|
||||||
PeerCoordinator newCoord = new PeerCoordinator(coordinator.getID(), coordinator.getMetaInfo(),
|
PeerCoordinator newCoord = new PeerCoordinator(_util, coordinator.getID(), coordinator.getMetaInfo(),
|
||||||
coordinator.getStorage(), coordinator.getListener(), this);
|
coordinator.getStorage(), coordinator.getListener(), this);
|
||||||
set.add(newCoord);
|
if (_peerCoordinatorSet != null)
|
||||||
|
_peerCoordinatorSet.add(newCoord);
|
||||||
coordinator = newCoord;
|
coordinator = newCoord;
|
||||||
coordinatorChanged = true;
|
coordinatorChanged = true;
|
||||||
}
|
}
|
||||||
@ -469,7 +491,7 @@ public class Snark
|
|||||||
}
|
}
|
||||||
fatal("Could not reopen storage", ioe);
|
fatal("Could not reopen storage", ioe);
|
||||||
}
|
}
|
||||||
TrackerClient newClient = new TrackerClient(coordinator.getMetaInfo(), coordinator);
|
TrackerClient newClient = new TrackerClient(_util, coordinator.getMetaInfo(), coordinator);
|
||||||
if (!trackerclient.halted())
|
if (!trackerclient.halted())
|
||||||
trackerclient.halt();
|
trackerclient.halt();
|
||||||
trackerclient = newClient;
|
trackerclient = newClient;
|
||||||
@ -499,8 +521,8 @@ public class Snark
|
|||||||
if (changed && completeListener != null)
|
if (changed && completeListener != null)
|
||||||
completeListener.updateStatus(this);
|
completeListener.updateStatus(this);
|
||||||
}
|
}
|
||||||
if (pc != null)
|
if (pc != null && _peerCoordinatorSet != null)
|
||||||
PeerCoordinatorSet.instance().remove(pc);
|
_peerCoordinatorSet.remove(pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Snark parseArguments(String[] args)
|
static Snark parseArguments(String[] args)
|
||||||
@ -522,7 +544,8 @@ public class Snark
|
|||||||
String ip = null;
|
String ip = null;
|
||||||
String torrent = null;
|
String torrent = null;
|
||||||
|
|
||||||
boolean configured = I2PSnarkUtil.instance().configured();
|
I2PSnarkUtil util = new I2PSnarkUtil(I2PAppContext.getGlobalContext());
|
||||||
|
boolean configured = util.configured();
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < args.length)
|
while (i < args.length)
|
||||||
@ -572,7 +595,7 @@ public class Snark
|
|||||||
String proxyHost = args[i+1];
|
String proxyHost = args[i+1];
|
||||||
String proxyPort = args[i+2];
|
String proxyPort = args[i+2];
|
||||||
if (!configured)
|
if (!configured)
|
||||||
I2PSnarkUtil.instance().setProxy(proxyHost, Integer.parseInt(proxyPort));
|
util.setProxy(proxyHost, Integer.parseInt(proxyPort));
|
||||||
i += 3;
|
i += 3;
|
||||||
}
|
}
|
||||||
else if (args[i].equals("--i2cp"))
|
else if (args[i].equals("--i2cp"))
|
||||||
@ -594,7 +617,7 @@ public class Snark
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!configured)
|
if (!configured)
|
||||||
I2PSnarkUtil.instance().setI2CPConfig(i2cpHost, Integer.parseInt(i2cpPort), opts);
|
util.setI2CPConfig(i2cpHost, Integer.parseInt(i2cpPort), opts);
|
||||||
i += 3 + (opts != null ? 1 : 0);
|
i += 3 + (opts != null ? 1 : 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -611,7 +634,7 @@ public class Snark
|
|||||||
else
|
else
|
||||||
usage("Need exactly one <url>, <file> or <dir>.");
|
usage("Need exactly one <url>, <file> or <dir>.");
|
||||||
|
|
||||||
return new Snark(torrent, ip, user_port, slistener, clistener);
|
return new Snark(util, torrent, ip, user_port, slistener, clistener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void usage(String s)
|
private static void usage(String s)
|
||||||
@ -678,7 +701,7 @@ public class Snark
|
|||||||
*/
|
*/
|
||||||
public void fatal(String s, Throwable t)
|
public void fatal(String s, Throwable t)
|
||||||
{
|
{
|
||||||
I2PSnarkUtil.instance().debug(s, ERROR, t);
|
_util.debug(s, ERROR, t);
|
||||||
//System.err.println("snark: " + s + ((t == null) ? "" : (": " + t)));
|
//System.err.println("snark: " + s + ((t == null) ? "" : (": " + t)));
|
||||||
//if (debug >= INFO && t != null)
|
//if (debug >= INFO && t != null)
|
||||||
// t.printStackTrace();
|
// t.printStackTrace();
|
||||||
@ -689,13 +712,12 @@ public class Snark
|
|||||||
/**
|
/**
|
||||||
* Show debug info if debug is true.
|
* Show debug info if debug is true.
|
||||||
*/
|
*/
|
||||||
public static void debug(String s, int level)
|
private void debug(String s, int level)
|
||||||
{
|
{
|
||||||
I2PSnarkUtil.instance().debug(s, level, null);
|
_util.debug(s, level, null);
|
||||||
//if (debug >= level)
|
|
||||||
// System.out.println(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** coordinatorListener */
|
||||||
public void peerChange(PeerCoordinator coordinator, Peer peer)
|
public void peerChange(PeerCoordinator coordinator, Peer peer)
|
||||||
{
|
{
|
||||||
// System.out.println(peer.toString());
|
// System.out.println(peer.toString());
|
||||||
@ -742,7 +764,7 @@ public class Snark
|
|||||||
checking = true;
|
checking = true;
|
||||||
}
|
}
|
||||||
if (!checking)
|
if (!checking)
|
||||||
Snark.debug("Got " + (checked ? "" : "BAD ") + "piece: " + num,
|
debug("Got " + (checked ? "" : "BAD ") + "piece: " + num,
|
||||||
Snark.INFO);
|
Snark.INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -759,7 +781,7 @@ public class Snark
|
|||||||
|
|
||||||
public void storageCompleted(Storage storage)
|
public void storageCompleted(Storage storage)
|
||||||
{
|
{
|
||||||
Snark.debug("Completely received " + torrent, Snark.INFO);
|
debug("Completely received " + torrent, Snark.INFO);
|
||||||
//storage.close();
|
//storage.close();
|
||||||
//System.out.println("Completely received: " + torrent);
|
//System.out.println("Completely received: " + torrent);
|
||||||
if (completeListener != null)
|
if (completeListener != null)
|
||||||
@ -787,41 +809,40 @@ public class Snark
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Maintain a configurable total uploader cap
|
/** Maintain a configurable total uploader cap
|
||||||
|
* coordinatorListener
|
||||||
*/
|
*/
|
||||||
final static int MIN_TOTAL_UPLOADERS = 4;
|
final static int MIN_TOTAL_UPLOADERS = 4;
|
||||||
final static int MAX_TOTAL_UPLOADERS = 10;
|
final static int MAX_TOTAL_UPLOADERS = 10;
|
||||||
public static boolean overUploadLimit(int uploaders) {
|
public boolean overUploadLimit(int uploaders) {
|
||||||
PeerCoordinatorSet coordinators = PeerCoordinatorSet.instance();
|
if (_peerCoordinatorSet == null || uploaders <= 0)
|
||||||
if (coordinators == null || uploaders <= 0)
|
|
||||||
return false;
|
return false;
|
||||||
int totalUploaders = 0;
|
int totalUploaders = 0;
|
||||||
for (Iterator iter = coordinators.iterator(); iter.hasNext(); ) {
|
for (Iterator iter = _peerCoordinatorSet.iterator(); iter.hasNext(); ) {
|
||||||
PeerCoordinator c = (PeerCoordinator)iter.next();
|
PeerCoordinator c = (PeerCoordinator)iter.next();
|
||||||
if (!c.halted())
|
if (!c.halted())
|
||||||
totalUploaders += c.uploaders;
|
totalUploaders += c.uploaders;
|
||||||
}
|
}
|
||||||
int limit = I2PSnarkUtil.instance().getMaxUploaders();
|
int limit = _util.getMaxUploaders();
|
||||||
// Snark.debug("Total uploaders: " + totalUploaders + " Limit: " + limit, Snark.DEBUG);
|
// debug("Total uploaders: " + totalUploaders + " Limit: " + limit, Snark.DEBUG);
|
||||||
return totalUploaders > limit;
|
return totalUploaders > limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean overUpBWLimit() {
|
public boolean overUpBWLimit() {
|
||||||
PeerCoordinatorSet coordinators = PeerCoordinatorSet.instance();
|
if (_peerCoordinatorSet == null)
|
||||||
if (coordinators == null)
|
|
||||||
return false;
|
return false;
|
||||||
long total = 0;
|
long total = 0;
|
||||||
for (Iterator iter = coordinators.iterator(); iter.hasNext(); ) {
|
for (Iterator iter = _peerCoordinatorSet.iterator(); iter.hasNext(); ) {
|
||||||
PeerCoordinator c = (PeerCoordinator)iter.next();
|
PeerCoordinator c = (PeerCoordinator)iter.next();
|
||||||
if (!c.halted())
|
if (!c.halted())
|
||||||
total += c.getCurrentUploadRate();
|
total += c.getCurrentUploadRate();
|
||||||
}
|
}
|
||||||
long limit = 1024l * I2PSnarkUtil.instance().getMaxUpBW();
|
long limit = 1024l * _util.getMaxUpBW();
|
||||||
Snark.debug("Total up bw: " + total + " Limit: " + limit, Snark.WARNING);
|
debug("Total up bw: " + total + " Limit: " + limit, Snark.WARNING);
|
||||||
return total > limit;
|
return total > limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean overUpBWLimit(long total) {
|
public boolean overUpBWLimit(long total) {
|
||||||
long limit = 1024l * I2PSnarkUtil.instance().getMaxUpBW();
|
long limit = 1024l * _util.getMaxUpBW();
|
||||||
return total > limit;
|
return total > limit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,9 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
private I2PAppContext _context;
|
private I2PAppContext _context;
|
||||||
private Log _log;
|
private Log _log;
|
||||||
private List _messages;
|
private List _messages;
|
||||||
|
private I2PSnarkUtil _util;
|
||||||
|
private PeerCoordinatorSet _peerCoordinatorSet;
|
||||||
|
private ConnectionAcceptor _connectionAcceptor;
|
||||||
|
|
||||||
public static final String PROP_I2CP_HOST = "i2psnark.i2cpHost";
|
public static final String PROP_I2CP_HOST = "i2psnark.i2cpHost";
|
||||||
public static final String PROP_I2CP_PORT = "i2psnark.i2cpPort";
|
public static final String PROP_I2CP_PORT = "i2psnark.i2cpPort";
|
||||||
@ -63,6 +66,9 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
_context = I2PAppContext.getGlobalContext();
|
_context = I2PAppContext.getGlobalContext();
|
||||||
_log = _context.logManager().getLog(SnarkManager.class);
|
_log = _context.logManager().getLog(SnarkManager.class);
|
||||||
_messages = new ArrayList(16);
|
_messages = new ArrayList(16);
|
||||||
|
_util = new I2PSnarkUtil(_context);
|
||||||
|
_peerCoordinatorSet = new PeerCoordinatorSet();
|
||||||
|
_connectionAcceptor = new ConnectionAcceptor(_util);
|
||||||
loadConfig("i2psnark.config");
|
loadConfig("i2psnark.config");
|
||||||
int minutes = getStartupDelayMinutes();
|
int minutes = getStartupDelayMinutes();
|
||||||
_messages.add("Adding torrents in " + minutes + (minutes == 1 ? " minute" : " minutes"));
|
_messages.add("Adding torrents in " + minutes + (minutes == 1 ? " minute" : " minutes"));
|
||||||
@ -73,6 +79,9 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
((RouterContext)_context).router().addShutdownTask(new SnarkManagerShutdown());
|
((RouterContext)_context).router().addShutdownTask(new SnarkManagerShutdown());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** hook to I2PSnarkUtil for the servlet */
|
||||||
|
public I2PSnarkUtil util() { return _util; }
|
||||||
|
|
||||||
private static final int MAX_MESSAGES = 5;
|
private static final int MAX_MESSAGES = 5;
|
||||||
public void addMessage(String message) {
|
public void addMessage(String message) {
|
||||||
synchronized (_messages) {
|
synchronized (_messages) {
|
||||||
@ -162,16 +171,16 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i2cpHost != null) {
|
if (i2cpHost != null) {
|
||||||
I2PSnarkUtil.instance().setI2CPConfig(i2cpHost, i2cpPort, i2cpOpts);
|
_util.setI2CPConfig(i2cpHost, i2cpPort, i2cpOpts);
|
||||||
_log.debug("Configuring with I2CP options " + i2cpOpts);
|
_log.debug("Configuring with I2CP options " + i2cpOpts);
|
||||||
}
|
}
|
||||||
//I2PSnarkUtil.instance().setI2CPConfig("66.111.51.110", 7654, new Properties());
|
//I2PSnarkUtil.instance().setI2CPConfig("66.111.51.110", 7654, new Properties());
|
||||||
String eepHost = _config.getProperty(PROP_EEP_HOST);
|
String eepHost = _config.getProperty(PROP_EEP_HOST);
|
||||||
int eepPort = getInt(PROP_EEP_PORT, 4444);
|
int eepPort = getInt(PROP_EEP_PORT, 4444);
|
||||||
if (eepHost != null)
|
if (eepHost != null)
|
||||||
I2PSnarkUtil.instance().setProxy(eepHost, eepPort);
|
_util.setProxy(eepHost, eepPort);
|
||||||
I2PSnarkUtil.instance().setMaxUploaders(getInt(PROP_UPLOADERS_TOTAL, Snark.MAX_TOTAL_UPLOADERS));
|
_util.setMaxUploaders(getInt(PROP_UPLOADERS_TOTAL, Snark.MAX_TOTAL_UPLOADERS));
|
||||||
I2PSnarkUtil.instance().setMaxUpBW(getInt(PROP_UPBW_MAX, DEFAULT_MAX_UP_BW));
|
_util.setMaxUpBW(getInt(PROP_UPBW_MAX, DEFAULT_MAX_UP_BW));
|
||||||
getDataDir().mkdirs();
|
getDataDir().mkdirs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,12 +200,12 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
String upLimit, String upBW, boolean useOpenTrackers, String openTrackers) {
|
String upLimit, String upBW, boolean useOpenTrackers, String openTrackers) {
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
if (eepHost != null) {
|
if (eepHost != null) {
|
||||||
int port = I2PSnarkUtil.instance().getEepProxyPort();
|
int port = _util.getEepProxyPort();
|
||||||
try { port = Integer.parseInt(eepPort); } catch (NumberFormatException nfe) {}
|
try { port = Integer.parseInt(eepPort); } catch (NumberFormatException nfe) {}
|
||||||
String host = I2PSnarkUtil.instance().getEepProxyHost();
|
String host = _util.getEepProxyHost();
|
||||||
if ( (eepHost.trim().length() > 0) && (port > 0) &&
|
if ( (eepHost.trim().length() > 0) && (port > 0) &&
|
||||||
((!host.equals(eepHost) || (port != I2PSnarkUtil.instance().getEepProxyPort()) )) ) {
|
((!host.equals(eepHost) || (port != _util.getEepProxyPort()) )) ) {
|
||||||
I2PSnarkUtil.instance().setProxy(eepHost, port);
|
_util.setProxy(eepHost, port);
|
||||||
changed = true;
|
changed = true;
|
||||||
_config.setProperty(PROP_EEP_HOST, eepHost);
|
_config.setProperty(PROP_EEP_HOST, eepHost);
|
||||||
_config.setProperty(PROP_EEP_PORT, eepPort+"");
|
_config.setProperty(PROP_EEP_PORT, eepPort+"");
|
||||||
@ -204,11 +213,11 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (upLimit != null) {
|
if (upLimit != null) {
|
||||||
int limit = I2PSnarkUtil.instance().getMaxUploaders();
|
int limit = _util.getMaxUploaders();
|
||||||
try { limit = Integer.parseInt(upLimit); } catch (NumberFormatException nfe) {}
|
try { limit = Integer.parseInt(upLimit); } catch (NumberFormatException nfe) {}
|
||||||
if ( limit != I2PSnarkUtil.instance().getMaxUploaders()) {
|
if ( limit != _util.getMaxUploaders()) {
|
||||||
if ( limit >= Snark.MIN_TOTAL_UPLOADERS ) {
|
if ( limit >= Snark.MIN_TOTAL_UPLOADERS ) {
|
||||||
I2PSnarkUtil.instance().setMaxUploaders(limit);
|
_util.setMaxUploaders(limit);
|
||||||
changed = true;
|
changed = true;
|
||||||
_config.setProperty(PROP_UPLOADERS_TOTAL, "" + limit);
|
_config.setProperty(PROP_UPLOADERS_TOTAL, "" + limit);
|
||||||
addMessage("Total uploaders limit changed to " + limit);
|
addMessage("Total uploaders limit changed to " + limit);
|
||||||
@ -218,11 +227,11 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (upBW != null) {
|
if (upBW != null) {
|
||||||
int limit = I2PSnarkUtil.instance().getMaxUpBW();
|
int limit = _util.getMaxUpBW();
|
||||||
try { limit = Integer.parseInt(upBW); } catch (NumberFormatException nfe) {}
|
try { limit = Integer.parseInt(upBW); } catch (NumberFormatException nfe) {}
|
||||||
if ( limit != I2PSnarkUtil.instance().getMaxUpBW()) {
|
if ( limit != _util.getMaxUpBW()) {
|
||||||
if ( limit >= MIN_UP_BW ) {
|
if ( limit >= MIN_UP_BW ) {
|
||||||
I2PSnarkUtil.instance().setMaxUpBW(limit);
|
_util.setMaxUpBW(limit);
|
||||||
changed = true;
|
changed = true;
|
||||||
_config.setProperty(PROP_UPBW_MAX, "" + limit);
|
_config.setProperty(PROP_UPBW_MAX, "" + limit);
|
||||||
addMessage("Up BW limit changed to " + limit + "KBps");
|
addMessage("Up BW limit changed to " + limit + "KBps");
|
||||||
@ -232,8 +241,8 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i2cpHost != null) {
|
if (i2cpHost != null) {
|
||||||
int oldI2CPPort = I2PSnarkUtil.instance().getI2CPPort();
|
int oldI2CPPort = _util.getI2CPPort();
|
||||||
String oldI2CPHost = I2PSnarkUtil.instance().getI2CPHost();
|
String oldI2CPHost = _util.getI2CPHost();
|
||||||
int port = oldI2CPPort;
|
int port = oldI2CPPort;
|
||||||
try { port = Integer.parseInt(i2cpPort); } catch (NumberFormatException nfe) {}
|
try { port = Integer.parseInt(i2cpPort); } catch (NumberFormatException nfe) {}
|
||||||
String host = oldI2CPHost;
|
String host = oldI2CPHost;
|
||||||
@ -259,7 +268,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
|
|
||||||
if ( (i2cpHost.trim().length() > 0) && (port > 0) &&
|
if ( (i2cpHost.trim().length() > 0) && (port > 0) &&
|
||||||
((!host.equals(i2cpHost) ||
|
((!host.equals(i2cpHost) ||
|
||||||
(port != I2PSnarkUtil.instance().getI2CPPort()) ||
|
(port != _util.getI2CPPort()) ||
|
||||||
(!oldOpts.equals(opts)))) ) {
|
(!oldOpts.equals(opts)))) ) {
|
||||||
boolean snarksActive = false;
|
boolean snarksActive = false;
|
||||||
Set names = listTorrentFiles();
|
Set names = listTorrentFiles();
|
||||||
@ -275,19 +284,19 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
_log.debug("i2cp host [" + i2cpHost + "] i2cp port " + port + " opts [" + opts
|
_log.debug("i2cp host [" + i2cpHost + "] i2cp port " + port + " opts [" + opts
|
||||||
+ "] oldOpts [" + oldOpts + "]");
|
+ "] oldOpts [" + oldOpts + "]");
|
||||||
} else {
|
} else {
|
||||||
if (I2PSnarkUtil.instance().connected()) {
|
if (_util.connected()) {
|
||||||
I2PSnarkUtil.instance().disconnect();
|
_util.disconnect();
|
||||||
addMessage("Disconnecting old I2CP destination");
|
addMessage("Disconnecting old I2CP destination");
|
||||||
}
|
}
|
||||||
Properties p = new Properties();
|
Properties p = new Properties();
|
||||||
p.putAll(opts);
|
p.putAll(opts);
|
||||||
addMessage("I2CP settings changed to " + i2cpHost + ":" + port + " (" + i2cpOpts.trim() + ")");
|
addMessage("I2CP settings changed to " + i2cpHost + ":" + port + " (" + i2cpOpts.trim() + ")");
|
||||||
I2PSnarkUtil.instance().setI2CPConfig(i2cpHost, port, p);
|
_util.setI2CPConfig(i2cpHost, port, p);
|
||||||
boolean ok = I2PSnarkUtil.instance().connect();
|
boolean ok = _util.connect();
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
addMessage("Unable to connect with the new settings, reverting to the old I2CP settings");
|
addMessage("Unable to connect with the new settings, reverting to the old I2CP settings");
|
||||||
I2PSnarkUtil.instance().setI2CPConfig(oldI2CPHost, oldI2CPPort, oldOpts);
|
_util.setI2CPConfig(oldI2CPHost, oldI2CPPort, oldOpts);
|
||||||
ok = I2PSnarkUtil.instance().connect();
|
ok = _util.connect();
|
||||||
if (!ok)
|
if (!ok)
|
||||||
addMessage("Unable to reconnect with the old settings!");
|
addMessage("Unable to reconnect with the old settings!");
|
||||||
} else {
|
} else {
|
||||||
@ -315,13 +324,13 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
addMessage("Adjusted autostart to " + autoStart);
|
addMessage("Adjusted autostart to " + autoStart);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
if (I2PSnarkUtil.instance().shouldUseOpenTrackers() != useOpenTrackers) {
|
if (_util.shouldUseOpenTrackers() != useOpenTrackers) {
|
||||||
_config.setProperty(I2PSnarkUtil.PROP_USE_OPENTRACKERS, useOpenTrackers + "");
|
_config.setProperty(I2PSnarkUtil.PROP_USE_OPENTRACKERS, useOpenTrackers + "");
|
||||||
addMessage((useOpenTrackers ? "En" : "Dis") + "abled open trackers - torrent restart required to take effect");
|
addMessage((useOpenTrackers ? "En" : "Dis") + "abled open trackers - torrent restart required to take effect");
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
if (openTrackers != null) {
|
if (openTrackers != null) {
|
||||||
if (openTrackers.trim().length() > 0 && !openTrackers.trim().equals(I2PSnarkUtil.instance().getOpenTrackerString())) {
|
if (openTrackers.trim().length() > 0 && !openTrackers.trim().equals(_util.getOpenTrackerString())) {
|
||||||
_config.setProperty(I2PSnarkUtil.PROP_OPENTRACKERS, openTrackers.trim());
|
_config.setProperty(I2PSnarkUtil.PROP_OPENTRACKERS, openTrackers.trim());
|
||||||
addMessage("Open Tracker list changed - torrent restart required to take effect");
|
addMessage("Open Tracker list changed - torrent restart required to take effect");
|
||||||
changed = true;
|
changed = true;
|
||||||
@ -357,9 +366,9 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
public Snark getTorrent(String filename) { synchronized (_snarks) { return (Snark)_snarks.get(filename); } }
|
public Snark getTorrent(String filename) { synchronized (_snarks) { return (Snark)_snarks.get(filename); } }
|
||||||
public void addTorrent(String filename) { addTorrent(filename, false); }
|
public void addTorrent(String filename) { addTorrent(filename, false); }
|
||||||
public void addTorrent(String filename, boolean dontAutoStart) {
|
public void addTorrent(String filename, boolean dontAutoStart) {
|
||||||
if ((!dontAutoStart) && !I2PSnarkUtil.instance().connected()) {
|
if ((!dontAutoStart) && !_util.connected()) {
|
||||||
addMessage("Connecting to I2P");
|
addMessage("Connecting to I2P");
|
||||||
boolean ok = I2PSnarkUtil.instance().connect();
|
boolean ok = _util.connect();
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
addMessage("Error connecting to I2P - check your I2CP settings");
|
addMessage("Error connecting to I2P - check your I2CP settings");
|
||||||
return;
|
return;
|
||||||
@ -400,7 +409,9 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
addMessage(rejectMessage);
|
addMessage(rejectMessage);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
torrent = new Snark(filename, null, -1, null, null, this, false, dataDir.getPath());
|
torrent = new Snark(_util, filename, null, -1, null, null, this,
|
||||||
|
_peerCoordinatorSet, _connectionAcceptor,
|
||||||
|
false, dataDir.getPath());
|
||||||
torrent.completeListener = this;
|
torrent.completeListener = this;
|
||||||
synchronized (_snarks) {
|
synchronized (_snarks) {
|
||||||
_snarks.put(filename, torrent);
|
_snarks.put(filename, torrent);
|
||||||
@ -569,7 +580,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
if (remaining == 0) {
|
if (remaining == 0) {
|
||||||
// should we disconnect/reconnect here (taking care to deal with the other thread's
|
// should we disconnect/reconnect here (taking care to deal with the other thread's
|
||||||
// I2PServerSocket.accept() call properly?)
|
// I2PServerSocket.accept() call properly?)
|
||||||
////I2PSnarkUtil.instance().
|
////_util.
|
||||||
}
|
}
|
||||||
if (!wasStopped)
|
if (!wasStopped)
|
||||||
addMessage("Torrent stopped: '" + sfile.getName() + "'");
|
addMessage("Torrent stopped: '" + sfile.getName() + "'");
|
||||||
@ -645,7 +656,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
if (existingNames.contains(foundNames.get(i))) {
|
if (existingNames.contains(foundNames.get(i))) {
|
||||||
// already known. noop
|
// already known. noop
|
||||||
} else {
|
} else {
|
||||||
if (shouldAutoStart() && !I2PSnarkUtil.instance().connect())
|
if (shouldAutoStart() && !_util.connect())
|
||||||
addMessage("Unable to connect to I2P");
|
addMessage("Unable to connect to I2P");
|
||||||
addTorrent((String)foundNames.get(i), !shouldAutoStart());
|
addTorrent((String)foundNames.get(i), !shouldAutoStart());
|
||||||
}
|
}
|
||||||
|
@ -51,21 +51,21 @@ public class SnarkShutdown extends I2PThread
|
|||||||
|
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
Snark.debug("Shutting down...", Snark.NOTICE);
|
//Snark.debug("Shutting down...", Snark.NOTICE);
|
||||||
|
|
||||||
Snark.debug("Halting ConnectionAcceptor...", Snark.INFO);
|
//Snark.debug("Halting ConnectionAcceptor...", Snark.INFO);
|
||||||
if (acceptor != null)
|
if (acceptor != null)
|
||||||
acceptor.halt();
|
acceptor.halt();
|
||||||
|
|
||||||
Snark.debug("Halting TrackerClient...", Snark.INFO);
|
//Snark.debug("Halting TrackerClient...", Snark.INFO);
|
||||||
if (trackerclient != null)
|
if (trackerclient != null)
|
||||||
trackerclient.halt();
|
trackerclient.halt();
|
||||||
|
|
||||||
Snark.debug("Halting PeerCoordinator...", Snark.INFO);
|
//Snark.debug("Halting PeerCoordinator...", Snark.INFO);
|
||||||
if (coordinator != null)
|
if (coordinator != null)
|
||||||
coordinator.halt();
|
coordinator.halt();
|
||||||
|
|
||||||
Snark.debug("Closing Storage...", Snark.INFO);
|
//Snark.debug("Closing Storage...", Snark.INFO);
|
||||||
if (storage != null)
|
if (storage != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -74,7 +74,7 @@ public class SnarkShutdown extends I2PThread
|
|||||||
}
|
}
|
||||||
catch(IOException ioe)
|
catch(IOException ioe)
|
||||||
{
|
{
|
||||||
I2PSnarkUtil.instance().debug("Couldn't properly close storage", Snark.ERROR, ioe);
|
//I2PSnarkUtil.instance().debug("Couldn't properly close storage", Snark.ERROR, ioe);
|
||||||
throw new RuntimeException("b0rking");
|
throw new RuntimeException("b0rking");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ public class SnarkShutdown extends I2PThread
|
|||||||
// XXX - Should actually wait till done...
|
// XXX - Should actually wait till done...
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Snark.debug("Waiting 5 seconds...", Snark.INFO);
|
//Snark.debug("Waiting 5 seconds...", Snark.INFO);
|
||||||
Thread.sleep(5*1000);
|
Thread.sleep(5*1000);
|
||||||
}
|
}
|
||||||
catch (InterruptedException ie) { /* ignored */ }
|
catch (InterruptedException ie) { /* ignored */ }
|
||||||
|
@ -44,6 +44,7 @@ public class Storage
|
|||||||
private File[] RAFfile; // File to make it easier to reopen
|
private File[] RAFfile; // File to make it easier to reopen
|
||||||
|
|
||||||
private final StorageListener listener;
|
private final StorageListener listener;
|
||||||
|
private I2PSnarkUtil _util;
|
||||||
|
|
||||||
private BitField bitfield; // BitField to represent the pieces
|
private BitField bitfield; // BitField to represent the pieces
|
||||||
private int needed; // Number of pieces needed
|
private int needed; // Number of pieces needed
|
||||||
@ -66,9 +67,10 @@ public class Storage
|
|||||||
*
|
*
|
||||||
* @exception IOException when creating and/or checking files fails.
|
* @exception IOException when creating and/or checking files fails.
|
||||||
*/
|
*/
|
||||||
public Storage(MetaInfo metainfo, StorageListener listener)
|
public Storage(I2PSnarkUtil util, MetaInfo metainfo, StorageListener listener)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
|
_util = util;
|
||||||
this.metainfo = metainfo;
|
this.metainfo = metainfo;
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
needed = metainfo.getPieces();
|
needed = metainfo.getPieces();
|
||||||
@ -81,9 +83,10 @@ public class Storage
|
|||||||
* with an appropriate MetaInfo file as can be announced on the
|
* with an appropriate MetaInfo file as can be announced on the
|
||||||
* given announce String location.
|
* given announce String location.
|
||||||
*/
|
*/
|
||||||
public Storage(File baseFile, String announce, StorageListener listener)
|
public Storage(I2PSnarkUtil util, File baseFile, String announce, StorageListener listener)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
|
_util = util;
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
// Create names, rafs and lengths arrays.
|
// Create names, rafs and lengths arrays.
|
||||||
getFiles(baseFile);
|
getFiles(baseFile);
|
||||||
@ -236,7 +239,7 @@ public class Storage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void addFiles(List l, File f)
|
private void addFiles(List l, File f)
|
||||||
{
|
{
|
||||||
if (!f.isDirectory())
|
if (!f.isDirectory())
|
||||||
l.add(f);
|
l.add(f);
|
||||||
@ -245,7 +248,7 @@ public class Storage
|
|||||||
File[] files = f.listFiles();
|
File[] files = f.listFiles();
|
||||||
if (files == null)
|
if (files == null)
|
||||||
{
|
{
|
||||||
Snark.debug("WARNING: Skipping '" + f
|
_util.debug("WARNING: Skipping '" + f
|
||||||
+ "' not a normal file.", Snark.WARNING);
|
+ "' not a normal file.", Snark.WARNING);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -305,7 +308,7 @@ public class Storage
|
|||||||
if (files == null)
|
if (files == null)
|
||||||
{
|
{
|
||||||
// Create base as file.
|
// Create base as file.
|
||||||
Snark.debug("Creating/Checking file: " + base, Snark.NOTICE);
|
_util.debug("Creating/Checking file: " + base, Snark.NOTICE);
|
||||||
if (!base.createNewFile() && !base.exists())
|
if (!base.createNewFile() && !base.exists())
|
||||||
throw new IOException("Could not create file " + base);
|
throw new IOException("Could not create file " + base);
|
||||||
|
|
||||||
@ -328,7 +331,7 @@ public class Storage
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Create base as dir.
|
// Create base as dir.
|
||||||
Snark.debug("Creating/Checking directory: " + base, Snark.NOTICE);
|
_util.debug("Creating/Checking directory: " + base, Snark.NOTICE);
|
||||||
if (!base.mkdir() && !base.isDirectory())
|
if (!base.mkdir() && !base.isDirectory())
|
||||||
throw new IOException("Could not create directory " + base);
|
throw new IOException("Could not create directory " + base);
|
||||||
|
|
||||||
@ -366,16 +369,16 @@ public class Storage
|
|||||||
bitfield = savedBitField;
|
bitfield = savedBitField;
|
||||||
needed = metainfo.getPieces() - bitfield.count();
|
needed = metainfo.getPieces() - bitfield.count();
|
||||||
_probablyComplete = complete();
|
_probablyComplete = complete();
|
||||||
Snark.debug("Found saved state and files unchanged, skipping check", Snark.NOTICE);
|
_util.debug("Found saved state and files unchanged, skipping check", Snark.NOTICE);
|
||||||
} else {
|
} else {
|
||||||
// the following sets the needed variable
|
// the following sets the needed variable
|
||||||
changed = true;
|
changed = true;
|
||||||
checkCreateFiles();
|
checkCreateFiles();
|
||||||
}
|
}
|
||||||
if (complete())
|
if (complete())
|
||||||
Snark.debug("Torrent is complete", Snark.NOTICE);
|
_util.debug("Torrent is complete", Snark.NOTICE);
|
||||||
else
|
else
|
||||||
Snark.debug("Still need " + needed + " out of " + metainfo.getPieces() + " pieces", Snark.NOTICE);
|
_util.debug("Still need " + needed + " out of " + metainfo.getPieces() + " pieces", Snark.NOTICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -390,14 +393,14 @@ public class Storage
|
|||||||
if (files == null)
|
if (files == null)
|
||||||
{
|
{
|
||||||
// Reopen base as file.
|
// Reopen base as file.
|
||||||
Snark.debug("Reopening file: " + base, Snark.NOTICE);
|
_util.debug("Reopening file: " + base, Snark.NOTICE);
|
||||||
if (!base.exists())
|
if (!base.exists())
|
||||||
throw new IOException("Could not reopen file " + base);
|
throw new IOException("Could not reopen file " + base);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Reopen base as dir.
|
// Reopen base as dir.
|
||||||
Snark.debug("Reopening directory: " + base, Snark.NOTICE);
|
_util.debug("Reopening directory: " + base, Snark.NOTICE);
|
||||||
if (!base.isDirectory())
|
if (!base.isDirectory())
|
||||||
throw new IOException("Could not reopen directory " + base);
|
throw new IOException("Could not reopen directory " + base);
|
||||||
|
|
||||||
@ -487,7 +490,7 @@ public class Storage
|
|||||||
allocateFile(i);
|
allocateFile(i);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Snark.debug("File '" + names[i] + "' exists, but has wrong length - repairing corruption", Snark.ERROR);
|
_util.debug("File '" + names[i] + "' exists, but has wrong length - repairing corruption", Snark.ERROR);
|
||||||
changed = true;
|
changed = true;
|
||||||
_probablyComplete = false; // to force RW
|
_probablyComplete = false; // to force RW
|
||||||
synchronized(RAFlock[i]) {
|
synchronized(RAFlock[i]) {
|
||||||
@ -574,7 +577,7 @@ public class Storage
|
|||||||
closeRAF(i);
|
closeRAF(i);
|
||||||
}
|
}
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
I2PSnarkUtil.instance().debug("Error closing " + RAFfile[i], Snark.ERROR, ioe);
|
_util.debug("Error closing " + RAFfile[i], Snark.ERROR, ioe);
|
||||||
// gobble gobble
|
// gobble gobble
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -595,7 +598,7 @@ public class Storage
|
|||||||
try {
|
try {
|
||||||
bs = new byte[len];
|
bs = new byte[len];
|
||||||
} catch (OutOfMemoryError oom) {
|
} catch (OutOfMemoryError oom) {
|
||||||
I2PSnarkUtil.instance().debug("Out of memory, can't honor request for piece " + piece, Snark.WARNING, oom);
|
_util.debug("Out of memory, can't honor request for piece " + piece, Snark.WARNING, oom);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
getUncheckedPiece(piece, bs, off, len);
|
getUncheckedPiece(piece, bs, off, len);
|
||||||
@ -691,7 +694,7 @@ public class Storage
|
|||||||
if (needed > 0) {
|
if (needed > 0) {
|
||||||
if (listener != null)
|
if (listener != null)
|
||||||
listener.setWantedPieces(this);
|
listener.setWantedPieces(this);
|
||||||
Snark.debug("WARNING: Not really done, missing " + needed
|
_util.debug("WARNING: Not really done, missing " + needed
|
||||||
+ " pieces", Snark.WARNING);
|
+ " pieces", Snark.WARNING);
|
||||||
} else {
|
} else {
|
||||||
if (listener != null)
|
if (listener != null)
|
||||||
|
@ -57,6 +57,7 @@ public class TrackerClient extends I2PThread
|
|||||||
private final static int MAX_CONSEC_FAILS = 5; // slow down after this
|
private final static int MAX_CONSEC_FAILS = 5; // slow down after this
|
||||||
private final static int LONG_SLEEP = 30*60*1000; // sleep a while after lots of fails
|
private final static int LONG_SLEEP = 30*60*1000; // sleep a while after lots of fails
|
||||||
|
|
||||||
|
private I2PSnarkUtil _util;
|
||||||
private final MetaInfo meta;
|
private final MetaInfo meta;
|
||||||
private final PeerCoordinator coordinator;
|
private final PeerCoordinator coordinator;
|
||||||
private final int port;
|
private final int port;
|
||||||
@ -66,10 +67,11 @@ public class TrackerClient extends I2PThread
|
|||||||
|
|
||||||
private List trackers;
|
private List trackers;
|
||||||
|
|
||||||
public TrackerClient(MetaInfo meta, PeerCoordinator coordinator)
|
public TrackerClient(I2PSnarkUtil util, MetaInfo meta, PeerCoordinator coordinator)
|
||||||
{
|
{
|
||||||
// Set unique name.
|
// Set unique name.
|
||||||
super("TrackerClient-" + urlencode(coordinator.getID()));
|
super("TrackerClient-" + urlencode(coordinator.getID()));
|
||||||
|
_util = util;
|
||||||
this.meta = meta;
|
this.meta = meta;
|
||||||
this.coordinator = coordinator;
|
this.coordinator = coordinator;
|
||||||
|
|
||||||
@ -98,13 +100,13 @@ public class TrackerClient extends I2PThread
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean verifyConnected() {
|
private boolean verifyConnected() {
|
||||||
while (!stop && !I2PSnarkUtil.instance().connected()) {
|
while (!stop && !_util.connected()) {
|
||||||
boolean ok = I2PSnarkUtil.instance().connect();
|
boolean ok = _util.connect();
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
try { Thread.sleep(30*1000); } catch (InterruptedException ie) {}
|
try { Thread.sleep(30*1000); } catch (InterruptedException ie) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return !stop && I2PSnarkUtil.instance().connected();
|
return !stop && _util.connected();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run()
|
public void run()
|
||||||
@ -121,7 +123,7 @@ public class TrackerClient extends I2PThread
|
|||||||
// the primary tracker, that we don't add it twice.
|
// the primary tracker, that we don't add it twice.
|
||||||
trackers = new ArrayList(2);
|
trackers = new ArrayList(2);
|
||||||
trackers.add(new Tracker(meta.getAnnounce(), true));
|
trackers.add(new Tracker(meta.getAnnounce(), true));
|
||||||
List tlist = I2PSnarkUtil.instance().getOpenTrackers();
|
List tlist = _util.getOpenTrackers();
|
||||||
if (tlist != null) {
|
if (tlist != null) {
|
||||||
for (int i = 0; i < tlist.size(); i++) {
|
for (int i = 0; i < tlist.size(); i++) {
|
||||||
String url = (String)tlist.get(i);
|
String url = (String)tlist.get(i);
|
||||||
@ -136,7 +138,7 @@ public class TrackerClient extends I2PThread
|
|||||||
}
|
}
|
||||||
if (meta.getAnnounce().startsWith(url.substring(0, slash)))
|
if (meta.getAnnounce().startsWith(url.substring(0, slash)))
|
||||||
continue;
|
continue;
|
||||||
String dest = I2PSnarkUtil.instance().lookup(url.substring(7, slash));
|
String dest = _util.lookup(url.substring(7, slash));
|
||||||
if (dest == null) {
|
if (dest == null) {
|
||||||
_log.error("Announce host unknown: [" + url + "]");
|
_log.error("Announce host unknown: [" + url + "]");
|
||||||
continue;
|
continue;
|
||||||
@ -264,7 +266,7 @@ public class TrackerClient extends I2PThread
|
|||||||
catch (IOException ioe)
|
catch (IOException ioe)
|
||||||
{
|
{
|
||||||
// Probably not fatal (if it doesn't last to long...)
|
// Probably not fatal (if it doesn't last to long...)
|
||||||
Snark.debug
|
_util.debug
|
||||||
("WARNING: Could not contact tracker at '"
|
("WARNING: Could not contact tracker at '"
|
||||||
+ tr.announce + "': " + ioe, Snark.WARNING);
|
+ tr.announce + "': " + ioe, Snark.WARNING);
|
||||||
tr.trackerProblems = ioe.getMessage();
|
tr.trackerProblems = ioe.getMessage();
|
||||||
@ -295,12 +297,12 @@ public class TrackerClient extends I2PThread
|
|||||||
// we could try and total the unique peers but that's too hard for now
|
// we could try and total the unique peers but that's too hard for now
|
||||||
coordinator.trackerSeenPeers = maxSeenPeers;
|
coordinator.trackerSeenPeers = maxSeenPeers;
|
||||||
if (!started)
|
if (!started)
|
||||||
Snark.debug(" Retrying in one minute...", Snark.DEBUG);
|
_util.debug(" Retrying in one minute...", Snark.DEBUG);
|
||||||
} // *** end of while loop
|
} // *** end of while loop
|
||||||
} // try
|
} // try
|
||||||
catch (Throwable t)
|
catch (Throwable t)
|
||||||
{
|
{
|
||||||
I2PSnarkUtil.instance().debug("TrackerClient: " + t, Snark.ERROR, t);
|
_util.debug("TrackerClient: " + t, Snark.ERROR, t);
|
||||||
if (t instanceof OutOfMemoryError)
|
if (t instanceof OutOfMemoryError)
|
||||||
throw (OutOfMemoryError)t;
|
throw (OutOfMemoryError)t;
|
||||||
}
|
}
|
||||||
@ -332,15 +334,15 @@ public class TrackerClient extends I2PThread
|
|||||||
+ "?info_hash=" + infoHash
|
+ "?info_hash=" + infoHash
|
||||||
+ "&peer_id=" + peerID
|
+ "&peer_id=" + peerID
|
||||||
+ "&port=" + port
|
+ "&port=" + port
|
||||||
+ "&ip=" + I2PSnarkUtil.instance().getOurIPString() + ".i2p"
|
+ "&ip=" + _util.getOurIPString() + ".i2p"
|
||||||
+ "&uploaded=" + uploaded
|
+ "&uploaded=" + uploaded
|
||||||
+ "&downloaded=" + downloaded
|
+ "&downloaded=" + downloaded
|
||||||
+ "&left=" + left
|
+ "&left=" + left
|
||||||
+ ((event != NO_EVENT) ? ("&event=" + event) : "");
|
+ ((event != NO_EVENT) ? ("&event=" + event) : "");
|
||||||
Snark.debug("Sending TrackerClient request: " + s, Snark.INFO);
|
_util.debug("Sending TrackerClient request: " + s, Snark.INFO);
|
||||||
|
|
||||||
tr.lastRequestTime = System.currentTimeMillis();
|
tr.lastRequestTime = System.currentTimeMillis();
|
||||||
File fetched = I2PSnarkUtil.instance().get(s);
|
File fetched = _util.get(s);
|
||||||
if (fetched == null) {
|
if (fetched == null) {
|
||||||
throw new IOException("Error fetching " + s);
|
throw new IOException("Error fetching " + s);
|
||||||
}
|
}
|
||||||
@ -352,7 +354,7 @@ public class TrackerClient extends I2PThread
|
|||||||
|
|
||||||
TrackerInfo info = new TrackerInfo(in, coordinator.getID(),
|
TrackerInfo info = new TrackerInfo(in, coordinator.getID(),
|
||||||
coordinator.getMetaInfo());
|
coordinator.getMetaInfo());
|
||||||
Snark.debug("TrackerClient response: " + info, Snark.INFO);
|
_util.debug("TrackerClient response: " + info, Snark.INFO);
|
||||||
|
|
||||||
String failure = info.getFailureReason();
|
String failure = info.getFailureReason();
|
||||||
if (failure != null)
|
if (failure != null)
|
||||||
|
@ -101,7 +101,7 @@ public class TrackerInfo
|
|||||||
peerID = new PeerID(((BEValue)it.next()).getMap());
|
peerID = new PeerID(((BEValue)it.next()).getMap());
|
||||||
} catch (InvalidBEncodingException ibe) {
|
} catch (InvalidBEncodingException ibe) {
|
||||||
// don't let one bad entry spoil the whole list
|
// don't let one bad entry spoil the whole list
|
||||||
Snark.debug("Discarding peer from list: " + ibe, Snark.ERROR);
|
//Snark.debug("Discarding peer from list: " + ibe, Snark.ERROR);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
peers.add(new Peer(peerID, my_id, metainfo));
|
peers.add(new Peer(peerID, my_id, metainfo));
|
||||||
|
@ -116,7 +116,7 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
List snarks = getSortedSnarks(req);
|
List snarks = getSortedSnarks(req);
|
||||||
String uri = req.getRequestURI();
|
String uri = req.getRequestURI();
|
||||||
out.write(TABLE_HEADER);
|
out.write(TABLE_HEADER);
|
||||||
if (I2PSnarkUtil.instance().connected() && snarks.size() > 0) {
|
if (_manager.util().connected() && snarks.size() > 0) {
|
||||||
if (peerParam != null)
|
if (peerParam != null)
|
||||||
out.write("(<a href=\"" + req.getRequestURI() + "\">Hide Peers</a>)<br />\n");
|
out.write("(<a href=\"" + req.getRequestURI() + "\">Hide Peers</a>)<br />\n");
|
||||||
else
|
else
|
||||||
@ -124,7 +124,7 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
}
|
}
|
||||||
out.write(TABLE_HEADER2);
|
out.write(TABLE_HEADER2);
|
||||||
out.write("<th align=\"left\" valign=\"top\">");
|
out.write("<th align=\"left\" valign=\"top\">");
|
||||||
if (I2PSnarkUtil.instance().connected())
|
if (_manager.util().connected())
|
||||||
out.write("<a href=\"" + uri + "?action=StopAll&nonce=" + _nonce +
|
out.write("<a href=\"" + uri + "?action=StopAll&nonce=" + _nonce +
|
||||||
"\" title=\"Stop all torrents and the i2p tunnel\">Stop All</a>");
|
"\" title=\"Stop all torrents and the i2p tunnel\">Stop All</a>");
|
||||||
else if (snarks.size() > 0)
|
else if (snarks.size() > 0)
|
||||||
@ -330,7 +330,7 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
_manager.addMessage("Error creating torrent - you must select a tracker");
|
_manager.addMessage("Error creating torrent - you must select a tracker");
|
||||||
else if (baseFile.exists()) {
|
else if (baseFile.exists()) {
|
||||||
try {
|
try {
|
||||||
Storage s = new Storage(baseFile, announceURL, null);
|
Storage s = new Storage(_manager.util(), baseFile, announceURL, null);
|
||||||
s.create();
|
s.create();
|
||||||
s.close(); // close the files... maybe need a way to pass this Storage to addTorrent rather than starting over
|
s.close(); // close the files... maybe need a way to pass this Storage to addTorrent rather than starting over
|
||||||
MetaInfo info = s.getMetaInfo();
|
MetaInfo info = s.getMetaInfo();
|
||||||
@ -361,8 +361,8 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
if (!snark.stopped)
|
if (!snark.stopped)
|
||||||
_manager.stopTorrent(snark.torrent, false);
|
_manager.stopTorrent(snark.torrent, false);
|
||||||
}
|
}
|
||||||
if (I2PSnarkUtil.instance().connected()) {
|
if (_manager.util().connected()) {
|
||||||
I2PSnarkUtil.instance().disconnect();
|
_manager.util().disconnect();
|
||||||
_manager.addMessage("I2P tunnel closed");
|
_manager.addMessage("I2P tunnel closed");
|
||||||
}
|
}
|
||||||
} else if ("StartAll".equals(action)) {
|
} else if ("StartAll".equals(action)) {
|
||||||
@ -690,8 +690,8 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
String uri = req.getRequestURI();
|
String uri = req.getRequestURI();
|
||||||
String dataDir = _manager.getDataDir().getAbsolutePath();
|
String dataDir = _manager.getDataDir().getAbsolutePath();
|
||||||
boolean autoStart = _manager.shouldAutoStart();
|
boolean autoStart = _manager.shouldAutoStart();
|
||||||
boolean useOpenTrackers = I2PSnarkUtil.instance().shouldUseOpenTrackers();
|
boolean useOpenTrackers = _manager.util().shouldUseOpenTrackers();
|
||||||
String openTrackers = I2PSnarkUtil.instance().getOpenTrackerString();
|
String openTrackers = _manager.util().getOpenTrackerString();
|
||||||
//int seedPct = 0;
|
//int seedPct = 0;
|
||||||
|
|
||||||
out.write("<form action=\"" + uri + "\" method=\"POST\">\n");
|
out.write("<form action=\"" + uri + "\" method=\"POST\">\n");
|
||||||
@ -723,9 +723,9 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
out.write("</select><br />\n");
|
out.write("</select><br />\n");
|
||||||
*/
|
*/
|
||||||
out.write("Total uploader limit: <input type=\"text\" name=\"upLimit\" value=\""
|
out.write("Total uploader limit: <input type=\"text\" name=\"upLimit\" value=\""
|
||||||
+ I2PSnarkUtil.instance().getMaxUploaders() + "\" size=\"3\" maxlength=\"3\" /> peers<br />\n");
|
+ _manager.util().getMaxUploaders() + "\" size=\"3\" maxlength=\"3\" /> peers<br />\n");
|
||||||
out.write("Up bandwidth limit: <input type=\"text\" name=\"upBW\" value=\""
|
out.write("Up bandwidth limit: <input type=\"text\" name=\"upBW\" value=\""
|
||||||
+ I2PSnarkUtil.instance().getMaxUpBW() + "\" size=\"3\" maxlength=\"3\" /> KBps <i>(Router Up BW / 2 recommended)</i><br />\n");
|
+ _manager.util().getMaxUpBW() + "\" size=\"3\" maxlength=\"3\" /> KBps <i>(Router Up BW / 2 recommended)</i><br />\n");
|
||||||
|
|
||||||
out.write("Use open trackers also: <input type=\"checkbox\" name=\"useOpenTrackers\" value=\"true\" "
|
out.write("Use open trackers also: <input type=\"checkbox\" name=\"useOpenTrackers\" value=\"true\" "
|
||||||
+ (useOpenTrackers ? "checked " : "")
|
+ (useOpenTrackers ? "checked " : "")
|
||||||
@ -735,15 +735,15 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
|
|
||||||
//out.write("<hr />\n");
|
//out.write("<hr />\n");
|
||||||
out.write("EepProxy host: <input type=\"text\" name=\"eepHost\" value=\""
|
out.write("EepProxy host: <input type=\"text\" name=\"eepHost\" value=\""
|
||||||
+ I2PSnarkUtil.instance().getEepProxyHost() + "\" size=\"15\" /> ");
|
+ _manager.util().getEepProxyHost() + "\" size=\"15\" /> ");
|
||||||
out.write("port: <input type=\"text\" name=\"eepPort\" value=\""
|
out.write("port: <input type=\"text\" name=\"eepPort\" value=\""
|
||||||
+ I2PSnarkUtil.instance().getEepProxyPort() + "\" size=\"5\" maxlength=\"5\" /><br />\n");
|
+ _manager.util().getEepProxyPort() + "\" size=\"5\" maxlength=\"5\" /><br />\n");
|
||||||
out.write("I2CP host: <input type=\"text\" name=\"i2cpHost\" value=\""
|
out.write("I2CP host: <input type=\"text\" name=\"i2cpHost\" value=\""
|
||||||
+ I2PSnarkUtil.instance().getI2CPHost() + "\" size=\"15\" /> ");
|
+ _manager.util().getI2CPHost() + "\" size=\"15\" /> ");
|
||||||
out.write("port: <input type=\"text\" name=\"i2cpPort\" value=\"" +
|
out.write("port: <input type=\"text\" name=\"i2cpPort\" value=\"" +
|
||||||
+ I2PSnarkUtil.instance().getI2CPPort() + "\" size=\"5\" maxlength=\"5\" /> <br />\n");
|
+ _manager.util().getI2CPPort() + "\" size=\"5\" maxlength=\"5\" /> <br />\n");
|
||||||
StringBuffer opts = new StringBuffer(64);
|
StringBuffer opts = new StringBuffer(64);
|
||||||
Map options = new TreeMap(I2PSnarkUtil.instance().getI2CPOptions());
|
Map options = new TreeMap(_manager.util().getI2CPOptions());
|
||||||
for (Iterator iter = options.entrySet().iterator(); iter.hasNext(); ) {
|
for (Iterator iter = options.entrySet().iterator(); iter.hasNext(); ) {
|
||||||
Map.Entry entry = (Map.Entry)iter.next();
|
Map.Entry entry = (Map.Entry)iter.next();
|
||||||
String key = (String)entry.getKey();
|
String key = (String)entry.getKey();
|
||||||
@ -877,7 +877,7 @@ class FetchAndAdd implements Runnable {
|
|||||||
public void run() {
|
public void run() {
|
||||||
_url = _url.trim();
|
_url = _url.trim();
|
||||||
// 3 retries
|
// 3 retries
|
||||||
File file = I2PSnarkUtil.instance().get(_url, false, 3);
|
File file = _manager.util().get(_url, false, 3);
|
||||||
try {
|
try {
|
||||||
if ( (file != null) && (file.exists()) && (file.length() > 0) ) {
|
if ( (file != null) && (file.exists()) && (file.length() > 0) ) {
|
||||||
_manager.addMessage("Torrent fetched from " + _url);
|
_manager.addMessage("Torrent fetched from " + _url);
|
||||||
|
Reference in New Issue
Block a user