forked from I2P_Developers/i2p.i2p
* i2psnark:
- Add per-hour conn limit - Blacklist peer after two bad handshakes - Reduce connect timeout
This commit is contained in:
@ -29,8 +29,12 @@ import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.streaming.I2PServerSocket;
|
||||
import net.i2p.client.streaming.I2PSocket;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.ObjectCounter;
|
||||
import net.i2p.util.SimpleScheduler;
|
||||
import net.i2p.util.SimpleTimer;
|
||||
|
||||
/**
|
||||
* Accepts connections on a TCP port and routes them to sub-acceptors.
|
||||
@ -41,11 +45,15 @@ public class ConnectionAcceptor implements Runnable
|
||||
private I2PServerSocket serverSocket;
|
||||
private PeerAcceptor peeracceptor;
|
||||
private Thread thread;
|
||||
private I2PSnarkUtil _util;
|
||||
private final I2PSnarkUtil _util;
|
||||
private final ObjectCounter<Hash> _badCounter = new ObjectCounter();
|
||||
|
||||
private boolean stop;
|
||||
private boolean socketChanged;
|
||||
|
||||
private static final int MAX_BAD = 2;
|
||||
private static final long BAD_CLEAN_INTERVAL = 30*60*1000;
|
||||
|
||||
public ConnectionAcceptor(I2PSnarkUtil util) { _util = util; }
|
||||
|
||||
public synchronized void startAccepting(PeerCoordinatorSet set, I2PServerSocket socket) {
|
||||
@ -59,6 +67,7 @@ public class ConnectionAcceptor implements Runnable
|
||||
thread = new I2PAppThread(this, "I2PSnark acceptor");
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
SimpleScheduler.getInstance().addPeriodicEvent(new Cleaner(), BAD_CLEAN_INTERVAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -70,11 +79,10 @@ public class ConnectionAcceptor implements Runnable
|
||||
this.peeracceptor = peeracceptor;
|
||||
_util = util;
|
||||
|
||||
socketChanged = false;
|
||||
stop = false;
|
||||
thread = new I2PAppThread(this, "I2PSnark acceptor");
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
SimpleScheduler.getInstance().addPeriodicEvent(new Cleaner(), BAD_CLEAN_INTERVAL);
|
||||
}
|
||||
|
||||
public void halt()
|
||||
@ -142,6 +150,12 @@ public class ConnectionAcceptor implements Runnable
|
||||
try { socket.close(); } catch (IOException ioe) {}
|
||||
continue;
|
||||
}
|
||||
if (_badCounter.count(socket.getPeerDestination().calculateHash()) >= MAX_BAD) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Rejecting connection from " + socket.getPeerDestination().calculateHash() + " after " + MAX_BAD + " failures");
|
||||
try { socket.close(); } catch (IOException ioe) {}
|
||||
continue;
|
||||
}
|
||||
Thread t = new I2PAppThread(new Handler(socket), "I2PSnark incoming connection");
|
||||
t.start();
|
||||
}
|
||||
@ -171,10 +185,12 @@ public class ConnectionAcceptor implements Runnable
|
||||
}
|
||||
|
||||
private class Handler implements Runnable {
|
||||
private I2PSocket _socket;
|
||||
private final I2PSocket _socket;
|
||||
|
||||
public Handler(I2PSocket socket) {
|
||||
_socket = socket;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
InputStream in = _socket.getInputStream();
|
||||
@ -184,6 +200,9 @@ public class ConnectionAcceptor implements Runnable
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Handling socket from " + _socket.getPeerDestination().calculateHash().toBase64());
|
||||
peeracceptor.connection(_socket, in, out);
|
||||
} catch (PeerAcceptor.ProtocolException ihe) {
|
||||
_badCounter.increment(_socket.getPeerDestination().calculateHash());
|
||||
try { _socket.close(); } catch (IOException ignored) { }
|
||||
} catch (IOException ioe) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Error handling connection from " + _socket.getPeerDestination().calculateHash().toBase64(), ioe);
|
||||
@ -191,4 +210,9 @@ public class ConnectionAcceptor implements Runnable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 0.9.1 */
|
||||
private class Cleaner implements SimpleTimer.TimedEvent {
|
||||
public void timeReached() { _badCounter.clear(); }
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import net.i2p.client.streaming.I2PSocket;
|
||||
import net.i2p.client.streaming.I2PSocketEepGet;
|
||||
import net.i2p.client.streaming.I2PSocketManager;
|
||||
import net.i2p.client.streaming.I2PSocketManagerFactory;
|
||||
import net.i2p.client.streaming.I2PSocketOptions;
|
||||
import net.i2p.data.Base32;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.Destination;
|
||||
@ -210,6 +211,8 @@ public class I2PSnarkUtil {
|
||||
// we don't need fast handshake for peer connections.
|
||||
//if (opts.getProperty("i2p.streaming.connectDelay") == null)
|
||||
// opts.setProperty("i2p.streaming.connectDelay", "500");
|
||||
if (opts.getProperty(I2PSocketOptions.PROP_CONNECT_TIMEOUT) == null)
|
||||
opts.setProperty(I2PSocketOptions.PROP_CONNECT_TIMEOUT, "75000");
|
||||
if (opts.getProperty("i2p.streaming.inactivityTimeout") == null)
|
||||
opts.setProperty("i2p.streaming.inactivityTimeout", "240000");
|
||||
if (opts.getProperty("i2p.streaming.inactivityAction") == null)
|
||||
@ -226,6 +229,8 @@ public class I2PSnarkUtil {
|
||||
opts.setProperty("i2p.streaming.maxConnsPerMinute", "2");
|
||||
if (opts.getProperty("i2p.streaming.maxTotalConnsPerMinute") == null)
|
||||
opts.setProperty("i2p.streaming.maxTotalConnsPerMinute", "8");
|
||||
if (opts.getProperty("i2p.streaming.maxConnsPerHour") == null)
|
||||
opts.setProperty("i2p.streaming.maxConnsPerHour", "20");
|
||||
_manager = I2PSocketManagerFactory.createManager(_i2cpHost, _i2cpPort, opts);
|
||||
}
|
||||
// FIXME this only instantiates krpc once, left stuck with old manager
|
||||
|
@ -143,9 +143,19 @@ public class PeerAcceptor
|
||||
byte buf[] = new byte[LOOKAHEAD_SIZE];
|
||||
int read = DataHelper.read(in, buf);
|
||||
if (read != buf.length)
|
||||
throw new IOException("Unable to read the hash (read " + read + ")");
|
||||
throw new ProtocolException("Unable to read the hash (read " + read + ")");
|
||||
byte rv[] = new byte[20];
|
||||
System.arraycopy(buf, buf.length-rv.length, rv, 0, rv.length);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* A unique exception so we can tell the ConnectionAcceptor about non-BT connections
|
||||
* @since 0.9.1
|
||||
*/
|
||||
public static class ProtocolException extends IOException {
|
||||
public ProtocolException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user