2005-12-16 jrandom

* Added some I2PSnark sanity checks, an OOMListener when running
      standalone, and a guard against keeping memory tied up indefinitely.
    * Sanity check on the watchdog (thanks zzz!)
    * Handle invalid HTTP requests in I2PTunnel a little better
This commit is contained in:
jrandom
2005-12-17 03:47:02 +00:00
committed by zzz
parent 7d234b1978
commit 1eb3ae5e1b
8 changed files with 98 additions and 8 deletions

View File

@ -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;
}

View File

@ -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]);

View File

@ -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
*/

View File

@ -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;
}
}

View File

@ -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("<p /><i>Generated on: ".getBytes());
out.write(new Date().toString().getBytes());
out.write("</i></body></html>\n".getBytes());
out.flush();
}
s.close();
return;
}
destination = request.substring(0, pos);
line = method + " " + request.substring(pos);
}

View File

@ -1,4 +1,10 @@
$Id: history.txt,v 1.359 2005/12/16 06:01:20 jrandom Exp $
$Id: history.txt,v 1.360 2005/12/16 18:18:56 jrandom Exp $
2005-12-16 jrandom
* Added some I2PSnark sanity checks, an OOMListener when running
standalone, and a guard against keeping memory tied up indefinitely.
* Sanity check on the watchdog (thanks zzz!)
* Handle invalid HTTP requests in I2PTunnel a little better
2005-12-16 jrandom
* Moved I2PSnark from using Threads to I2PThreads, so we handle OOMs

View File

@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
*
*/
public class RouterVersion {
public final static String ID = "$Revision: 1.310 $ $Date: 2005/12/13 16:56:42 $";
public final static String ID = "$Revision: 1.311 $ $Date: 2005/12/14 04:32:51 $";
public final static String VERSION = "0.6.1.7";
public final static long BUILD = 4;
public final static long BUILD = 5;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID);

View File

@ -91,7 +91,14 @@ class RouterWatchdog implements Runnable {
public void monitorRouter() {
boolean ok = verifyJobQueueLiveliness();
// If we aren't connected to the network that's why there's nobody to talk to
int netErrors = (int) _context.statManager().getRate("udp.sendException").getRate(60*1000).getLastEventCount();
long netErrors = 0;
RateStat rs = _context.statManager().getRate("udp.sendException");
if (rs != null) {
Rate r = rs.getRate(60*1000);
if (r != null)
netErrors = r.getLastEventCount();
}
ok = ok && (verifyClientLiveliness() || netErrors >= 5);
if (!ok) {