Author: toad
Date: 2008-11-29 19:21:46 +0000 (Sat, 29 Nov 2008)
New Revision: 23981
Added:
branches/db4o/freenet/src/freenet/node/BlockedTooLongException.java
Modified:
branches/db4o/freenet/
branches/db4o/freenet/src/freenet/clients/http/staticfiles/defaultbookmarks.dat
branches/db4o/freenet/src/freenet/l10n/freenet.l10n.en.properties
branches/db4o/freenet/src/freenet/node/FNPPacketMangler.java
branches/db4o/freenet/src/freenet/node/KeyTracker.java
branches/db4o/freenet/src/freenet/node/LoggingConfigHandler.java
branches/db4o/freenet/src/freenet/node/NodeDispatcher.java
branches/db4o/freenet/src/freenet/node/OutgoingPacketMangler.java
branches/db4o/freenet/src/freenet/node/PacketSender.java
branches/db4o/freenet/src/freenet/node/PeerNode.java
branches/db4o/freenet/src/freenet/node/StillNotAckedException.java
branches/db4o/freenet/src/freenet/node/Version.java
branches/db4o/freenet/src/freenet/support/BinaryBloomFilter.java
branches/db4o/freenet/src/freenet/support/BloomFilter.java
branches/db4o/freenet/src/freenet/support/CountingBloomFilter.java
branches/db4o/freenet/src/freenet/support/LimitedRangeIntByteArrayMap.java
branches/db4o/freenet/test/freenet/support/io/MockInputStream.java
Log:
Merge 1176
Property changes on: branches/db4o/freenet
___________________________________________________________________
Modified: svn:mergeinfo
- /trunk/freenet:19964-23531
+ /trunk/freenet:19964-23583
Modified:
branches/db4o/freenet/src/freenet/clients/http/staticfiles/defaultbookmarks.dat
===================================================================
---
branches/db4o/freenet/src/freenet/clients/http/staticfiles/defaultbookmarks.dat
2008-11-29 19:18:00 UTC (rev 23980)
+++
branches/db4o/freenet/src/freenet/clients/http/staticfiles/defaultbookmarks.dat
2008-11-29 19:21:46 UTC (rev 23981)
@@ -22,7 +22,7 @@
[EMAIL
PROTECTED],xTFOV9ddCQQk6vQ6G~jfL6IzRUgmfMcZJ6nuySu~NUc,AQACAAE/activelink-index-text/54/
BookmarkCategory1.Name=Freenet related software and documentation
BookmarkCategory1.Content.BookmarkCategory=0
-BookmarkCategory1.Content.Bookmark=6
+BookmarkCategory1.Content.Bookmark=5
BookmarkCategory1.Content.Bookmark0.Name=Freenet Message System
BookmarkCategory1.Content.Bookmark0.Description=The official freesite of FMS,
a spam resistant message board system for Freenet
BookmarkCategory1.Content.Bookmark0.hasAnActivelink=true
@@ -43,8 +43,4 @@
BookmarkCategory1.Content.Bookmark4.hasAnActivelink=true
BookmarkCategory1.Content.Bookmark4.Name=The Freenet Applications Freesite
BookmarkCategory1.Content.Bookmark4.Description=Various links to Freenet
applications, and instructions for using them
-BookmarkCategory1.Content.Bookmark5.Name=wAnnA search Freenet?
-BookmarkCategory1.Content.Bookmark5.Description=How to search Freenet
-BookmarkCategory1.Content.Bookmark5.hasAnActivelink=true
[EMAIL PROTECTED],~31qR8wv08tVkj--3bfCwJAC7ndaXh7uLFgafpimOik,AQACAAE/wAnnA/13/
End
Modified: branches/db4o/freenet/src/freenet/l10n/freenet.l10n.en.properties
===================================================================
--- branches/db4o/freenet/src/freenet/l10n/freenet.l10n.en.properties
2008-11-29 19:18:00 UTC (rev 23980)
+++ branches/db4o/freenet/src/freenet/l10n/freenet.l10n.en.properties
2008-11-29 19:21:46 UTC (rev 23981)
@@ -472,6 +472,10 @@
FileOffer.succeededReceiveTitle=Successfully received file
FileOffer.succeededReceiveHeader=The transfer of the file ${filename} from
${node} was a success.
FileOffer.succeededReceiveShort=Successfully received ${filename} from ${node}.
+FNPPacketMangler.somePeersDisconnectedStillNotAcked=Probably a bug: please
report: ${count} peers forcibly disconnected due to not acknowledging packets.
+FNPPacketMangler.somePeersDisconnectedStillNotAckedDetail=${count} of your
peers are having severe problems (not acknowledging packets even after 10
minutes). This is probably due to a bug in the code. Please report it to us at
the bug tracker at ${link}https://bugs.freenetproject.org/${/link} or at [EMAIL
PROTECTED] Please include this message and what version of the node you are
running. The affected peers (you may not want to include this in your bug
report if they are darknet peers) are:
+PacketSender.somePeersDisconnectedStillNotAcked=Probably a bug: please report:
${count} peers forcibly disconnected due to blocking for a packet number for
over 10 minutes.
+PacketSender.somePeersDisconnectedStillNotAckedDetail=${count} of your peers
are having severe problems (failing to allocate a packet number after 10
minutes). This is probably due to a bug in the code. Please report it to us at
the bug tracker at ${link}https://bugs.freenetproject.org/${/link} or at [EMAIL
PROTECTED] Please include this message and what version of the node you are
running. The affected peers (you may not want to include this in your bug
report if they are darknet peers) are:
GIFFilter.invalidHeader=The file does not contain a valid GIF header.
GIFFilter.invalidHeaderTitle=Invalid header
GIFFilter.notGif=The file you tried to fetch is not a GIF. It might be some
other file format, and your browser may do something dangerous with it,
therefore we have blocked it.
@@ -704,8 +708,8 @@
Node.opennetEnabledLong=Enable insecure mode (aka opennet)? If this is
enabled, the node will automatically exchange node references with other
untrusted nodes (Strangers as opposed to Friends). But this means that the fact
that you are running a node is no longer private, and many attacks are much
easier. If you know enough people running Freenet, you should stick to trusted
(Friends) connections to them, and turn this off.
Node.outBWLimit=Output bandwidth limit (bytes per second)
Node.outBWLimitLong=Hard output bandwidth limit (bytes/sec); the node should
almost never exceed this
-Node.paddDataPackets=Padd data packets sent by the node with random-length
content? (READ WARNING!)
-Node.paddDataPacketsLong=Padd data packets sent by the node with random-length
content? For security, on a single node, this is bad; if a large part of the
network starts doing it, we become very vulnerable to a passive attacker.
However, it should improve performance, particularly the payload percentage.
You have been warned!
+Node.paddDataPackets=Pad data packets sent by the node with random-length
content? (READ WARNING!)
+Node.paddDataPacketsLong=Pad data packets sent by the node with random-length
content? For security, on a single node, turning this off is bad; if a large
part of the network starts doing it, we become very vulnerable to a passive
attacker. However, it should improve performance, particularly the payload
percentage. You have been warned!
Node.passOpennetPeersThroughDarknet=Relay opennet noderefs through darknet
peers?
Node.passOpennetPeersThroughDarknetLong=If true, opennet noderefs (NEVER our
own darknet noderef) will be relayed through our darknet peers. So a node (this
node, or its peers) can get opennet peers from its darknet peers. This is
useful because it allows us to bootstrap new opennet peers after having lost
our peers due to downtime, for example. However, it may make traffic analysis
slightly easier, so turn it off if you are paranoid.
Node.port=FNP port number (UDP)
Copied: branches/db4o/freenet/src/freenet/node/BlockedTooLongException.java
(from rev 23583, trunk/freenet/src/freenet/node/BlockedTooLongException.java)
===================================================================
--- branches/db4o/freenet/src/freenet/node/BlockedTooLongException.java
(rev 0)
+++ branches/db4o/freenet/src/freenet/node/BlockedTooLongException.java
2008-11-29 19:21:46 UTC (rev 23981)
@@ -0,0 +1,13 @@
+package freenet.node;
+
+public class BlockedTooLongException extends Exception {
+
+ public final KeyTracker tracker;
+ public final long delta;
+
+ public BlockedTooLongException(KeyTracker tracker, long delta) {
+ this.tracker = tracker;
+ this.delta = delta;
+ }
+
+}
Modified: branches/db4o/freenet/src/freenet/node/FNPPacketMangler.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/FNPPacketMangler.java
2008-11-29 19:18:00 UTC (rev 23980)
+++ branches/db4o/freenet/src/freenet/node/FNPPacketMangler.java
2008-11-29 19:21:46 UTC (rev 23981)
@@ -8,6 +8,7 @@
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedList;
import net.i2p.util.NativeBigInteger;
@@ -39,8 +40,11 @@
import freenet.io.comm.ReferenceSignatureVerificationException;
import freenet.io.comm.SocketHandler;
import freenet.io.comm.Peer.LocalAddressException;
+import freenet.l10n.L10n;
+import freenet.node.useralerts.UserAlert;
import freenet.support.ByteArrayWrapper;
import freenet.support.Fields;
+import freenet.support.HTMLNode;
import freenet.support.HexUtil;
import freenet.support.Logger;
import freenet.support.SimpleFieldSet;
@@ -950,8 +954,8 @@
Logger.normal(this, "We received an unexpected
JFK(2) message from "+pn.getPeer()+" (time since added:
"+pn.timeSinceAddedOrRestarted()+" time last
receive:"+pn.lastReceivedPacketTime()+')');
return;
} else if(!Arrays.equals(myNi, nonceInitiator)){
- if(logMINOR)
- Logger.minor(this, "Ignoring old JFK(2)
(different nonce to the one we sent - either a timing artefact or an attempt to
change the nonce)");
+ if(shouldLogErrorInHandshake(t1))
+ Logger.normal(this, "Ignoring old JFK(2)
(different nonce to the one we sent - either a timing artefact or an attempt to
change the nonce)");
return;
}
@@ -1346,6 +1350,9 @@
return true;
}
+ // Received a packet
+ pn.receivedPacket(true, false);
+
// Promote if necessary
boolean dontWant = false;
if(oldOpennetPeer) {
@@ -2007,7 +2014,7 @@
/* (non-Javadoc)
* @see
freenet.node.OutgoingPacketMangler#processOutgoingOrRequeue(freenet.node.MessageItem[],
freenet.node.PeerNode, boolean, boolean)
*/
- public void processOutgoingOrRequeue(MessageItem[] messages, PeerNode
pn, boolean neverWaitForPacketNumber, boolean dontRequeue, boolean onePacket) {
+ public boolean processOutgoingOrRequeue(MessageItem[] messages,
PeerNode pn, boolean neverWaitForPacketNumber, boolean dontRequeue, boolean
onePacket) throws BlockedTooLongException {
String requeueLogString = "";
if(!dontRequeue) {
requeueLogString = ", requeueing";
@@ -2018,8 +2025,12 @@
KeyTracker kt = pn.getCurrentKeyTracker();
if(kt == null) {
Logger.error(this, "Not connected while sending
packets: "+pn);
- return;
+ return false;
}
+ if(kt.wouldBlock(false)) {
+ if(logMINOR) Logger.minor(this, "Would block: "+kt);
+ return false;
+ }
int length = 1;
length += kt.countAcks() + kt.countAckRequests() +
kt.countResendRequests();
int callbacksCount = 0;
@@ -2044,7 +2055,7 @@
pn.requeueMessageItems(newMsgs,
0, x, false, "NotConnectedException(1a)");
pn.requeueMessageItems(messages, i, messages.length-i, false,
"NotConnectedException(1b)");
}
- return;
+ return false;
} catch (WouldBlockException e) {
if(logMINOR) Logger.minor(this, "Caught
"+e+" while sending messages ("+mi_name+") to "+pn.getPeer()+requeueLogString,
e);
// Requeue
@@ -2052,7 +2063,7 @@
pn.requeueMessageItems(newMsgs,
0, x, false, "WouldBlockException(1a)");
pn.requeueMessageItems(messages, i, messages.length-i, false,
"WouldBlockException(1b)");
}
- return;
+ return false;
} catch (KeyChangedException e) {
if(logMINOR) Logger.minor(this, "Caught
"+e+" while sending messages ("+mi_name+") to "+pn.getPeer()+requeueLogString,
e);
// Requeue
@@ -2060,7 +2071,7 @@
pn.requeueMessageItems(newMsgs,
0, x, false, "KeyChangedException(1a)");
pn.requeueMessageItems(messages, i, messages.length-i, false,
"KeyChangedException(1b)");
}
- return;
+ return false;
} catch (Throwable e) {
Logger.error(this, "Caught "+e+" while
sending messages ("+mi_name+") to "+pn.getPeer()+requeueLogString, e);
// Requeue
@@ -2068,7 +2079,7 @@
pn.requeueMessageItems(newMsgs,
0, x, false, "Throwable(1)");
pn.requeueMessageItems(messages, i, messages.length-i, false, "Throwable(1)");
}
- return;
+ return false;
}
} else {
byte[] data = mi.getData();
@@ -2126,19 +2137,19 @@
// Requeue
if(!dontRequeue)
pn.requeueMessageItems(messages, 0,
messages.length, false, "NotConnectedException(2)");
- return;
+ return false;
} catch (WouldBlockException e) {
if(logMINOR) Logger.minor(this, "Caught "+e+"
while sending messages ("+mi_name+") to "+pn.getPeer()+requeueLogString, e);
// Requeue
if(!dontRequeue)
pn.requeueMessageItems(messages, 0,
messages.length, false, "WouldBlockException(2)");
- return;
+ return false;
} catch (Throwable e) {
Logger.error(this, "Caught "+e+" while sending
messages ("+mi_name+") to "+pn.getPeer()+requeueLogString, e);
// Requeue
if(!dontRequeue)
pn.requeueMessageItems(messages, 0,
messages.length, false, "Throwable(2)");
- return;
+ return false;
}
} else {
@@ -2180,23 +2191,23 @@
// Requeue
if(!dontRequeue)
pn.requeueMessageItems(messages, lastIndex, messages.length - lastIndex, false,
"NotConnectedException(3)");
- return;
+ return false;
} catch (WouldBlockException e)
{
if(logMINOR)
Logger.minor(this, "Caught "+e+" while sending messages ("+mi_name+") to
"+pn.getPeer()+requeueLogString, e);
// Requeue
if(!dontRequeue)
pn.requeueMessageItems(messages, lastIndex, messages.length - lastIndex, false,
"WouldBlockException(3)");
- return;
+ return false;
} catch (Throwable e) {
Logger.error(this,
"Caught "+e+" while sending messages ("+mi_name+") to
"+pn.getPeer()+requeueLogString, e);
// Requeue
if(!dontRequeue)
pn.requeueMessageItems(messages, lastIndex, messages.length - lastIndex, false,
"Throwable(3)");
- return;
+ return false;
}
if(onePacket) {
pn.requeueMessageItems(messages, i, messageData.length - i, true, "Didn't fit
in single packet");
- return;
+ return false;
}
}
lastIndex = i;
@@ -2209,6 +2220,7 @@
}
}
}
+ return true;
}
/**
@@ -2354,6 +2366,7 @@
} catch (StillNotAckedException e) {
Logger.error(this, "Forcing disconnect on
"+tracker.pn+" for "+tracker+" because packets not acked after 10 minutes!");
tracker.pn.forceDisconnect(true);
+ disconnectedStillNotAcked(tracker);
throw new NotConnectedException();
}
@@ -2550,6 +2563,106 @@
return ret;
}
+ private HashSet<Peer> peersWithProblems = new HashSet<Peer>();
+
+ private void disconnectedStillNotAcked(KeyTracker tracker) {
+ synchronized(peersWithProblems) {
+ peersWithProblems.add(tracker.pn.getPeer());
+ if(peersWithProblems.size() > 1) return;
+ }
+ node.clientCore.alerts.register(disconnectedStillNotAckedAlert);
+ }
+
+ private UserAlert disconnectedStillNotAckedAlert = new UserAlert() {
+
+ public String anchor() {
+ return "disconnectedStillNotAcked";
+ }
+
+ public String dismissButtonText() {
+ return null;
+ }
+
+ public short getPriorityClass() {
+ return UserAlert.ERROR;
+ }
+
+ public String getShortText() {
+ int sz;
+ synchronized(peersWithProblems) {
+ sz = peersWithProblems.size();
+ }
+ return l10n("somePeersDisconnectedStillNotAcked",
"count", Integer.toString(sz));
+ }
+
+ public HTMLNode getHTMLText() {
+ HTMLNode div = new HTMLNode("div");
+ Peer[] peers;
+ synchronized(peersWithProblems) {
+ peers = peersWithProblems.toArray(new
Peer[peersWithProblems.size()]);
+ }
+ L10n.addL10nSubstitution(div,
"FNPPacketMangler.somePeersDisconnectedStillNotAckedDetail",
+ new String[] { "count", "link", "/link"
}
+ , new String[] {
Integer.toString(peers.length), "<a
href=\"/?_CHECKED_HTTP_=https://bugs.freenetproject.org/\">", "</a>" });
+ HTMLNode list = div.addChild("ul");
+ for(Peer peer : peers) {
+ list.addChild("li", peer.toString());
+ }
+ return div;
+ }
+
+ public String getText() {
+ StringBuffer sb = new StringBuffer();
+ Peer[] peers;
+ synchronized(peersWithProblems) {
+ peers = peersWithProblems.toArray(new
Peer[peersWithProblems.size()]);
+ }
+
sb.append(l10n("somePeersDisconnectedStillNotAckedDetail",
+ new String[] { "count", "link", "/link"
},
+ new String[] {
Integer.toString(peers.length), "", "" } ));
+ sb.append('\n');
+ for(Peer peer : peers) {
+ sb.append('\t');
+ sb.append(peer.toString());
+ sb.append('\n');
+ }
+ return sb.toString();
+ }
+
+ public String getTitle() {
+ return getShortText();
+ }
+
+ public Object getUserIdentifier() {
+ return FNPPacketMangler.this;
+ }
+
+ public boolean isEventNotification() {
+ return false;
+ }
+
+ public boolean isValid() {
+ return true;
+ }
+
+ public void isValid(boolean validity) {
+ // Ignore
+ }
+
+ public void onDismiss() {
+ // Ignore
+ }
+
+ public boolean shouldUnregisterOnDismiss() {
+ return false;
+ }
+
+ public boolean userCanDismiss() {
+ return false;
+ }
+
+ };
+
/**
* Encrypt and send a packet.
* @param plaintext The packet's plaintext, including all formatting,
@@ -2619,6 +2732,14 @@
return output.length + sock.getHeadersLength();
}
+ protected String l10n(String key, String[] patterns, String[] values) {
+ return L10n.getString("FNPPacketMangler."+key, patterns,
values);
+ }
+
+ protected String l10n(String key, String pattern, String value) {
+ return L10n.getString("FNPPacketMangler."+key, pattern, value);
+ }
+
/* (non-Javadoc)
* @see
freenet.node.OutgoingPacketMangler#sendHandshake(freenet.node.PeerNode)
*/
Modified: branches/db4o/freenet/src/freenet/node/KeyTracker.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/KeyTracker.java 2008-11-29
19:18:00 UTC (rev 23980)
+++ branches/db4o/freenet/src/freenet/node/KeyTracker.java 2008-11-29
19:21:46 UTC (rev 23981)
@@ -541,6 +541,11 @@
}
if(cbCount > 0 && logMINOR)
Logger.minor(this, "Executed " + cbCount + "
callbacks");
+ try {
+ wouldBlock(true);
+ } catch (BlockedTooLongException e) {
+ // Ignore, will come up again. In any case it's rather
unlikely...
+ }
}
/**
@@ -570,6 +575,11 @@
throttle.notifyOfPacketAcknowledged();
throttle.setRoundTripTime(System.currentTimeMillis() - timeAdded);
}
+ try {
+ wouldBlock(true);
+ } catch (BlockedTooLongException e) {
+ // Ignore, will come up again. In any case it's rather
unlikely...
+ }
if(callbacks != null) {
for(int i = 0; i < callbacks.length; i++)
callbacks[i].acknowledged();
@@ -711,6 +721,37 @@
}
}
}
+
+ private long timeWouldBlock = -1;
+
+ static final long MAX_WOULD_BLOCK_DELTA = 10*60*1000;
+
+ public boolean wouldBlock(boolean wakeTicker) throws
BlockedTooLongException {
+ long now = System.currentTimeMillis();
+ synchronized(this) {
+ if(sentPacketsContents.wouldBlock(nextPacketNumber)) {
+ if(timeWouldBlock == -1)
+ timeWouldBlock = now;
+ else {
+ long delta = now - timeWouldBlock;
+ if(delta > MAX_WOULD_BLOCK_DELTA) {
+ Logger.error(this, "Not been
able to allocate a packet to tracker "+this+" for "+TimeUtil.formatTime(delta));
+ throw new
BlockedTooLongException(this, delta);
+ }
+ }
+ return true;
+ } else {
+ if(timeWouldBlock != -1) {
+ long delta = now - timeWouldBlock;
+ if(delta >
PacketSender.MAX_COALESCING_DELAY) {
+ Logger.error(this, "Waking
PacketSender: have been blocking for packet ack for
"+TimeUtil.formatTime(delta));
+ } else return false;
+ } else return false;
+ }
+ }
+ pn.node.ps.wakeUp();
+ return false;
+ }
/**
* @return A packet number for a new outgoing packet.
@@ -727,6 +768,7 @@
if(isDeprecated)
throw new KeyChangedException();
sentPacketsContents.lockNeverBlock(packetNumber);
+ timeWouldBlock = -1;
nextPacketNumber = packetNumber + 1;
if(logMINOR)
Logger.minor(this, "Allocated " + packetNumber
+ " in allocateOutgoingPacketNumberNeverBlock for " + this);
@@ -859,7 +901,7 @@
Logger.minor(this, "Packet " + qr.packetNumber + " sent over " + (now -
qr.createdTime) + "ms ago and still not acked on " + this + " for " + pn);
if(now - qr.createdTime
> 10 * 60 * 1000) {
Logger.error(this, "Packet " + qr.packetNumber + " sent over " + (now -
qr.createdTime) + "ms ago and still not acked on " + this + " for " + pn);
- throw new
StillNotAckedException();
+ throw new
StillNotAckedException(this);
}
}
packetNumbers[realLength++] =
packetNumber;
Modified: branches/db4o/freenet/src/freenet/node/LoggingConfigHandler.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/LoggingConfigHandler.java
2008-11-29 19:18:00 UTC (rev 23980)
+++ branches/db4o/freenet/src/freenet/node/LoggingConfigHandler.java
2008-11-29 19:21:46 UTC (rev 23981)
@@ -163,7 +163,7 @@
// interval
- config.register("interval", "1HOUR", 5, true, false,
"LogConfigHandler.rotationInterval", "LogConfigHandler.rotationIntervalLong",
+ config.register("interval", "10MINUTE", 5, true, false,
"LogConfigHandler.rotationInterval", "LogConfigHandler.rotationIntervalLong",
new StringCallback() {
@Override
public String get() {
Modified: branches/db4o/freenet/src/freenet/node/NodeDispatcher.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/NodeDispatcher.java 2008-11-29
19:18:00 UTC (rev 23980)
+++ branches/db4o/freenet/src/freenet/node/NodeDispatcher.java 2008-11-29
19:21:46 UTC (rev 23981)
@@ -298,11 +298,7 @@
node.getTicker().queueTimedJob(new FastRunnable() {
public void run() {
// Send the ack
- try {
source.sendAnyUrgentNotifications(true);
- } catch (PacketSequenceException e) {
- // Ignore
- }
finishDisconnect(m, source);
}
}, 0);
Modified: branches/db4o/freenet/src/freenet/node/OutgoingPacketMangler.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/OutgoingPacketMangler.java
2008-11-29 19:18:00 UTC (rev 23980)
+++ branches/db4o/freenet/src/freenet/node/OutgoingPacketMangler.java
2008-11-29 19:21:46 UTC (rev 23981)
@@ -26,9 +26,11 @@
* Any packets which cannot be sent will be requeued on the PeerNode.
* @param onePacketOnly If true, we will only send one packet, and will
requeue any
* messages that don't fit in that single packet.
+ * @return True if we sent a packet.
+ * @throws BlockedTooLongException
*/
- public void processOutgoingOrRequeue(MessageItem[] messages, PeerNode
pn,
- boolean neverWaitForPacketNumber, boolean dontRequeue,
boolean onePacketOnly);
+ public boolean processOutgoingOrRequeue(MessageItem[] messages,
PeerNode pn,
+ boolean neverWaitForPacketNumber, boolean dontRequeue,
boolean onePacketOnly) throws BlockedTooLongException;
/**
* Resend a single packet.
Modified: branches/db4o/freenet/src/freenet/node/PacketSender.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/PacketSender.java 2008-11-29
19:18:00 UTC (rev 23980)
+++ branches/db4o/freenet/src/freenet/node/PacketSender.java 2008-11-29
19:21:46 UTC (rev 23981)
@@ -4,15 +4,21 @@
package freenet.node;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import java.util.TreeMap;
import java.util.Vector;
import org.tanukisoftware.wrapper.WrapperManager;
+import freenet.io.comm.Peer;
+import freenet.l10n.L10n;
+import freenet.node.useralerts.UserAlert;
import freenet.support.FileLoggerHook;
+import freenet.support.HTMLNode;
import freenet.support.Logger;
import freenet.support.OOMHandler;
+import freenet.support.TimeUtil;
import freenet.support.io.NativeThread;
/**
@@ -251,6 +257,7 @@
continue;
}
+ try {
if(pn.maybeSendPacket(now, rpiTemp, rpiIntTemp)
&& canSendThrottled) {
canSendThrottled = false;
count = node.outputThrottle.getCount();
@@ -265,6 +272,11 @@
newBrokeAt = i;
}
}
+ } catch (BlockedTooLongException e) {
+ Logger.error(this, "Waited too long:
"+TimeUtil.formatTime(e.delta)+" to allocate a packet number to send to
"+this+" on "+e.tracker+" - DISCONNECTING!");
+ pn.forceDisconnect(true);
+ onForceDisconnectBlockTooLong(pn, e);
+ }
long urgentTime = pn.getNextUrgentTime(now);
// Should spam the logs, unless there is a
deadlock
@@ -409,6 +421,107 @@
return brokeAt;
}
+ private HashSet<Peer> peersDumpedBlockedTooLong = new HashSet<Peer>();
+
+ private void onForceDisconnectBlockTooLong(PeerNode pn,
BlockedTooLongException e) {
+ Peer p = pn.getPeer();
+ synchronized(peersDumpedBlockedTooLong) {
+ peersDumpedBlockedTooLong.add(p);
+ if(peersDumpedBlockedTooLong.size() > 1) return;
+ }
+ node.clientCore.alerts.register(peersDumpedBlockedTooLongAlert);
+ }
+
+ private UserAlert peersDumpedBlockedTooLongAlert = new UserAlert() {
+
+ public String anchor() {
+ return "disconnectedStillNotAcked";
+ }
+
+ public String dismissButtonText() {
+ return null;
+ }
+
+ public short getPriorityClass() {
+ return UserAlert.ERROR;
+ }
+
+ public String getShortText() {
+ int sz;
+ synchronized(peersDumpedBlockedTooLong) {
+ sz = peersDumpedBlockedTooLong.size();
+ }
+ return l10n("somePeersDisconnectedBlockedTooLong",
"count", Integer.toString(sz));
+ }
+
+ public HTMLNode getHTMLText() {
+ HTMLNode div = new HTMLNode("div");
+ Peer[] peers;
+ synchronized(peersDumpedBlockedTooLong) {
+ peers = peersDumpedBlockedTooLong.toArray(new
Peer[peersDumpedBlockedTooLong.size()]);
+ }
+ L10n.addL10nSubstitution(div,
"FNPPacketMangler.somePeersDisconnectedBlockedTooLongDetail",
+ new String[] { "count", "link", "/link"
}
+ , new String[] {
Integer.toString(peers.length), "<a
href=\"/?_CHECKED_HTTP_=https://bugs.freenetproject.org/\">", "</a>" });
+ HTMLNode list = div.addChild("ul");
+ for(Peer peer : peers) {
+ list.addChild("li", peer.toString());
+ }
+ return div;
+ }
+
+ public String getText() {
+ StringBuffer sb = new StringBuffer();
+ Peer[] peers;
+ synchronized(peersDumpedBlockedTooLong) {
+ peers = peersDumpedBlockedTooLong.toArray(new
Peer[peersDumpedBlockedTooLong.size()]);
+ }
+
sb.append(l10n("somePeersDisconnectedStillNotAckedDetail",
+ new String[] { "count", "link", "/link"
},
+ new String[] {
Integer.toString(peers.length), "", "" } ));
+ sb.append('\n');
+ for(Peer peer : peers) {
+ sb.append('\t');
+ sb.append(peer.toString());
+ sb.append('\n');
+ }
+ return sb.toString();
+ }
+
+ public String getTitle() {
+ return getShortText();
+ }
+
+ public Object getUserIdentifier() {
+ return PacketSender.this;
+ }
+
+ public boolean isEventNotification() {
+ return false;
+ }
+
+ public boolean isValid() {
+ return true;
+ }
+
+ public void isValid(boolean validity) {
+ // Ignore
+ }
+
+ public void onDismiss() {
+ // Ignore
+ }
+
+ public boolean shouldUnregisterOnDismiss() {
+ return false;
+ }
+
+ public boolean userCanDismiss() {
+ return false;
+ }
+
+ };
+
/** Wake up, and send any queued packets. */
void wakeUp() {
// Wake up if needed
@@ -417,12 +530,18 @@
}
}
+ protected String l10n(String key, String[] patterns, String[] values) {
+ return L10n.getString("PacketSender."+key, patterns, values);
+ }
+
+ protected String l10n(String key, String pattern, String value) {
+ return L10n.getString("PacketSender."+key, pattern, value);
+ }
+
public void queueTimedJob(Runnable job, long offset) {
queueTimedJob(job, "Scheduled job: "+job, offset, false);
}
-
-
public void queueTimedJob(Runnable runner, String name, long offset,
boolean runOnTickerAnyway) {
// Run directly *if* that won't cause any priority problems.
if(offset <= 0 && !runOnTickerAnyway) {
Modified: branches/db4o/freenet/src/freenet/node/PeerNode.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/PeerNode.java 2008-11-29
19:18:00 UTC (rev 23980)
+++ branches/db4o/freenet/src/freenet/node/PeerNode.java 2008-11-29
19:21:46 UTC (rev 23981)
@@ -1256,8 +1256,13 @@
*/
public long getNextUrgentTime(long now) {
long t = Long.MAX_VALUE;
+ KeyTracker cur;
+ KeyTracker prev;
synchronized(this) {
- KeyTracker kt = currentTracker;
+ cur = currentTracker;
+ prev = previousTracker;
+ }
+ KeyTracker kt = cur;
if(kt != null) {
long next = kt.getNextUrgentTime();
t = Math.min(t, next);
@@ -1265,7 +1270,7 @@
Logger.minor(this, "Next urgent time from
curTracker less than now");
if(kt.hasPacketsToResend()) return now;
}
- kt = previousTracker;
+ kt = prev;
if(kt != null) {
long next = kt.getNextUrgentTime();
t = Math.min(t, next);
@@ -1273,8 +1278,12 @@
Logger.minor(this, "Next urgent time from
prevTracker less than now");
if(kt.hasPacketsToResend()) return now;
}
+ try {
+ if(!cur.wouldBlock(false))
+ t = messageQueue.getNextUrgentTime(t, now);
+ } catch (BlockedTooLongException e) {
+ // Ignore for now, it will come back around
}
- t = messageQueue.getNextUrgentTime(t, now);
return t;
}
@@ -1859,7 +1868,9 @@
unroutableNewerVersion = newer;
unroutableOlderVersion = older;
bootIDChanged = (thisBootID != this.bootID);
- if(bootIDChanged && logMINOR)
+ if(bootIDChanged && wasARekey)
+ Logger.error(this, "Changed boot ID while
rekeying! from " + bootID + " to " + thisBootID + " for " + getPeer());
+ else if(bootIDChanged && logMINOR)
Logger.minor(this, "Changed boot ID from " +
bootID + " to " + thisBootID + " for " + getPeer());
this.bootID = thisBootID;
if(bootIDChanged) {
@@ -1896,7 +1907,7 @@
}
ctx = null;
isRekeying = false;
- timeLastRekeyed = now;
+ timeLastRekeyed = now - (unverified ? 0 :
FNPPacketMangler.MAX_SESSION_KEY_REKEYING_DELAY / 2);
totalBytesExchangedWithCurrentTracker = 0;
// This has happened in the past, and caused problems,
check for it.
if(currentTracker != null && previousTracker != null &&
@@ -2407,7 +2418,7 @@
* @throws PacketSequenceException If there is an error sending the
packet
* caused by a sequence inconsistency.
*/
- public boolean sendAnyUrgentNotifications(boolean forceSendPrimary)
throws PacketSequenceException {
+ public boolean sendAnyUrgentNotifications(boolean forceSendPrimary) {
boolean sent = false;
if(logMINOR)
Logger.minor(this, "sendAnyUrgentNotifications");
@@ -2432,7 +2443,9 @@
} catch(KeyChangedException e) {
// Ignore
} catch(WouldBlockException e) {
- // Impossible, ignore
+ Logger.error(this, "Caught impossible:
"+e, e);
+ } catch(PacketSequenceException e) {
+ Logger.error(this, "Caught impossible:
"+e, e);
}
}
}
@@ -2450,7 +2463,9 @@
} catch(KeyChangedException e) {
// Ignore
} catch(WouldBlockException e) {
- Logger.error(this, "Impossible: " + e,
e);
+ Logger.error(this, "Caught impossible:
"+e, e);
+ } catch(PacketSequenceException e) {
+ Logger.error(this, "Caught impossible:
"+e, e);
}
}
return sent;
@@ -4010,14 +4025,17 @@
* @param now
* @param rpiTemp
* @param rpiTemp
+ * @throws BlockedTooLongException
*/
- public boolean maybeSendPacket(long now, Vector<ResendPacketItem>
rpiTemp, int[] rpiIntTemp) {
+ public boolean maybeSendPacket(long now, Vector<ResendPacketItem>
rpiTemp, int[] rpiIntTemp) throws BlockedTooLongException {
// If there are any urgent notifications, we must send a packet.
boolean mustSend = false;
+ boolean mustSendPacket = false;
if(mustSendNotificationsNow(now)) {
if(logMINOR)
Logger.minor(this, "Sending notification");
mustSend = true;
+ mustSendPacket = true;
}
// Any packets to resend? If so, resend ONE packet and then
return.
for(int j = 0; j < 2; j++) {
@@ -4074,6 +4092,7 @@
Logger.minor(this, "Sending keepalive");
keepalive = true;
mustSend = true;
+ mustSendPacket = true;
}
ArrayList<MessageItem> messages = new
ArrayList<MessageItem>(10);
@@ -4122,17 +4141,17 @@
// Send packets, right now, blocking, including any
active notifications
// Note that processOutgoingOrRequeue will drop
messages from the end
// if necessary to fit the messages into a single
packet.
-
getOutgoingMangler().processOutgoingOrRequeue(messages.toArray(new
MessageItem[messages.size()]), this, true, false, true);
+
if(!getOutgoingMangler().processOutgoingOrRequeue(messages.toArray(new
MessageItem[messages.size()]), this, true, false, true)) {
+ if(mustSendPacket) {
+ if(!sendAnyUrgentNotifications(false))
+
sendAnyUrgentNotifications(true);
+ }
+ }
return true;
} else {
if(mustSend) {
- try {
if(sendAnyUrgentNotifications(false))
return true;
- } catch (PacketSequenceException e) {
- Logger.error(this, "Caught "+e, e);
- return false;
- }
// Can happen occasionally as a race
condition...
Logger.normal(this, "No notifications sent
despite no messages and mustSend=true for "+this);
}
Modified: branches/db4o/freenet/src/freenet/node/StillNotAckedException.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/StillNotAckedException.java
2008-11-29 19:18:00 UTC (rev 23980)
+++ branches/db4o/freenet/src/freenet/node/StillNotAckedException.java
2008-11-29 19:21:46 UTC (rev 23981)
@@ -12,4 +12,10 @@
*/
public class StillNotAckedException extends Exception {
+ public StillNotAckedException(KeyTracker tracker) {
+ this.tracker = tracker;
+ }
+
+ final KeyTracker tracker;
+
}
Modified: branches/db4o/freenet/src/freenet/node/Version.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/Version.java 2008-11-29 19:18:00 UTC
(rev 23980)
+++ branches/db4o/freenet/src/freenet/node/Version.java 2008-11-29 19:21:46 UTC
(rev 23981)
@@ -24,11 +24,11 @@
public static final String protocolVersion = "1.0";
/** The build number of the current revision */
- private static final int buildNumber = 1175;
+ private static final int buildNumber = 1176;
/** Oldest build of Fred we will talk to */
- private static final int oldLastGoodBuild = 1174;
- private static final int newLastGoodBuild = 1175;
+ private static final int oldLastGoodBuild = 1175;
+ private static final int newLastGoodBuild = 1176;
static final long transitionTime;
static {
Property changes on:
branches/db4o/freenet/src/freenet/support/BinaryBloomFilter.java
___________________________________________________________________
Modified: svn:mergeinfo
- /trunk/freenet/src/freenet/support/BinaryBloomFilter.java:22002-23531
+ /trunk/freenet/src/freenet/support/BinaryBloomFilter.java:22002-23583
Property changes on: branches/db4o/freenet/src/freenet/support/BloomFilter.java
___________________________________________________________________
Modified: svn:mergeinfo
- /trunk/freenet/src/freenet/support/BloomFilter.java:22002-23531
+ /trunk/freenet/src/freenet/support/BloomFilter.java:22002-23583
Property changes on:
branches/db4o/freenet/src/freenet/support/CountingBloomFilter.java
___________________________________________________________________
Modified: svn:mergeinfo
- /trunk/freenet/src/freenet/support/CountingBloomFilter.java:22002-23531
+ /trunk/freenet/src/freenet/support/CountingBloomFilter.java:22002-23583
Modified:
branches/db4o/freenet/src/freenet/support/LimitedRangeIntByteArrayMap.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/LimitedRangeIntByteArrayMap.java
2008-11-29 19:18:00 UTC (rev 23980)
+++ branches/db4o/freenet/src/freenet/support/LimitedRangeIntByteArrayMap.java
2008-11-29 19:21:46 UTC (rev 23981)
@@ -146,6 +146,11 @@
}
}
+ public boolean wouldBlock(int index) {
+ if(minValue == -1) return false;
+ return (index - minValue >= maxRange);
+ }
+
/**
* Wait until add(index, whatever) would return true.
* If this returns, add(index, whatever) will work.
Property changes on:
branches/db4o/freenet/test/freenet/support/io/MockInputStream.java
___________________________________________________________________
Modified: svn:mergeinfo
- /trunk/freenet/test/freenet/support/io/MockInputStream.java:22002-23531
+ /trunk/freenet/test/freenet/support/io/MockInputStream.java:22002-23583
_______________________________________________
cvs mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs