diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java b/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java index b9388bda1..00f9f42fd 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java @@ -26,6 +26,7 @@ import java.util.*; import net.i2p.util.I2PThread; import net.i2p.util.Log; +import net.i2p.util.SimpleTimer; class PeerConnectionOut implements Runnable { @@ -94,6 +95,8 @@ class PeerConnectionOut implements Runnable // being send even if we get unchoked a little later. // (Since we will resent them anyway in that case.) // And remove piece messages if we are choking. + + // this should get fixed for starvation Iterator it = sendQueue.iterator(); while (m == null && it.hasNext()) { @@ -177,10 +180,30 @@ class PeerConnectionOut implements Runnable */ private void addMessage(Message m) { + SimpleTimer.getInstance().addEvent(new RemoveTooSlow(m), SEND_TIMEOUT); synchronized(sendQueue) { sendQueue.add(m); - sendQueue.notify(); + sendQueue.notifyAll(); + } + } + + /** remove messages not sent in 30s */ + private static final int SEND_TIMEOUT = 30*1000; + private class RemoveTooSlow implements SimpleTimer.TimedEvent { + private Message _m; + public RemoveTooSlow(Message m) { + _m = m; + } + + public void timeReached() { + boolean removed = false; + synchronized (sendQueue) { + removed = sendQueue.remove(_m); + sendQueue.notifyAll(); + } + if (removed) + _log.info("Took too long to send " + _m + " to " + peer); } } @@ -206,6 +229,7 @@ class PeerConnectionOut implements Runnable removed = true; } } + sendQueue.notifyAll(); } return removed; } diff --git a/apps/i2psnark/java/src/org/klomp/snark/Snark.java b/apps/i2psnark/java/src/org/klomp/snark/Snark.java index 09d438bc2..3b5f4c4fb 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/Snark.java +++ b/apps/i2psnark/java/src/org/klomp/snark/Snark.java @@ -28,6 +28,7 @@ import org.klomp.snark.bencode.*; import net.i2p.client.streaming.I2PSocket; import net.i2p.client.streaming.I2PServerSocket; +import net.i2p.util.I2PThread; /** * Main Snark program startup class. @@ -87,12 +88,26 @@ public class Snark // String indicating main activity String activity = "Not started"; + private static class OOMListener implements I2PThread.OOMEventListener { + public void outOfMemory(OutOfMemoryError err) { + try { + err.printStackTrace(); + I2PSnarkUtil.instance().debug("OOM in the snark", Snark.ERROR, err); + } catch (Throwable t) { + System.out.println("OOM in the OOM"); + } + System.exit(0); + } + + } + public static void main(String[] args) { System.out.println(copyright); System.out.println(); if ( (args.length > 0) && ("--config".equals(args[0])) ) { + I2PThread.addOOMEventListener(new OOMListener()); SnarkManager sm = SnarkManager.instance(); if (args.length > 1) sm.loadConfig(args[1]); diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index 31508cc1b..1f5183a8a 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -281,10 +281,10 @@ public class SnarkManager implements Snark.CompleteListener { fis.close(); fis = null; - List files = info.getFiles(); - if ( (files != null) && (files.size() > MAX_FILES_PER_TORRENT) ) { + String rejectMessage = locked_validateTorrent(info); + if (rejectMessage != null) { sfile.delete(); - addMessage("Too many files in " + sfile.getName() + " (" + files.size() + "), deleting it"); + addMessage(rejectMessage); return; } else { torrent = new Snark(filename, null, -1, null, null, false, dataDir.getPath()); @@ -313,6 +313,28 @@ public class SnarkManager implements Snark.CompleteListener { } } + private String locked_validateTorrent(MetaInfo info) throws IOException { + List files = info.getFiles(); + if ( (files != null) && (files.size() > MAX_FILES_PER_TORRENT) ) { + return "Too many files in " + info.getName() + " (" + files.size() + "), deleting it"; + } else if (info.getPieces() <= 0) { + return "No pieces in " + info.getName() + "? deleting it"; + } else if (info.getPieceLength(0) > 1024*1024) { + return "Pieces are too large in " + info.getName() + " (" + info.getPieceLength(0)/1024 + "KB, deleting it"; + } else if (info.getTotalLength() > 10*1024*1024*1024l) { + System.out.println("torrent info: " + info.toString()); + List lengths = info.getLengths(); + if (lengths != null) + for (int i = 0; i < lengths.size(); i++) + System.out.println("File " + i + " is " + lengths.get(i) + " long"); + + return "Torrents larger than 10GB are not supported yet (because we're paranoid): " + info.getName() + ", deleting it"; + } else { + // ok + return null; + } + } + /** * Stop the torrent, leaving it on the list of torrents unless told to remove it */ diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index 4594ac9de..8d2967c59 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -172,6 +172,10 @@ public class I2PSnarkServlet extends HttpServlet { if ( (snark != null) && (DataHelper.eq(infoHash, snark.meta.getInfoHash())) ) { _manager.stopTorrent(name, true); // should we delete the torrent file? + // yeah, need to, otherwise it'll get autoadded again (at the moment + File f = new File(name); + f.delete(); + _manager.addMessage("Torrent file deleted: " + f.getAbsolutePath()); break; } } diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java index a9ba96284..b9f6fd342 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java @@ -386,6 +386,18 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable } else { request = request.substring(pos + 1); pos = request.indexOf("/"); + if (pos < 0) { + l.log("Invalid request url [" + request + "]"); + if (out != null) { + out.write(ERR_REQUEST_DENIED); + out.write("
Generated on: ".getBytes()); + out.write(new Date().toString().getBytes()); + out.write("