forked from I2P_Developers/i2p.i2p
i2psnark: Don't disconnect seeds immediately if comments enabled (ticket #2288)
Implement variable timeout Hardcode handshake bytes Log tweaks
This commit is contained in:
@ -79,6 +79,7 @@ public class Peer implements Comparable<Peer>
|
||||
private long uploaded_old[] = {-1,-1,-1};
|
||||
private long downloaded_old[] = {-1,-1,-1};
|
||||
|
||||
private static final byte[] HANDSHAKE = DataHelper.getASCII("BitTorrent protocol");
|
||||
// bytes per bt spec: 0011223344556677
|
||||
private static final long OPTION_EXTENSION = 0x0000000000100000l;
|
||||
private static final long OPTION_FAST = 0x0000000000000004l;
|
||||
@ -343,8 +344,8 @@ public class Peer implements Comparable<Peer>
|
||||
dout = new DataOutputStream(out);
|
||||
|
||||
// Handshake write - header
|
||||
dout.write(19);
|
||||
dout.write("BitTorrent protocol".getBytes("UTF-8"));
|
||||
dout.write(HANDSHAKE.length);
|
||||
dout.write(HANDSHAKE);
|
||||
// Handshake write - options
|
||||
long myOptions = OPTION_EXTENSION;
|
||||
// we can't handle HAVE_ALL or HAVE_NONE if we don't know the number of pieces
|
||||
@ -365,17 +366,15 @@ public class Peer implements Comparable<Peer>
|
||||
|
||||
// Handshake read - header
|
||||
byte b = din.readByte();
|
||||
if (b != 19)
|
||||
if (b != HANDSHAKE.length)
|
||||
throw new IOException("Handshake failure, expected 19, got "
|
||||
+ (b & 0xff) + " on " + sock);
|
||||
|
||||
byte[] bs = new byte[19];
|
||||
byte[] bs = new byte[HANDSHAKE.length];
|
||||
din.readFully(bs);
|
||||
String bittorrentProtocol = new String(bs, "UTF-8");
|
||||
if (!"BitTorrent protocol".equals(bittorrentProtocol))
|
||||
if (!Arrays.equals(HANDSHAKE, bs))
|
||||
throw new IOException("Handshake failure, expected "
|
||||
+ "'BitTorrent protocol', got '"
|
||||
+ bittorrentProtocol + "'");
|
||||
+ "'BitTorrent protocol'");
|
||||
|
||||
// Handshake read - options
|
||||
options = din.readLong();
|
||||
@ -684,6 +683,13 @@ public class Peer implements Comparable<Peer>
|
||||
return -1; //"no state";
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 0.9.36 */
|
||||
public long getMaxInactiveTime() {
|
||||
return isCompleted() && !isInteresting() ?
|
||||
PeerCoordinator.MAX_SEED_INACTIVE :
|
||||
PeerCoordinator.MAX_INACTIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send keepalive
|
||||
|
@ -96,7 +96,7 @@ class PeerCheckerTask implements Runnable
|
||||
continue;
|
||||
}
|
||||
|
||||
if (peer.getInactiveTime() > PeerCoordinator.MAX_INACTIVE) {
|
||||
if (peer.getInactiveTime() > peer.getMaxInactiveTime()) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Disconnecting peer idle " +
|
||||
DataHelper.formatDuration(peer.getInactiveTime()) + ": " + peer);
|
||||
|
@ -75,6 +75,7 @@ class PeerCoordinator implements PeerListener
|
||||
final static long CHECK_PERIOD = 40*1000; // 40 seconds
|
||||
final static int MAX_UPLOADERS = 8;
|
||||
public static final long MAX_INACTIVE = 8*60*1000;
|
||||
public static final long MAX_SEED_INACTIVE = 2*60*1000;
|
||||
|
||||
/**
|
||||
* Approximation of the number of current uploaders (unchoked peers),
|
||||
@ -496,7 +497,7 @@ class PeerCoordinator implements PeerListener
|
||||
synchronized(peers)
|
||||
{
|
||||
Peer old = peerIDInList(peer.getPeerID(), peers);
|
||||
if ( (old != null) && (old.getInactiveTime() > MAX_INACTIVE) ) {
|
||||
if (old != null && old.getInactiveTime() > old.getMaxInactiveTime()) {
|
||||
// idle for 8 minutes, kill the old con (32KB/8min = 68B/sec minimum for one block)
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Remomving old peer: " + peer + ": " + old + ", inactive for " + old.getInactiveTime());
|
||||
@ -592,8 +593,10 @@ class PeerCoordinator implements PeerListener
|
||||
// thus there is an additional check in connected()
|
||||
need_more = (!peer.isConnected()) && peersize < getMaxConnections();
|
||||
// Check if we already have this peer before we build the connection
|
||||
Peer old = peerIDInList(peer.getPeerID(), peers);
|
||||
need_more = need_more && ((old == null) || (old.getInactiveTime() > MAX_INACTIVE));
|
||||
if (need_more) {
|
||||
Peer old = peerIDInList(peer.getPeerID(), peers);
|
||||
need_more = old == null || old.getInactiveTime() > old.getMaxInactiveTime();
|
||||
}
|
||||
}
|
||||
|
||||
if (need_more)
|
||||
@ -629,9 +632,9 @@ class PeerCoordinator implements PeerListener
|
||||
}
|
||||
if (_log.shouldLog(Log.DEBUG)) {
|
||||
if (peer.isConnected())
|
||||
_log.info("Add peer already connected: " + peer);
|
||||
_log.debug("Add peer already connected: " + peer);
|
||||
else
|
||||
_log.info("Connections: " + peersize + "/" + getMaxConnections()
|
||||
_log.debug("Connections: " + peersize + "/" + getMaxConnections()
|
||||
+ " not accepting extra peer: " + peer);
|
||||
}
|
||||
return false;
|
||||
|
@ -25,12 +25,16 @@ import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.ByteArray;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
import org.klomp.snark.bencode.BEValue;
|
||||
import org.klomp.snark.bencode.InvalidBEncodingException;
|
||||
|
||||
class PeerState implements DataLoader
|
||||
{
|
||||
private final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(PeerState.class);
|
||||
@ -242,14 +246,33 @@ class PeerState implements DataLoader
|
||||
} // synch
|
||||
|
||||
boolean interest = listener.gotBitField(peer, bitfield);
|
||||
setInteresting(interest);
|
||||
if (bitfield.complete() && !interest) {
|
||||
// They are seeding and we are seeding,
|
||||
// why did they contact us? (robert)
|
||||
// Dump them quick before we send our whole bitmap
|
||||
|
||||
// If we both support comments, allow it
|
||||
if (listener.getUtil().utCommentsEnabled()) {
|
||||
Map<String, BEValue> handshake = peer.getHandshakeMap();
|
||||
if (handshake != null) {
|
||||
BEValue bev = handshake.get("m");
|
||||
if (bev != null) {
|
||||
try {
|
||||
if (bev.getMap().get(ExtensionHandler.TYPE_COMMENT) != null) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Allowing seed that connects to seeds for comments: " + peer);
|
||||
setInteresting(interest);
|
||||
return;
|
||||
}
|
||||
} catch (InvalidBEncodingException ibee) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Disconnecting seed that connects to seeds: " + peer);
|
||||
peer.disconnect(true);
|
||||
} else {
|
||||
setInteresting(interest);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user