* i2psnark:

- Fix NPE and other partials bugs
      - More extension message stubbing
      - Log tweaks
This commit is contained in:
zzz
2010-11-28 04:01:20 +00:00
parent 9ba86e86aa
commit a52fb65c64
5 changed files with 62 additions and 10 deletions

View File

@ -0,0 +1,36 @@
package org.klomp.snark;
import java.util.HashMap;
import java.util.Map;
import org.klomp.snark.bencode.BEncoder;
import org.klomp.snark.bencode.BEValue;
/**
* REF: BEP 10 Extension Protocol
* @since 0.8.2
*/
class ExtensionHandshake {
private static final byte[] _payload = buildPayload();
/**
* @return bencoded data
*/
static byte[] getPayload() {
return _payload;
}
/** just a test for now */
private static byte[] buildPayload() {
Map<String, Object> handshake = new HashMap();
Map<String, Integer> m = new HashMap();
m.put("foo", Integer.valueOf(99));
m.put("bar", Integer.valueOf(101));
handshake.put("m", m);
handshake.put("p", Integer.valueOf(6881));
handshake.put("v", "I2PSnark");
handshake.put("reqq", Integer.valueOf(5));
return BEncoder.bencode(handshake);
}
}

View File

@ -66,6 +66,7 @@ public class Peer implements Comparable
private long options;
/**
* Outgoing connection.
* Creates a disconnected peer given a PeerID, your own id and the
* relevant MetaInfo.
*/
@ -80,6 +81,7 @@ public class Peer implements Comparable
}
/**
* Incoming connection.
* Creates a unconnected peer from the input and output stream got
* from the socket. Note that the complete handshake (which can take
* some time or block indefinitely) is done in the calling Thread to
@ -201,6 +203,7 @@ public class Peer implements Comparable
// Do we need to handshake?
if (din == null)
{
// Outgoing connection
sock = util.connect(peerID);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Connected to " + peerID + ": " + sock);
@ -234,6 +237,7 @@ public class Peer implements Comparable
+ PeerID.idencode(expected_id) + "'");
}
} else {
// Incoming connection
if (_log.shouldLog(Log.DEBUG))
_log.debug("Already have din [" + sock + "] with " + toString());
}
@ -242,6 +246,12 @@ public class Peer implements Comparable
PeerConnectionOut out = new PeerConnectionOut(this, dout);
PeerState s = new PeerState(this, listener, metainfo, in, out);
if ((options & OPTION_EXTENSION) != 0) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Peer supports extensions, sending test message");
out.sendExtension(0, ExtensionHandshake.getPayload());
}
// Send our bitmap
if (bitfield != null)
s.out.sendBitfield(bitfield);
@ -331,12 +341,10 @@ public class Peer implements Comparable
if (_log.shouldLog(Log.DEBUG))
_log.debug("Read the remote side's hash and peerID fully from " + toString());
// if ((options & OPTION_EXTENSION) != 0) {
if (options != 0) {
// send them something
if (_log.shouldLog(Log.DEBUG))
//_log.debug("Peer supports extension message, what should we say? " + toString());
_log.debug("Peer supports options 0x" + Long.toString(options, 16) + ", what should we say? " + toString());
_log.debug("Peer supports options 0x" + Long.toString(options, 16) + ": " + toString());
}
return bs;

View File

@ -114,8 +114,9 @@ class PeerCheckerTask extends TimerTask
// Choke a percentage of them rather than all so it isn't so drastic...
// unless this torrent is over the limit all by itself.
// choke 5/8 of the time when seeding and 3/8 when leeching
boolean overBWLimitChoke = upload > 0 &&
((overBWLimit && random.nextBoolean()) ||
((overBWLimit && (random.nextInt(8) > (coordinator.completed() ? 2 : 4))) ||
(coordinator.overUpBWLimit(uploaded)));
// If we are at our max uploaders and we have lots of other

View File

@ -615,13 +615,13 @@ public class PeerCoordinator implements PeerListener
// share blocks rather than starting from 0 with each peer.
// This is where the flaws of the snark data model are really exposed.
// Could also randomize within the duplicate set rather than strict rarest-first
if (_log.shouldLog(Log.DEBUG))
_log.debug("parallel request (end game?) for " + peer + ": piece = " + piece);
if (_log.shouldLog(Log.INFO))
_log.info("parallel request (end game?) for " + peer + ": piece = " + piece);
}
}
if (record) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Now requesting: piece " + piece + " priority " + piece.getPriority());
if (_log.shouldLog(Log.INFO))
_log.info(peer + " is now requesting: piece " + piece + " priority " + piece.getPriority());
piece.setRequested(true);
}
return piece.getId();
@ -945,11 +945,11 @@ public class PeerCoordinator implements PeerListener
PartialPiece pp = iter.next();
int savedPiece = pp.getPiece();
if (havePieces.get(savedPiece)) {
iter.remove();
// this is just a double-check, it should be in there
for(Piece piece : wantedPieces) {
if (piece.getId() == savedPiece) {
piece.setRequested(true);
iter.remove();
if (_log.shouldLog(Log.INFO)) {
_log.info("Restoring orphaned partial piece " + pp +
" Partial list size now: " + partialPieces.size());
@ -957,8 +957,12 @@ public class PeerCoordinator implements PeerListener
return pp;
}
}
if (_log.shouldLog(Log.WARN))
_log.warn("Partial piece " + pp + " NOT in wantedPieces??");
}
}
if (_log.shouldLog(Log.WARN) && !partialPieces.isEmpty())
_log.warn("Peer " + peer + " has none of our partials " + partialPieces);
}
// ...and this section turns this into the general move-requests-around code!
// Temporary? So PeerState never calls wantPiece() directly for now...
@ -1004,7 +1008,7 @@ public class PeerCoordinator implements PeerListener
}
}
}
return wantPiece(peer, havePieces, false) > 0;
return wantPiece(peer, havePieces, false) >= 0;
}
/**

View File

@ -609,6 +609,9 @@ class PeerState implements DataLoader
*/
synchronized void addRequest()
{
// no bitfield yet? nothing to request then.
if (bitfield == null)
return;
boolean more_pieces = true;
while (more_pieces)
{