* i2psnark:

- Improved magnet link parsing, use tr parameter if present
This commit is contained in:
zzz
2011-02-10 17:12:15 +00:00
parent 03bc4fc133
commit ae9c160734
6 changed files with 89 additions and 24 deletions

View File

@ -254,6 +254,7 @@ public class Snark
private boolean stopped;
private byte[] id;
private byte[] infoHash;
private String additionalTrackerURL;
private final I2PSnarkUtil _util;
private final PeerCoordinatorSet _peerCoordinatorSet;
private String trackerProblems;
@ -453,9 +454,10 @@ public class Snark
*
* @param torrent a fake name for now (not a file name)
* @param ih 20-byte info hash
* @param trackerURL may be null
* @since 0.8.4
*/
public Snark(I2PSnarkUtil util, String torrent, byte[] ih,
public Snark(I2PSnarkUtil util, String torrent, byte[] ih, String trackerURL,
CompleteListener complistener, PeerCoordinatorSet peerCoordinatorSet,
ConnectionAcceptor connectionAcceptor, boolean start, String rootDir)
{
@ -465,6 +467,7 @@ public class Snark
acceptor = connectionAcceptor;
this.torrent = torrent;
this.infoHash = ih;
this.additionalTrackerURL = trackerURL;
this.rootDataDir = rootDir;
stopped = true;
id = generateID();
@ -535,7 +538,7 @@ public class Snark
acceptor = new ConnectionAcceptor(_util, serversocket, new PeerAcceptor(coordinator));
}
// TODO pass saved closest DHT nodes to the tracker? or direct to the coordinator?
trackerclient = new TrackerClient(_util, meta, coordinator, this);
trackerclient = new TrackerClient(_util, meta, additionalTrackerURL, coordinator, this);
}
stopped = false;
@ -564,11 +567,13 @@ public class Snark
fatal("Could not reopen storage", ioe);
}
}
TrackerClient newClient = new TrackerClient(_util, meta, coordinator, this);
TrackerClient newClient = new TrackerClient(_util, meta, additionalTrackerURL, coordinator, this);
if (!trackerclient.halted())
trackerclient.halt();
trackerclient = newClient;
trackerclient.start();
} else {
debug("NOT starting TrackerClient???", NOTICE);
}
}
/**
@ -825,6 +830,14 @@ public class Snark
return true;
}
/**
* @return trackerURL string from magnet-mode constructor, may be null
* @since 0.8.4
*/
public String getTrackerURL() {
return additionalTrackerURL;
}
/**
* Sets debug, ip and torrent variables then creates a Snark
* instance. Calls usage(), which terminates the program, if

View File

@ -643,11 +643,15 @@ public class SnarkManager implements Snark.CompleteListener {
*
* @param name hex or b32 name from the magnet link
* @param ih 20 byte info hash
* @param trackerURL may be null
* @param udpateStatus should we add this magnet to the config file,
* to save it across restarts, in case we don't get
* the metadata before shutdown?
* @throws RuntimeException via Snark.fatal()
* @since 0.8.4
*/
public void addMagnet(String name, byte[] ih, boolean updateStatus) {
Snark torrent = new Snark(_util, name, ih, this,
public void addMagnet(String name, byte[] ih, String trackerURL, boolean updateStatus) {
Snark torrent = new Snark(_util, name, ih, trackerURL, this,
_peerCoordinatorSet, _connectionAcceptor,
false, getDataDir().getPath());
@ -1151,6 +1155,10 @@ public class SnarkManager implements Snark.CompleteListener {
saveTorrentStatus(meta, storage.getBitField(), null); // no file priorities
String name = (new File(getDataDir(), storage.getBaseName() + ".torrent")).getAbsolutePath();
try {
// put the announce URL in the file
String announce = snark.getTrackerURL();
if (announce != null)
meta = meta.reannounce(announce);
synchronized (_snarks) {
locked_writeMetaInfo(meta, name);
// put it in the list under the new name
@ -1183,9 +1191,9 @@ public class SnarkManager implements Snark.CompleteListener {
String b64 = k.substring(PROP_META_MAGNET_PREFIX.length());
b64 = b64.replace('$', '=');
byte[] ih = Base64.decode(b64);
// ignore value
// ignore value - TODO put tracker URL in value
if (ih != null && ih.length == 20)
addMagnet("Magnet: " + I2PSnarkUtil.toHex(ih), ih, false);
addMagnet("Magnet: " + I2PSnarkUtil.toHex(ih), ih, null, false);
// else remove from config?
}
}

View File

@ -65,6 +65,7 @@ public class TrackerClient extends I2PAppThread
private I2PSnarkUtil _util;
private final MetaInfo meta;
private final String additionalTrackerURL;
private final PeerCoordinator coordinator;
private final Snark snark;
private final int port;
@ -76,8 +77,10 @@ public class TrackerClient extends I2PAppThread
/**
* @param meta null if in magnet mode
* @param additionalTrackerURL may be null, from the ?tr= param in magnet mode, otherwise ignored
*/
public TrackerClient(I2PSnarkUtil util, MetaInfo meta, PeerCoordinator coordinator, Snark snark)
public TrackerClient(I2PSnarkUtil util, MetaInfo meta, String additionalTrackerURL,
PeerCoordinator coordinator, Snark snark)
{
super();
// Set unique name.
@ -85,13 +88,11 @@ public class TrackerClient extends I2PAppThread
setName("TrackerClient " + id.substring(id.length() - 12));
_util = util;
this.meta = meta;
this.additionalTrackerURL = additionalTrackerURL;
this.coordinator = coordinator;
this.snark = snark;
this.port = 6881; //(port == -1) ? 9 : port;
stop = false;
started = false;
}
@Override
@ -138,17 +139,21 @@ public class TrackerClient extends I2PAppThread
// todo: check for b32 matches as well
trackers = new ArrayList(2);
String primary = null;
if (meta != null) {
if (meta != null)
primary = meta.getAnnounce();
else if (additionalTrackerURL != null)
primary = additionalTrackerURL;
if (primary != null) {
if (isValidAnnounce(primary)) {
trackers.add(new Tracker(meta.getAnnounce(), true));
trackers.add(new Tracker(primary, true));
_log.debug("Announce: [" + primary + "] infoHash: " + infoHash);
} else {
_log.warn("Skipping invalid or non-i2p announce: " + primary);
}
}
if (primary == null)
} else {
_log.warn("No primary announce");
primary = "";
}
List tlist = _util.getOpenTrackers();
if (tlist != null) {
for (int i = 0; i < tlist.size(); i++) {

View File

@ -65,7 +65,8 @@ public class I2PSnarkServlet extends Default {
public static final String PROP_CONFIG_FILE = "i2psnark.configFile";
/** BEP 9 */
private static final String MAGNET = "magnet:?xt=urn:btih:";
private static final String MAGNET = "magnet:";
private static final String MAGNET_FULL = MAGNET + "?xt=urn:btih:";
/** http://sponge.i2p/files/maggotspec.txt */
private static final String MAGGOT = "maggot://";
@ -1406,13 +1407,22 @@ public class I2PSnarkServlet extends Default {
private void addMagnet(String url) {
String ihash;
String name;
String trackerURL = null;
if (url.startsWith(MAGNET)) {
ihash = url.substring(MAGNET.length()).trim();
int amp = ihash.indexOf('&');
if (amp >= 0)
ihash = ihash.substring(0, amp);
// magnet:?xt=urn:btih:0691e40aae02e552cfcb57af1dca56214680c0c5&tr=http://tracker2.postman.i2p/announce.php
String xt = getParam("xt", url);
if (xt == null || !xt.startsWith("urn:btih:")) {
_manager.addMessage(_("Invalid magnet URL {0}", url));
return;
}
ihash = xt.substring("urn:btih:".length());
trackerURL = getParam("tr", url);
name = "Magnet " + ihash;
String dn = getParam("dn", url);
if (dn != null)
name += " (" + Storage.filterName(dn) + ')';
} else if (url.startsWith(MAGGOT)) {
// maggot://0691e40aae02e552cfcb57af1dca56214680c0c5:0b557bbdf8718e95d352fbe994dec3a383e2ede7
ihash = url.substring(MAGGOT.length()).trim();
int col = ihash.indexOf(':');
if (col >= 0)
@ -1439,7 +1449,27 @@ public class I2PSnarkServlet extends Default {
_manager.addMessage(_("Invalid info hash in magnet URL {0}", url));
return;
}
_manager.addMagnet(name, ih, true);
_manager.addMagnet(name, ih, trackerURL, true);
}
private static String getParam(String key, String uri) {
int idx = uri.indexOf('?' + key + '=');
if (idx >= 0) {
idx += key.length() + 2;
} else {
idx = uri.indexOf('&' + key + '=');
if (idx >= 0)
idx += key.length() + 2;
}
if (idx < 0 || idx > uri.length())
return null;
String rv = uri.substring(idx);
idx = rv.indexOf('&');
if (idx >= 0)
rv = rv.substring(0, idx);
else
rv = rv.trim();
return rv;
}
/** copied from ConfigTunnelsHelper */
@ -1644,8 +1674,8 @@ public class I2PSnarkServlet extends Default {
String hex = I2PSnarkUtil.toHex(snark.getInfoHash());
buf.append("<br>").append(toImg("magnet", _("Magnet link"))).append(" <a href=\"")
.append(MAGNET).append(hex).append("\">")
.append(MAGNET).append(hex).append("</a>");
.append(MAGNET_FULL).append(hex).append("\">")
.append(MAGNET_FULL).append(hex).append("</a>");
// We don't have the hash of the torrent file
//buf.append("<br>").append(_("Maggot link")).append(": <a href=\"").append(MAGGOT).append(hex).append(':').append(hex).append("\">")
// .append(MAGGOT).append(hex).append(':').append(hex).append("</a>");

View File

@ -1,3 +1,12 @@
2011-02-10 zzz
* I2CP: Correctly close internal connections on the router side
when closed by the client, was causing massive memory leak
for internal clients using lots of sessions (thanks sponge)
* i2psnark:
- Improved magnet link parsing, use tr parameter if present
* i2ptunnel: Change shared clients default for new clients to false
* Streaming: Don't use iter.remove() on a COWAS
2011-02-09 sponge
* BOB: fixup delivery in config, adds config file versioning.
* I2CP: Fix most of the I2CP leaks. Two leaks remain, but they are small.

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */
public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 5;
public final static long BUILD = 6;
/** for example "-test" */
public final static String EXTRA = "";