Author: toad
Date: 2007-06-29 17:30:56 +0000 (Fri, 29 Jun 2007)
New Revision: 13823
Added:
trunk/freenet/src/freenet/clients/http/OpennetConnectionsToadlet.java
trunk/freenet/src/freenet/node/NodeCryptoConfig.java
trunk/freenet/src/freenet/node/OpennetManager.java
trunk/freenet/src/freenet/node/OpennetPeerNode.java
trunk/freenet/src/freenet/node/OpennetPeerNodeStatus.java
Modified:
trunk/freenet/src/freenet/clients/http/ConnectionsToadlet.java
trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
trunk/freenet/src/freenet/clients/http/FProxyToadlet.java
trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties
trunk/freenet/src/freenet/node/DarknetPeerNode.java
trunk/freenet/src/freenet/node/FNPPacketMangler.java
trunk/freenet/src/freenet/node/Node.java
trunk/freenet/src/freenet/node/NodeARKInserter.java
trunk/freenet/src/freenet/node/NodeCrypto.java
trunk/freenet/src/freenet/node/PeerManager.java
trunk/freenet/src/freenet/node/PeerNode.java
trunk/freenet/src/freenet/node/TestnetHandler.java
trunk/freenet/src/freenet/node/TestnetStatusUploader.java
trunk/freenet/src/freenet/node/TextModeClientInterface.java
trunk/freenet/src/freenet/node/fcp/NodeData.java
trunk/freenet/src/freenet/node/simulator/RealNodeRequestInsertTest.java
Log:
Fix bugs, add support for opennet nodes (these are not very different from
darknet nodes yet), second port, Opennet page on web interface, node.opennet
config section etc - infrastructure for opennet (includes much refactoring)
Modified: trunk/freenet/src/freenet/clients/http/ConnectionsToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ConnectionsToadlet.java
2007-06-29 16:11:36 UTC (rev 13822)
+++ trunk/freenet/src/freenet/clients/http/ConnectionsToadlet.java
2007-06-29 17:30:56 UTC (rev 13823)
@@ -33,6 +33,65 @@
public abstract class ConnectionsToadlet extends Toadlet {
+ protected class ComparatorByStatus implements Comparator {
+
+ protected final String sortBy;
+ protected final boolean reversed;
+
+ ComparatorByStatus(String sortBy, boolean reversed) {
+ this.sortBy = sortBy;
+ this.reversed = reversed;
+ }
+
+ public int compare(Object first, Object second) {
+ int result = 0;
+ boolean isSet = true;
+ PeerNodeStatus firstNode = (DarknetPeerNodeStatus)
first;
+ PeerNodeStatus secondNode = (DarknetPeerNodeStatus)
second;
+
+ if(sortBy != null){
+ result = customCompare(firstNode, secondNode,
sortBy);
+ isSet = (result != 0);
+
+ }else
+ isSet=false;
+
+ if(!isSet){
+ int statusDifference =
firstNode.getStatusValue() - secondNode.getStatusValue();
+ if (statusDifference != 0)
+ result = (statusDifference < 0 ? -1 :
1);
+ else
+ result = lastResortCompare(firstNode,
secondNode);
+ }
+
+ if(result == 0){
+ return 0;
+ }else if(reversed){
+ isReversed = true;
+ return result > 0 ? -1 : 1;
+ }else{
+ isReversed = false;
+ return result < 0 ? -1 : 1;
+ }
+ }
+
+ protected int customCompare(PeerNodeStatus firstNode,
PeerNodeStatus secondNode, String sortBy2) {
+ if(sortBy.equals("address")){
+ return
firstNode.getPeerAddress().compareToIgnoreCase(secondNode.getPeerAddress());
+ }else if(sortBy.equals("location")){
+ return (firstNode.getLocation() -
secondNode.getLocation()) < 0 ? -1 : 1; // Shouldn't be equal anyway
+ }else if(sortBy.equals("version")){
+ return
Version.getArbitraryBuildNumber(firstNode.getVersion()) -
Version.getArbitraryBuildNumber(secondNode.getVersion());
+ }else
+ return 0;
+ }
+
+ /** Default comparison, after taking into account status */
+ protected int lastResortCompare(PeerNodeStatus firstNode,
PeerNodeStatus secondNode) {
+ return (firstNode.getLocation() -
secondNode.getLocation()) < 0 ? -1 : 1;
+ }
+ }
+
protected final Node node;
protected final NodeClientCore core;
protected final NodeStats stats;
@@ -55,7 +114,7 @@
public void handleGet(URI uri, final HTTPRequest request,
ToadletContext ctx) throws ToadletContextClosedException, IOException,
RedirectException {
String path = uri.getPath();
if(path.endsWith("myref.fref")) {
- SimpleFieldSet fs = node.exportPublicFieldSet();
+ SimpleFieldSet fs = getNoderef();
StringWriter sw = new StringWriter();
fs.writeTo(sw);
MultiValueTable extraHeaders = new MultiValueTable();
@@ -66,7 +125,7 @@
}
if(path.endsWith("myref.txt")) {
- SimpleFieldSet fs = node.exportPublicFieldSet();
+ SimpleFieldSet fs = getNoderef();
StringWriter sw = new StringWriter();
fs.writeTo(sw);
this.writeReply(ctx, 200, "text/plain", "OK",
sw.toString());
@@ -82,51 +141,8 @@
final boolean fProxyJavascriptEnabled =
node.isFProxyJavascriptEnabled();
/* gather connection statistics */
- DarknetPeerNodeStatus[] peerNodeStatuses =
peers.getDarknetPeerNodeStatuses();
- Arrays.sort(peerNodeStatuses, new Comparator() {
- public int compare(Object first, Object second) {
- int result = 0;
- boolean isSet = true;
- DarknetPeerNodeStatus firstNode =
(DarknetPeerNodeStatus) first;
- DarknetPeerNodeStatus secondNode =
(DarknetPeerNodeStatus) second;
-
- if(request.isParameterSet("sortBy")){
- final String sortBy =
request.getParam("sortBy");
-
- if(sortBy.equals("name")){
- result =
firstNode.getName().compareToIgnoreCase(secondNode.getName());
- }else if(sortBy.equals("address")){
- result =
firstNode.getPeerAddress().compareToIgnoreCase(secondNode.getPeerAddress());
- }else if(sortBy.equals("location")){
- result =
(firstNode.getLocation() - secondNode.getLocation()) < 0 ? -1 : 1; // Shouldn't
be equal anyway
- }else if(sortBy.equals("version")){
- result =
Version.getArbitraryBuildNumber(firstNode.getVersion()) -
Version.getArbitraryBuildNumber(secondNode.getVersion());
- }else if(sortBy.equals("privnote")){
- result =
firstNode.getPrivateDarknetCommentNote().compareToIgnoreCase(secondNode.getPrivateDarknetCommentNote());
- }else
- isSet=false;
- }else
- isSet=false;
-
- if(!isSet){
- int statusDifference =
firstNode.getStatusValue() - secondNode.getStatusValue();
- if (statusDifference != 0)
- result = (statusDifference < 0
? -1 : 1);
- else
- result =
firstNode.getName().compareToIgnoreCase(secondNode.getName());
- }
-
- if(result == 0){
- return 0;
- }else if(request.isParameterSet("reversed")){
- isReversed = true;
- return result > 0 ? -1 : 1;
- }else{
- isReversed = false;
- return result < 0 ? -1 : 1;
- }
- }
- });
+ PeerNodeStatus[] peerNodeStatuses = getPeerNodeStatuses();
+ Arrays.sort(peerNodeStatuses,
comparator(request.getParam("sortBy", null),
request.isParameterSet("reversed")));
int numberOfConnected =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_CONNECTED);
int numberOfRoutingBackedOff =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_ROUTING_BACKED_OFF);
@@ -433,7 +449,7 @@
L10n.addL10nSubstitution(warningSentence,
"DarknetConnectionsToadlet.referenceCopyWarning",
new String[] { "bold", "/bold" },
new String[] { "<b>", "</b>" });
- referenceInfobox.addChild("div", "class",
"infobox-content").addChild("pre", "id", "reference",
node.exportPublicFieldSet().toString() + '\n');
+ referenceInfobox.addChild("div", "class",
"infobox-content").addChild("pre", "id", "reference", getNoderef().toString() +
'\n');
// our ports
HTMLNode portInfobox = contentNode.addChild("div", "class",
"infobox infobox-normal");
@@ -468,6 +484,14 @@
}
+ protected Comparator comparator(String sortBy, boolean reversed) {
+ return new ComparatorByStatus(sortBy, reversed);
+ }
+
+ abstract protected PeerNodeStatus[] getPeerNodeStatuses();
+
+ abstract protected SimpleFieldSet getNoderef();
+
private void drawRow(HTMLNode peerTable, PeerNodeStatus peerNodeStatus,
boolean advancedModeEnabled, boolean fProxyJavascriptEnabled, long now, String
path) {
HTMLNode peerRow = peerTable.addChild("tr");
Modified: trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
2007-06-29 16:11:36 UTC (rev 13822)
+++ trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
2007-06-29 17:30:56 UTC (rev 13823)
@@ -7,6 +7,7 @@
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
+import java.util.Comparator;
import java.util.HashMap;
import freenet.client.HighLevelSimpleClient;
@@ -40,6 +41,32 @@
return L10n.getString("DarknetConnectionsToadlet."+string);
}
+ protected class DarknetComparator extends ComparatorByStatus {
+
+ DarknetComparator(String sortBy, boolean reversed) {
+ super(sortBy, reversed);
+ }
+
+ protected int customCompare(PeerNodeStatus firstNode,
PeerNodeStatus secondNode, String sortBy) {
+ if(sortBy.equals("name")) {
+ return
((DarknetPeerNodeStatus)firstNode).getName().compareToIgnoreCase(((DarknetPeerNodeStatus)secondNode).getName());
+ }else if(sortBy.equals("privnote")){
+ return
((DarknetPeerNodeStatus)firstNode).getPrivateDarknetCommentNote().compareToIgnoreCase(((DarknetPeerNodeStatus)secondNode).getPrivateDarknetCommentNote());
+ } else
+ return super.customCompare(firstNode,
secondNode, sortBy);
+ }
+
+ /** Default comparison, after taking into account status */
+ protected int lastResortCompare(PeerNodeStatus firstNode,
PeerNodeStatus secondNode) {
+ return
((DarknetPeerNodeStatus)firstNode).getName().compareToIgnoreCase(((DarknetPeerNodeStatus)secondNode).getName());
+ }
+
+ }
+
+ protected Comparator comparator(String sortBy, boolean reversed) {
+ return new DarknetComparator(sortBy, reversed);
+ }
+
public void handlePost(URI uri, final HTTPRequest request,
ToadletContext ctx) throws ToadletContextClosedException, IOException,
RedirectException {
boolean logMINOR = Logger.shouldLog(Logger.MINOR, this);
@@ -409,5 +436,13 @@
}
}
+ protected SimpleFieldSet getNoderef() {
+ return node.exportDarknetPublicFieldSet();
+ }
+ protected PeerNodeStatus[] getPeerNodeStatuses() {
+ return node.peers.getDarknetPeerNodeStatuses();
+ }
+
+
}
Modified: trunk/freenet/src/freenet/clients/http/FProxyToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/FProxyToadlet.java 2007-06-29
16:11:36 UTC (rev 13822)
+++ trunk/freenet/src/freenet/clients/http/FProxyToadlet.java 2007-06-29
17:30:56 UTC (rev 13823)
@@ -599,6 +599,9 @@
// server.register(friendsToadlet, "/darknet/", true,
l10n("friendsTitle"), l10n("friends"), true);
server.register(friendsToadlet, "/friends/", true,
l10n("friendsTitle"), l10n("friends"), true);
+ OpennetConnectionsToadlet opennetToadlet = new
OpennetConnectionsToadlet(node, core, client);
+ server.register(opennetToadlet, "/opennet/", true,
l10n("opennetTitle"), l10n("opennet"), true);
+
N2NTMToadlet n2ntmToadlet = new N2NTMToadlet(node,
core, client);
server.register(n2ntmToadlet, "/send_n2ntm/", true,
true);
Added: trunk/freenet/src/freenet/clients/http/OpennetConnectionsToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/OpennetConnectionsToadlet.java
(rev 0)
+++ trunk/freenet/src/freenet/clients/http/OpennetConnectionsToadlet.java
2007-06-29 17:30:56 UTC (rev 13823)
@@ -0,0 +1,42 @@
+package freenet.clients.http;
+
+import freenet.client.HighLevelSimpleClient;
+import freenet.node.Node;
+import freenet.node.NodeClientCore;
+import freenet.node.PeerNodeStatus;
+import freenet.support.HTMLNode;
+import freenet.support.SimpleFieldSet;
+
+public class OpennetConnectionsToadlet extends ConnectionsToadlet {
+
+ protected OpennetConnectionsToadlet(Node n, NodeClientCore core,
HighLevelSimpleClient client) {
+ super(n, core, client);
+ }
+
+ protected void drawNameColumn(HTMLNode peerRow,
+ PeerNodeStatus peerNodeStatus) {
+ // Do nothing - no names on opennet
+ }
+
+ protected void drawPrivateNoteColumn(HTMLNode peerRow,
+ PeerNodeStatus peerNodeStatus, boolean
fProxyJavascriptEnabled) {
+ // Do nothing - no private notes either (no such thing as
negative trust in cyberspace)
+ }
+
+ protected boolean hasNameColumn() {
+ return false;
+ }
+
+ protected boolean hasPrivateNoteColumn() {
+ return false;
+ }
+
+ protected SimpleFieldSet getNoderef() {
+ return node.exportOpennetPublicFieldSet();
+ }
+
+ protected PeerNodeStatus[] getPeerNodeStatuses() {
+ return node.peers.getOpennetPeerNodeStatuses();
+ }
+
+}
Modified: trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties
===================================================================
--- trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties 2007-06-29
16:11:36 UTC (rev 13822)
+++ trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties 2007-06-29
17:30:56 UTC (rev 13823)
@@ -227,6 +227,8 @@
FProxyToadlet.openPossRSSAsPlainText=${link}Click here${/link} to open the
file as plain text (this ${bold}may be dangerous${/bold} if you are running IE7
or FF2).
FProxyToadlet.openRSSAsRSS=${link}Click here${/link} to open the file as RSS
(this ${bold}is dangerous${/bold} if the site author is malicious as Freenet
does not know how to filter RSS yet).
FProxyToadlet.openRSSForce=${link}Click here${/link} to open the file as
${mime} (this ${bold}may be dangerous${/bold} on IE7 or FF2).
+FProxyToadlet.opennet=manage opennet peers
+FProxyToadlet.opennetTitle=Opennet
FProxyToadlet.options=Your options are:
FProxyToadlet.pathNotFound=The specified path does not exist.
FProxyToadlet.pathNotFoundTitle=Path Not Found
@@ -513,6 +515,8 @@
Node.nodeDirLong=Name of directory to put node-related files e.g. peers list in
Node.nodeName=Nickname for this Freenet node
Node.nodeNameLong=Node nickname. This will be visible to your friends only.
+Node.opennetEnabled=Enable Opennet support?
+Node.opennetEnabledLong=Enable Opennet? If opennet is enabled, the node will
automatically exchange node references with other nodes. 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
darknet connections to them.
Node.outBWLimit=Output bandwidth limit (bytes per second)
Node.outBWLimitLong=Hard output bandwidth limit (bytes/sec); the node should
almost never exceed this
Node.port=FNP port number (UDP)
Modified: trunk/freenet/src/freenet/node/DarknetPeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/DarknetPeerNode.java 2007-06-29 16:11:36 UTC
(rev 13822)
+++ trunk/freenet/src/freenet/node/DarknetPeerNode.java 2007-06-29 17:30:56 UTC
(rev 13823)
@@ -188,7 +188,7 @@
}
public synchronized SimpleFieldSet exportFieldSet() {
- SimpleFieldSet fs = super.exportMetadataFieldSet();
+ SimpleFieldSet fs = super.exportFieldSet();
fs.putSingle("myName", getName());
return fs;
}
Modified: trunk/freenet/src/freenet/node/FNPPacketMangler.java
===================================================================
--- trunk/freenet/src/freenet/node/FNPPacketMangler.java 2007-06-29
16:11:36 UTC (rev 13822)
+++ trunk/freenet/src/freenet/node/FNPPacketMangler.java 2007-06-29
17:30:56 UTC (rev 13823)
@@ -333,7 +333,7 @@
PCFBMode pcfb = PCFBMode.create(cipher);
byte[] iv = new byte[pcfb.lengthIV()];
- byte[] myRef = node.myCompressedSetupRef();
+ byte[] myRef = crypto.myCompressedSetupRef();
byte[] data = new byte[myRef.length + 8];
System.arraycopy(Fields.longToBytes(node.bootID), 0, data, 0, 8);
System.arraycopy(myRef, 0, data, 8, myRef.length);
Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java 2007-06-29 16:11:36 UTC (rev
13822)
+++ trunk/freenet/src/freenet/node/Node.java 2007-06-29 17:30:56 UTC (rev
13823)
@@ -8,7 +8,6 @@
import java.io.BufferedReader;
import java.io.BufferedWriter;
-import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -26,7 +25,6 @@
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.Random;
-import java.util.zip.DeflaterOutputStream;
import org.spaceroots.mantissa.random.MersenneTwister;
import org.tanukisoftware.wrapper.WrapperManager;
@@ -46,7 +44,6 @@
import freenet.config.PersistentConfig;
import freenet.config.SubConfig;
import freenet.crypt.DSAPublicKey;
-import freenet.crypt.DSASignature;
import freenet.crypt.RandomSource;
import freenet.crypt.SHA256;
import freenet.io.comm.DMT;
@@ -297,12 +294,6 @@
/** Semi-unique ID for swap requests. Used to identify us so that the
* topology can be reconstructed. */
public long swapIdentifier;
- /** The signature of the above fieldset */
- private DSASignature myReferenceSignature = null;
- /** A synchronization object used while signing the reference fiedlset
*/
- private volatile Object referenceSync = new Object();
- /** An ordered version of the FieldSet, without the signature */
- private String mySignedReference = null;
private String myName;
final LocationManager lm;
/** My peers */
@@ -324,7 +315,8 @@
// Opennet stuff
- private NodeCrypto opennetCrypto;
+ private final NodeCryptoConfig opennetCryptoConfig;
+ private OpennetManager opennet;
// General stuff
@@ -459,7 +451,7 @@
}
private void writeNodeFile(File orig, File backup) {
- SimpleFieldSet fs = exportPrivateFieldSet();
+ SimpleFieldSet fs = darknetCrypto.exportPrivateFieldSet();
if(orig.exists()) backup.delete();
@@ -608,7 +600,9 @@
// Determine the port number
- darknetCrypto = new NodeCrypto(nodeConfig, sortOrder++, this);
+ NodeCryptoConfig darknetConfig = new
NodeCryptoConfig(nodeConfig, sortOrder++);
+ sortOrder += NodeCryptoConfig.OPTION_COUNT;
+ darknetCrypto = new NodeCrypto(sortOrder++, this, false,
darknetConfig);
// Must be created after darknetCrypto
dnsr = new DNSRequester(this);
@@ -767,10 +761,53 @@
usm.setDispatcher(dispatcher=new NodeDispatcher(this));
// Then read the peers
- peers = new PeerManager(this, darknetCrypto, new File(nodeDir,
"peers-"+getDarknetPortNumber()).getPath(), darknetCrypto.packetMangler);
+ peers = new PeerManager(this);
+ peers.tryReadPeers(new File(nodeDir,
"peers-"+getDarknetPortNumber()).getPath(), darknetCrypto, false);
peers.writePeers();
peers.updatePMUserAlert();
+ // Opennet
+
+ final SubConfig opennetConfig = new SubConfig("node.opennet",
config);
+
+ // Can be enabled on the fly
+ opennetConfig.register("enabled", false, 0, false, true,
"Node.opennetEnabled", "Node.opennetEnabledLong", new BooleanCallback() {
+ public boolean get() {
+ synchronized(Node.this) {
+ return opennet != null;
+ }
+ }
+ public void set(boolean val) throws
InvalidConfigValueException {
+ synchronized(Node.this) {
+ if(val == (opennet != null)) return;
+ if(val) {
+ try {
+ opennet = new
OpennetManager(Node.this, opennetCryptoConfig);
+ } catch (NodeInitException e) {
+ throw new
InvalidConfigValueException(e.getMessage());
+ }
+ } else {
+ opennet = null;
+ }
+ }
+ if(val) opennet.start();
+ else opennet.stop();
+ }
+ });
+
+ boolean opennetEnabled = opennetConfig.getBoolean("enabled");
+
+ opennetCryptoConfig = new NodeCryptoConfig(opennetConfig, 1 /*
0 = enabled */);
+
+ if(opennetEnabled) {
+ opennet = new OpennetManager(this, opennetCryptoConfig);
+ // Will be started later
+ } else {
+ opennet = null;
+ }
+
+ opennetConfig.finishedInitialization();
+
// Extra Peer Data Directory
nodeConfig.register("extraPeerDataDir", new File(nodeDir,
"extra-peer-data-"+getDarknetPortNumber()).toString(), sortOrder++, true,
false, "Node.extraPeerDir", "Node.extraPeerDirLong",
new StringCallback() {
@@ -1216,6 +1253,8 @@
usm.start(ps);
darknetCrypto.start(disableHangCheckers);
+ if(opennet != null)
+ opennet.start();
if(isUsingWrapper()) {
Logger.normal(this, "Using wrapper correctly:
"+nodeStarter);
@@ -1456,61 +1495,7 @@
return L10n.getString("Node."+key, pattern, value);
}
- public SimpleFieldSet exportPrivateFieldSet() {
- SimpleFieldSet fs = exportPublicFieldSet(false);
- darknetCrypto.addPrivateFields(fs);
- return fs;
- }
-
/**
- * Export my node reference so that another node can connect to me.
- * Public version, includes everything apart from private keys.
- * @see exportPublicFieldSet(boolean forSetup).
- */
- public SimpleFieldSet exportPublicFieldSet() {
- return exportPublicFieldSet(false);
- }
-
- /**
- * Export my reference so that another node can connect to me.
- * @param forSetup If true, strip out everything that isn't needed for
the references
- * exchanged immediately after connection setup. I.e. strip out
everything that is invariant,
- * or that can safely be exchanged later.
- */
- SimpleFieldSet exportPublicFieldSet(boolean forSetup) {
- SimpleFieldSet fs =
darknetCrypto.exportPublicFieldSet(forSetup);
- // IP addresses
- Peer[] ips = ipDetector.getPrimaryIPAddress();
- if(ips != null) {
- for(int i=0;i<ips.length;i++)
- fs.putAppend("physical.udp",
ips[i].toString()); // Keep; important that node know all our IPs
- }
- // Negotiation types
- fs.put("location", lm.getLocation().getValue()); // FIXME maybe
!forSetup; see #943
- fs.putSingle("version", Version.getVersionString()); // Keep,
vital that peer know our version. For example, some types may be sent in
different formats to different node versions (e.g. Peer).
- fs.put("testnet", testnetEnabled); // Vital that peer know this!
- fs.putSingle("lastGoodVersion",
Version.getLastGoodVersionString()); // Also vital
- if(testnetEnabled)
- fs.put("testnetPort", testnetHandler.getPort()); //
Useful, saves a lot of complexity
- fs.putSingle("myName", myName); // FIXME see #942
-
- synchronized (referenceSync) {
- if(myReferenceSignature == null || mySignedReference ==
null || !mySignedReference.equals(fs.toOrderedString())){
- mySignedReference = fs.toOrderedString();
- try {
- myReferenceSignature =
darknetCrypto.signRef(mySignedReference);
- } catch (NodeInitException e) {
- exit(e.exitCode);
- }
- }
- fs.putSingle("sig",
myReferenceSignature.toLongString());
- }
-
- if(logMINOR) Logger.minor(this, "My reference:
"+fs.toOrderedString());
- return fs;
- }
-
- /**
* Export volatile data about the node as a SimpleFieldSet
*/
public SimpleFieldSet exportVolatileFieldSet() {
@@ -2099,34 +2084,6 @@
return sb.toString();
}
- /**
- * The part of our node reference which is exchanged in the connection
setup, compressed.
- * @see exportSetupFieldSet()
- */
- public byte[] myCompressedSetupRef() {
- SimpleFieldSet fs = exportPublicFieldSet(true);
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- DeflaterOutputStream gis;
- gis = new DeflaterOutputStream(baos);
- OutputStreamWriter osw = new OutputStreamWriter(gis);
- BufferedWriter bw = new BufferedWriter(osw);
- try {
- fs.writeTo(bw);
- } catch (IOException e) {
- throw new Error(e);
- }
- try {
- bw.close();
- } catch (IOException e1) {
- throw new Error(e1);
- }
- byte[] buf = baos.toByteArray();
- byte[] obuf = new byte[buf.length + 1];
- obuf[0] = 1;
- System.arraycopy(buf, 0, obuf, 1, buf.length);
- return obuf;
- }
-
final LRUQueue recentlyCompletedIDs;
static final int MAX_RECENTLY_COMPLETED_IDS = 10*1000;
@@ -2560,7 +2517,7 @@
* Connect this node to another node (for purposes of testing)
*/
public void connect(Node node) throws FSParseException,
PeerParseException, ReferenceSignatureVerificationException {
- peers.connect(node.exportPublicFieldSet(),
darknetCrypto.packetMangler);
+ peers.connect(node.darknetCrypto.exportPublicFieldSet(),
darknetCrypto.packetMangler);
}
public short maxHTL() {
@@ -2612,4 +2569,20 @@
public int estimateFullHeadersLengthOneMessage() {
return
darknetCrypto.packetMangler.fullHeadersLengthOneMessage();
}
+
+ public synchronized boolean isOpennetEnabled() {
+ return opennet != null;
+ }
+
+ public SimpleFieldSet exportDarknetPublicFieldSet() {
+ return darknetCrypto.exportPublicFieldSet();
+ }
+
+ public SimpleFieldSet exportOpennetPublicFieldSet() {
+ return opennet.crypto.exportPublicFieldSet();
+ }
+
+ public SimpleFieldSet exportDarknetPrivateFieldSet() {
+ return darknetCrypto.exportPrivateFieldSet();
+ }
}
Modified: trunk/freenet/src/freenet/node/NodeARKInserter.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeARKInserter.java 2007-06-29 16:11:36 UTC
(rev 13822)
+++ trunk/freenet/src/freenet/node/NodeARKInserter.java 2007-06-29 17:30:56 UTC
(rev 13823)
@@ -109,7 +109,7 @@
if(logMINOR) Logger.minor(this, "starting inserter");
- SimpleFieldSet fs = this.node.exportPublicFieldSet(true); //
More or less
+ SimpleFieldSet fs = crypto.exportPublicFieldSet(true); // More
or less
// Remove some unnecessary fields that only cause collisions.
Modified: trunk/freenet/src/freenet/node/NodeCrypto.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeCrypto.java 2007-06-29 16:11:36 UTC
(rev 13822)
+++ trunk/freenet/src/freenet/node/NodeCrypto.java 2007-06-29 17:30:56 UTC
(rev 13823)
@@ -1,16 +1,20 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
package freenet.node;
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.security.MessageDigest;
+import java.util.zip.DeflaterOutputStream;
import net.i2p.util.NativeBigInteger;
-
-import freenet.config.InvalidConfigValueException;
-import freenet.config.SubConfig;
import freenet.crypt.DSA;
import freenet.crypt.DSAGroup;
import freenet.crypt.DSAPrivateKey;
@@ -19,6 +23,7 @@
import freenet.crypt.Global;
import freenet.crypt.RandomSource;
import freenet.crypt.SHA256;
+import freenet.io.comm.Peer;
import freenet.io.comm.UdpSocketHandler;
import freenet.keys.FreenetURI;
import freenet.keys.InsertableClientSSK;
@@ -27,8 +32,6 @@
import freenet.support.IllegalBase64Exception;
import freenet.support.Logger;
import freenet.support.SimpleFieldSet;
-import freenet.support.api.IntCallback;
-import freenet.support.api.StringCallback;
/**
* Cryptographic and transport level node identity.
@@ -36,11 +39,13 @@
*/
class NodeCrypto {
+ final Node node;
+ final boolean isOpennet;
final RandomSource random;
/** The object which handles our specific UDP port, pulls messages from
it, feeds them to the packet mangler for decryption etc */
UdpSocketHandler socket;
public FNPPacketMangler packetMangler;
- final String bindto;
+ final InetAddress bindto;
// FIXME: abstract out address stuff? Possibly to something like
NodeReference?
final int portNumber;
byte[] myIdentity; // FIXME: simple identity block; should be unique
@@ -60,41 +65,32 @@
long myARKNumber;
static boolean logMINOR;
+ // Noderef related
+ /** The signature of the above fieldset */
+ private DSASignature myReferenceSignature = null;
+ /** A synchronization object used while signing the reference fiedlset
*/
+ private volatile Object referenceSync = new Object();
+ /** An ordered version of the FieldSet, without the signature */
+ private String mySignedReference = null;
+
/**
* Get port number from a config, create socket and packet mangler
* @throws NodeInitException
*/
- public NodeCrypto(SubConfig nodeConfig, int sortOrder, Node node)
throws NodeInitException {
-
+ public NodeCrypto(int sortOrder, Node node, boolean isOpennet,
NodeCryptoConfig config) throws NodeInitException {
+
+ this.node = node;
random = node.random;
+ this.isOpennet = isOpennet;
logMINOR = Logger.shouldLog(Logger.MINOR, this);
- nodeConfig.register("listenPort", -1 /* means random */,
sortOrder++, true, true, "Node.port", "Node.portLong", new IntCallback() {
- public int get() {
- return portNumber;
- }
- public void set(int val) throws
InvalidConfigValueException {
- // FIXME implement on the fly listenPort
changing
- // Note that this sort of thing should be the
exception rather than the rule!!!!
- String msg = "Switching listenPort on the fly
not yet supported!";
- Logger.error(this, msg);
- throw new InvalidConfigValueException(msg);
- }
- });
+ config.starting(this);
- int port=-1;
- try{
- port=nodeConfig.getInt("listenPort");
- }catch (Exception e){
- Logger.error(this, "Caught "+e, e);
- System.err.println(e);
- e.printStackTrace();
- port=-1;
- }
+ try {
- nodeConfig.register("bindTo", "0.0.0.0", sortOrder++, true,
true, "Node.bindTo", "Node.bindToLong", new NodeBindtoCallback());
+ int port = config.getPort();
- this.bindto = nodeConfig.getString("bindTo");
+ bindto = config.getBindTo();
UdpSocketHandler u = null;
@@ -105,7 +101,7 @@
for(int i=0;i<200000;i++) {
int portNo = 1024 + random.nextInt(65535-1024);
try {
- u = new UdpSocketHandler(portNo,
InetAddress.getByName(bindto), node);
+ u = new UdpSocketHandler(portNo,
bindto, node);
port = u.getPortNumber();
break;
} catch (Exception e) {
@@ -119,7 +115,7 @@
throw new
NodeInitException(NodeInitException.EXIT_NO_AVAILABLE_UDP_PORTS, "Could not
find an available UDP port number for FNP (none specified)");
} else {
try {
- u = new UdpSocketHandler(port,
InetAddress.getByName(bindto), node);
+ u = new UdpSocketHandler(port, bindto, node);
} catch (Exception e) {
throw new
NodeInitException(NodeInitException.EXIT_IMPOSSIBLE_USM_PORT, "Could not bind
to port: "+port+" (node already running?)");
}
@@ -129,39 +125,25 @@
Logger.normal(this, "FNP port created on "+bindto+ ':' +port);
System.out.println("FNP port created on "+bindto+ ':' +port);
portNumber = port;
+ config.setPort(port);
- nodeConfig.register("testingDropPacketsEvery", 0, sortOrder++,
true, false, "Node.dropPacketEvery", "Node.dropPacketEveryLong",
- new IntCallback() {
-
- public int get() {
- return
((UdpSocketHandler)socket).getDropProbability();
- }
-
- public void set(int val) throws
InvalidConfigValueException {
-
((UdpSocketHandler)socket).setDropProbability(val);
- }
-
- });
+
((UdpSocketHandler)socket).setDropProbability(config.getDropProbability());
- int dropProb = nodeConfig.getInt("testingDropPacketsEvery");
- ((UdpSocketHandler)socket).setDropProbability(dropProb);
-
socket.setLowLevelFilter(packetMangler = new
FNPPacketMangler(node, this, socket));
+ } catch (NodeInitException e) {
+ config.stopping(this);
+ throw e;
+ } catch (RuntimeException e) {
+ config.stopping(this);
+ throw e;
+ } catch (Error e) {
+ config.stopping(this);
+ throw e;
+ } finally {
+ config.maybeStarted(this);
+ }
}
- class NodeBindtoCallback implements StringCallback {
-
- public String get() {
- return bindto;
- }
-
- public void set(String val) throws InvalidConfigValueException {
- if(val.equals(get())) return;
- // FIXME why not? Can't we use
freenet.io.NetworkInterface like everywhere else, just adapt it for UDP?
- throw new InvalidConfigValueException("Cannot be
updated on the fly");
- }
- }
-
/**
* Read the cryptographic keys etc from a SimpleFieldSet
* @param fs
@@ -246,8 +228,64 @@
public void start(boolean disableHangchecker) {
socket.start(disableHangchecker);
}
+
+ public SimpleFieldSet exportPrivateFieldSet() {
+ SimpleFieldSet fs = exportPublicFieldSet(false);
+ addPrivateFields(fs);
+ return fs;
+ }
+
+ /**
+ * Export my node reference so that another node can connect to me.
+ * Public version, includes everything apart from private keys.
+ * @see exportPublicFieldSet(boolean forSetup).
+ */
+ public SimpleFieldSet exportPublicFieldSet() {
+ return exportPublicFieldSet(false);
+ }
+
+ /**
+ * Export my reference so that another node can connect to me.
+ * @param forSetup If true, strip out everything that isn't needed for
the references
+ * exchanged immediately after connection setup. I.e. strip out
everything that is invariant,
+ * or that can safely be exchanged later.
+ */
+ SimpleFieldSet exportPublicFieldSet(boolean forSetup) {
+ SimpleFieldSet fs = exportPublicCryptoFieldSet(forSetup);
+ // IP addresses
+ Peer[] ips = node.ipDetector.getPrimaryIPAddress();
+ if(ips != null) {
+ for(int i=0;i<ips.length;i++)
+ fs.putAppend("physical.udp",
ips[i].toString()); // Keep; important that node know all our IPs
+ }
+ // Negotiation types
+ fs.put("location", node.lm.getLocation().getValue()); // FIXME
maybe !forSetup; see #943
+ fs.putSingle("version", Version.getVersionString()); // Keep,
vital that peer know our version. For example, some types may be sent in
different formats to different node versions (e.g. Peer).
+ fs.put("testnet", node.testnetEnabled); // Vital that peer know
this!
+ fs.putSingle("lastGoodVersion",
Version.getLastGoodVersionString()); // Also vital
+ if(node.testnetEnabled)
+ fs.put("testnetPort", node.testnetHandler.getPort());
// Useful, saves a lot of complexity
+ if(!isOpennet)
+ fs.putSingle("myName", node.getMyName()); // FIXME see
#942
+
+ synchronized (referenceSync) {
+ if(myReferenceSignature == null || mySignedReference ==
null || !mySignedReference.equals(fs.toOrderedString())){
+ mySignedReference = fs.toOrderedString();
+ try {
+ myReferenceSignature =
signRef(mySignedReference);
+ } catch (NodeInitException e) {
+ node.exit(e.exitCode);
+ }
+ }
+ fs.putSingle("sig",
myReferenceSignature.toLongString());
+ }
+ fs.put("opennet", isOpennet);
+
+ if(logMINOR) Logger.minor(this, "My reference:
"+fs.toOrderedString());
+ return fs;
+ }
- SimpleFieldSet exportPublicFieldSet(boolean forSetup) {
+ SimpleFieldSet exportPublicCryptoFieldSet(boolean forSetup) {
SimpleFieldSet fs = new SimpleFieldSet(true);
int[] negTypes = packetMangler.supportedNegTypes();
fs.put("auth.negTypes", negTypes);
@@ -283,15 +321,39 @@
}
}
+ /**
+ * The part of our node reference which is exchanged in the connection
setup, compressed.
+ * @see exportSetupFieldSet()
+ */
+ public byte[] myCompressedSetupRef() {
+ SimpleFieldSet fs = exportPublicFieldSet(true);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DeflaterOutputStream gis;
+ gis = new DeflaterOutputStream(baos);
+ OutputStreamWriter osw = new OutputStreamWriter(gis);
+ BufferedWriter bw = new BufferedWriter(osw);
+ try {
+ fs.writeTo(bw);
+ } catch (IOException e) {
+ throw new Error(e);
+ }
+ try {
+ bw.close();
+ } catch (IOException e1) {
+ throw new Error(e1);
+ }
+ byte[] buf = baos.toByteArray();
+ byte[] obuf = new byte[buf.length + 1];
+ obuf[0] = 1;
+ System.arraycopy(buf, 0, obuf, 1, buf.length);
+ return obuf;
+ }
+
void addPrivateFields(SimpleFieldSet fs) {
fs.put("dsaPrivKey", privKey.asFieldSet());
fs.putSingle("ark.privURI",
myARK.getInsertURI().toString(false, false));
}
- public String getBindTo(){
- return this.bindto;
- }
-
public int getIdentityHash(){
return Fields.hashCode(identityHash);
}
@@ -300,5 +362,12 @@
DSASignature sign(byte[] hash) {
return DSA.sign(cryptoGroup, privKey, new NativeBigInteger(1,
hash), random);
}
+
+ public void onSetDropProbability(int val) {
+ synchronized(this) {
+ if(socket == null) return;
+ }
+ socket.setDropProbability(val);
+ }
}
Added: trunk/freenet/src/freenet/node/NodeCryptoConfig.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeCryptoConfig.java
(rev 0)
+++ trunk/freenet/src/freenet/node/NodeCryptoConfig.java 2007-06-29
17:30:56 UTC (rev 13823)
@@ -0,0 +1,162 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+package freenet.node;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import freenet.config.InvalidConfigValueException;
+import freenet.config.SubConfig;
+import freenet.io.comm.FreenetInetAddress;
+import freenet.support.Logger;
+import freenet.support.api.IntCallback;
+import freenet.support.api.StringCallback;
+
+/**
+ * Tracks config parameters related to a NodeCrypto. The NodeCrypto may or may
not exist. If it exists,
+ * parameter changes are passed on to it, if it doesn't, they can be changed
trivially.
+ *
+ * Allows users to set the opennet port number while opennet is disabled,
enable opennet on the fly etc.
+ * @author toad
+ */
+public class NodeCryptoConfig {
+
+ /** Port number. -1 = choose a random available port number at
activation time. */
+ private int portNumber;
+
+ /** Bind address. 0.0.0.0 = all addresses. */
+ private InetAddress bindTo;
+
+ /** If nonzero, 1/dropProbability = probability of UdpSocketHandler
dropping a packet (for debugging
+ * purposes; not static as we may need to simulate some nodes with more
loss than others). */
+ private int dropProbability;
+
+ /** The NodeCrypto, if there is one */
+ private NodeCrypto crypto;
+
+ /** Whether the NodeCrypto has finished starting */
+ private boolean started;
+
+ NodeCryptoConfig(SubConfig config, int sortOrder) throws
NodeInitException {
+
+ config.register("listenPort", -1 /* means random */,
sortOrder++, true, true, "Node.port", "Node.portLong", new IntCallback() {
+ public int get() {
+ synchronized(NodeCryptoConfig.class) {
+ if(crypto != null)
+ portNumber = crypto.portNumber;
+ return portNumber;
+ }
+ }
+ public void set(int val) throws
InvalidConfigValueException {
+
+ if(portNumber < -1 || portNumber == 0 ||
portNumber > 65535) {
+ throw new
InvalidConfigValueException("Invalid port number");
+ }
+
+
+ synchronized(NodeCryptoConfig.class) {
+ if(portNumber == val) return;
+ // FIXME implement on the fly
listenPort changing
+ // Note that this sort of thing should
be the exception rather than the rule!!!!
+ if(crypto != null)
+ throw new
InvalidConfigValueException("Switching listenPort on the fly not yet
supported");
+ portNumber = val;
+ }
+ }
+ });
+
+ try{
+ portNumber = config.getInt("listenPort");
+ }catch (Exception e){
+ // FIXME is this really necessary?
+ Logger.error(this, "Caught "+e, e);
+ System.err.println(e);
+ e.printStackTrace();
+ portNumber = -1;
+ }
+
+ config.register("bindTo", "0.0.0.0", sortOrder++, true, true,
"Node.bindTo", "Node.bindToLong", new NodeBindtoCallback());
+
+ try {
+ bindTo =
InetAddress.getByName(config.getString("bindTo"));
+ } catch (UnknownHostException e) {
+ throw new
NodeInitException(NodeInitException.EXIT_COULD_NOT_BIND_USM, "Invalid bindTo:
"+config.getString("bindTo"));
+ }
+
+ config.register("testingDropPacketsEvery", 0, sortOrder++,
true, false, "Node.dropPacketEvery", "Node.dropPacketEveryLong",
+ new IntCallback() {
+
+ public int get() {
+
synchronized(NodeCryptoConfig.this) {
+ return dropProbability;
+ }
+ }
+
+ public void set(int val) throws
InvalidConfigValueException {
+ if(val < 0) throw new
InvalidConfigValueException("testingDropPacketsEvery must not be negative");
+
synchronized(NodeCryptoConfig.this) {
+ if(val ==
dropProbability) return;
+ dropProbability = val;
+ if(crypto == null)
return;
+ }
+
crypto.onSetDropProbability(val);
+ }
+
+ });
+
+ }
+
+ /** The number of config options i.e. the amount to increment sortOrder
by */
+ public static final int OPTION_COUNT = 3;
+
+ synchronized void starting(NodeCrypto crypto2) {
+ if(crypto != null) throw new IllegalStateException("Replacing
existing NodeCrypto "+crypto+" with "+crypto2);
+ crypto = crypto2;
+ started = false;
+ }
+
+ synchronized void started(NodeCrypto crypto2) {
+ if(crypto != null) throw new IllegalStateException("Replacing
existing NodeCrypto "+crypto+" with "+crypto2);
+ started = true;
+ }
+
+ synchronized void maybeStarted(NodeCrypto crypto2) {
+ if(crypto != null)
+ started = true;
+ }
+
+ synchronized void stopping(NodeCrypto crypto2) {
+ crypto = null;
+ }
+
+ public int getPort() {
+ return portNumber;
+ }
+
+ class NodeBindtoCallback implements StringCallback {
+
+ public String get() {
+ return FreenetInetAddress.getHostName(bindTo);
+ }
+
+ public void set(String val) throws InvalidConfigValueException {
+ if(val.equals(get())) return;
+ // FIXME why not? Can't we use
freenet.io.NetworkInterface like everywhere else, just adapt it for UDP?
+ throw new InvalidConfigValueException("Cannot be
updated on the fly");
+ }
+ }
+
+ public InetAddress getBindTo() {
+ return bindTo;
+ }
+
+ public synchronized void setPort(int port) {
+ portNumber = port;
+ }
+
+ public synchronized int getDropProbability() {
+ return dropProbability;
+ }
+
+}
Added: trunk/freenet/src/freenet/node/OpennetManager.java
===================================================================
--- trunk/freenet/src/freenet/node/OpennetManager.java
(rev 0)
+++ trunk/freenet/src/freenet/node/OpennetManager.java 2007-06-29 17:30:56 UTC
(rev 13823)
@@ -0,0 +1,85 @@
+package freenet.node;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import freenet.io.comm.Peer;
+import freenet.io.comm.PeerParseException;
+import freenet.support.SimpleFieldSet;
+
+/**
+ * Central location for all things opennet.
+ * In particular:
+ * - Opennet crypto
+ * - LRU connections
+ * @author toad
+ */
+public class OpennetManager {
+
+ final Node node;
+ final NodeCrypto crypto;
+
+ public OpennetManager(Node node, NodeCryptoConfig opennetConfig) throws
NodeInitException {
+ this.node = node;
+ crypto =
+ new NodeCrypto(1 /* 0 is enabled */, node, true,
opennetConfig);
+
+ // Keep opennet crypto details in a separate file
+ try {
+ readFile(new File(node.nodeDir,
"opennet-"+crypto.portNumber).getPath());
+ } catch (IOException e) {
+ try {
+ readFile(new
File("node-"+crypto.portNumber+".bak").getPath());
+ } catch (IOException e1) {
+ crypto.initCrypto();
+ }
+ }
+ node.peers.tryReadPeers(new File(node.nodeDir,
"openpeers-"+crypto.portNumber).toString(), crypto, true);
+ }
+
+ private void readFile(String filename) throws IOException {
+ // REDFLAG: Any way to share this code with Node and NodePeer?
+ FileInputStream fis = new FileInputStream(filename);
+ InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
+ BufferedReader br = new BufferedReader(isr);
+ SimpleFieldSet fs = new SimpleFieldSet(br, false, true);
+ br.close();
+ // Read contents
+ String[] udp = fs.getAll("physical.udp");
+ if((udp != null) && (udp.length > 0)) {
+ for(int i=0;i<udp.length;i++) {
+ // Just keep the first one with the correct
port number.
+ Peer p;
+ try {
+ p = new Peer(udp[i], false);
+ } catch (PeerParseException e) {
+ IOException e1 = new IOException();
+ e1.initCause(e);
+ throw e1;
+ }
+ if(p.getPort() == crypto.portNumber) {
+ // DNSRequester doesn't deal with our
own node
+
node.ipDetector.setOldIPAddress(p.getFreenetAddress());
+ break;
+ }
+ }
+ }
+
+ crypto.readCrypto(fs);
+ }
+
+ public void start() {
+ // FIXME do something
+ }
+
+ /**
+ * Called when opennet is disabled
+ */
+ public void stop() {
+ // FIXME do something
+ }
+
+}
Added: trunk/freenet/src/freenet/node/OpennetPeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/OpennetPeerNode.java
(rev 0)
+++ trunk/freenet/src/freenet/node/OpennetPeerNode.java 2007-06-29 17:30:56 UTC
(rev 13823)
@@ -0,0 +1,17 @@
+package freenet.node;
+
+import freenet.io.comm.PeerParseException;
+import freenet.io.comm.ReferenceSignatureVerificationException;
+import freenet.support.SimpleFieldSet;
+
+public class OpennetPeerNode extends PeerNode {
+
+ public OpennetPeerNode(SimpleFieldSet fs, Node node2, NodeCrypto
crypto, PeerManager peers, boolean fromLocal, OutgoingPacketMangler mangler)
throws FSParseException, PeerParseException,
ReferenceSignatureVerificationException {
+ super(fs, node2, crypto, peers, fromLocal, mangler);
+ }
+
+ public PeerNodeStatus getStatus() {
+ return new OpennetPeerNodeStatus(this);
+ }
+
+}
Added: trunk/freenet/src/freenet/node/OpennetPeerNodeStatus.java
===================================================================
--- trunk/freenet/src/freenet/node/OpennetPeerNodeStatus.java
(rev 0)
+++ trunk/freenet/src/freenet/node/OpennetPeerNodeStatus.java 2007-06-29
17:30:56 UTC (rev 13823)
@@ -0,0 +1,9 @@
+package freenet.node;
+
+public class OpennetPeerNodeStatus extends PeerNodeStatus {
+
+ OpennetPeerNodeStatus(PeerNode peerNode) {
+ super(peerNode);
+ }
+
+}
Modified: trunk/freenet/src/freenet/node/PeerManager.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerManager.java 2007-06-29 16:11:36 UTC
(rev 13822)
+++ trunk/freenet/src/freenet/node/PeerManager.java 2007-06-29 17:30:56 UTC
(rev 13823)
@@ -52,7 +52,8 @@
/** All the peers we are actually connected to */
PeerNode[] connectedPeers;
- final String filename;
+ private String darkFilename;
+ private String openFilename;
private PeerManagerUserAlert ua;
@@ -93,16 +94,26 @@
* @param node
* @param filename
*/
- public PeerManager(Node node, NodeCrypto crypto, String filename,
OutgoingPacketMangler mangler) {
+ public PeerManager(Node node) {
Logger.normal(this, "Creating PeerManager");
logMINOR = Logger.shouldLog(Logger.MINOR, this);
peerNodeStatuses = new HashMap();
peerNodeRoutingBackoffReasons = new HashMap();
System.out.println("Creating PeerManager");
- this.filename = filename;
myPeers = new PeerNode[0];
connectedPeers = new PeerNode[0];
this.node = node;
+ }
+
+ void tryReadPeers(String filename, NodeCrypto crypto, boolean isOpennet) {
+ synchronized(writePeersSync) {
+ if(isOpennet) {
+ openFilename = filename;
+ } else {
+ darkFilename = filename;
+ }
+ }
+ OutgoingPacketMangler mangler = crypto.packetMangler;
File peersFile = new File(filename);
File backupFile = new File(filename+".bak");
// Try to read the node list from disk
@@ -125,9 +136,9 @@
System.err.println("No (readable) peers file with peers
in it found");
}
}
- }
+ }
- private boolean readPeers(File peersFile, OutgoingPacketMangler mangler,
NodeCrypto crypto) {
+ private boolean readPeers(File peersFile, OutgoingPacketMangler
mangler, NodeCrypto crypto) {
boolean gotSome = false;
FileInputStream fis;
try {
@@ -172,7 +183,7 @@
try {
br.close();
} catch (IOException e3) {
- Logger.error(this, "Ignoring "+e3+" caught reading "+filename,
e3);
+ Logger.error(this, "Ignoring "+e3+" caught reading "+peersFile,
e3);
}
return gotSome;
}
@@ -727,11 +738,20 @@
}
}, 0);
}
+
+ private void writePeersInner() {
+ synchronized(writePeersSync) {
+ if(darkFilename != null)
+ writePeersInner(darkFilename, getDarknetPeers());
+ if(openFilename != null)
+ writePeersInner(openFilename, getOpennetPeers());
+ }
+ }
/**
* Write the peers file to disk
*/
- private void writePeersInner() {
+ private void writePeersInner(String filename, PeerNode[] peers) {
synchronized (writePeersSync) {
FileOutputStream fos;
String f = filename + ".bak";
@@ -750,7 +770,7 @@
}
BufferedWriter bw = new BufferedWriter(w);
try {
- boolean succeeded = writePeers(bw);
+ boolean succeeded = writePeers(bw, peers);
bw.close();
if(!succeeded) return;
} catch (IOException e) {
@@ -762,9 +782,10 @@
Logger.error(this, "Cannot write file: " + e, e);
return; // don't overwrite old file!
}
- if (!new File(f).renameTo(new File(filename))) {
- new File(filename).delete();
- if (!new File(f).renameTo(new File(filename))) {
+ File fnam = new File(filename);
+ if (!new File(f).renameTo(fnam)) {
+ fnam.delete();
+ if (!new File(f).renameTo(fnam)) {
Logger.error(this, "Could not rename " + f + " to "
+ filename + " writing peers");
}
@@ -772,11 +793,13 @@
}
}
- public boolean writePeers(Writer bw) {
- PeerNode[] peers;
- synchronized (this) {
- peers = myPeers;
- }
+ public boolean writePeers(Writer bw) {
+ if(!writePeers(bw, getDarknetPeers())) return false;
+ if(!writePeers(bw, getOpennetPeers())) return false;
+ return true;
+ }
+
+ public boolean writePeers(Writer bw, PeerNode[] peers) {
for (int i = 0; i < peers.length; i++) {
try {
peers[i].write(bw);
@@ -1114,6 +1137,15 @@
return peerNodeStatuses;
}
+ public OpennetPeerNodeStatus[] getOpennetPeerNodeStatuses() {
+ OpennetPeerNode[] peers = getOpennetPeers();
+ OpennetPeerNodeStatus[] peerNodeStatuses = new
OpennetPeerNodeStatus[peers.length];
+ for (int peerIndex = 0, peerCount = peers.length; peerIndex <
peerCount; peerIndex++) {
+ peerNodeStatuses[peerIndex] = (OpennetPeerNodeStatus)
peers[peerIndex].getStatus();
+ }
+ return peerNodeStatuses;
+ }
+
/**
* Update hadRoutableConnectionCount/routableConnectionCheckCount on
peers if the timer has expired
*/
@@ -1133,6 +1165,7 @@
/**
* Get the darknet peers list.
+ * FIXME: optimise
*/
public DarknetPeerNode[] getDarknetPeers() {
PeerNode[] peers;
@@ -1148,4 +1181,20 @@
return (DarknetPeerNode[])v.toArray(new
DarknetPeerNode[v.size()]);
}
+ /**
+ * Get the opennet peers list.
+ */
+ public OpennetPeerNode[] getOpennetPeers() {
+ PeerNode[] peers;
+ synchronized(this) {
+ peers = myPeers;
+ }
+ // FIXME optimise! Maybe maintain as a separate list?
+ Vector v = new Vector(myPeers.length);
+ for(int i=0;i<peers.length;i++) {
+ if(peers[i] instanceof OpennetPeerNode)
+ v.add(peers[i]);
+ }
+ return (OpennetPeerNode[])v.toArray(new
OpennetPeerNode[v.size()]);
+ }
}
Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java 2007-06-29 16:11:36 UTC
(rev 13822)
+++ trunk/freenet/src/freenet/node/PeerNode.java 2007-06-29 17:30:56 UTC
(rev 13823)
@@ -2648,7 +2648,10 @@
* Create a DarknetPeerNode or an OpennetPeerNode as appropriate
*/
public static PeerNode create(SimpleFieldSet fs, Node node2, NodeCrypto
crypto, PeerManager manager, boolean b, OutgoingPacketMangler mangler) throws
FSParseException, PeerParseException, ReferenceSignatureVerificationException {
- return new DarknetPeerNode(fs, node2, crypto, manager, b,
mangler);
+ if(crypto.isOpennet)
+ return new OpennetPeerNode(fs, node2, crypto, manager,
b, mangler);
+ else
+ return new DarknetPeerNode(fs, node2, crypto, manager,
b, mangler);
}
public byte[] getIdentity() {
Modified: trunk/freenet/src/freenet/node/TestnetHandler.java
===================================================================
--- trunk/freenet/src/freenet/node/TestnetHandler.java 2007-06-29 16:11:36 UTC
(rev 13822)
+++ trunk/freenet/src/freenet/node/TestnetHandler.java 2007-06-29 17:30:56 UTC
(rev 13823)
@@ -177,9 +177,14 @@
if(logMINOR) Logger.minor(this,
"Sending references");
OutputStreamWriter osw = new
OutputStreamWriter(os, "ISO-8859-1");
BufferedWriter bw = new
BufferedWriter(osw);
- bw.write("My ref:\n\n");
- SimpleFieldSet fs =
node.exportPublicFieldSet();
+ bw.write("My darknet ref:\n\n");
+ SimpleFieldSet fs =
node.exportDarknetPublicFieldSet();
fs.writeTo(bw);
+ if(node.isOpennetEnabled()) {
+ bw.write("My opennet ref:\n\n");
+ fs =
node.exportOpennetPublicFieldSet();
+ fs.writeTo(bw);
+ }
bw.write("\n\nMy peers:\n");
node.peers.writePeers(bw);
bw.close();
Modified: trunk/freenet/src/freenet/node/TestnetStatusUploader.java
===================================================================
--- trunk/freenet/src/freenet/node/TestnetStatusUploader.java 2007-06-29
16:11:36 UTC (rev 13822)
+++ trunk/freenet/src/freenet/node/TestnetStatusUploader.java 2007-06-29
17:30:56 UTC (rev 13823)
@@ -55,7 +55,7 @@
client = new
Socket("emu.freenetproject.org", 23415);
PrintStream output = new
PrintStream(client.getOutputStream());
-
output.println(node.exportPublicFieldSet().toString());
+
output.println(node.exportDarknetPublicFieldSet().toString());
output.println();
output.println(node.getFreevizOutput());
output.close();
Modified: trunk/freenet/src/freenet/node/TextModeClientInterface.java
===================================================================
--- trunk/freenet/src/freenet/node/TextModeClientInterface.java 2007-06-29
16:11:36 UTC (rev 13822)
+++ trunk/freenet/src/freenet/node/TextModeClientInterface.java 2007-06-29
17:30:56 UTC (rev 13823)
@@ -647,8 +647,14 @@
}
} else if(uline.startsWith("STATUS")) {
- SimpleFieldSet fs = n.exportPublicFieldSet();
+ outsb.append("DARKNET:\n");
+ SimpleFieldSet fs = n.exportDarknetPublicFieldSet();
outsb.append(fs.toString());
+ if(n.isOpennetEnabled()) {
+ outsb.append("OPENNET:\n");
+ fs = n.exportOpennetPublicFieldSet();
+ outsb.append(fs.toString());
+ }
outsb.append(n.getStatus());
if(Version.buildNumber()<Version.highestSeenBuild){
outsb.append("The latest version is :
").append(Version.highestSeenBuild);
Modified: trunk/freenet/src/freenet/node/fcp/NodeData.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/NodeData.java 2007-06-29 16:11:36 UTC
(rev 13822)
+++ trunk/freenet/src/freenet/node/fcp/NodeData.java 2007-06-29 17:30:56 UTC
(rev 13823)
@@ -22,9 +22,9 @@
public SimpleFieldSet getFieldSet() {
SimpleFieldSet fs;
if(withPrivate) {
- fs = node.exportPrivateFieldSet();
+ fs = node.exportDarknetPublicFieldSet();
} else {
- fs = node.exportPublicFieldSet();
+ fs = node.exportDarknetPrivateFieldSet();
}
if(withVolatile) {
SimpleFieldSet vol = node.exportVolatileFieldSet();
Modified:
trunk/freenet/src/freenet/node/simulator/RealNodeRequestInsertTest.java
===================================================================
--- trunk/freenet/src/freenet/node/simulator/RealNodeRequestInsertTest.java
2007-06-29 16:11:36 UTC (rev 13822)
+++ trunk/freenet/src/freenet/node/simulator/RealNodeRequestInsertTest.java
2007-06-29 17:30:56 UTC (rev 13823)
@@ -56,7 +56,7 @@
}
SimpleFieldSet refs[] = new SimpleFieldSet[NUMBER_OF_NODES];
for(int i=0;i<NUMBER_OF_NODES;i++)
- refs[i] = nodes[i].exportPublicFieldSet();
+ refs[i] = nodes[i].exportDarknetPublicFieldSet();
Logger.normal(RealNodeRoutingTest.class, "Created "+NUMBER_OF_NODES+"
nodes");
// Now link them up
// Connect the set