Disable PEX/metadata extensions and open trackers for private torrents

Handle announce URLs with parameters correctly
This commit is contained in:
zzz
2012-02-18 17:58:54 +00:00
parent c957577e72
commit 295242316b
5 changed files with 49 additions and 24 deletions

View File

@ -39,15 +39,19 @@ abstract class ExtensionHandler {
/**
* @param metasize -1 if unknown
* @param pexAndMetadata advertise these capabilities
* @return bencoded outgoing handshake message
*/
public static byte[] getHandshake(int metasize) {
public static byte[] getHandshake(int metasize, boolean pexAndMetadata) {
Map<String, Object> handshake = new HashMap();
Map<String, Integer> m = new HashMap();
m.put(TYPE_METADATA, Integer.valueOf(ID_METADATA));
m.put(TYPE_PEX, Integer.valueOf(ID_PEX));
if (metasize >= 0)
handshake.put("metadata_size", Integer.valueOf(metasize));
if (pexAndMetadata) {
m.put(TYPE_METADATA, Integer.valueOf(ID_METADATA));
m.put(TYPE_PEX, Integer.valueOf(ID_PEX));
if (metasize >= 0)
handshake.put("metadata_size", Integer.valueOf(metasize));
}
// include the map even if empty so the far-end doesn't NPE
handshake.put("m", m);
handshake.put("p", Integer.valueOf(6881));
handshake.put("v", "I2PSnark");

View File

@ -268,7 +268,8 @@ public class Peer implements Comparable
if (_log.shouldLog(Log.DEBUG))
_log.debug("Peer supports extensions, sending reply message");
int metasize = metainfo != null ? metainfo.getInfoBytes().length : -1;
out.sendExtension(0, ExtensionHandler.getHandshake(metasize));
boolean pexAndMetadata = metainfo == null || !metainfo.isPrivate();
out.sendExtension(0, ExtensionHandler.getHandshake(metasize, pexAndMetadata));
}
if ((options & OPTION_I2P_DHT) != 0 && util.getDHT() != null) {

View File

@ -1186,6 +1186,8 @@ public class PeerCoordinator implements PeerListener
* @since 0.8.4
*/
void sendPeers(Peer peer) {
if (metainfo != null && metainfo.isPrivate())
return;
Map<String, BEValue> handshake = peer.getHandshakeMap();
if (handshake == null)
return;

View File

@ -489,6 +489,13 @@ class PeerState implements DataLoader
/** @since 0.8.2 */
void extensionMessage(int id, byte[] bs)
{
if (metainfo != null && metainfo.isPrivate() &&
(id == ExtensionHandler.ID_METADATA || id == ExtensionHandler.ID_PEX)) {
// shouldn't get this since we didn't advertise it but they could send it anyway
if (_log.shouldLog(Log.WARN))
_log.warn("Private torrent, ignoring ext msg " + id);
return;
}
ExtensionHandler.handleMessage(peer, listener, id, bs);
// Peer coord will get metadata from MagnetState,
// verify, and then call gotMetaInfo()

View File

@ -156,7 +156,7 @@ public class TrackerClient extends I2PAppThread
primary = "";
}
List tlist = _util.getOpenTrackers();
if (tlist != null) {
if (tlist != null && !meta.isPrivate()) {
for (int i = 0; i < tlist.size(); i++) {
String url = (String)tlist.get(i);
if (!isValidAnnounce(url)) {
@ -348,7 +348,7 @@ public class TrackerClient extends I2PAppThread
} // *** end of trackers loop here
// Get peers from PEX
if (left > 0 && coordinator.needPeers() && !stop) {
if (left > 0 && coordinator.needPeers() && (!meta.isPrivate()) && !stop) {
Set<PeerID> pids = coordinator.getPEXPeers();
if (!pids.isEmpty()) {
_util.debug("Got " + pids.size() + " from PEX", Snark.INFO);
@ -370,7 +370,7 @@ public class TrackerClient extends I2PAppThread
// Get peers from DHT
// FIXME this needs to be in its own thread
if (_util.getDHT() != null && !stop) {
if (_util.getDHT() != null && (!meta.isPrivate()) && !stop) {
int numwant;
if (left == 0 || event.equals(STOPPED_EVENT) || !coordinator.needPeers())
numwant = 1;
@ -444,22 +444,33 @@ public class TrackerClient extends I2PAppThread
long downloaded, long left, String event)
throws IOException
{
// What do we send for left in magnet mode? Can we omit it?
long tleft = left >= 0 ? left : 1;
String s = tr.announce
+ "?info_hash=" + infoHash
+ "&peer_id=" + peerID
+ "&port=" + port
+ "&ip=" + _util.getOurIPString() + ".i2p"
+ "&uploaded=" + uploaded
+ "&downloaded=" + downloaded
+ "&left=" + tleft
+ "&compact=1" // NOTE: opentracker will return 400 for &compact alone
+ ((! event.equals(NO_EVENT)) ? ("&event=" + event) : "");
if (left == 0 || event.equals(STOPPED_EVENT) || !coordinator.needPeers())
s += "&numwant=0";
StringBuilder buf = new StringBuilder(512);
buf.append(tr.announce);
if (tr.announce.contains("?"))
buf.append('&');
else
s += "&numwant=" + _util.getMaxConnections();
buf.append('?');
buf.append("info_hash=").append(infoHash)
.append("&peer_id=").append(peerID)
.append("&port=").append(port)
.append("&ip=" ).append(_util.getOurIPString()).append(".i2p")
.append("&uploaded=").append(uploaded)
.append("&downloaded=").append(downloaded)
.append("&left=");
// What do we send for left in magnet mode? Can we omit it?
if (left >= 0)
buf.append(left);
else
buf.append('1');
buf.append("&compact=1"); // NOTE: opentracker will return 400 for &compact alone
if (! event.equals(NO_EVENT))
buf.append("&event=").append(event);
buf.append("&numwant=");
if (left == 0 || event.equals(STOPPED_EVENT) || !coordinator.needPeers())
buf.append('0');
else
buf.append(_util.getMaxConnections());
String s = buf.toString();
_util.debug("Sending TrackerClient request: " + s, Snark.INFO);
tr.lastRequestTime = System.currentTimeMillis();