Author: toad
Date: 2006-05-11 16:02:26 +0000 (Thu, 11 May 2006)
New Revision: 8657
Modified:
trunk/freenet/src/freenet/keys/FreenetURI.java
trunk/freenet/src/freenet/keys/InsertableClientSSK.java
trunk/freenet/src/freenet/node/KeyTracker.java
trunk/freenet/src/freenet/node/Node.java
trunk/freenet/src/freenet/node/PeerManager.java
trunk/freenet/src/freenet/node/PeerNode.java
trunk/freenet/src/freenet/node/TextModeClientInterface.java
trunk/freenet/src/freenet/node/Version.java
trunk/freenet/src/freenet/node/fcp/GenerateSSKMessage.java
Log:
690:
Possibly fix #346 (Unmatchable packet from nodes we are CONNECTED to).
Insert ARKs (doesn't fetch yet, always inserts a new one on startup even if not
changed).
Modified: trunk/freenet/src/freenet/keys/FreenetURI.java
===================================================================
--- trunk/freenet/src/freenet/keys/FreenetURI.java 2006-05-11 14:36:36 UTC
(rev 8656)
+++ trunk/freenet/src/freenet/keys/FreenetURI.java 2006-05-11 16:02:26 UTC
(rev 8657)
@@ -406,7 +406,8 @@
metaStr,
routingKey,
cryptoKey,
- extra);
+ extra,
+ suggestedEdition);
}
@@ -655,4 +656,26 @@
return sb.toString();
}
+ public FreenetURI setSuggestedEdition(long newEdition) {
+ return new FreenetURI(
+ keyType,
+ docName,
+ metaStr,
+ routingKey,
+ cryptoKey,
+ extra,
+ newEdition);
+ }
+
+ public FreenetURI setKeyType(String newKeyType) {
+ return new FreenetURI(
+ newKeyType,
+ docName,
+ metaStr,
+ routingKey,
+ cryptoKey,
+ extra,
+ suggestedEdition);
+ }
+
}
Modified: trunk/freenet/src/freenet/keys/InsertableClientSSK.java
===================================================================
--- trunk/freenet/src/freenet/keys/InsertableClientSSK.java 2006-05-11
14:36:36 UTC (rev 8656)
+++ trunk/freenet/src/freenet/keys/InsertableClientSSK.java 2006-05-11
16:02:26 UTC (rev 8657)
@@ -185,7 +185,7 @@
}
}
- public static InsertableClientSSK createRandom(RandomSource r) {
+ public static InsertableClientSSK createRandom(RandomSource r, String
docName) {
byte[] ckey = new byte[CRYPTO_KEY_LENGTH];
r.nextBytes(ckey);
DSAGroup g = Global.DSAgroupBigA;
@@ -198,7 +198,7 @@
throw new Error(e);
}
try {
- return new InsertableClientSSK("",
md.digest(pubKey.asBytes()), pubKey, privKey, ckey);
+ return new InsertableClientSSK(docName,
md.digest(pubKey.asBytes()), pubKey, privKey, ckey);
} catch (MalformedURLException e) {
throw new Error(e);
}
Modified: trunk/freenet/src/freenet/node/KeyTracker.java
===================================================================
--- trunk/freenet/src/freenet/node/KeyTracker.java 2006-05-11 14:36:36 UTC
(rev 8656)
+++ trunk/freenet/src/freenet/node/KeyTracker.java 2006-05-11 16:02:26 UTC
(rev 8657)
@@ -906,4 +906,8 @@
}
return items;
}
+
+ public boolean isDeprecated() {
+ return this.isDeprecated;
+ }
}
Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java 2006-05-11 14:36:36 UTC (rev
8656)
+++ trunk/freenet/src/freenet/node/Node.java 2006-05-11 16:02:26 UTC (rev
8657)
@@ -15,7 +15,9 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
+import java.net.MalformedURLException;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.security.MessageDigest;
@@ -27,8 +29,16 @@
import java.util.zip.DeflaterOutputStream;
import freenet.client.ArchiveManager;
+import freenet.client.ClientMetadata;
+import freenet.client.FetchException;
+import freenet.client.FetchResult;
import freenet.client.HighLevelSimpleClient;
import freenet.client.HighLevelSimpleClientImpl;
+import freenet.client.InserterException;
+import freenet.client.async.BaseClientPutter;
+import freenet.client.async.ClientCallback;
+import freenet.client.async.ClientGetter;
+import freenet.client.async.ClientPutter;
import freenet.client.async.ClientRequestScheduler;
import freenet.client.async.USKManager;
import freenet.clients.http.FproxyToadlet;
@@ -65,6 +75,8 @@
import freenet.keys.ClientKeyBlock;
import freenet.keys.ClientSSK;
import freenet.keys.ClientSSKBlock;
+import freenet.keys.FreenetURI;
+import freenet.keys.InsertableClientSSK;
import freenet.keys.Key;
import freenet.keys.KeyBlock;
import freenet.keys.KeyVerifyException;
@@ -77,6 +89,7 @@
import freenet.store.BerkeleyDBFreenetStore;
import freenet.store.FreenetStore;
import freenet.support.Base64;
+import freenet.support.Bucket;
import freenet.support.BucketFactory;
import freenet.support.Fields;
import freenet.support.FileLoggerHook;
@@ -88,6 +101,7 @@
import freenet.support.Logger;
import freenet.support.PaddedEphemerallyEncryptedBucketFactory;
import freenet.support.SimpleFieldSet;
+import freenet.support.SimpleReadOnlyArrayBucket;
import freenet.support.io.FilenameGenerator;
import freenet.support.io.PersistentTempBucketFactory;
import freenet.support.io.TempBucketFactory;
@@ -102,6 +116,126 @@
*/
public class Node {
+ public class MyARKInserter implements ClientCallback {
+
+ private ClientPutter inserter;
+ private boolean shouldInsert;
+
+ public void update() {
+ Logger.minor(this, "update()");
+ synchronized(this) {
+ if(inserter != null) {
+ // Already inserting.
+ // Re-insert after finished.
+ shouldInsert = true;
+ return;
+ }
+ // Otherwise need to start an insert
+ if(!peers.anyConnectedPeers()) {
+ // Can't start an insert yet
+ shouldInsert = true;
+ return;
+ }
+ startInserter();
+ }
+ }
+
+ private void startInserter() {
+
+ Logger.minor(this, "starting inserter");
+
+ SimpleFieldSet fs = exportPublicFieldSet();
+
+ String s = fs.toString();
+
+ byte[] buf;
+ try {
+ buf = s.getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new Error("UTF-8 not supported");
+ }
+
+ Bucket b = new SimpleReadOnlyArrayBucket(buf);
+
+ FreenetURI uri =
myARK.getInsertURI().setKeyType("USK").setSuggestedEdition(Node.this.myARKNumber);
+
+ Logger.minor(this, "Inserting ARK: "+uri);
+
+ inserter = new ClientPutter(this, b, uri,
+ new ClientMetadata("text/plain") /* it
won't quite fit in an SSK anyway */,
+
Node.this.makeClient((short)0).getInserterContext(),
+ chkPutScheduler, sskPutScheduler,
RequestStarter.INTERACTIVE_PRIORITY_CLASS, false, false, this);
+
+ try {
+ inserter.start();
+ } catch (InserterException e) {
+ onFailure(e, inserter);
+ }
+ }
+
+ public void onSuccess(FetchResult result, ClientGetter state) {
+ // Impossible
+ }
+
+ public void onFailure(FetchException e, ClientGetter state) {
+ // Impossible
+ }
+
+ public void onSuccess(BaseClientPutter state) {
+ Logger.minor(this, "ARK insert succeeded");
+ synchronized(this) {
+ inserter = null;
+ if(shouldInsert)
+ startInserter();
+ }
+ }
+
+ public void onFailure(InserterException e, BaseClientPutter
state) {
+ Logger.minor(this, "ARK insert failed: "+e);
+ // :(
+ // Better try again
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e1) {
+ // Ignore
+ }
+ synchronized(this) {
+ startInserter();
+ }
+ }
+
+ public void onGeneratedURI(FreenetURI uri, BaseClientPutter
state) {
+ Logger.minor(this, "Generated URI for ARK: "+uri);
+ long l = uri.getSuggestedEdition();
+ if(l < myARKNumber) {
+ Logger.error(this, "Inserted edition # lower
than attempted: "+l+" expected "+myARKNumber);
+ } else if(l > myARKNumber) {
+ Logger.minor(this, "ARK number moving from
"+myARKNumber+" to "+l);
+ myARKNumber = l;
+ writeNodeFile();
+ }
+ }
+
+ public void onConnectedPeer() {
+ synchronized(this) {
+ if(!shouldInsert) return;
+ if(inserter != null) {
+ // Already inserting.
+ return;
+ }
+ // Otherwise need to start an insert
+ if(!peers.anyConnectedPeers()) {
+ // Can't start an insert yet
+ shouldInsert = true;
+ return;
+ }
+ shouldInsert = false;
+ startInserter();
+ }
+ }
+
+ }
+
private static IPUndetectedUserAlert primaryIPUndetectedAlert;
private static MeaningfulNodeNameUserAlert nodeNameUserAlert;
@@ -258,6 +392,10 @@
private DSAPrivateKey myPrivKey;
/** My public key */
private DSAPublicKey myPubKey;
+ /** My ARK SSK private key */
+ private InsertableClientSSK myARK;
+ /** My ARK sequence number */
+ private long myARKNumber;
private final HashSet runningUIDs;
@@ -305,9 +443,7 @@
static final int EXIT_COULD_NOT_START_FPROXY = 18;
static final int EXIT_COULD_NOT_START_TMCI = 19;
public static final int EXIT_DATABASE_REQUIRES_RESTART = 20;
-
-
public final long bootID;
public final long startupTime;
@@ -355,6 +491,9 @@
public final InetAddress localhostAddress;
private boolean wasTestnet;
+
+ // USK inserter.
+ private final MyARKInserter arkPutter;
/**
* Read all storable settings (identity etc) from the node file.
@@ -431,6 +570,34 @@
this.myPrivKey = new DSAPrivateKey(myCryptoGroup, r);
this.myPubKey = new DSAPublicKey(myCryptoGroup, myPrivKey);
}
+ InsertableClientSSK ark = null;
+ String s = fs.get("ark.number");
+
+ String privARK = fs.get("ark.privURI");
+ try {
+ if(privARK != null) {
+ FreenetURI uri = new FreenetURI(privARK);
+ ark = InsertableClientSSK.create(uri);
+ if(s == null) {
+ ark = null;
+ } else {
+ try {
+ myARKNumber = Long.parseLong(s);
+ } catch (NumberFormatException e) {
+ myARKNumber = 0;
+ ark = null;
+ }
+ }
+ }
+ } catch (MalformedURLException e) {
+ Logger.minor(this, "Caught "+e, e);
+ ark = null;
+ }
+ if(ark == null) {
+ ark = InsertableClientSSK.createRandom(r, "ark");
+ myARKNumber = 0;
+ }
+ this.myARK = ark;
wasTestnet = Fields.stringToBool(fs.get("testnet"), false);
}
@@ -473,6 +640,8 @@
this.myCryptoGroup = Global.DSAgroupBigA;
this.myPrivKey = new DSAPrivateKey(myCryptoGroup, r);
this.myPubKey = new DSAPublicKey(myCryptoGroup, myPrivKey);
+ myARK = InsertableClientSSK.createRandom(r, "ark");
+ myARKNumber = 0;
}
/**
@@ -569,6 +738,7 @@
private Node(Config config, RandomSource random) throws NodeInitException {
// Easy stuff
+ arkPutter = new MyARKInserter();
startupTime = System.currentTimeMillis();
throttleWindow = new ThrottleWindowManager(2.0);
alerts = new UserAlertManager();
@@ -1081,13 +1251,19 @@
testnetHandler.start();
persistentTempBucketFactory.completedInit();
+
+ shouldInsertARK();
Thread t = new Thread(ipDetector, "IP address re-detector");
t.setDaemon(true);
t.start();
}
- public ClientKeyBlock realGetKey(ClientKey key, boolean localOnly, boolean
cache, boolean ignoreStore) throws LowLevelGetException {
+ private void shouldInsertARK() {
+ arkPutter.update();
+ }
+
+ public ClientKeyBlock realGetKey(ClientKey key, boolean localOnly,
boolean cache, boolean ignoreStore) throws LowLevelGetException {
if(key instanceof ClientCHK)
return realGetCHK((ClientCHK)key, localOnly, cache,
ignoreStore);
else if(key instanceof ClientSSK)
@@ -1537,6 +1713,7 @@
public SimpleFieldSet exportPrivateFieldSet() {
SimpleFieldSet fs = exportPublicFieldSet();
fs.put("dsaPrivKey", myPrivKey.asFieldSet());
+ fs.put("ark.privURI", this.myARK.getInsertURI().toString(false));
return fs;
}
@@ -1560,6 +1737,8 @@
fs.put("myName", myName);
fs.put("dsaGroup", myCryptoGroup.asFieldSet());
fs.put("dsaPubKey", myPubKey.asFieldSet());
+ fs.put("ark.number", Long.toString(this.myARKNumber));
+ fs.put("ark.pubURI", this.myARK.getURI().toString(false));
Logger.minor(this, "My reference: "+fs);
return fs;
}
@@ -2301,4 +2480,10 @@
public File getDownloadDir() {
return downloadDir;
}
+
+ public void onConnectedPeer() {
+ Logger.minor(this, "onConnectedPeer()");
+ if(arkPutter != null)
+ arkPutter.onConnectedPeer();
+ }
}
Modified: trunk/freenet/src/freenet/node/PeerManager.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerManager.java 2006-05-11 14:36:36 UTC
(rev 8656)
+++ trunk/freenet/src/freenet/node/PeerManager.java 2006-05-11 16:02:26 UTC
(rev 8657)
@@ -515,6 +515,16 @@
ua.conns = conns;
ua.peers = peers;
}
+ if(anyConnectedPeers())
+ node.onConnectedPeer();
}
+ public boolean anyConnectedPeers() {
+ PeerNode[] conns = connectedPeers;
+ for(int i=0;i<conns.length;i++) {
+ if(conns[i].isConnected()) return true;
+ }
+ return false;
+ }
+
}
Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java 2006-05-11 14:36:36 UTC
(rev 8656)
+++ trunk/freenet/src/freenet/node/PeerNode.java 2006-05-11 16:02:26 UTC
(rev 8657)
@@ -433,17 +433,16 @@
node.usm.onDisconnect(this);
node.peers.disconnected(this);
synchronized(this) {
+ // Force renegotiation.
isConnected = false;
+ // Prevent sending packets to the node until that happens.
if(currentTracker != null)
- currentTracker.disconnected();
+ currentTracker.disconnected();
if(previousTracker != null)
previousTracker.disconnected();
if(unverifiedTracker != null)
unverifiedTracker.disconnected();
- // Must null out to make other side prove it can
- // *receive* from us as well as send *to* us before
- // sending any more packets.
- currentTracker = previousTracker = unverifiedTracker = null;
+ // DO NOT clear trackers, so can still receive.
}
node.lm.lostOrRestartedNode(this);
sendHandshakeTime = System.currentTimeMillis();
@@ -698,9 +697,13 @@
* @throws NotConnectedException
*/
synchronized void receivedPacket() throws NotConnectedException {
- if(isConnected == false && unverifiedTracker == null) {
- Logger.error(this, "Received packet while disconnected!: "+this,
new Exception("error"));
- throw new NotConnectedException();
+ if(isConnected == false) {
+ if(unverifiedTracker == null && currentTracker == null) {
+ Logger.error(this, "Received packet while
disconnected!: "+this, new Exception("error"));
+ throw new NotConnectedException();
+ } else {
+ Logger.minor(this, "Received packet while disconnected
on "+this+" - recently disconnected() ?");
+ }
}
timeLastReceivedPacket = System.currentTimeMillis();
}
@@ -1013,6 +1016,7 @@
}
tracker = prev;
if(tracker != null) {
+ if(tracker.isDeprecated()) return;
long t = tracker.getNextUrgentTime();
if(t < now) {
try {
Modified: trunk/freenet/src/freenet/node/TextModeClientInterface.java
===================================================================
--- trunk/freenet/src/freenet/node/TextModeClientInterface.java 2006-05-11
14:36:36 UTC (rev 8656)
+++ trunk/freenet/src/freenet/node/TextModeClientInterface.java 2006-05-11
16:02:26 UTC (rev 8657)
@@ -486,7 +486,7 @@
t.printStackTrace();
}
} else if(uline.startsWith("MAKESSK")) {
- InsertableClientSSK key = InsertableClientSSK.createRandom(r);
+ InsertableClientSSK key = InsertableClientSSK.createRandom(r,
"");
outsb.append("Insert URI:
"+key.getInsertURI().toString(false)+"\r\n");
outsb.append("Request URI:
"+key.getURI().toString(false)+"\r\n");
FreenetURI insertURI =
key.getInsertURI().setDocName("testsite");
Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-05-11 14:36:36 UTC (rev
8656)
+++ trunk/freenet/src/freenet/node/Version.java 2006-05-11 16:02:26 UTC (rev
8657)
@@ -20,7 +20,7 @@
public static final String protocolVersion = "1.0";
/** The build number of the current revision */
- private static final int buildNumber = 689;
+ private static final int buildNumber = 690;
/** Oldest build of Fred we will talk to */
private static final int lastGoodBuild = 591;
Modified: trunk/freenet/src/freenet/node/fcp/GenerateSSKMessage.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/GenerateSSKMessage.java 2006-05-11
14:36:36 UTC (rev 8656)
+++ trunk/freenet/src/freenet/node/fcp/GenerateSSKMessage.java 2006-05-11
16:02:26 UTC (rev 8657)
@@ -24,7 +24,7 @@
public void run(FCPConnectionHandler handler, Node node)
throws MessageInvalidException {
- InsertableClientSSK key = InsertableClientSSK.createRandom(node.random);
+ InsertableClientSSK key = InsertableClientSSK.createRandom(node.random,
"");
FreenetURI insertURI = key.getInsertURI();
FreenetURI requestURI = key.getURI();
SSKKeypairMessage msg = new SSKKeypairMessage(insertURI, requestURI,
identifier);