forked from I2P_Developers/i2p.i2p
propagate from branch 'i2p.i2p.zzz.update' (head 267311f29e501fcc8b3d674a93e78b5520ac985e)
to branch 'i2p.i2p' (head edeca2ab47e734c2314ff394609292d8bd3d5293)
This commit is contained in:
@ -58,7 +58,7 @@ public class I2PSnarkUtil {
|
||||
private volatile I2PSocketManager _manager;
|
||||
private boolean _configured;
|
||||
private volatile boolean _connecting;
|
||||
private final Set<Hash> _shitlist;
|
||||
private final Set<Hash> _banlist;
|
||||
private int _maxUploaders;
|
||||
private int _maxUpBW;
|
||||
private int _maxConnections;
|
||||
@ -86,7 +86,7 @@ public class I2PSnarkUtil {
|
||||
_opts = new HashMap();
|
||||
//setProxy("127.0.0.1", 4444);
|
||||
setI2CPConfig("127.0.0.1", 7654, null);
|
||||
_shitlist = new ConcurrentHashSet();
|
||||
_banlist = new ConcurrentHashSet();
|
||||
_maxUploaders = Snark.MAX_TOTAL_UPLOADERS;
|
||||
_maxUpBW = DEFAULT_MAX_UP_BW;
|
||||
_maxConnections = MAX_CONNECTIONS;
|
||||
@ -283,7 +283,7 @@ public class I2PSnarkUtil {
|
||||
I2PSocketManager mgr = _manager;
|
||||
// FIXME this can cause race NPEs elsewhere
|
||||
_manager = null;
|
||||
_shitlist.clear();
|
||||
_banlist.clear();
|
||||
if (mgr != null) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Disconnecting from I2P", new Exception("I did it"));
|
||||
@ -306,24 +306,24 @@ public class I2PSnarkUtil {
|
||||
if (addr.equals(getMyDestination()))
|
||||
throw new IOException("Attempt to connect to myself");
|
||||
Hash dest = addr.calculateHash();
|
||||
if (_shitlist.contains(dest))
|
||||
throw new IOException("Not trying to contact " + dest.toBase64() + ", as they are shitlisted");
|
||||
if (_banlist.contains(dest))
|
||||
throw new IOException("Not trying to contact " + dest.toBase64() + ", as they are banlisted");
|
||||
try {
|
||||
I2PSocket rv = _manager.connect(addr);
|
||||
if (rv != null)
|
||||
_shitlist.remove(dest);
|
||||
_banlist.remove(dest);
|
||||
return rv;
|
||||
} catch (I2PException ie) {
|
||||
_shitlist.add(dest);
|
||||
_context.simpleScheduler().addEvent(new Unshitlist(dest), 10*60*1000);
|
||||
_banlist.add(dest);
|
||||
_context.simpleScheduler().addEvent(new Unbanlist(dest), 10*60*1000);
|
||||
throw new IOException("Unable to reach the peer " + peer + ": " + ie.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private class Unshitlist implements SimpleTimer.TimedEvent {
|
||||
private class Unbanlist implements SimpleTimer.TimedEvent {
|
||||
private Hash _dest;
|
||||
public Unshitlist(Hash dest) { _dest = dest; }
|
||||
public void timeReached() { _shitlist.remove(_dest); }
|
||||
public Unbanlist(Hash dest) { _dest = dest; }
|
||||
public void timeReached() { _banlist.remove(_dest); }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -377,7 +377,10 @@ class PeerCoordinator implements PeerListener
|
||||
public boolean needOutboundPeers() {
|
||||
//return wantedBytes != 0 && needPeers();
|
||||
// minus one to make it a little easier for new peers to get in on large swarms
|
||||
return wantedBytes != 0 && !halted && peers.size() < getMaxConnections() - 1;
|
||||
return wantedBytes != 0 &&
|
||||
!halted &&
|
||||
peers.size() < getMaxConnections() - 1 &&
|
||||
(storage == null || !storage.isChecking());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -741,7 +744,19 @@ class PeerCoordinator implements PeerListener
|
||||
break;
|
||||
if (havePieces.get(p.getId()) && !p.isRequested())
|
||||
{
|
||||
piece = p;
|
||||
// never ever choose one that's in partialPieces, or we
|
||||
// will create a second one and leak
|
||||
boolean hasPartial = false;
|
||||
for (PartialPiece pp : partialPieces) {
|
||||
if (pp.getPiece() == p.getId()) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("wantPiece() skipping partial for " + peer + ": piece = " + pp);
|
||||
hasPartial = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasPartial)
|
||||
piece = p;
|
||||
}
|
||||
else if (p.isRequested())
|
||||
{
|
||||
@ -943,11 +958,14 @@ class PeerCoordinator implements PeerListener
|
||||
*/
|
||||
public boolean gotPiece(Peer peer, PartialPiece pp)
|
||||
{
|
||||
if (metainfo == null || storage == null)
|
||||
if (metainfo == null || storage == null || storage.isChecking()) {
|
||||
pp.release();
|
||||
return true;
|
||||
}
|
||||
int piece = pp.getPiece();
|
||||
if (halted) {
|
||||
_log.info("Got while-halted piece " + piece + "/" + metainfo.getPieces() +" from " + peer + " for " + metainfo.getName());
|
||||
pp.release();
|
||||
return true; // We don't actually care anymore.
|
||||
}
|
||||
|
||||
@ -962,12 +980,15 @@ class PeerCoordinator implements PeerListener
|
||||
// Assume we got a good piece, we don't really care anymore.
|
||||
// Well, this could be caused by a change in priorities, so
|
||||
// only return true if we already have it, otherwise might as well keep it.
|
||||
if (storage.getBitField().get(piece))
|
||||
if (storage.getBitField().get(piece)) {
|
||||
pp.release();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// this takes forever if complete, as it rechecks
|
||||
if (storage.putPiece(pp))
|
||||
{
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
@ -1173,6 +1194,8 @@ class PeerCoordinator implements PeerListener
|
||||
public PartialPiece getPartialPiece(Peer peer, BitField havePieces) {
|
||||
if (metainfo == null)
|
||||
return null;
|
||||
if (storage != null && storage.isChecking())
|
||||
return null;
|
||||
synchronized(wantedPieces) {
|
||||
// sorts by remaining bytes, least first
|
||||
Collections.sort(partialPieces);
|
||||
@ -1277,6 +1300,7 @@ class PeerCoordinator implements PeerListener
|
||||
PartialPiece pp = iter.next();
|
||||
if (pp.getPiece() == piece) {
|
||||
iter.remove();
|
||||
pp.release();
|
||||
// there should be only one but keep going to be sure
|
||||
}
|
||||
}
|
||||
|
@ -592,6 +592,7 @@ class PeerState implements DataLoader
|
||||
// Send cancel even when we are choked to make sure that it is
|
||||
// really never ever send.
|
||||
out.sendCancel(req);
|
||||
req.getPartialPiece().release();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -741,6 +742,10 @@ class PeerState implements DataLoader
|
||||
out.sendRequest(r);
|
||||
lastRequest = r;
|
||||
return true;
|
||||
} else {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Got dup from coord: " + pp);
|
||||
pp.release();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -985,6 +985,8 @@ public class Storage
|
||||
|
||||
/**
|
||||
* Put the piece in the Storage if it is correct.
|
||||
* Warning - takes a LONG time if complete as it does the recheck here.
|
||||
* TODO thread the recheck?
|
||||
*
|
||||
* @return true if the piece was correct (sha metainfo hash
|
||||
* matches), otherwise false.
|
||||
|
@ -995,14 +995,16 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
} else if (snark.isAllocating()) {
|
||||
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "stalled.png\" title=\"" + _("Allocating") + "\"></td>" +
|
||||
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Allocating");
|
||||
} else if (err != null) {
|
||||
if (isRunning && curPeers > 0 && !showPeers)
|
||||
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "trackererror.png\" title=\"" + err + "\"></td>" +
|
||||
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Tracker Error") +
|
||||
": <a href=\"" + uri + "?p=" + Base64.encode(snark.getInfoHash()) + "\">" +
|
||||
curPeers + thinsp(noThinsp) +
|
||||
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
|
||||
else if (isRunning)
|
||||
} else if (err != null && curPeers == 0) {
|
||||
// let's only show this if we have no peers, otherwise PEX and DHT should bail us out, user doesn't care
|
||||
//if (isRunning && curPeers > 0 && !showPeers)
|
||||
// statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "trackererror.png\" title=\"" + err + "\"></td>" +
|
||||
// "<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Tracker Error") +
|
||||
// ": <a href=\"" + uri + "?p=" + Base64.encode(snark.getInfoHash()) + "\">" +
|
||||
// curPeers + thinsp(noThinsp) +
|
||||
// ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
|
||||
//else if (isRunning)
|
||||
if (isRunning)
|
||||
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "trackererror.png\" title=\"" + err + "\"></td>" +
|
||||
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Tracker Error") +
|
||||
": " + curPeers + thinsp(noThinsp) +
|
||||
@ -1149,7 +1151,7 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
out.write("</a>");
|
||||
|
||||
out.write("<td align=\"right\" class=\"snarkTorrentETA " + rowClass + "\">");
|
||||
if(isRunning && remainingSeconds > 0)
|
||||
if(isRunning && remainingSeconds > 0 && !snark.isChecking())
|
||||
out.write(DataHelper.formatDuration2(Math.max(remainingSeconds, 10) * 1000)); // (eta 6h)
|
||||
out.write("</td>\n\t");
|
||||
out.write("<td align=\"right\" class=\"snarkTorrentDownloaded " + rowClass + "\">");
|
||||
|
Reference in New Issue
Block a user