Author: toad
Date: 2006-01-07 20:27:35 +0000 (Sat, 07 Jan 2006)
New Revision: 7806

Added:
   trunk/freenet/src/freenet/keys/KeyVerifyException.java
Modified:
   trunk/freenet/src/freenet/client/Fetcher.java
   trunk/freenet/src/freenet/io/comm/DMT.java
   trunk/freenet/src/freenet/keys/CHKVerifyException.java
   trunk/freenet/src/freenet/keys/Key.java
   trunk/freenet/src/freenet/keys/NodeCHK.java
   trunk/freenet/src/freenet/keys/NodeSSK.java
   trunk/freenet/src/freenet/keys/SSKVerifyException.java
   trunk/freenet/src/freenet/node/Node.java
   trunk/freenet/src/freenet/node/NodeDispatcher.java
   trunk/freenet/src/freenet/node/RequestHandler.java
   trunk/freenet/src/freenet/node/RequestSender.java
   trunk/freenet/src/freenet/node/SSKInsertHandler.java
   trunk/freenet/src/freenet/node/SSKInsertSender.java
   trunk/freenet/src/freenet/node/Version.java
   trunk/freenet/src/freenet/support/Serializer.java
Log:
331: SSK support compiles. Need to add code to insert them though.

Modified: trunk/freenet/src/freenet/client/Fetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/Fetcher.java       2006-01-07 19:46:58 UTC 
(rev 7805)
+++ trunk/freenet/src/freenet/client/Fetcher.java       2006-01-07 20:27:35 UTC 
(rev 7806)
@@ -7,11 +7,9 @@
 import freenet.client.events.DecodedBlockEvent;
 import freenet.client.events.FetchedMetadataEvent;
 import freenet.client.events.GotBlockEvent;
-import freenet.keys.ClientCHK;
 import freenet.keys.ClientKey;
 import freenet.keys.ClientKeyBlock;
 import freenet.keys.FreenetURI;
-import freenet.keys.KeyBlock;
 import freenet.keys.KeyDecodeException;
 import freenet.node.LowLevelGetException;
 import freenet.support.Bucket;
@@ -194,7 +192,11 @@
        throws MetadataParseException, FetchException, ArchiveFailureException, 
ArchiveRestartException {

                if(metadata.isSimpleManifest()) {
-                       String name = (String) metaStrings.removeFirst();
+                       String name;
+                       if(metaStrings.isEmpty())
+                               name = null;
+                       else
+                               name = (String) metaStrings.removeFirst();
                        // Since metadata is a document, we just replace 
metadata here
                        if(name == null) {
                                metadata = metadata.getDefaultDocument();

Modified: trunk/freenet/src/freenet/io/comm/DMT.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/DMT.java  2006-01-07 19:46:58 UTC (rev 
7805)
+++ trunk/freenet/src/freenet/io/comm/DMT.java  2006-01-07 20:27:35 UTC (rev 
7806)
@@ -23,6 +23,7 @@
 import java.util.List;

 import freenet.keys.Key;
+import freenet.keys.NodeCHK;
 import freenet.keys.NodeSSK;
 import freenet.support.BitArray;
 import freenet.support.Buffer;
@@ -503,15 +504,15 @@
     }

     // FNP messages
-    public static final MessageType FNPDataRequest = new 
MessageType("FNPDataRequest") {{
+    public static final MessageType FNPCHKDataRequest = new 
MessageType("FNPCHKDataRequest") {{
         addField(UID, Long.class);
         addField(HTL, Short.class);
         addField(NEAREST_LOCATION, Double.class);
-        addField(FREENET_ROUTING_KEY, Key.class);
+        addField(FREENET_ROUTING_KEY, NodeCHK.class);
     }};

-    public static final Message createFNPDataRequest(long id, short htl, Key 
key, double nearestLocation) {
-        Message msg = new Message(FNPDataRequest);
+    public static final Message createFNPCHKDataRequest(long id, short htl, 
NodeCHK key, double nearestLocation) {
+        Message msg = new Message(FNPCHKDataRequest);
         msg.set(UID, id);
         msg.set(HTL, htl);
         msg.set(FREENET_ROUTING_KEY, key);
@@ -519,6 +520,24 @@
         return msg;
     }

+    public static final MessageType FNPSSKDataRequest = new 
MessageType("FNPSSKDataRequest") {{
+        addField(UID, Long.class);
+        addField(HTL, Short.class);
+        addField(NEAREST_LOCATION, Double.class);
+        addField(FREENET_ROUTING_KEY, NodeSSK.class);
+       addField(NEED_PUB_KEY, Boolean.class);
+    }};
+    
+    public static final Message createFNPSSKDataRequest(long id, short htl, 
NodeSSK key, double nearestLocation, boolean needPubKey) {
+        Message msg = new Message(FNPCHKDataRequest);
+        msg.set(UID, id);
+        msg.set(HTL, htl);
+        msg.set(FREENET_ROUTING_KEY, key);
+        msg.set(NEAREST_LOCATION, nearestLocation);
+        msg.set(NEED_PUB_KEY, needPubKey);
+        return msg;
+    }
+    
     // Hit our tail, try a different node.
     public static final MessageType FNPRejectedLoop = new 
MessageType("FNPRejectLoop") {{
         addField(UID, Long.class);
@@ -564,13 +583,13 @@
         return msg;
     }

-    public static final MessageType FNPDataFound = new 
MessageType("FNPDataFound") {{
+    public static final MessageType FNPCHKDataFound = new 
MessageType("FNPDataFound") {{
         addField(UID, Long.class);
         addField(BLOCK_HEADERS, ShortBuffer.class);
     }};

-    public static final Message createFNPDataFound(long id, byte[] buf) {
-        Message msg = new Message(FNPDataFound);
+    public static final Message createFNPCHKDataFound(long id, byte[] buf) {
+        Message msg = new Message(FNPCHKDataFound);
         msg.set(UID, id);
         msg.set(BLOCK_HEADERS, new ShortBuffer(buf));
         return msg;
@@ -696,18 +715,14 @@

        public static final MessageType FNPSSKDataFound = new 
MessageType("FNPSSKDataFound") {{
        addField(UID, Long.class);
-       addField(FREENET_ROUTING_KEY, NodeSSK.class);
         addField(BLOCK_HEADERS, ShortBuffer.class);
-        addField(PUBKEY_HASH, ShortBuffer.class);
         addField(DATA, ShortBuffer.class);
        }};

-       public static Message createFNPSSKDataFound(long uid, NodeSSK myKey, 
byte[] headers, byte[] data, byte[] pubKeyHash) {
+       public static Message createFNPSSKDataFound(long uid, byte[] headers, 
byte[] data) {
                Message msg = new Message(FNPSSKDataFound);
                msg.set(UID, uid);
-               msg.set(FREENET_ROUTING_KEY, myKey);
                msg.set(BLOCK_HEADERS, new ShortBuffer(headers));
-               msg.set(PUBKEY_HASH, new ShortBuffer(pubKeyHash));
                msg.set(DATA, new ShortBuffer(data));
                return msg;
        }

Modified: trunk/freenet/src/freenet/keys/CHKVerifyException.java
===================================================================
--- trunk/freenet/src/freenet/keys/CHKVerifyException.java      2006-01-07 
19:46:58 UTC (rev 7805)
+++ trunk/freenet/src/freenet/keys/CHKVerifyException.java      2006-01-07 
20:27:35 UTC (rev 7806)
@@ -5,7 +5,7 @@
  * 
  * Exception thrown when a CHK doesn't verify.
  */
-public class CHKVerifyException extends Exception {
+public class CHKVerifyException extends KeyVerifyException {
        static final long serialVersionUID = -1;

        /**

Modified: trunk/freenet/src/freenet/keys/Key.java
===================================================================
--- trunk/freenet/src/freenet/keys/Key.java     2006-01-07 19:46:58 UTC (rev 
7805)
+++ trunk/freenet/src/freenet/keys/Key.java     2006-01-07 20:27:35 UTC (rev 
7806)
@@ -49,7 +49,7 @@
      * @param raf The file to read from.
      * @return a Key, or throw an exception, or return null if the key is not 
parsable.
      */
-    public static Key read(DataInput raf) throws IOException {
+    public static final Key read(DataInput raf) throws IOException {
         short type = raf.readShort();
         if(type == NodeCHK.TYPE) {
             return NodeCHK.read(raf);

Added: trunk/freenet/src/freenet/keys/KeyVerifyException.java
===================================================================
--- trunk/freenet/src/freenet/keys/KeyVerifyException.java      2006-01-07 
19:46:58 UTC (rev 7805)
+++ trunk/freenet/src/freenet/keys/KeyVerifyException.java      2006-01-07 
20:27:35 UTC (rev 7806)
@@ -0,0 +1,21 @@
+package freenet.keys;
+
+public class KeyVerifyException extends Exception {
+
+       public KeyVerifyException(String message) {
+               super(message);
+       }
+
+       public KeyVerifyException(String message, Throwable cause) {
+               super(message, cause);
+       }
+
+       public KeyVerifyException() {
+               super();
+       }
+
+       public KeyVerifyException(Throwable cause) {
+               super(cause);
+       }
+
+}

Modified: trunk/freenet/src/freenet/keys/NodeCHK.java
===================================================================
--- trunk/freenet/src/freenet/keys/NodeCHK.java 2006-01-07 19:46:58 UTC (rev 
7805)
+++ trunk/freenet/src/freenet/keys/NodeCHK.java 2006-01-07 20:27:35 UTC (rev 
7806)
@@ -44,7 +44,7 @@
         _index.write(routingKey);
     }

-    public static Key read(DataInput raf) throws IOException {
+    public static Key readCHK(DataInput raf) throws IOException {
         byte[] buf = new byte[KEY_LENGTH];
         raf.readFully(buf);
         return new NodeCHK(buf);

Modified: trunk/freenet/src/freenet/keys/NodeSSK.java
===================================================================
--- trunk/freenet/src/freenet/keys/NodeSSK.java 2006-01-07 19:46:58 UTC (rev 
7805)
+++ trunk/freenet/src/freenet/keys/NodeSSK.java 2006-01-07 20:27:35 UTC (rev 
7806)
@@ -1,5 +1,6 @@
 package freenet.keys;

+import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.DataOutputStream;
 import java.io.IOException;
@@ -26,6 +27,9 @@
        /** The signature key, if we know it */
        DSAPublicKey pubKey;

+       static final int PUBKEY_HASH_SIZE = 32;
+       static final int E_H_DOCNAME_SIZE = 32;
+       
        public NodeSSK(byte[] pkHash, byte[] ehDocname) {
                super(makeRoutingKey(pkHash, ehDocname));
                this.encryptedHashedDocname = ehDocname;
@@ -54,6 +58,14 @@
         _index.write(pubKeyHash);
        }

+    public static Key readSSK(DataInput raf) throws IOException {
+        byte[] buf = new byte[E_H_DOCNAME_SIZE];
+        raf.readFully(buf);
+        byte[] buf2 = new byte[PUBKEY_HASH_SIZE];
+        raf.readFully(buf2);
+        return new NodeSSK(buf, buf2);
+    }
+
        public short getType() {
                return TYPE;
        }
@@ -76,4 +88,8 @@
                return pubKey;
        }

+       public byte[] getPubKeyHash() {
+               return pubKeyHash;
+       }
+
 }

Modified: trunk/freenet/src/freenet/keys/SSKVerifyException.java
===================================================================
--- trunk/freenet/src/freenet/keys/SSKVerifyException.java      2006-01-07 
19:46:58 UTC (rev 7805)
+++ trunk/freenet/src/freenet/keys/SSKVerifyException.java      2006-01-07 
20:27:35 UTC (rev 7806)
@@ -3,7 +3,7 @@
 /**
  * Thrown when an SSK fails to verify at the node level.
  */
-public class SSKVerifyException extends Exception {
+public class SSKVerifyException extends KeyVerifyException {

        public SSKVerifyException(String string) {
                super(string);

Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java    2006-01-07 19:46:58 UTC (rev 
7805)
+++ trunk/freenet/src/freenet/node/Node.java    2006-01-07 20:27:35 UTC (rev 
7806)
@@ -48,6 +48,7 @@
 import freenet.keys.ClientKey;
 import freenet.keys.ClientKeyBlock;
 import freenet.keys.Key;
+import freenet.keys.KeyBlock;
 import freenet.keys.NodeCHK;
 import freenet.keys.NodeSSK;
 import freenet.keys.SSKBlock;
@@ -754,12 +755,17 @@
      * a RequestSender, unless the HTL is 0, in which case NULL.
      * RequestSender.
      */
-    public synchronized Object makeRequestSender(NodeCHK key, short htl, long 
uid, PeerNode source, double closestLocation, boolean localOnly, boolean cache) 
{
+    public synchronized Object makeRequestSender(Key key, short htl, long uid, 
PeerNode source, double closestLocation, boolean localOnly, boolean cache) {
         Logger.minor(this, 
"makeRequestSender("+key+","+htl+","+uid+","+source+") on "+portNumber);
         // In store?
-        CHKBlock chk = null;
+        KeyBlock chk = null;
         try {
-            chk = chkDatastore.fetch(key, !cache);
+               if(key instanceof NodeCHK)
+                       chk = chkDatastore.fetch((NodeCHK)key, !cache);
+               else if(key instanceof NodeSSK)
+                       chk = sskDatastore.fetch((NodeSSK)key, !cache);
+               else
+                       throw new IllegalStateException("Unknown key type: 
"+key.getClass());
         } catch (IOException e) {
             Logger.error(this, "Error accessing store: "+e, e);
         }
@@ -788,7 +794,7 @@
             return sender;
         }

-        sender = new RequestSender(key, htl, uid, this, closestLocation, 
source);
+        sender = new RequestSender(key, null, htl, uid, this, closestLocation, 
source);
         requestSenders.put(kh, sender);
         Logger.minor(this, "Created new sender: "+sender);
         return sender;
@@ -821,7 +827,7 @@
     /**
      * Add a RequestSender to our HashSet.
      */
-    public synchronized void addSender(NodeCHK key, short htl, RequestSender 
sender) {
+    public synchronized void addSender(Key key, short htl, RequestSender 
sender) {
         KeyHTLPair kh = new KeyHTLPair(key, htl);
         requestSenders.put(kh, sender);
     }
@@ -865,7 +871,7 @@
     /**
      * Remove a RequestSender from the map.
      */
-    public synchronized void removeSender(NodeCHK key, short htl, 
RequestSender sender) {
+    public synchronized void removeSender(Key key, short htl, RequestSender 
sender) {
         KeyHTLPair kh = new KeyHTLPair(key, htl);
         RequestSender rs = (RequestSender) requestSenders.remove(kh);
         if(rs != sender) {

Modified: trunk/freenet/src/freenet/node/NodeDispatcher.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeDispatcher.java  2006-01-07 19:46:58 UTC 
(rev 7805)
+++ trunk/freenet/src/freenet/node/NodeDispatcher.java  2006-01-07 20:27:35 UTC 
(rev 7806)
@@ -70,7 +70,7 @@
             return handleRoutedReply(m);
         } else if(spec == DMT.FNPRoutedRejected) {
             return handleRoutedRejected(m);
-        } else if(spec == DMT.FNPDataRequest) {
+        } else if(spec == DMT.FNPCHKDataRequest || spec == 
DMT.FNPSSKDataRequest) {
             return handleDataRequest(m);
         } else if(spec == DMT.FNPInsertRequest) {
             return handleInsertRequest(m);

Modified: trunk/freenet/src/freenet/node/RequestHandler.java
===================================================================
--- trunk/freenet/src/freenet/node/RequestHandler.java  2006-01-07 19:46:58 UTC 
(rev 7805)
+++ trunk/freenet/src/freenet/node/RequestHandler.java  2006-01-07 20:27:35 UTC 
(rev 7806)
@@ -5,7 +5,11 @@
 import freenet.io.xfer.BlockTransmitter;
 import freenet.io.xfer.PartiallyReceivedBlock;
 import freenet.keys.CHKBlock;
+import freenet.keys.Key;
+import freenet.keys.KeyBlock;
 import freenet.keys.NodeCHK;
+import freenet.keys.NodeSSK;
+import freenet.keys.SSKBlock;
 import freenet.support.Logger;

 /**
@@ -21,7 +25,7 @@
     private short htl;
     final PeerNode source;
     private double closestLoc;
-    final NodeCHK key;
+    final Key key;

     public String toString() {
         return super.toString()+" for "+uid;
@@ -51,15 +55,17 @@
         source.send(accepted);

         Object o = node.makeRequestSender(key, htl, uid, source, closestLoc, 
false, true);
-        if(o instanceof CHKBlock) {
-            CHKBlock block = (CHKBlock) o;
-            Message df = DMT.createFNPDataFound(uid, block.getHeaders());
+        if(o instanceof KeyBlock) {
+            KeyBlock block = (KeyBlock) o;
+            Message df = createDataFound(block);
             source.send(df);
-            PartiallyReceivedBlock prb =
-                new PartiallyReceivedBlock(Node.PACKETS_IN_BLOCK, 
Node.PACKET_SIZE, block.getData());
-            BlockTransmitter bt =
-                new BlockTransmitter(node.usm, source, uid, prb);
-            bt.send();
+            if(block instanceof NodeCHK) {
+               PartiallyReceivedBlock prb =
+                       new PartiallyReceivedBlock(Node.PACKETS_IN_BLOCK, 
Node.PACKET_SIZE, block.getRawData());
+               BlockTransmitter bt =
+                       new BlockTransmitter(node.usm, source, uid, prb);
+               bt.send();
+            }
             return;
         }
         RequestSender rs = (RequestSender) o;
@@ -81,7 +87,8 @@
             }

             if(rs.transferStarted()) {
-                Message df = DMT.createFNPDataFound(uid, rs.getHeaders());
+               // Is a CHK.
+                Message df = DMT.createFNPCHKDataFound(uid, rs.getHeaders());
                 source.send(df);
                 PartiallyReceivedBlock prb = rs.getPRB();
                BlockTransmitter bt =
@@ -112,12 +119,18 @@
                        source.sendAsync(rnf, null);
                        return;
                case RequestSender.SUCCESS:
+                       if(key instanceof NodeSSK) {
+                        Message df = DMT.createFNPSSKDataFound(uid, 
rs.getHeaders(), rs.getSSKData());
+                        source.send(df);
+                       }
                case RequestSender.TRANSFER_FAILED:
                case RequestSender.VERIFY_FAILURE:
-                   if(shouldHaveStartedTransfer)
-                       throw new IllegalStateException("Got status code 
"+status+" but transfer not started");
-                   shouldHaveStartedTransfer = true;
-                   continue; // should have started transfer
+                       if(key instanceof NodeCHK) {
+                               if(shouldHaveStartedTransfer)
+                                       throw new IllegalStateException("Got 
status code "+status+" but transfer not started");
+                               shouldHaveStartedTransfer = true;
+                               continue; // should have started transfer
+                       }
                default:
                    throw new IllegalStateException("Unknown status code 
"+status);
             }
@@ -129,4 +142,13 @@
         }
     }

+       private Message createDataFound(KeyBlock block) {
+               if(block instanceof CHKBlock)
+                       return DMT.createFNPCHKDataFound(uid, 
block.getRawHeaders());
+               else if(block instanceof SSKBlock)
+                       return DMT.createFNPSSKDataFound(uid, 
block.getRawHeaders(), block.getRawData());
+               else
+                       throw new IllegalStateException("Unknown key block 
type: "+block.getClass());
+       }
+
 }

Modified: trunk/freenet/src/freenet/node/RequestSender.java
===================================================================
--- trunk/freenet/src/freenet/node/RequestSender.java   2006-01-07 19:46:58 UTC 
(rev 7805)
+++ trunk/freenet/src/freenet/node/RequestSender.java   2006-01-07 20:27:35 UTC 
(rev 7806)
@@ -1,17 +1,25 @@
 package freenet.node;

+import java.io.IOException;
 import java.util.HashSet;

+import freenet.crypt.DSAPublicKey;
 import freenet.io.comm.DMT;
 import freenet.io.comm.DisconnectedException;
 import freenet.io.comm.Message;
 import freenet.io.comm.MessageFilter;
+import freenet.io.comm.NotConnectedException;
 import freenet.io.comm.RetrievalException;
 import freenet.io.xfer.BlockReceiver;
 import freenet.io.xfer.PartiallyReceivedBlock;
 import freenet.keys.CHKBlock;
 import freenet.keys.CHKVerifyException;
+import freenet.keys.Key;
+import freenet.keys.KeyVerifyException;
 import freenet.keys.NodeCHK;
+import freenet.keys.NodeSSK;
+import freenet.keys.SSKBlock;
+import freenet.keys.SSKVerifyException;
 import freenet.support.Logger;
 import freenet.support.ShortBuffer;

@@ -34,7 +42,7 @@
     static final int FETCH_TIMEOUT = 60000;

     // Basics
-    final NodeCHK key;
+    final Key key;
     final double target;
     private short htl;
     final long uid;
@@ -43,7 +51,9 @@
     /** The source of this request if any - purely so we can avoid routing to 
it */
     final PeerNode source;
     private PartiallyReceivedBlock prb = null;
+    private DSAPublicKey pubKey;
     private byte[] headers;
+    private byte[] sskData;
     private boolean sentRequest;

     // Terminal status
@@ -65,14 +75,18 @@
         return super.toString()+" for "+uid;
     }

-    public RequestSender(NodeCHK key, short htl, long uid, Node n, double 
nearestLoc, 
+    public RequestSender(Key key, DSAPublicKey pubKey, short htl, long uid, 
Node n, double nearestLoc, 
             PeerNode source) {
         this.key = key;
+        this.pubKey = pubKey;
         this.htl = htl;
         this.uid = uid;
         this.node = n;
         this.source = source;
         this.nearestLoc = nearestLoc;
+        if(key instanceof NodeSSK && pubKey == null) {
+               pubKey = node.getKey(((NodeSSK)key).getPubKeyHash());
+        }

         target = key.toNormalizedDouble();
         Thread t = new Thread(this, "RequestSender for UID "+uid);
@@ -120,7 +134,7 @@
                 Logger.minor(this, "Backtracking: target="+target+" 
next="+nextValue+" closest="+nearestLoc+" so htl="+htl);
             }

-            Message req = DMT.createFNPDataRequest(uid, htl, key, nearestLoc);
+            Message req = createDataRequest();


             next.send(req);
@@ -207,7 +221,7 @@
             while(true) {

                 MessageFilter mfDNF = 
MessageFilter.create().setSource(next).setField(DMT.UID, 
uid).setTimeout(FETCH_TIMEOUT).setType(DMT.FNPDataNotFound);
-                MessageFilter mfDF = 
MessageFilter.create().setSource(next).setField(DMT.UID, 
uid).setTimeout(FETCH_TIMEOUT).setType(DMT.FNPDataFound);
+                MessageFilter mfDF = makeDataFoundFilter(next);
                 MessageFilter mfRouteNotFound = 
MessageFilter.create().setSource(next).setField(DMT.UID, 
uid).setTimeout(FETCH_TIMEOUT).setType(DMT.FNPRouteNotFound);
                 MessageFilter mfRejectedOverload = 
MessageFilter.create().setSource(next).setField(DMT.UID, 
uid).setTimeout(FETCH_TIMEOUT).setType(DMT.FNPRejectedOverload);
                 MessageFilter mf = 
mfDNF.or(mfDF.or(mfRouteNotFound.or(mfRejectedOverload)));
@@ -255,52 +269,101 @@
                                        continue; // Wait for any further 
response
                }

-               if(msg.getSpec() != DMT.FNPDataFound) {
-                       Logger.error(this, "Unexpected message: "+msg);
+               if(msg.getSpec() == DMT.FNPCHKDataFound) {
+                       if(!(key instanceof NodeCHK)) {
+                               Logger.error(this, "Got "+msg+" but expected a 
different key type from "+next);
+                               break;
+                       }
+                       
+                       // Found data
+                       next.successNotOverload();
+                       
+                       // First get headers
+                       
+                       headers = 
((ShortBuffer)msg.getObject(DMT.BLOCK_HEADERS)).getData();
+                       
+                       // FIXME: Validate headers
+                       
+                       node.addTransferringSender((NodeCHK)key, this);
+                       
+                       try {
+                               
+                               prb = new 
PartiallyReceivedBlock(Node.PACKETS_IN_BLOCK, Node.PACKET_SIZE);
+                               
+                               synchronized(this) {
+                                       notifyAll();
+                               }
+                               
+                               BlockReceiver br = new BlockReceiver(node.usm, 
next, uid, prb);
+                               
+                               try {
+                                       byte[] data = br.receive();
+                                       // Received data
+                                       CHKBlock block;
+                                       try {
+                                               verifyAndCommit(data);
+                                       } catch (KeyVerifyException e1) {
+                                               Logger.normal(this, "Got data 
but verify failed: "+e1, e1);
+                                               finish(VERIFY_FAILURE, next);
+                                               return;
+                                       }
+                                       finish(SUCCESS, next);
+                                       return;
+                               } catch (RetrievalException e) {
+                                       Logger.normal(this, "Transfer failed: 
"+e, e);
+                                       finish(TRANSFER_FAILED, next);
+                                       return;
+                               }
+                       } finally {
+                               node.removeTransferringSender((NodeCHK)key, 
this);
+                       }
                }

-               // Found data
-               next.successNotOverload();
-               
-               // First get headers
-               
-               headers = 
((ShortBuffer)msg.getObject(DMT.BLOCK_HEADERS)).getData();
-               
-               // FIXME: Validate headers
-               
-               node.addTransferringSender(key, this);
-               try {
+               if(msg.getSpec() == DMT.FNPSSKPubKey) {

-                       prb = new PartiallyReceivedBlock(Node.PACKETS_IN_BLOCK, 
Node.PACKET_SIZE);
+                       Logger.minor(this, "Got pubkey on "+uid);

-                       synchronized(this) {
-                               notifyAll();
+                       if(!(key instanceof NodeSSK)) {
+                               Logger.error(this, "Got "+msg+" but expected a 
different key type from "+next);
+                               break;
                        }
+                               byte[] pubkeyAsBytes = 
((ShortBuffer)msg.getObject(DMT.PUBKEY_AS_BYTES)).getData();
+                               try {
+                                       pubKey = new 
DSAPublicKey(pubkeyAsBytes);
+                               } catch (IOException e) {
+                                       Logger.error(this, "Invalid pubkey from 
"+source+" on "+uid);
+                                       finish(VERIFY_FAILURE, next);
+                                       return;
+                               }
+                               if(sskData != null) {
+                                       finishSSK(next);
+                                       return;
+                               }
+                               continue;
+               }
+               
+               if(msg.getSpec() == DMT.FNPSSKDataFound) {
+
+                       Logger.minor(this, "Got data on "+uid);

-                       BlockReceiver br = new BlockReceiver(node.usm, next, 
uid, prb);
+                       if(!(key instanceof NodeCHK)) {
+                               Logger.error(this, "Got "+msg+" but expected a 
different key type from "+next);
+                               break;
+                       }

-                       try {
-                               byte[] data = br.receive();
-                               // Received data
-                               CHKBlock block;
-                               try {
-                                       block = new CHKBlock(data, headers, 
key);
-                               } catch (CHKVerifyException e1) {
-                                       Logger.normal(this, "Got data but 
verify failed: "+e1, e1);
-                                       finish(VERIFY_FAILURE, next);
-                                       return;
-                               }
-                               node.store(block);
-                               finish(SUCCESS, next);
-                               return;
-                       } catch (RetrievalException e) {
-                               Logger.normal(this, "Transfer failed: "+e, e);
-                               finish(TRANSFER_FAILED, next);
-                               return;
-                       }
-               } finally {
-                       node.removeTransferringSender(key, this);
+                       headers = 
((ShortBuffer)msg.getObject(DMT.BLOCK_HEADERS)).getData();
+                       
+                       sskData = 
((ShortBuffer)msg.getObject(DMT.DATA)).getData();
+                       
+                       if(pubKey != null) {
+                               finishSSK(next);
+                               return;
+                       }
+                       continue;
                }
+               
+                       Logger.error(this, "Unexpected message: "+msg);
+               
             }
         }
         } catch (Throwable t) {
@@ -312,7 +375,45 @@
         }
     }

-    private volatile boolean hasForwardedRejectedOverload;
+    private void finishSSK(PeerNode next) {
+       try {
+                       SSKBlock block = new SSKBlock(sskData, headers, 
(NodeSSK)key, false);
+                       node.store(block);
+                       finish(SUCCESS, next);
+               } catch (SSKVerifyException e) {
+                       Logger.error(this, "Failed to verify: "+e+" from 
"+next);
+                       finish(VERIFY_FAILURE, next);
+                       return;
+               }
+       }
+
+       private MessageFilter makeDataFoundFilter(PeerNode next) {
+       if(key instanceof NodeCHK)
+               return MessageFilter.create().setSource(next).setField(DMT.UID, 
uid).setTimeout(FETCH_TIMEOUT).setType(DMT.FNPCHKDataFound);
+       else if(key instanceof NodeSSK)
+               return MessageFilter.create().setSource(next).setField(DMT.UID, 
uid).setTimeout(FETCH_TIMEOUT).setType(DMT.FNPSSKDataFound);
+       else throw new IllegalStateException("Unknown keytype: "+key);
+       }
+
+       private Message createDataRequest() {
+       if(key instanceof NodeCHK)
+               return DMT.createFNPCHKDataRequest(uid, htl, (NodeCHK)key, 
nearestLoc);
+       else if(key instanceof NodeSSK)
+               return DMT.createFNPSSKDataRequest(uid, htl, (NodeSSK)key, 
nearestLoc, pubKey == null);
+       else throw new IllegalStateException("Unknown keytype: "+key);
+       }
+
+       private void verifyAndCommit(byte[] data) throws KeyVerifyException {
+       if(key instanceof NodeCHK) {
+               CHKBlock block = new CHKBlock(data, headers, (NodeCHK)key);
+               node.store(block);
+       } else if (key instanceof NodeSSK) {
+               SSKBlock block = new SSKBlock(data, headers, (NodeSSK)key, 
false);
+               node.store(block);
+       }
+       }
+
+       private volatile boolean hasForwardedRejectedOverload;

     /** Forward RejectedOverload to the request originator */
     private synchronized void forwardRejectedOverload() {
@@ -392,4 +493,8 @@
     public short getHTL() {
         return htl;
     }
+    
+    final byte[] getSSKData() {
+       return sskData;
+    }
 }

Modified: trunk/freenet/src/freenet/node/SSKInsertHandler.java
===================================================================
--- trunk/freenet/src/freenet/node/SSKInsertHandler.java        2006-01-07 
19:46:58 UTC (rev 7805)
+++ trunk/freenet/src/freenet/node/SSKInsertHandler.java        2006-01-07 
20:27:35 UTC (rev 7806)
@@ -186,7 +186,7 @@
                                        // Is verified elsewhere...
                                        throw new Error("Impossible: "+e1);
                                }
-               Message msg = DMT.createFNPSSKDataFound(uid, key, headers, 
data, sender.getPubkeyHash());
+               Message msg = DMT.createFNPSSKDataFound(uid, headers, data);
                try {
                        source.send(msg);
                } catch (NotConnectedException e) {

Modified: trunk/freenet/src/freenet/node/SSKInsertSender.java
===================================================================
--- trunk/freenet/src/freenet/node/SSKInsertSender.java 2006-01-07 19:46:58 UTC 
(rev 7805)
+++ trunk/freenet/src/freenet/node/SSKInsertSender.java 2006-01-07 20:27:35 UTC 
(rev 7806)
@@ -390,9 +390,8 @@
                                                break;
                                        }

-                                       SSKBlock newBlock;
                                        try {
-                                               newBlock = new 
SSKBlock(newData, newHeaders, myKey, false);
+                                               SSKBlock newBlock = new 
SSKBlock(newData, newHeaders, myKey, false);
                                        } catch (SSKVerifyException e) {
                                                Logger.error(this, "Node sent 
us collision but got corrupt SSK!! from "+next+" on "+uid);
                                                // Try next node, no way to 
tell this one about its mistake as it's stopped listening. FIXME should it?

Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-01-07 19:46:58 UTC (rev 
7805)
+++ trunk/freenet/src/freenet/node/Version.java 2006-01-07 20:27:35 UTC (rev 
7806)
@@ -20,7 +20,7 @@
        public static final String protocolVersion = "1.0";

        /** The build number of the current revision */
-       public static final int buildNumber = 330;
+       public static final int buildNumber = 331;

        /** Oldest build of Fred we will talk to */
        public static final int lastGoodBuild = 330;

Modified: trunk/freenet/src/freenet/support/Serializer.java
===================================================================
--- trunk/freenet/src/freenet/support/Serializer.java   2006-01-07 19:46:58 UTC 
(rev 7805)
+++ trunk/freenet/src/freenet/support/Serializer.java   2006-01-07 20:27:35 UTC 
(rev 7806)
@@ -29,6 +29,8 @@
 import freenet.io.WritableToDataOutputStream;
 import freenet.io.comm.Peer;
 import freenet.keys.Key;
+import freenet.keys.NodeCHK;
+import freenet.keys.NodeSSK;

 /**
  * @author ian
@@ -79,6 +81,12 @@
                        return new Peer(dis);
                } else if (type.equals(BitArray.class)) {
                        return new BitArray(dis);
+               } else if (type.equals(NodeCHK.class)) {
+                       // Use Key.read(...) because write(...) writes the TYPE 
field.
+                       return (NodeCHK) Key.read(dis);
+               } else if (type.equals(NodeSSK.class)) {
+                       // Use Key.read(...) because write(...) writes the TYPE 
field.
+                       return (NodeSSK) Key.read(dis);
                } else if (type.equals(Key.class)) {
                    return Key.read(dis);
                } else {


Reply via email to