Author: toad
Date: 2008-02-29 15:51:23 +0000 (Fri, 29 Feb 2008)
New Revision: 18249
Modified:
trunk/freenet/src/freenet/node/FailureTable.java
trunk/freenet/src/freenet/node/NodeDispatcher.java
Log:
Offered-key sends: unlock only after the send has finished.
Modified: trunk/freenet/src/freenet/node/FailureTable.java
===================================================================
--- trunk/freenet/src/freenet/node/FailureTable.java 2008-02-29 15:30:33 UTC
(rev 18248)
+++ trunk/freenet/src/freenet/node/FailureTable.java 2008-02-29 15:51:23 UTC
(rev 18249)
@@ -6,6 +6,7 @@
import java.lang.ref.WeakReference;
import java.util.Vector;
+import freenet.io.comm.AsyncMessageCallback;
import freenet.io.comm.ByteCounter;
import freenet.io.comm.DMT;
import freenet.io.comm.Message;
@@ -20,6 +21,7 @@
import freenet.keys.SSKBlock;
import freenet.support.LRUHashtable;
import freenet.support.Logger;
+import freenet.support.io.NativeThread;
// FIXME it is ESSENTIAL that we delete the ULPR data on requestors etc once
we have found the key.
// Otherwise it will be much too easy to trace a request if an attacker busts
the node afterwards.
@@ -335,14 +337,15 @@
/**
* We offered a key, a node has responded to the offer. Note that this
runs on the incoming
- * packets thread so should allocate a new thread if it does anything
heavy.
+ * packets thread so should allocate a new thread if it does anything
heavy. Note also that
+ * it is responsible for unlocking the UID.
* @param key The key to send.
* @param isSSK Whether it is an SSK.
* @param uid The UID.
* @param source The node that asked for the key.
* @throws NotConnectedException If the sender ceases to be connected.
*/
- public void sendOfferedKey(Key key, boolean isSSK, boolean needPubKey,
long uid, PeerNode source) throws NotConnectedException {
+ public void sendOfferedKey(Key key, final boolean isSSK, boolean
needPubKey, final long uid, PeerNode source) throws NotConnectedException {
if(isSSK) {
SSKBlock block = node.fetch((NodeSSK)key, false);
if(block == null) {
@@ -352,7 +355,31 @@
}
Message df = DMT.createFNPSSKDataFound(uid,
block.getRawHeaders(), block.getRawData());
node.sentPayload(block.getRawData().length);
- source.sendAsync(df, null, 0, senderCounter);
+ source.sendAsync(df, new AsyncMessageCallback() {
+ boolean finished = false;
+ public synchronized void acknowledged() {
+ if(finished) return;
+ finished = true;
+ node.unlockUID(uid, isSSK, false,
false, true);
+ }
+
+ public void disconnected() {
+ if(finished) return;
+ finished = true;
+ node.unlockUID(uid, isSSK, false,
false, true);
+ }
+
+ public void fatalError() {
+ if(finished) return;
+ finished = true;
+ node.unlockUID(uid, isSSK, false,
false, true);
+ }
+
+ public void sent() {
+ // Ignore
+ }
+
+ }, 0, senderCounter);
if(needPubKey) {
Message pk = DMT.createFNPSSKPubKey(uid,
block.getPubKey());
source.sendAsync(pk, null, 0, senderCounter);
@@ -368,9 +395,25 @@
source.sendAsync(df, null, 0, null);
PartiallyReceivedBlock prb =
new PartiallyReceivedBlock(Node.PACKETS_IN_BLOCK,
Node.PACKET_SIZE, block.getRawData());
- BlockTransmitter bt =
+ final BlockTransmitter bt =
new BlockTransmitter(node.usm, source, uid, prb,
node.outputThrottle, senderCounter);
- bt.sendAsync(node.executor);
+ node.executor.execute(new PrioRunnable() {
+
+ public int getPriority() {
+ return NativeThread.HIGH_PRIORITY;
+ }
+
+ public void run() {
+ try {
+ bt.send(node.executor);
+ } catch (Throwable t) {
+ Logger.error(this, "Sending
offered key failed: "+t, t);
+ } finally {
+ node.unlockUID(uid, isSSK,
false, false, true);
+ }
+ }
+
+ }, "CHK offer sender");
}
}
Modified: trunk/freenet/src/freenet/node/NodeDispatcher.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeDispatcher.java 2008-02-29 15:30:33 UTC
(rev 18248)
+++ trunk/freenet/src/freenet/node/NodeDispatcher.java 2008-02-29 15:51:23 UTC
(rev 18249)
@@ -204,8 +204,9 @@
// Do we want it? We can RejectOverload if we don't have the
bandwidth...
boolean isSSK = key instanceof NodeSSK;
node.lockUID(uid, isSSK, false, true);
+ boolean needPubKey;
try {
- boolean needPubKey = m.getBoolean(DMT.NEED_PUB_KEY);
+ needPubKey = m.getBoolean(DMT.NEED_PUB_KEY);
String reject =
nodeStats.shouldRejectRequest(true, false, isSSK,
false, true, source);
if(reject != null) {
@@ -219,6 +220,14 @@
return true;
}
+ } catch (Error e) {
+ node.unlockUID(uid, isSSK, false, false, true);
+ throw e;
+ } catch (RuntimeException e) {
+ node.unlockUID(uid, isSSK, false, false, true);
+ throw e;
+ } // Otherwise, sendOfferedKey is responsible for unlocking.
+
// Accept it.
try {
@@ -226,9 +235,6 @@
} catch (NotConnectedException e) {
// Too bad.
}
- } finally {
- node.unlockUID(uid, isSSK, false, false, true);
- }
return true;
}