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()
|
// this is for the readahead in PeerAcceptor.connection()
|
||||||
in = new BufferedInputStream(in);
|
in = new BufferedInputStream(in);
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
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);
|
peeracceptor.connection(_socket, in, out);
|
||||||
} catch (PeerAcceptor.ProtocolException ihe) {
|
} catch (PeerAcceptor.ProtocolException ihe) {
|
||||||
_badCounter.increment(_socket.getPeerDestination().calculateHash());
|
_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) { }
|
try { _socket.close(); } catch (IOException ignored) { }
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
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) { }
|
try { _socket.close(); } catch (IOException ignored) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,10 @@ public class PeerAcceptor
|
|||||||
private final PeerCoordinator coordinator;
|
private final PeerCoordinator coordinator;
|
||||||
final PeerCoordinatorSet coordinators;
|
final PeerCoordinatorSet coordinators;
|
||||||
|
|
||||||
|
/** shorten timeout while reading handshake */
|
||||||
|
private static final long HASH_READ_TIMEOUT = 45*1000;
|
||||||
|
|
||||||
|
|
||||||
public PeerAcceptor(PeerCoordinator coordinator)
|
public PeerAcceptor(PeerCoordinator coordinator)
|
||||||
{
|
{
|
||||||
this.coordinator = 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.
|
// talk about, and we can just look for that in our list of active torrents.
|
||||||
byte peerInfoHash[] = null;
|
byte peerInfoHash[] = null;
|
||||||
if (in instanceof BufferedInputStream) {
|
if (in instanceof BufferedInputStream) {
|
||||||
|
// multitorrent
|
||||||
in.mark(LOOKAHEAD_SIZE);
|
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();
|
in.reset();
|
||||||
} else {
|
} else {
|
||||||
// is this working right?
|
// Single torrent - is this working right?
|
||||||
try {
|
try {
|
||||||
peerInfoHash = readHash(in);
|
peerInfoHash = readHash(in);
|
||||||
if (_log.shouldLog(Log.INFO))
|
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 */
|
/** 48 */
|
||||||
private static final int LOOKAHEAD_SIZE = 1 + // chr(19)
|
private static final int LOOKAHEAD_SIZE = PROTO_LEN +
|
||||||
"BitTorrent protocol".length() +
|
|
||||||
8 + // blank, reserved
|
8 + // blank, reserved
|
||||||
20; // infohash
|
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 {
|
private static byte[] readHash(InputStream in) throws IOException {
|
||||||
byte buf[] = new byte[LOOKAHEAD_SIZE];
|
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);
|
int read = DataHelper.read(in, buf);
|
||||||
if (read != buf.length)
|
if (read != buf.length)
|
||||||
throw new ProtocolException("Unable to read the hash (read " + read + ")");
|
throw new IOException("Unable to read the hash (read " + read + ")");
|
||||||
byte rv[] = new byte[20];
|
return buf;
|
||||||
System.arraycopy(buf, buf.length-rv.length, rv, 0, rv.length);
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -371,7 +371,9 @@ class PeerCoordinator implements PeerListener
|
|||||||
* @since 0.9.1
|
* @since 0.9.1
|
||||||
*/
|
*/
|
||||||
public boolean needOutboundPeers() {
|
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);
|
List<Peer> ordered = new ArrayList(peers);
|
||||||
Collections.shuffle(ordered, r);
|
Collections.shuffle(ordered, r);
|
||||||
Iterator<Peer> it = ordered.iterator();
|
Iterator<Peer> it = ordered.iterator();
|
||||||
while ((!stop) && it.hasNext()) {
|
while ((!stop) && it.hasNext() && coordinator.needOutboundPeers()) {
|
||||||
Peer cur = it.next();
|
Peer cur = it.next();
|
||||||
// FIXME if id == us || dest == us continue;
|
// FIXME if id == us || dest == us continue;
|
||||||
// only delay if we actually make an attempt to add peer
|
// only delay if we actually make an attempt to add peer
|
||||||
@ -351,7 +351,7 @@ public class TrackerClient extends I2PAppThread
|
|||||||
}
|
}
|
||||||
Collections.shuffle(peers, r);
|
Collections.shuffle(peers, r);
|
||||||
Iterator<Peer> it = peers.iterator();
|
Iterator<Peer> it = peers.iterator();
|
||||||
while ((!stop) && it.hasNext()) {
|
while ((!stop) && it.hasNext() && coordinator.needOutboundPeers()) {
|
||||||
Peer cur = it.next();
|
Peer cur = it.next();
|
||||||
if (coordinator.addPeer(cur) && it.hasNext()) {
|
if (coordinator.addPeer(cur) && it.hasNext()) {
|
||||||
int delay = (DELAY_MUL * r.nextInt(10)) + DELAY_MIN;
|
int delay = (DELAY_MUL * r.nextInt(10)) + DELAY_MIN;
|
||||||
@ -387,7 +387,7 @@ public class TrackerClient extends I2PAppThread
|
|||||||
}
|
}
|
||||||
Collections.shuffle(peers, r);
|
Collections.shuffle(peers, r);
|
||||||
Iterator<Peer> it = peers.iterator();
|
Iterator<Peer> it = peers.iterator();
|
||||||
while ((!stop) && it.hasNext()) {
|
while ((!stop) && it.hasNext() && coordinator.needOutboundPeers()) {
|
||||||
Peer cur = it.next();
|
Peer cur = it.next();
|
||||||
if (coordinator.addPeer(cur) && it.hasNext()) {
|
if (coordinator.addPeer(cur) && it.hasNext()) {
|
||||||
int delay = (DELAY_MUL * r.nextInt(10)) + DELAY_MIN;
|
int delay = (DELAY_MUL * r.nextInt(10)) + DELAY_MIN;
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
- Add per-hour conn limit
|
- Add per-hour conn limit
|
||||||
- Blacklist peer after two bad handshakes
|
- Blacklist peer after two bad handshakes
|
||||||
- Reduce connect timeout
|
- 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
|
2012-05-30 zzz
|
||||||
* Graphs: Reduce log EOF error to warn
|
* Graphs: Reduce log EOF error to warn
|
||||||
|
@ -18,7 +18,7 @@ public class RouterVersion {
|
|||||||
/** deprecated */
|
/** deprecated */
|
||||||
public final static String ID = "Monotone";
|
public final static String ID = "Monotone";
|
||||||
public final static String VERSION = CoreVersion.VERSION;
|
public final static String VERSION = CoreVersion.VERSION;
|
||||||
public final static long BUILD = 8;
|
public final static long BUILD = 9;
|
||||||
|
|
||||||
/** for example "-test" */
|
/** for example "-test" */
|
||||||
public final static String EXTRA = "";
|
public final static String EXTRA = "";
|
||||||
|
Reference in New Issue
Block a user