PORT msg support; port and extension listener stubs

This commit is contained in:
zzz
2010-12-19 15:37:11 +00:00
parent 91f1ece753
commit afe57512ab
7 changed files with 67 additions and 22 deletions

View File

@ -53,6 +53,7 @@ class Message
// Used for HAVE, REQUEST, PIECE and CANCEL messages.
// low byte used for EXTENSION message
// low two bytes used for PORT message
int piece;
// Used for REQUEST, PIECE and CANCEL messages.
@ -107,6 +108,9 @@ class Message
if (type == EXTENSION)
datalen += 1;
if (type == PORT)
datalen += 2;
// add length of data for piece or bitfield array.
if (type == BITFIELD || type == PIECE || type == EXTENSION)
datalen += len;
@ -130,6 +134,9 @@ class Message
if (type == EXTENSION)
dos.writeByte((byte) piece & 0xff);
if (type == PORT)
dos.writeShort(piece & 0xffff);
// Send actual data
if (type == BITFIELD || type == PIECE || type == EXTENSION)
dos.write(data, off, len);

View File

@ -72,7 +72,6 @@ public class Peer implements Comparable
* relevant MetaInfo.
*/
public Peer(PeerID peerID, byte[] my_id, MetaInfo metainfo)
throws IOException
{
this.peerID = peerID;
this.my_id = my_id;
@ -253,6 +252,13 @@ public class Peer implements Comparable
out.sendExtension(0, ExtensionHandshake.getPayload());
}
if ((options & OPTION_DHT) != 0 && util.getDHT() != null) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Peer supports DHT, sending PORT message");
int port = util.getDHT().getPort();
out.sendPort(port);
}
// Send our bitmap
if (bitfield != null)
s.out.sendBitfield(bitfield);
@ -303,7 +309,8 @@ public class Peer implements Comparable
dout.write(19);
dout.write("BitTorrent protocol".getBytes("UTF-8"));
// Handshake write - options
dout.writeLong(OPTION_EXTENSION);
// FIXME not if DHT disabled
dout.writeLong(OPTION_EXTENSION | OPTION_DHT);
// Handshake write - metainfo hash
byte[] shared_hash = metainfo.getInfoHash();
dout.write(shared_hash);
@ -343,7 +350,7 @@ public class Peer implements Comparable
_log.debug("Read the remote side's hash and peerID fully from " + toString());
if (options != 0) {
// send them something
// send them something in runConnection() above
if (_log.shouldLog(Log.DEBUG))
_log.debug("Peer supports options 0x" + Long.toString(options, 16) + ": " + toString());
}
@ -351,6 +358,11 @@ public class Peer implements Comparable
return bs;
}
/** @since 0.8.4 */
public long getOptions() {
return options;
}
public boolean isConnected()
{
return state != null;

View File

@ -171,6 +171,11 @@ class PeerConnectionIn implements Runnable
if (_log.shouldLog(Log.DEBUG))
_log.debug("Received cancel(" + piece + "," + begin + ") from " + peer + " on " + peer.metainfo.getName());
break;
case 9: // PORT message
int port = din.readUnsignedShort();
ps.portMessage(port);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Received port message from " + peer + " on " + peer.metainfo.getName());
case 20: // Extension message
int id = din.readUnsignedByte();
byte[] payload = new byte[i-2];

View File

@ -547,4 +547,12 @@ class PeerConnectionOut implements Runnable
m.len = bytes.length;
addMessage(m);
}
/** @since 0.8.4 */
void sendPort(int port) {
Message m = new Message();
m.type = Message.PORT;
m.piece = port;
addMessage(m);
}
}

View File

@ -1086,6 +1086,12 @@ public class PeerCoordinator implements PeerListener
}
}
/** @since 0.8.4 */
public void gotExtension(Peer peer, int id, byte[] bs) {}
/** @since 0.8.4 */
public void gotPort(Peer peer, int port) {}
/** Return number of allowed uploaders for this torrent.
** Check with Snark to see if we are over the total upload limit.
*/

View File

@ -179,4 +179,23 @@ interface PeerListener
* @since 0.8.2
*/
PartialPiece getPartialPiece(Peer peer, BitField havePieces);
/**
* Called when an extension message is received.
*
* @param peer the Peer that got the message.
* @param id the message ID
* @param bs the message payload
* @since 0.8.4
*/
void gotExtension(Peer peer, int id, byte[] bs);
/**
* Called when an extension message is received.
*
* @param peer the Peer that got the message.
* @param port the port
* @since 0.8.4
*/
void gotPort(Peer peer, int port);
}

View File

@ -32,9 +32,6 @@ import java.util.Set;
import net.i2p.I2PAppContext;
import net.i2p.util.Log;
import org.klomp.snark.bencode.BDecoder;
import org.klomp.snark.bencode.BEValue;
class PeerState implements DataLoader
{
private final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(PeerState.class);
@ -485,22 +482,13 @@ class PeerState implements DataLoader
/** @since 0.8.2 */
void extensionMessage(int id, byte[] bs)
{
if (id == 0) {
InputStream is = new ByteArrayInputStream(bs);
try {
BDecoder dec = new BDecoder(is);
BEValue bev = dec.bdecodeMap();
Map map = bev.getMap();
if (_log.shouldLog(Log.DEBUG))
_log.debug("Got extension handshake message " + bev.toString());
} catch (Exception e) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Failed extension decode", e);
}
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Got extended message type: " + id + " length: " + bs.length);
}
listener.gotExtension(peer, id, bs);
}
/** @since 0.8.4 */
void portMessage(int port)
{
listener.gotPort(peer, port);
}
void unknownMessage(int type, byte[] bs)