forked from I2P_Developers/i2p.i2p
The build in tracker has been removed for simplicity.
Example usage:
java -jar lib/i2psnark.jar myFile.torrent
or, a more verbose setting:
java -jar lib/i2psnark.jar --eepproxy 127.0.0.1 4444 \
--i2cp 127.0.0.1 7654 "inbound.length=2 outbound.length=2" \
--debug 6 myFile.torrent
166 lines
4.8 KiB
Java
166 lines
4.8 KiB
Java
package org.klomp.snark;
|
|
|
|
import net.i2p.I2PAppContext;
|
|
import net.i2p.I2PException;
|
|
import net.i2p.util.EepGet;
|
|
import net.i2p.data.Base64;
|
|
import net.i2p.data.DataFormatException;
|
|
import net.i2p.data.Destination;
|
|
import net.i2p.client.streaming.I2PServerSocket;
|
|
import net.i2p.client.streaming.I2PSocket;
|
|
import net.i2p.client.streaming.I2PSocketManager;
|
|
import net.i2p.client.streaming.I2PSocketManagerFactory;
|
|
import net.i2p.util.Log;
|
|
|
|
import java.io.*;
|
|
import java.util.Properties;
|
|
|
|
/**
|
|
* I2P specific helpers for I2PSnark
|
|
*/
|
|
public class I2PSnarkUtil {
|
|
private I2PAppContext _context;
|
|
private Log _log;
|
|
private static I2PSnarkUtil _instance = new I2PSnarkUtil();
|
|
public static I2PSnarkUtil instance() { return _instance; }
|
|
|
|
private boolean _shouldProxy;
|
|
private String _proxyHost;
|
|
private int _proxyPort;
|
|
private String _i2cpHost;
|
|
private int _i2cpPort;
|
|
private Properties _opts;
|
|
private I2PSocketManager _manager;
|
|
|
|
private I2PSnarkUtil() {
|
|
_context = I2PAppContext.getGlobalContext();
|
|
_log = _context.logManager().getLog(Snark.class);
|
|
setProxy("127.0.0.1", 4444);
|
|
setI2CPConfig("127.0.0.1", 7654, null);
|
|
}
|
|
|
|
/**
|
|
* Specify what HTTP proxy tracker requests should go through (specify a null
|
|
* host for no proxying)
|
|
*
|
|
*/
|
|
public void setProxy(String host, int port) {
|
|
if ( (host != null) && (port > 0) ) {
|
|
_shouldProxy = true;
|
|
_proxyHost = host;
|
|
_proxyPort = port;
|
|
} else {
|
|
_shouldProxy = false;
|
|
_proxyHost = null;
|
|
_proxyPort = -1;
|
|
}
|
|
}
|
|
|
|
public void setI2CPConfig(String i2cpHost, int i2cpPort, Properties opts) {
|
|
_i2cpHost = i2cpHost;
|
|
_i2cpPort = i2cpPort;
|
|
if (opts != null)
|
|
_opts = opts;
|
|
}
|
|
|
|
/**
|
|
* Connect to the router, if we aren't already
|
|
*/
|
|
boolean connect() {
|
|
if (_manager == null) {
|
|
_manager = I2PSocketManagerFactory.createManager(_i2cpHost, _i2cpPort, _opts);
|
|
}
|
|
return (_manager != null);
|
|
}
|
|
|
|
/** connect to the given destination */
|
|
I2PSocket connect(PeerID peer) throws IOException {
|
|
try {
|
|
return _manager.connect(peer.getAddress());
|
|
} catch (I2PException ie) {
|
|
throw new IOException("Unable to reach the peer " + peer + ": " + ie.getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* fetch the given URL, returning the file it is stored in, or null on error
|
|
*/
|
|
File get(String url) {
|
|
File out = null;
|
|
try {
|
|
out = File.createTempFile("i2psnark", "url");
|
|
} catch (IOException ioe) {
|
|
ioe.printStackTrace();
|
|
return null;
|
|
}
|
|
EepGet get = new EepGet(_context, _shouldProxy, _proxyHost, _proxyPort, 1, out.getAbsolutePath(), url);
|
|
if (get.fetch()) {
|
|
return out;
|
|
} else {
|
|
out.delete();
|
|
return null;
|
|
}
|
|
}
|
|
|
|
I2PServerSocket getServerSocket() {
|
|
return _manager.getServerSocket();
|
|
}
|
|
|
|
String getOurIPString() {
|
|
return _manager.getSession().getMyDestination().toBase64();
|
|
}
|
|
Destination getDestination(String ip) {
|
|
if (ip == null) return null;
|
|
if (ip.endsWith(".i2p")) {
|
|
Destination dest = _context.namingService().lookup(ip);
|
|
if (dest != null) {
|
|
return dest;
|
|
} else {
|
|
try {
|
|
return new Destination(ip.substring(0, ip.length()-4)); // sans .i2p
|
|
} catch (DataFormatException dfe) {
|
|
return null;
|
|
}
|
|
}
|
|
} else {
|
|
try {
|
|
return new Destination(ip);
|
|
} catch (DataFormatException dfe) {
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Given http://blah.i2p/foo/announce turn it into http://i2p/blah/foo/announce
|
|
*/
|
|
String rewriteAnnounce(String origAnnounce) {
|
|
int destStart = "http://".length();
|
|
int destEnd = origAnnounce.indexOf(".i2p");
|
|
int pathStart = origAnnounce.indexOf('/', destEnd);
|
|
return "http://i2p/" + origAnnounce.substring(destStart, destEnd) + origAnnounce.substring(pathStart);
|
|
}
|
|
|
|
/** hook between snark's logger and an i2p log */
|
|
void debug(String msg, int snarkDebugLevel, Throwable t) {
|
|
switch (snarkDebugLevel) {
|
|
case 0:
|
|
case 1:
|
|
_log.error(msg, t);
|
|
break;
|
|
case 2:
|
|
_log.warn(msg, t);
|
|
break;
|
|
case 3:
|
|
case 4:
|
|
_log.info(msg, t);
|
|
break;
|
|
case 5:
|
|
case 6:
|
|
default:
|
|
_log.debug(msg, t);
|
|
break;
|
|
}
|
|
}
|
|
}
|