Author: toad
Date: 2008-03-20 18:19:26 +0000 (Thu, 20 Mar 2008)
New Revision: 18655

Modified:
   trunk/freenet/src/freenet/node/SSKInsertSender.java
Log:
Handle collisions with new messages.

Modified: trunk/freenet/src/freenet/node/SSKInsertSender.java
===================================================================
--- trunk/freenet/src/freenet/node/SSKInsertSender.java 2008-03-20 17:29:27 UTC 
(rev 18654)
+++ trunk/freenet/src/freenet/node/SSKInsertSender.java 2008-03-20 18:19:26 UTC 
(rev 18655)
@@ -428,6 +428,54 @@
                                        continue;
                                }

+                               if(msg.getSpec() == DMT.FNPSSKDataFoundHeaders) 
{
+                                       /**
+                                        * Data was already on node, and was 
NOT equal to what we sent. COLLISION!
+                                        * 
+                                        * We can either accept the old data or 
the new data.
+                                        * OLD DATA:
+                                        * - KSK-based stuff is usable. Well, 
somewhat; a node could spoof KSKs on
+                                        * receiving an insert, (if it knows 
them in advance), but it cannot just 
+                                        * start inserts to overwrite old SSKs.
+                                        * - You cannot "update" an SSK.
+                                        * NEW DATA:
+                                        * - KSK-based stuff not usable. (Some 
people think this is a good idea!).
+                                        * - Illusion of updatability. (VERY 
BAD IMHO, because it's not really
+                                        * updatable... FIXME implement TUKs; 
would determine latest version based
+                                        * on version number, and propagate on 
request with a certain probability or
+                                        * according to time. However there are 
good arguments to do updating at a
+                                        * higher level (e.g. key bottleneck 
argument), and TUKs should probably be 
+                                        * distinct from SSKs.
+                                        * 
+                                        * For now, accept the "old" i.e. 
preexisting data.
+                                        */
+                                       Logger.normal(this, "Got collision on 
"+myKey+" ("+uid+") sending to "+next.getPeer());
+                                       
+                               headers = ((ShortBuffer) 
msg.getObject(DMT.BLOCK_HEADERS)).getData();
+                               // Wait for the data
+                               MessageFilter mfData = 
MessageFilter.create().setSource(next).setField(DMT.UID, 
uid).setTimeout(RequestSender.FETCH_TIMEOUT).setType(DMT.FNPSSKDataFoundData);
+                               Message dataMessage;
+                               try {
+                                               dataMessage = 
node.usm.waitFor(mfData, this);
+                                       } catch (DisconnectedException e) {
+                                               if(logMINOR)
+                                                       Logger.minor(this, 
"Disconnected: "+next+" getting datareply for "+this);
+                                               break;
+                                       }
+                                       if(dataMessage == null) {
+                                       Logger.error(this, "Got headers but not 
data for datareply for insert from "+this);
+                                       break;
+                                       }
+                                       data = ((ShortBuffer) 
dataMessage.getObject(DMT.DATA)).getData();
+                                       
+                                       synchronized(this) {
+                                               hasRecentlyCollided = true;
+                                               hasCollided = true;
+                                               notifyAll();
+                                       }
+                                       continue; // The node will now 
propagate the new data. There is no need to move to the next node yet.
+                       }
+                               
                                if (msg.getSpec() != DMT.FNPInsertReply) {
                                        Logger.error(this, "Unknown reply: " + 
msg);
                                        finish(INTERNAL_ERROR, next);


Reply via email to