diff --git a/Slackware/i2p-base/rc.i2p_def b/Slackware/i2p-base/rc.i2p_def
index 075e9e847..c231922e5 100644
--- a/Slackware/i2p-base/rc.i2p_def
+++ b/Slackware/i2p-base/rc.i2p_def
@@ -4,7 +4,7 @@
i2p_start() {
# Check if router is up first!
/bin/su - -c "( export PATH=\"$PATH:/usr/lib/java/bin:/usr/lib/java/jre/bin\"; directory status )" > /dev/null
- if [ ! $? -eq 0 ] ; then {
+ if [ $? -eq 0 ] ; then {
# I2p is already running, so tell the user.
echo "I2P is already running..."
i2p_status
diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerState.java b/apps/i2psnark/java/src/org/klomp/snark/PeerState.java
index 8ba5c8969..d649b8227 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/PeerState.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/PeerState.java
@@ -261,11 +261,16 @@ class PeerState implements DataLoader
// This is used to flag that we have to back up from the firstOutstandingRequest
// when calculating how far we've gotten
- Request pendingRequest = null;
+ private Request pendingRequest;
/**
- * Called when a partial piece request has been handled by
+ * Called when a full chunk (i.e. a piece message) has been received by
* PeerConnectionIn.
+ *
+ * This may block quite a while if it is the last chunk for a piece,
+ * as it calls the listener, who stores the piece and then calls
+ * havePiece for every peer on the torrent (including us).
+ *
*/
void pieceMessage(Request req)
{
@@ -273,11 +278,15 @@ class PeerState implements DataLoader
downloaded += size;
listener.downloaded(peer, size);
- pendingRequest = null;
+ if (_log.shouldLog(Log.DEBUG))
+ _log.debug("got end of Chunk("
+ + req.piece + "," + req.off + "," + req.len + ") from "
+ + peer);
// Last chunk needed for this piece?
if (getFirstOutstandingRequest(req.piece) == -1)
{
+ // warning - may block here for a while
if (listener.gotPiece(peer, req.piece, req.bs))
{
if (_log.shouldLog(Log.DEBUG))
@@ -288,9 +297,15 @@ class PeerState implements DataLoader
if (_log.shouldLog(Log.WARN))
_log.warn("Got BAD " + req.piece + " from " + peer);
// XXX ARGH What now !?!
+ // FIXME Why would we set downloaded to 0?
downloaded = 0;
}
}
+
+ // ok done with this one
+ synchronized(this) {
+ pendingRequest = null;
+ }
}
synchronized private int getFirstOutstandingRequest(int piece)
@@ -303,15 +318,16 @@ class PeerState implements DataLoader
/**
* Called when a piece message is being processed by the incoming
- * connection. Returns null when there was no such request. It also
+ * connection. That is, when the header of the piece message was received.
+ * Returns null when there was no such request. It also
* requeues/sends requests when it thinks that they must have been
* lost.
*/
Request getOutstandingRequest(int piece, int begin, int length)
{
if (_log.shouldLog(Log.DEBUG))
- _log.debug("getChunk("
- + piece + "," + begin + "," + length + ") "
+ _log.debug("got start of Chunk("
+ + piece + "," + begin + "," + length + ") from "
+ peer);
int r = getFirstOutstandingRequest(piece);
@@ -351,6 +367,9 @@ class PeerState implements DataLoader
downloaded = 0; // XXX - punishment?
return null;
}
+
+ // note that this request is being read
+ pendingRequest = req;
// Report missing requests.
if (r != 0)
@@ -374,13 +393,12 @@ class PeerState implements DataLoader
// Request more if necessary to keep the pipeline filled.
addRequest();
- pendingRequest = req;
return req;
}
// get longest partial piece
- Request getPartialRequest()
+ synchronized Request getPartialRequest()
{
Request req = null;
for (int i = 0; i < outstandingRequests.size(); i++) {
@@ -401,10 +419,13 @@ class PeerState implements DataLoader
return req;
}
- // return array of pieces terminated by -1
- // remove most duplicates
- // but still could be some duplicates, not guaranteed
- int[] getRequestedPieces()
+ /**
+ * return array of pieces terminated by -1
+ * remove most duplicates
+ * but still could be some duplicates, not guaranteed
+ * TODO rework this Java-style to return a Set or a List
+ */
+ synchronized int[] getRequestedPieces()
{
int size = outstandingRequests.size();
int[] arr = new int[size+2];
@@ -514,6 +535,8 @@ class PeerState implements DataLoader
* @since 0.8.1
*/
synchronized boolean isRequesting(int piece) {
+ if (pendingRequest != null && pendingRequest.piece == piece)
+ return true;
for (Request req : outstandingRequests) {
if (req.piece == piece)
return true;
@@ -616,6 +639,10 @@ class PeerState implements DataLoader
return true;
}
}
+
+ // Note that in addition to the bitfield, PeerCoordinator uses
+ // its request tracking and isRequesting() to determine
+ // what piece to give us next.
int nextPiece = listener.wantPiece(peer, bitfield);
if (nextPiece != -1
&& (lastRequest == null || lastRequest.piece != nextPiece)) {
diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
index 0545b9f55..41d0f0ec2 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
@@ -533,9 +533,9 @@ public class SnarkManager implements Snark.CompleteListener {
File f = new File(filename);
if (!dontAutoStart && shouldAutoStart()) {
torrent.startTorrent();
- addMessage(_("Torrent added and started: \"{0}\"", f.getName()));
+ addMessage(_("Torrent added and started: \"{0}\"", torrent.storage.getBaseName()));
} else {
- addMessage(_("Torrent added: \"{0}\"", f.getName()));
+ addMessage(_("Torrent added: \"{0}\"", torrent.storage.getBaseName()));
}
}
@@ -742,8 +742,14 @@ public class SnarkManager implements Snark.CompleteListener {
// I2PServerSocket.accept() call properly?)
////_util.
}
+ String name;
+ if (torrent.storage != null) {
+ name = torrent.storage.getBaseName();
+ } else {
+ name = sfile.getName();
+ }
if (!wasStopped)
- addMessage(_("Torrent stopped: \"{0}\"", sfile.getName()));
+ addMessage(_("Torrent stopped: \"{0}\"", name));
}
return torrent;
}
@@ -756,9 +762,14 @@ public class SnarkManager implements Snark.CompleteListener {
if (torrent != null) {
File torrentFile = new File(filename);
torrentFile.delete();
- if (torrent.storage != null)
+ String name;
+ if (torrent.storage != null) {
removeTorrentStatus(torrent.storage.getMetaInfo());
- addMessage(_("Torrent removed: \"{0}\"", torrentFile.getName()));
+ name = torrent.storage.getBaseName();
+ } else {
+ name = torrentFile.getName();
+ }
+ addMessage(_("Torrent removed: \"{0}\"", name));
}
}
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 b9f06c877..f49178b0f 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
@@ -163,7 +163,7 @@ public class I2PSnarkServlet extends Default {
String peerParam = req.getParameter("p");
String peerString;
- if (peerParam == null) {
+ if (peerParam == null || !_manager.util().connected()) {
peerString = "";
} else {
peerString = "?p=" + peerParam;
@@ -248,6 +248,9 @@ public class I2PSnarkServlet extends Default {
out.write(uri);
out.write("\" method=\"POST\">\n");
out.write("\n");
+ // don't lose peer setting
+ if (peerParam != null)
+ out.write("\n");
}
out.write(TABLE_HEADER);
out.write("\n");
out.write("\n");
out.write("\n");
+ // don't lose peer setting
+ String peerParam = req.getParameter("p");
+ if (peerParam != null)
+ out.write("\n");
out.write("
* +-------+-------+--//--+---//----+-------+-------+-------+-------+ * | sizeof(data) | data | padding | adler checksum of sz+data+pad | * +-------+-------+--//--+---//----+-------+-------+-------+-------+ + ** That message is then encrypted with the DH/2048 negotiated session key * (station to station authenticated per the EstablishState class) using the * last 16 bytes of the previous encrypted message as the IV. * * One special case is a metadata message where the sizeof(data) is 0. In * that case, the unencrypted message is encoded as: + *
* +-------+-------+-------+-------+-------+-------+-------+-------+ * | 0 | timestamp in seconds | uninterpreted * +-------+-------+-------+-------+-------+-------+-------+-------+ * uninterpreted | adler checksum of sz+data+pad | * +-------+-------+-------+-------+-------+-------+-------+-------+ - * + ** */ public class NTCPConnection implements FIFOBandwidthLimiter.CompleteListener {