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:
@ -26,6 +26,7 @@ import java.util.*;
|
|||||||
|
|
||||||
import net.i2p.util.I2PThread;
|
import net.i2p.util.I2PThread;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
import net.i2p.util.SimpleTimer;
|
||||||
|
|
||||||
class PeerConnectionOut implements Runnable
|
class PeerConnectionOut implements Runnable
|
||||||
{
|
{
|
||||||
@ -94,6 +95,8 @@ class PeerConnectionOut implements Runnable
|
|||||||
// being send even if we get unchoked a little later.
|
// being send even if we get unchoked a little later.
|
||||||
// (Since we will resent them anyway in that case.)
|
// (Since we will resent them anyway in that case.)
|
||||||
// And remove piece messages if we are choking.
|
// And remove piece messages if we are choking.
|
||||||
|
|
||||||
|
// this should get fixed for starvation
|
||||||
Iterator it = sendQueue.iterator();
|
Iterator it = sendQueue.iterator();
|
||||||
while (m == null && it.hasNext())
|
while (m == null && it.hasNext())
|
||||||
{
|
{
|
||||||
@ -177,10 +180,30 @@ class PeerConnectionOut implements Runnable
|
|||||||
*/
|
*/
|
||||||
private void addMessage(Message m)
|
private void addMessage(Message m)
|
||||||
{
|
{
|
||||||
|
SimpleTimer.getInstance().addEvent(new RemoveTooSlow(m), SEND_TIMEOUT);
|
||||||
synchronized(sendQueue)
|
synchronized(sendQueue)
|
||||||
{
|
{
|
||||||
sendQueue.add(m);
|
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;
|
removed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sendQueue.notifyAll();
|
||||||
}
|
}
|
||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ import org.klomp.snark.bencode.*;
|
|||||||
|
|
||||||
import net.i2p.client.streaming.I2PSocket;
|
import net.i2p.client.streaming.I2PSocket;
|
||||||
import net.i2p.client.streaming.I2PServerSocket;
|
import net.i2p.client.streaming.I2PServerSocket;
|
||||||
|
import net.i2p.util.I2PThread;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main Snark program startup class.
|
* Main Snark program startup class.
|
||||||
@ -87,12 +88,26 @@ public class Snark
|
|||||||
// String indicating main activity
|
// String indicating main activity
|
||||||
String activity = "Not started";
|
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)
|
public static void main(String[] args)
|
||||||
{
|
{
|
||||||
System.out.println(copyright);
|
System.out.println(copyright);
|
||||||
System.out.println();
|
System.out.println();
|
||||||
|
|
||||||
if ( (args.length > 0) && ("--config".equals(args[0])) ) {
|
if ( (args.length > 0) && ("--config".equals(args[0])) ) {
|
||||||
|
I2PThread.addOOMEventListener(new OOMListener());
|
||||||
SnarkManager sm = SnarkManager.instance();
|
SnarkManager sm = SnarkManager.instance();
|
||||||
if (args.length > 1)
|
if (args.length > 1)
|
||||||
sm.loadConfig(args[1]);
|
sm.loadConfig(args[1]);
|
||||||
|
@ -281,10 +281,10 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
fis.close();
|
fis.close();
|
||||||
fis = null;
|
fis = null;
|
||||||
|
|
||||||
List files = info.getFiles();
|
String rejectMessage = locked_validateTorrent(info);
|
||||||
if ( (files != null) && (files.size() > MAX_FILES_PER_TORRENT) ) {
|
if (rejectMessage != null) {
|
||||||
sfile.delete();
|
sfile.delete();
|
||||||
addMessage("Too many files in " + sfile.getName() + " (" + files.size() + "), deleting it");
|
addMessage(rejectMessage);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
torrent = new Snark(filename, null, -1, null, null, false, dataDir.getPath());
|
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
|
* Stop the torrent, leaving it on the list of torrents unless told to remove it
|
||||||
*/
|
*/
|
||||||
|
@ -172,6 +172,10 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
if ( (snark != null) && (DataHelper.eq(infoHash, snark.meta.getInfoHash())) ) {
|
if ( (snark != null) && (DataHelper.eq(infoHash, snark.meta.getInfoHash())) ) {
|
||||||
_manager.stopTorrent(name, true);
|
_manager.stopTorrent(name, true);
|
||||||
// should we delete the torrent file?
|
// 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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -386,6 +386,18 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
|||||||
} else {
|
} else {
|
||||||
request = request.substring(pos + 1);
|
request = request.substring(pos + 1);
|
||||||
pos = request.indexOf("/");
|
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);
|
destination = request.substring(0, pos);
|
||||||
line = method + " " + request.substring(pos);
|
line = method + " " + request.substring(pos);
|
||||||
}
|
}
|
||||||
|
@ -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
|
2005-12-16 jrandom
|
||||||
* Moved I2PSnark from using Threads to I2PThreads, so we handle OOMs
|
* Moved I2PSnark from using Threads to I2PThreads, so we handle OOMs
|
||||||
|
@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RouterVersion {
|
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 String VERSION = "0.6.1.7";
|
||||||
public final static long BUILD = 4;
|
public final static long BUILD = 5;
|
||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
|
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
|
||||||
System.out.println("Router ID: " + RouterVersion.ID);
|
System.out.println("Router ID: " + RouterVersion.ID);
|
||||||
|
@ -91,7 +91,14 @@ class RouterWatchdog implements Runnable {
|
|||||||
public void monitorRouter() {
|
public void monitorRouter() {
|
||||||
boolean ok = verifyJobQueueLiveliness();
|
boolean ok = verifyJobQueueLiveliness();
|
||||||
// If we aren't connected to the network that's why there's nobody to talk to
|
// 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);
|
ok = ok && (verifyClientLiveliness() || netErrors >= 5);
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
|
Reference in New Issue
Block a user