diff --git a/apps/i2psnark/java/src/org/klomp/snark/Peer.java b/apps/i2psnark/java/src/org/klomp/snark/Peer.java
index 3958aed461..0dbd23bbb6 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/Peer.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/Peer.java
@@ -104,7 +104,10 @@ public class Peer implements Comparable
*/
public String toString()
{
- return peerID.toString() + _id;
+ if (peerID != null)
+ return peerID.toString() + _id;
+ else
+ return "[unknown id]" + _id;
}
/**
@@ -163,13 +166,16 @@ public class Peer implements Comparable
if (din == null)
{
sock = I2PSnarkUtil.instance().connect(peerID);
+ _log.debug("Connected to " + peerID + ": " + sock);
if ((sock == null) || (sock.isClosed())) {
throw new IOException("Unable to reach " + peerID);
}
- InputStream in = new BufferedInputStream(sock.getInputStream());
+ InputStream in = sock.getInputStream();
OutputStream out = sock.getOutputStream(); //new BufferedOutputStream(sock.getOutputStream());
- if (true)
+ if (true) {
out = new BufferedOutputStream(out);
+ in = new BufferedInputStream(sock.getInputStream());
+ }
//BufferedInputStream bis
// = new BufferedInputStream(sock.getInputStream());
//BufferedOutputStream bos
@@ -181,6 +187,9 @@ public class Peer implements Comparable
+ PeerID.idencode(id)
+ "' expected '"
+ PeerID.idencode(expected_id) + "'");
+ _log.debug("Handshake got matching IDs with " + toString());
+ } else {
+ _log.debug("Already have din [" + sock + "] with " + toString());
}
PeerConnectionIn in = new PeerConnectionIn(this, din);
@@ -195,8 +204,10 @@ public class Peer implements Comparable
state = s;
listener.connected(this);
+ _log.debug("Start running the reader with " + toString());
// Use this thread for running the incomming connection.
- // The outgoing connection has created its own Thread.
+ // The outgoing connection creates its own Thread.
+ out.startup();
s.in.run();
}
catch(IOException eofe)
@@ -241,6 +252,8 @@ public class Peer implements Comparable
dout.write(my_id);
dout.flush();
+ _log.debug("Wrote my shared hash and ID to " + toString());
+
// Handshake read - header
byte b = din.readByte();
if (b != 19)
@@ -266,6 +279,7 @@ public class Peer implements Comparable
// Handshake read - peer id
din.readFully(bs);
+ _log.debug("Read the remote side's hash and peerID fully from " + toString());
return bs;
}
diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerAcceptor.java b/apps/i2psnark/java/src/org/klomp/snark/PeerAcceptor.java
index 9e12db6ce2..e54d91b9cc 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/PeerAcceptor.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/PeerAcceptor.java
@@ -63,15 +63,22 @@ public class PeerAcceptor
// ahead the first $LOOKAHEAD_SIZE bytes to figure out which infohash they want to
// talk about, and we can just look for that in our list of active torrents.
byte peerInfoHash[] = null;
- try {
- peerInfoHash = readHash(in);
- _log.info("infohash read from " + socket.getPeerDestination().calculateHash().toBase64()
- + ": " + Base64.encode(peerInfoHash));
- } catch (IOException ioe) {
- _log.info("Unable to read the infohash from " + socket.getPeerDestination().calculateHash().toBase64());
- throw ioe;
+ if (in instanceof BufferedInputStream) {
+ in.mark(LOOKAHEAD_SIZE);
+ peerInfoHash = readHash(in);
+ in.reset();
+ } else {
+ // is this working right?
+ try {
+ peerInfoHash = readHash(in);
+ _log.info("infohash read from " + socket.getPeerDestination().calculateHash().toBase64()
+ + ": " + Base64.encode(peerInfoHash));
+ } catch (IOException ioe) {
+ _log.info("Unable to read the infohash from " + socket.getPeerDestination().calculateHash().toBase64());
+ throw ioe;
+ }
+ in = new SequenceInputStream(new ByteArrayInputStream(peerInfoHash), in);
}
- in = new SequenceInputStream(new ByteArrayInputStream(peerInfoHash), in);
if (coordinator != null) {
// single torrent capability
MetaInfo meta = coordinator.getMetaInfo();
diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java b/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java
index 8bbeb71723..7494daa31f 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java
@@ -53,6 +53,9 @@ class PeerConnectionOut implements Runnable
lastSent = System.currentTimeMillis();
quit = false;
+ }
+
+ public void startup() {
thread = new I2PThread(this, "Snark sender " + _id);
thread.start();
}
@@ -63,6 +66,7 @@ class PeerConnectionOut implements Runnable
*/
public void run()
{
+ try { Thread.sleep(1000); } catch (InterruptedException ie) {}
try
{
while (!quit && peer.isConnected())
diff --git a/apps/i2psnark/java/src/org/klomp/snark/Storage.java b/apps/i2psnark/java/src/org/klomp/snark/Storage.java
index 5a6690574d..b9eb7914b9 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/Storage.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/Storage.java
@@ -129,7 +129,7 @@ public class Storage
}
// Creates piece hases for a new storage.
- private void create() throws IOException
+ public void create() throws IOException
{
if (true) {
fast_digestCreate();
diff --git a/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java b/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java
index c29d2015e6..57b34d04ad 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java
@@ -209,7 +209,9 @@ public class TrackerClient extends I2PThread
if ( (left > 0) && (!completed) ) {
// we only want to talk to new people if we need things
// from them (duh)
- Iterator it = peers.iterator();
+ List ordered = new ArrayList(peers);
+ Collections.shuffle(ordered);
+ Iterator it = ordered.iterator();
while (it.hasNext()) {
Peer cur = (Peer)it.next();
coordinator.addPeer(cur);
diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
index 4df41ff30f..a9a6852965 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
@@ -80,6 +80,8 @@ public class I2PSnarkServlet extends HttpServlet {
out.write(TABLE_FOOTER);
writeAddForm(out, req);
+ if (false) // seeding needs to register the torrent first (boo, hiss)
+ writeSeedForm(out, req);
writeConfigForm(out, req);
out.write(FOOTER);
}
@@ -227,6 +229,36 @@ public class I2PSnarkServlet extends HttpServlet {
String i2cpPort = req.getParameter("i2cpPort");
String i2cpOpts = req.getParameter("i2cpOpts");
_manager.updateConfig(dataDir, autoStart, seedPct, eepHost, eepPort, i2cpHost, i2cpPort, i2cpOpts);
+ } else if ("Create torrent".equals(action)) {
+ String baseData = req.getParameter("baseFile");
+ if (baseData != null) {
+ File baseFile = new File(_manager.getDataDir(), baseData);
+ String announceURL = req.getParameter("announceURL");
+ String announceURLOther = req.getParameter("announceURLOther");
+ if ( (announceURLOther != null) && (announceURLOther.trim().length() > "http://.i2p/announce".length()) )
+ announceURL = announceURLOther;
+
+ if (baseFile.exists()) {
+ try {
+ Storage s = new Storage(baseFile, announceURL, null);
+ s.create();
+ MetaInfo info = s.getMetaInfo();
+ File torrentFile = new File(baseFile.getParent(), baseFile.getName() + ".torrent");
+ if (torrentFile.exists())
+ throw new IOException("Cannot overwrite an existing .torrent file: " + torrentFile.getPath());
+ FileOutputStream out = new FileOutputStream(torrentFile);
+ out.write(info.getTorrentData());
+ out.close();
+ _manager.addMessage("Torrent created for " + baseFile.getName() + ": " + torrentFile.getAbsolutePath());
+ // now fire it up and seed away!
+ _manager.addTorrent(torrentFile.getCanonicalPath());
+ } catch (IOException ioe) {
+ _manager.addMessage("Error creating a torrent for " + baseFile.getAbsolutePath() + ": " + ioe.getMessage());
+ }
+ } else {
+ _manager.addMessage("Cannot create a torrent for the nonexistant data: " + baseFile.getAbsolutePath());
+ }
+ }
}
}
@@ -399,7 +431,36 @@ public class I2PSnarkServlet extends HttpServlet {
out.write("
\n");
out.write("Alternately, you can copy .torrent files to " + _manager.getDataDir().getAbsolutePath() + "
\n");
out.write("Removing that .torrent file will cause the torrent to stop.
\n");
- out.write("\n\n");
+ out.write("\n\n");
+ }
+
+ private static final String DEFAULT_TRACKERS[] = {
+ "Postman's tracker", "http://YRgrgTLGnbTq2aZOZDJQ~o6Uk5k6TK-OZtx0St9pb0G-5EGYURZioxqYG8AQt~LgyyI~NCj6aYWpPO-150RcEvsfgXLR~CxkkZcVpgt6pns8SRc3Bi-QSAkXpJtloapRGcQfzTtwllokbdC-aMGpeDOjYLd8b5V9Im8wdCHYy7LRFxhEtGb~RL55DA8aYOgEXcTpr6RPPywbV~Qf3q5UK55el6Kex-6VCxreUnPEe4hmTAbqZNR7Fm0hpCiHKGoToRcygafpFqDw5frLXToYiqs9d4liyVB-BcOb0ihORbo0nS3CLmAwZGvdAP8BZ7cIYE3Z9IU9D1G8JCMxWarfKX1pix~6pIA-sp1gKlL1HhYhPMxwyxvuSqx34o3BqU7vdTYwWiLpGM~zU1~j9rHL7x60pVuYaXcFQDR4-QVy26b6Pt6BlAZoFmHhPcAuWfu-SFhjyZYsqzmEmHeYdAwa~HojSbofg0TMUgESRXMw6YThK1KXWeeJVeztGTz25sL8AAAA.i2p/announce.php",
+ "Orion's tracker", "http://gKik1lMlRmuroXVGTZ~7v4Vez3L3ZSpddrGZBrxVriosCQf7iHu6CIk8t15BKsj~P0JJpxrofeuxtm7SCUAJEr0AIYSYw8XOmp35UfcRPQWyb1LsxUkMT4WqxAT3s1ClIICWlBu5An~q-Mm0VFlrYLIPBWlUFnfPR7jZ9uP5ZMSzTKSMYUWao3ejiykr~mtEmyls6g-ZbgKZawa9II4zjOy-hdxHgP-eXMDseFsrym4Gpxvy~3Fv9TuiSqhpgm~UeTo5YBfxn6~TahKtE~~sdCiSydqmKBhxAQ7uT9lda7xt96SS09OYMsIWxLeQUWhns-C~FjJPp1D~IuTrUpAFcVEGVL-BRMmdWbfOJEcWPZ~CBCQSO~VkuN1ebvIOr9JBerFMZSxZtFl8JwcrjCIBxeKPBmfh~xYh16BJm1BBBmN1fp2DKmZ2jBNkAmnUbjQOqWvUcehrykWk5lZbE7bjJMDFH48v3SXwRuDBiHZmSbsTY6zhGY~GkMQHNGxPMMSIAAAA.i2p/bt",
+ "The freak's tracker", "http://mHKva9x24E5Ygfey2llR1KyQHv5f8hhMpDMwJDg1U-hABpJ2NrQJd6azirdfaR0OKt4jDlmP2o4Qx0H598~AteyD~RJU~xcWYdcOE0dmJ2e9Y8-HY51ie0B1yD9FtIV72ZI-V3TzFDcs6nkdX9b81DwrAwwFzx0EfNvK1GLVWl59Ow85muoRTBA1q8SsZImxdyZ-TApTVlMYIQbdI4iQRwU9OmmtefrCe~ZOf4UBS9-KvNIqUL0XeBSqm0OU1jq-D10Ykg6KfqvuPnBYT1BYHFDQJXW5DdPKwcaQE4MtAdSGmj1epDoaEBUa9btQlFsM2l9Cyn1hzxqNWXELmx8dRlomQLlV4b586dRzW~fLlOPIGC13ntPXogvYvHVyEyptXkv890jC7DZNHyxZd5cyrKC36r9huKvhQAmNABT2Y~pOGwVrb~RpPwT0tBuPZ3lHYhBFYmD8y~AOhhNHKMLzea1rfwTvovBMByDdFps54gMN1mX4MbCGT4w70vIopS9yAAAA.i2p/bytemonsoon/announce.php"
+ };
+ private void writeSeedForm(PrintWriter out, HttpServletRequest req) throws IOException {
+ String uri = req.getRequestURI();
+ String baseFile = req.getParameter("baseFile");
+ if (baseFile == null)
+ baseFile = "";
+
+ out.write("\n");
+ // *not* enctype="multipart/form-data", so that the input type=file sends the filename, not the file
+ out.write("\n\n");
}
private void writeConfigForm(PrintWriter out, HttpServletRequest req) throws IOException {
diff --git a/apps/syndie/java/src/net/i2p/syndie/User.java b/apps/syndie/java/src/net/i2p/syndie/User.java
index 3892cccc04..5d1f50ead7 100644
--- a/apps/syndie/java/src/net/i2p/syndie/User.java
+++ b/apps/syndie/java/src/net/i2p/syndie/User.java
@@ -49,7 +49,8 @@ public class User {
private static final String DEFAULT_FAVORITE_TAGS[] = {
"syndie", "syndie.tech", "syndie.intro", "syndie.bugs", "syndie.featurerequest", "syndie.announce",
- "i2p", "i2p.tech", "i2p.bugs", "i2p.i2phex", "i2p.susimail", "i2p.irc",
+ "i2p", "i2p.tech", "i2p.bugs", "i2p.i2phex", "i2p.susimail", "i2p.irc",
+ "bt.i2psnark", "bt.i2prufus", "bt.i2p-bt", "bt.azureus", "bt.misc",
"security.misc",
"chat",
"test"
diff --git a/apps/syndie/java/src/net/i2p/syndie/web/BaseServlet.java b/apps/syndie/java/src/net/i2p/syndie/web/BaseServlet.java
index 0458a6a0ad..d74b2a97f9 100644
--- a/apps/syndie/java/src/net/i2p/syndie/web/BaseServlet.java
+++ b/apps/syndie/java/src/net/i2p/syndie/web/BaseServlet.java
@@ -330,7 +330,8 @@ public abstract class BaseServlet extends HttpServlet {
(AddressesServlet.ACTION_DELETE_OTHER.equals(action)) ||
(AddressesServlet.ACTION_DELETE_TAG.equals(action)) ||
(AddressesServlet.ACTION_DELETE_PEER.equals(action)) ) {
- PetName pn = user.getPetNameDB().getByName(req.getParameter(AddressesServlet.PARAM_NAME));
+ String name = req.getParameter(AddressesServlet.PARAM_NAME);
+ PetName pn = user.getPetNameDB().getByName(name);
if (pn != null) {
user.getPetNameDB().remove(pn);
BlogManager.instance().saveUser(user);
@@ -580,7 +581,7 @@ public abstract class BaseServlet extends HttpServlet {
//out.write("