forked from I2P_Developers/i2p.i2p
* i2psnark:
- Close connection immediately if bad protocol, this makes blacklist work better too - Stop adding peers when we hit the limit - Lower limit for outbound connections so we give new peers a better chance in large swarms
This commit is contained in:
@ -198,14 +198,16 @@ public class ConnectionAcceptor implements Runnable
|
||||
// this is for the readahead in PeerAcceptor.connection()
|
||||
in = new BufferedInputStream(in);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Handling socket from " + _socket.getPeerDestination().calculateHash().toBase64());
|
||||
_log.debug("Handling socket from " + _socket.getPeerDestination().calculateHash());
|
||||
peeracceptor.connection(_socket, in, out);
|
||||
} catch (PeerAcceptor.ProtocolException ihe) {
|
||||
_badCounter.increment(_socket.getPeerDestination().calculateHash());
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Protocol error from " + _socket.getPeerDestination().calculateHash(), ihe);
|
||||
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);
|
||||
_log.debug("Error handling connection from " + _socket.getPeerDestination().calculateHash(), ioe);
|
||||
try { _socket.close(); } catch (IOException ignored) { }
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,10 @@ public class PeerAcceptor
|
||||
private final PeerCoordinator coordinator;
|
||||
final PeerCoordinatorSet coordinators;
|
||||
|
||||
/** shorten timeout while reading handshake */
|
||||
private static final long HASH_READ_TIMEOUT = 45*1000;
|
||||
|
||||
|
||||
public PeerAcceptor(PeerCoordinator coordinator)
|
||||
{
|
||||
this.coordinator = coordinator;
|
||||
@ -69,11 +73,20 @@ public class PeerAcceptor
|
||||
// talk about, and we can just look for that in our list of active torrents.
|
||||
byte peerInfoHash[] = null;
|
||||
if (in instanceof BufferedInputStream) {
|
||||
// multitorrent
|
||||
in.mark(LOOKAHEAD_SIZE);
|
||||
peerInfoHash = readHash(in);
|
||||
long timeout = socket.getReadTimeout();
|
||||
socket.setReadTimeout(HASH_READ_TIMEOUT);
|
||||
try {
|
||||
peerInfoHash = readHash(in);
|
||||
} catch (IOException ioe) {
|
||||
// unique exception so ConnectionAcceptor can blame the peer
|
||||
throw new ProtocolException(ioe.toString());
|
||||
}
|
||||
socket.setReadTimeout(timeout);
|
||||
in.reset();
|
||||
} else {
|
||||
// is this working right?
|
||||
// Single torrent - is this working right?
|
||||
try {
|
||||
peerInfoHash = readHash(in);
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
@ -130,23 +143,41 @@ public class PeerAcceptor
|
||||
}
|
||||
}
|
||||
|
||||
private static final String PROTO_STR = "BitTorrent protocol";
|
||||
private static final int PROTO_STR_LEN = PROTO_STR.length();
|
||||
private static final int PROTO_LEN = PROTO_STR_LEN + 1;
|
||||
private static final int[] PROTO = new int[PROTO_LEN];
|
||||
static {
|
||||
PROTO[0] = PROTO_STR_LEN;
|
||||
for (int i = 0; i < PROTO_STR_LEN; i++) {
|
||||
PROTO[i+1] = PROTO_STR.charAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
/** 48 */
|
||||
private static final int LOOKAHEAD_SIZE = 1 + // chr(19)
|
||||
"BitTorrent protocol".length() +
|
||||
private static final int LOOKAHEAD_SIZE = PROTO_LEN +
|
||||
8 + // blank, reserved
|
||||
20; // infohash
|
||||
|
||||
/**
|
||||
* Read ahead to the infohash, throwing an exception if there isn't enough data
|
||||
* Read ahead to the infohash, throwing an exception if there isn't enough data.
|
||||
* Also check the first 20 bytes for the correct protocol here and throw IOE if bad,
|
||||
* so we don't hang waiting for 48 bytes if it's not a bittorrent client.
|
||||
* The 20 bytes are checked again in Peer.handshake().
|
||||
*/
|
||||
private byte[] readHash(InputStream in) throws IOException {
|
||||
byte buf[] = new byte[LOOKAHEAD_SIZE];
|
||||
private static byte[] readHash(InputStream in) throws IOException {
|
||||
for (int i = 0; i < PROTO_LEN; i++) {
|
||||
int b = in.read();
|
||||
if (b != PROTO[i])
|
||||
throw new IOException("Bad protocol 0x" + Integer.toHexString(b) + " at byte " + i);
|
||||
}
|
||||
if (in.skip(8) != 8)
|
||||
throw new IOException("EOF before hash");
|
||||
byte buf[] = new byte[20];
|
||||
int read = DataHelper.read(in, buf);
|
||||
if (read != buf.length)
|
||||
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;
|
||||
throw new IOException("Unable to read the hash (read " + read + ")");
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -371,7 +371,9 @@ class PeerCoordinator implements PeerListener
|
||||
* @since 0.9.1
|
||||
*/
|
||||
public boolean needOutboundPeers() {
|
||||
return wantedBytes != 0 && needPeers();
|
||||
//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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -298,7 +298,7 @@ public class TrackerClient extends I2PAppThread
|
||||
List<Peer> ordered = new ArrayList(peers);
|
||||
Collections.shuffle(ordered, r);
|
||||
Iterator<Peer> it = ordered.iterator();
|
||||
while ((!stop) && it.hasNext()) {
|
||||
while ((!stop) && it.hasNext() && coordinator.needOutboundPeers()) {
|
||||
Peer cur = it.next();
|
||||
// FIXME if id == us || dest == us continue;
|
||||
// only delay if we actually make an attempt to add peer
|
||||
@ -351,7 +351,7 @@ public class TrackerClient extends I2PAppThread
|
||||
}
|
||||
Collections.shuffle(peers, r);
|
||||
Iterator<Peer> it = peers.iterator();
|
||||
while ((!stop) && it.hasNext()) {
|
||||
while ((!stop) && it.hasNext() && coordinator.needOutboundPeers()) {
|
||||
Peer cur = it.next();
|
||||
if (coordinator.addPeer(cur) && it.hasNext()) {
|
||||
int delay = (DELAY_MUL * r.nextInt(10)) + DELAY_MIN;
|
||||
@ -387,7 +387,7 @@ public class TrackerClient extends I2PAppThread
|
||||
}
|
||||
Collections.shuffle(peers, r);
|
||||
Iterator<Peer> it = peers.iterator();
|
||||
while ((!stop) && it.hasNext()) {
|
||||
while ((!stop) && it.hasNext() && coordinator.needOutboundPeers()) {
|
||||
Peer cur = it.next();
|
||||
if (coordinator.addPeer(cur) && it.hasNext()) {
|
||||
int delay = (DELAY_MUL * r.nextInt(10)) + DELAY_MIN;
|
||||
|
@ -3,6 +3,10 @@
|
||||
- Add per-hour conn limit
|
||||
- Blacklist peer after two bad handshakes
|
||||
- Reduce connect timeout
|
||||
- Close connection immediately if bad protocol
|
||||
- Stop adding peers when we hit the limit
|
||||
- Lower limit for outbound connections so we give
|
||||
new peers a better chance in large swarms
|
||||
|
||||
2012-05-30 zzz
|
||||
* Graphs: Reduce log EOF error to warn
|
||||
|
@ -18,7 +18,7 @@ public class RouterVersion {
|
||||
/** deprecated */
|
||||
public final static String ID = "Monotone";
|
||||
public final static String VERSION = CoreVersion.VERSION;
|
||||
public final static long BUILD = 8;
|
||||
public final static long BUILD = 9;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
|
Reference in New Issue
Block a user