Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/freenet/io/comm/MessageFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ public MessageFilter or(MessageFilter or) {
throw new IllegalStateException("Setting a second .or() on the same filter will replace the " +
"existing one, not add another. " + _or + " would be replaced by " + or + ".");
}
if(or._initialTimeout != _initialTimeout) {
Logger.error(this, "Message filters being or()ed have different timeouts! This is very dangerous! This is "+this+" or is "+or);
// FIXME throw new IllegalArgumentException()
}
_or = or;
return this;
}
Expand Down
26 changes: 17 additions & 9 deletions src/freenet/node/AnnounceSender.java
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,7 @@ private void realRun() {

if(onlyNode == null) {
// Route it
next = node.peers.closerPeer(source, nodesRoutedTo, target, true, node.isAdvancedModeEnabled(), -1,
null, null, htl, 0, source == null, false, false);
next = node.peers.closerPeerAnnouncement(source, nodesRoutedTo, target, htl);
} else {
next = onlyNode;
if(nodesRoutedTo.contains(onlyNode)) {
Expand Down Expand Up @@ -262,7 +261,7 @@ private void realRun() {
MessageFilter mfAnnounceReply = MessageFilter.create().setSource(next).setField(DMT.UID, uid).setTimeout(ANNOUNCE_TIMEOUT).setType(DMT.FNPOpennetAnnounceReply);
MessageFilter mfOpennetDisabled = MessageFilter.create().setSource(next).setField(DMT.UID, uid).setTimeout(ANNOUNCE_TIMEOUT).setType(DMT.FNPOpennetDisabled);
MessageFilter mfNotWanted = MessageFilter.create().setSource(next).setField(DMT.UID, uid).setTimeout(ANNOUNCE_TIMEOUT).setType(DMT.FNPOpennetAnnounceNodeNotWanted);
MessageFilter mfOpennetNoderefRejected = MessageFilter.create().setSource(next).setField(DMT.UID, uid).setTimeout(ACCEPTED_TIMEOUT).setType(DMT.FNPOpennetNoderefRejected);
MessageFilter mfOpennetNoderefRejected = MessageFilter.create().setSource(next).setField(DMT.UID, uid).setTimeout(ANNOUNCE_TIMEOUT).setType(DMT.FNPOpennetNoderefRejected);
MessageFilter mf = mfAnnounceCompleted.or(mfRouteNotFound.or(mfRejectedOverload.or(mfAnnounceReply.or(mfOpennetDisabled.or(mfNotWanted.or(mfOpennetNoderefRejected))))));

try {
Expand Down Expand Up @@ -290,6 +289,7 @@ private void realRun() {
if(msg.getSpec() == DMT.FNPOpennetAnnounceCompleted) {
// Send the completion on immediately. We don't want to accumulate 30 seconds per hop!
complete();
//"complete" should always be the last message, but we might grab it out-of-order from our queue.
mfAnnounceReply.setTimeout(END_TIMEOUT).setTimeoutRelativeToCreation(true);
mfNotWanted.setTimeout(END_TIMEOUT).setTimeoutRelativeToCreation(true);
mfAnnounceReply.clearOr();
Expand Down Expand Up @@ -494,6 +494,7 @@ private void rnf(PeerNode next) {
}

private void complete() {
addRefIfWanted();
synchronized(this) {
while(waitingForTransfers > 0) {
try {
Expand Down Expand Up @@ -521,12 +522,19 @@ private boolean transferNoderef() {
if(noderefBuf == null) {
return false;
}
SimpleFieldSet fs = OpennetManager.validateNoderef(noderefBuf, 0, noderefLength, source, false);
fs = OpennetManager.validateNoderef(noderefBuf, 0, noderefLength, source, false);
if(fs == null) {
OpennetManager.rejectRef(uid, source, DMT.NODEREF_REJECTED_INVALID, this);
return false;
}
return true;
}

private SimpleFieldSet fs;

private void addRefIfWanted() {
// If we want it, add it and send it.
if (fs==null ) return;
try {
// Allow reconnection - sometimes one side has the ref and the other side doesn't.
if(om.addNewOpennetNode(fs, ConnectionType.ANNOUNCE, true) != null) {
Expand All @@ -540,20 +548,20 @@ private boolean transferNoderef() {
} catch (FSParseException e) {
Logger.warning(this, "Rejecting noderef: "+e, e);
OpennetManager.rejectRef(uid, source, DMT.NODEREF_REJECTED_INVALID, this);
return false;
return;
} catch (PeerParseException e) {
Logger.warning(this, "Rejecting noderef: "+e, e);
OpennetManager.rejectRef(uid, source, DMT.NODEREF_REJECTED_INVALID, this);
return false;
return;
} catch (ReferenceSignatureVerificationException e) {
Logger.warning(this, "Rejecting noderef: "+e, e);
OpennetManager.rejectRef(uid, source, DMT.NODEREF_REJECTED_INVALID, this);
return false;
return;
} catch (NotConnectedException e) {
Logger.normal(this, "Could not receive noderef, disconnected");
return false;
return;
}
return true;
return;
}

private void sendNotWanted() throws NotConnectedException {
Expand Down
18 changes: 14 additions & 4 deletions src/freenet/node/Announcer.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ public class Announcer {
private int runningAnnouncements;
/** We want to announce to 5 different seednodes. */
private static final int WANT_ANNOUNCEMENTS = 5;
/** If true, announce through opennet peers as well as seednodes. If false, only announce through
* seednodes. FIXME SECURITY Capture by a single seednode may be slightly easier if we announce
* through opennet peers as well as seednodes, but until we have proper countermeasures to seed
* capture don't worry about it. FIXME make this configurable. */
private static final boolean ANNOUNCE_THROUGH_OPENNET_PEERS = true;
private int sentAnnouncements;
private long startTime;
private long timeAddedSeeds;
Expand Down Expand Up @@ -493,14 +498,16 @@ protected void maybeSendAnnouncement() {
return;
}
// Now find a node to announce to
List<SeedServerPeerNode> seeds = node.peers.getConnectedSeedServerPeersVector(announcedToIdentities);
List<? extends PeerNode> seeds =
ANNOUNCE_THROUGH_OPENNET_PEERS ? node.peers.getAnnounceStartPeersVector(announcedToIdentities) :
node.peers.getConnectedSeedServerPeersVector(announcedToIdentities);
while(sentAnnouncements < WANT_ANNOUNCEMENTS) {
if(seeds.isEmpty()) {
if(logMINOR)
Logger.minor(this, "No more seednodes, announcedTo = "+announcedToIdentities.size());
break;
}
final SeedServerPeerNode seed = ListUtils.removeRandomBySwapLastSimple(node.random, seeds);
final PeerNode seed = ListUtils.removeRandomBySwapLastSimple(node.random, seeds);
InetAddress[] addrs = seed.getInetAddresses();
if(!newAnnouncedIPs(addrs)) {
if(logMINOR)
Expand Down Expand Up @@ -565,7 +572,7 @@ private synchronized boolean newAnnouncedIPs(InetAddress[] addrs) {
return !hasNonLocalAddresses;
}

protected boolean sendAnnouncement(final SeedServerPeerNode seed) {
protected boolean sendAnnouncement(final PeerNode seed) {
if(!node.isOpennetEnabled()) {
if(logMINOR)
Logger.minor(this, "Not announcing to "+seed+" because opennet is disabled");
Expand Down Expand Up @@ -623,7 +630,10 @@ public void run() {
// If it takes more than COOLING_OFF_PERIOD to disconnect, we might not be able to reannounce to this
// node. However, we can't reannounce to it anyway until announcedTo is cleared, which probably will
// be more than that period in the future.
node.peers.disconnectAndRemove(seed, true, false, false);
if(seed instanceof SeedServerPeerNode) {
node.peers.disconnectAndRemove(seed, true, false, false);
if(logMINOR) Logger.minor(this, "Disconnected from seed server "+seed);
}
int shallow=node.maxHTL()-(totalAdded+totalNotWanted);
if(acceptedSomewhere)
System.out.println("Announcement to "+seed.userToString()+" completed ("+totalAdded+" added, "+totalNotWanted+" not wanted, "+shallow+" shallow)");
Expand Down
2 changes: 1 addition & 1 deletion src/freenet/node/BaseSender.java
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ protected void innerRouteRequestsNew(PeerNode next, UIDTag origTag) {

private PeerNode closerPeer(HashSet<PeerNode> exclude, long now, boolean newLoadManagement) {
return node.peers.closerPeer(sourceForRouting(), exclude, target, true, node.isAdvancedModeEnabled(), -1, null,
2.0, isInsert() ? null : key, htl, ignoreLowBackoff(), source == null, realTimeFlag, null, false, now, newLoadManagement);
2.0, isInsert() ? null : key, htl, ignoreLowBackoff(), source == null, realTimeFlag, null, false, now, newLoadManagement, false);
}

protected PeerNode sourceForRouting() {
Expand Down
6 changes: 6 additions & 0 deletions src/freenet/node/DarknetPeerNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -1948,4 +1948,10 @@ protected void sendInitialMessages() {
}
}
}

@Override
public int getMaxSimultaneousAnnouncements() {
// Darknet!
return 0;
}
}
10 changes: 6 additions & 4 deletions src/freenet/node/FNPPacketMangler.java
Original file line number Diff line number Diff line change
Expand Up @@ -1345,6 +1345,7 @@ private void processJFKMessage3(byte[] payload, int inputOffset, PeerNode pn,Pee
// Promote if necessary
boolean dontWant = false;
if(oldOpennetPeer) {
OpennetPeerNode opn = (OpennetPeerNode)pn;
OpennetManager opennet = node.getOpennet();
if(opennet == null) {
Logger.normal(this, "Dumping incoming old-opennet peer as opennet just turned off: "+pn+".");
Expand All @@ -1354,10 +1355,10 @@ private void processJFKMessage3(byte[] payload, int inputOffset, PeerNode pn,Pee
* immediately dropped when there is no droppable peer to drop. If it was dropped
* from the bottom of the LRU list, we would not have added it to the LRU; so it was
* somewhere in the middle. */
if(!opennet.wantPeer(pn, false, false, true, ConnectionType.RECONNECT)) {
if(!opennet.wantPeer(opn, false, false, true, ConnectionType.RECONNECT)) {
Logger.normal(this, "No longer want peer "+pn+" - dumping it after connecting");
dontWant = true;
opennet.purgeOldOpennetPeer(pn);
opennet.purgeOldOpennetPeer(opn);
}
// wantPeer will call node.peers.addPeer(), we don't have to.
}
Expand Down Expand Up @@ -1570,14 +1571,15 @@ private boolean processJFKMessage4(byte[] payload, int inputOffset, PeerNode pn,
Logger.normal(this, "Dumping incoming old-opennet peer as opennet just turned off: "+pn+".");
return true;
}
OpennetPeerNode opn = (OpennetPeerNode)pn;
/* When an old-opennet-peer connects, add it at the top of the LRU, so that it isn't
* immediately dropped when there is no droppable peer to drop. If it was dropped
* from the bottom of the LRU list, we would not have added it to the LRU; so it was
* somewhere in the middle. */
if(!opennet.wantPeer(pn, false, false, true, ConnectionType.RECONNECT)) {
if(!opennet.wantPeer(opn, false, false, true, ConnectionType.RECONNECT)) {
Logger.normal(this, "No longer want peer "+pn+" - dumping it after connecting");
dontWant = true;
opennet.purgeOldOpennetPeer(pn);
opennet.purgeOldOpennetPeer(opn);
}
// wantPeer will call node.peers.addPeer(), we don't have to.
}
Expand Down
2 changes: 1 addition & 1 deletion src/freenet/node/NodeClientCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -2112,7 +2112,7 @@ public long checkRecentlyFailed(Key key, boolean realTime) {
// slots and CPU. FIXME SECURITY/NETWORK: Reconsider if we ever decide
// not to decrement on the originator.
short origHTL = node.decrementHTL(null, node.maxHTL());
node.peers.closerPeer(null, new HashSet<PeerNode>(), key.toNormalizedDouble(), true, false, -1, null, 2.0, key, origHTL, 0, true, realTime, r, false, System.currentTimeMillis(), node.enableNewLoadManagement(realTime));
node.peers.closerPeer(null, new HashSet<PeerNode>(), key.toNormalizedDouble(), true, false, -1, null, 2.0, key, origHTL, 0, true, realTime, r, false, System.currentTimeMillis(), node.enableNewLoadManagement(realTime), false);
return r.recentlyFailed();
}

Expand Down
4 changes: 2 additions & 2 deletions src/freenet/node/NodeDispatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -432,10 +432,10 @@ private void finishDisconnect(final Message m, final PeerNode source) {
// around in secondary tables etc in order to more easily reconnect later.
// (Mostly used on opennet)
boolean purge = m.getBoolean(DMT.PURGE);
if(purge) {
if(purge && source instanceof OpennetPeerNode) {
OpennetManager om = node.getOpennet();
if(om != null)
om.purgeOldOpennetPeer(source);
om.purgeOldOpennetPeer((OpennetPeerNode)source);
}
// Process parting message
int type = m.getInt(DMT.NODE_TO_NODE_MESSAGE_TYPE);
Expand Down
40 changes: 20 additions & 20 deletions src/freenet/node/OpennetManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ public class OpennetManager {
final Announcer announcer;
final SeedAnnounceTracker seedTracker = new SeedAnnounceTracker();

/** Our peers. PeerNode's are promoted when they successfully fetch a key. Normally we take
/** Our peers. OpennetPeerNode's are promoted when they successfully fetch a key. Normally we take
* the bottom peer, but if that isn't eligible to be dropped, we iterate up the list. */
private final LRUQueue<PeerNode> peersLRU;
private final LRUQueue<OpennetPeerNode> peersLRU;
/** Old peers. Opennet peers which we dropped but would still like to talk to
* if we have no other option. */
private final LRUQueue<PeerNode> oldPeers;
private final LRUQueue<OpennetPeerNode> oldPeers;
/** Maximum number of old peers */
static final int MAX_OLD_PEERS = 25;
/** Time at which last dropped a peer due to an incoming connection of each type. */
Expand Down Expand Up @@ -205,8 +205,8 @@ public OpennetManager(Node node, NodeCryptoConfig opennetConfig, long startupTim
crypto.initCrypto();
}
}
peersLRU = new LRUQueue<PeerNode>();
oldPeers = new LRUQueue<PeerNode>();
peersLRU = new LRUQueue<OpennetPeerNode>();
oldPeers = new LRUQueue<OpennetPeerNode>();
node.peers.tryReadPeers(node.nodeDir().file("openpeers-"+crypto.portNumber).toString(), crypto, this, true, false);
OpennetPeerNode[] nodes = node.peers.getOpennetPeers();
Arrays.sort(nodes, new Comparator<OpennetPeerNode>() {
Expand Down Expand Up @@ -390,7 +390,7 @@ public OpennetPeerNode addNewOpennetNode(SimpleFieldSet fs, ConnectionType conne
/** When did we last offer our noderef to some other node? */
private long timeLastOffered;

void forceAddPeer(PeerNode nodeToAddNow, boolean addAtLRU) {
void forceAddPeer(OpennetPeerNode nodeToAddNow, boolean addAtLRU) {
synchronized(this) {
if(addAtLRU)
peersLRU.pushLeast(nodeToAddNow);
Expand Down Expand Up @@ -421,7 +421,7 @@ void forceAddPeer(PeerNode nodeToAddNow, boolean addAtLRU) {
* because of the first check.
* @return True if the node was added / should be added.
*/
public boolean wantPeer(PeerNode nodeToAddNow, boolean addAtLRU, boolean justChecking, boolean oldOpennetPeer, ConnectionType connectionType) {
public boolean wantPeer(OpennetPeerNode nodeToAddNow, boolean addAtLRU, boolean justChecking, boolean oldOpennetPeer, ConnectionType connectionType) {
boolean notMany = false;
boolean noDisconnect;
long now = System.currentTimeMillis();
Expand Down Expand Up @@ -512,7 +512,7 @@ public boolean wantPeer(PeerNode nodeToAddNow, boolean addAtLRU, boolean justChe
// Allow an offer to be predicated on throwing out a connected node,
// provided that we meet the other criteria e.g. time since last added,
// node isn't too new.
PeerNode toDrop = peerToDrop(noDisconnect, false, nodeToAddNow != null, connectionType, maxPeers);
OpennetPeerNode toDrop = peerToDrop(noDisconnect, false, nodeToAddNow != null, connectionType, maxPeers);
if(toDrop == null) {
if(logMINOR)
Logger.minor(this, "No more peers to drop (in first bit), still "+peersLRU.size()+" peers, cannot accept peer"+(nodeToAddNow == null ? "" : nodeToAddNow.toString()));
Expand Down Expand Up @@ -658,7 +658,7 @@ void dropExcessPeers() {
while(getSize() > maxPeers) {
if(logMINOR)
Logger.minor(this, "Dropping opennet peers: currently "+peersLRU.size());
PeerNode toDrop;
OpennetPeerNode toDrop;
toDrop = peerToDrop(false, false, false, null, maxPeers);
if(toDrop == null) toDrop = peerToDrop(false, true, false, null, maxPeers);
if(toDrop == null) return;
Expand All @@ -683,8 +683,8 @@ void dropExcessPeers() {
*/
synchronized public int getSize() {
int x = 0;
for (Enumeration<PeerNode> e = peersLRU.elements(); e.hasMoreElements();) {
PeerNode pn = e.nextElement();
for (Enumeration<OpennetPeerNode> e = peersLRU.elements(); e.hasMoreElements();) {
OpennetPeerNode pn = e.nextElement();
if(!pn.isUnroutableOlderVersion()) x++;
}
return x;
Expand Down Expand Up @@ -807,20 +807,20 @@ public void onRemove(OpennetPeerNode pn) {
}
}

synchronized PeerNode[] getOldPeers() {
return oldPeers.toArrayOrdered(new PeerNode[oldPeers.size()]);
synchronized OpennetPeerNode[] getOldPeers() {
return oldPeers.toArrayOrdered(new OpennetPeerNode[oldPeers.size()]);
}

synchronized PeerNode[] getUnsortedOldPeers() {
return oldPeers.toArray(new PeerNode[oldPeers.size()]);
synchronized OpennetPeerNode[] getUnsortedOldPeers() {
return oldPeers.toArray(new OpennetPeerNode[oldPeers.size()]);
}

/**
* Add an old opennet node - a node which might try to reconnect, and which we should accept
* if we are desperate.
* @param pn The node to add to the old opennet nodes LRU.
*/
synchronized void addOldOpennetNode(PeerNode pn) {
synchronized void addOldOpennetNode(OpennetPeerNode pn) {
oldPeers.push(pn);
}

Expand All @@ -832,13 +832,13 @@ synchronized int countOldOpennetPeers() {
return oldPeers.size();
}

PeerNode randomOldOpennetNode() {
PeerNode[] nodes = getUnsortedOldPeers();
OpennetPeerNode randomOldOpennetNode() {
OpennetPeerNode[] nodes = getUnsortedOldPeers();
if(nodes.length == 0) return null;
return nodes[node.random.nextInt(nodes.length)];
}

public synchronized void purgeOldOpennetPeer(PeerNode source) {
public synchronized void purgeOldOpennetPeer(OpennetPeerNode source) {
oldPeers.remove(source);
}

Expand Down Expand Up @@ -1200,7 +1200,7 @@ public int getAnnouncementThreshold() {

/** Notification that a peer was disconnected. Query the Announcer,
* it may need to rerun. */
public void onDisconnect(PeerNode node2) {
public void onDisconnect() {
if(announcer != null)
announcer.maybeSendAnnouncementOffThread();
}
Expand Down
9 changes: 9 additions & 0 deletions src/freenet/node/OpennetPeerNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -273,4 +273,13 @@ boolean dontKeepFullFieldSet() {
return true;
}

/** FIXME there clearly should be some limit, but if it's too low it'll
* be a problem for seednodes and their direct peers? */
static final int MAX_SIMULTANEOUS_ANNOUNCEMENTS_PER_PEER = 10;

@Override
public int getMaxSimultaneousAnnouncements() {
return MAX_SIMULTANEOUS_ANNOUNCEMENTS_PER_PEER;
}

}
4 changes: 2 additions & 2 deletions src/freenet/node/PacketSender.java
Original file line number Diff line number Diff line change
Expand Up @@ -426,9 +426,9 @@ private void realRun() {

OpennetManager om = node.getOpennet();
if(om != null && node.getUptime() > 30*1000) {
PeerNode[] peers = om.getOldPeers();
OpennetPeerNode[] peers = om.getOldPeers();

for(PeerNode pn : peers) {
for(OpennetPeerNode pn : peers) {
if(pn.timeLastConnected() <= 0)
Logger.error(this, "Last connected is zero or negative for old-opennet-peer "+pn);
// Will be removed by next line.
Expand Down
Loading