gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r13024 - in gnunet: . src/block src/datastore src/dht src/f


From: gnunet
Subject: [GNUnet-SVN] r13024 - in gnunet: . src/block src/datastore src/dht src/fs src/include src/util
Date: Sat, 18 Sep 2010 21:10:12 +0200

Author: grothoff
Date: 2010-09-18 21:10:12 +0200 (Sat, 18 Sep 2010)
New Revision: 13024

Added:
   gnunet/src/block/plugin_block_dht.c
   gnunet/src/block/plugin_block_test.c
   gnunet/src/include/gnunet_load_lib.h
   gnunet/src/util/load.c
Modified:
   gnunet/TODO
   gnunet/src/block/Makefile.am
   gnunet/src/block/plugin_block_fs.c
   gnunet/src/block/test_block.c
   gnunet/src/datastore/gnunet-service-datastore.c
   gnunet/src/dht/dht_api.c
   gnunet/src/fs/Makefile.am
   gnunet/src/fs/fs.h
   gnunet/src/fs/fs_download.c
   gnunet/src/fs/fs_namespace.c
   gnunet/src/fs/fs_publish.c
   gnunet/src/fs/fs_search.c
   gnunet/src/fs/fs_tree.c
   gnunet/src/fs/fs_unindex.c
   gnunet/src/fs/gnunet-service-fs.c
   gnunet/src/fs/gnunet-service-fs_indexing.c
   gnunet/src/include/Makefile.am
   gnunet/src/include/gnunet_block_lib.h
   gnunet/src/include/gnunet_dht_service.h
   gnunet/src/include/gnunet_protocols.h
   gnunet/src/util/Makefile.am
Log:
plane hacking

Modified: gnunet/TODO
===================================================================
--- gnunet/TODO 2010-09-18 05:17:21 UTC (rev 13023)
+++ gnunet/TODO 2010-09-18 19:10:12 UTC (rev 13024)
@@ -1,12 +1,13 @@
 0.9.0pre2:
  FS:
-  - move FS serivce to new block API
-  - integrate with DHT
   - measure latencies (core, datastore) => trust economy
   - refuse content migration message (or solicit?)
   - FS performance benchmarking
+  - integrate with DHT (need DHT API to fit block API better first; also, get 
rid of the continuation!)
 * DHT: [Nate]
-  - use new block lib
+  - use new block lib in service
+  - provide block-lib compatible API in gnunet_dht_service.h
+  - eliminate continuations in DHT API (not needed, we have auto-retransmit!)
 * CORE:
   - derived key generation [Nils]
   - Jun 27 11:51:54 core-7670 ERROR Assertion failed at 
gnunet-service-core.c:3616.

Modified: gnunet/src/block/Makefile.am
===================================================================
--- gnunet/src/block/Makefile.am        2010-09-18 05:17:21 UTC (rev 13023)
+++ gnunet/src/block/Makefile.am        2010-09-18 19:10:12 UTC (rev 13024)
@@ -13,9 +13,20 @@
 lib_LTLIBRARIES = libgnunetblock.la
 
 plugin_LTLIBRARIES = \
+  libgnunet_plugin_block_dht.la \
   libgnunet_plugin_block_fs.la \
-  libgnunet_plugin_block_template.la 
+  libgnunet_plugin_block_template.la \
+  libgnunet_plugin_block_test.la 
 
+libgnunet_plugin_block_dht_la_SOURCES = \
+  plugin_block_dht.c
+libgnunet_plugin_block_dht_la_LIBADD = \
+  $(top_builddir)/src/hello/libgnunethello.la \
+  $(top_builddir)/src/block/libgnunetblock.la \
+  $(top_builddir)/src/util/libgnunetutil.la 
+libgnunet_plugin_block_dht_la_LDFLAGS = \
+ $(GN_PLUGIN_LDFLAGS)
+
 libgnunet_plugin_block_fs_la_SOURCES = \
   plugin_block_fs.c
 libgnunet_plugin_block_fs_la_LIBADD = \
@@ -31,7 +42,15 @@
 libgnunet_plugin_block_template_la_LDFLAGS = \
  $(GN_PLUGIN_LDFLAGS)
 
+libgnunet_plugin_block_test_la_SOURCES = \
+  plugin_block_test.c
+libgnunet_plugin_block_test_la_LIBADD = \
+  $(top_builddir)/src/block/libgnunetblock.la \
+  $(top_builddir)/src/util/libgnunetutil.la 
+libgnunet_plugin_block_test_la_LDFLAGS = \
+ $(GN_PLUGIN_LDFLAGS)
 
+
 libgnunetblock_la_SOURCES = \
   block.c plugin_block.h
 libgnunetblock_la_LIBADD = \

Added: gnunet/src/block/plugin_block_dht.c
===================================================================
--- gnunet/src/block/plugin_block_dht.c                         (rev 0)
+++ gnunet/src/block/plugin_block_dht.c 2010-09-18 19:10:12 UTC (rev 13024)
@@ -0,0 +1,163 @@
+/*
+     This file is part of GNUnet
+     (C) 2010 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file block/plugin_block_dht.c
+ * @brief block plugin for DHT internals (right now, find-peer requests only);
+ *        other plugins should be used to store "useful" data in the
+ *        DHT (see fs block plugin)
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include "gnunet_hello_lib.h"
+#include "plugin_block.h"
+
+#define DEBUG_DHT GNUNET_NO
+
+
+/**
+ * Function called to validate a reply or a request.  For
+ * request evaluation, simply pass "NULL" for the reply_block.
+ *
+ * @param cls closure
+ * @param type block type
+ * @param query original query (hash)
+ * @param bf pointer to bloom filter associated with query; possibly updated 
(!)
+ * @param bf_mutator mutation value for bf
+ * @param xquery extrended query data (can be NULL, depending on type)
+ * @param xquery_size number of bytes in xquery
+ * @param reply_block response to validate
+ * @param reply_block_size number of bytes in reply block
+ * @return characterization of result
+ */
+static enum GNUNET_BLOCK_EvaluationResult
+block_plugin_dht_evaluate (void *cls,
+                          enum GNUNET_BLOCK_Type type,
+                          const GNUNET_HashCode *query,
+                          struct GNUNET_CONTAINER_BloomFilter **bf,
+                          int32_t bf_mutator,
+                          const void *xquery,
+                          size_t xquery_size,
+                          const void *reply_block,
+                          size_t reply_block_size)
+{
+  if (type != GNUNET_BLOCK_TYPE_DHT_HELLO)  
+    return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED;
+  if (xquery_size != 0)
+    return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID;
+  if (reply_block_size == 0)
+    return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
+  GNUNET_break (NULL == *bf);
+  return GNUNET_BLOCK_EVALUATION_OK_LAST;
+}
+
+
+/**
+ * Function called to obtain the key for a block.
+ *
+ * @param cls closure
+ * @param type block type
+ * @param block block to get the key for
+ * @param block_size number of bytes in block
+ * @param key set to the key (query) for the given block
+ * @return GNUNET_OK on success, GNUNET_SYSERR if type not supported
+ *         (or if extracting a key from a block of this type does not work)
+ */
+static int
+block_plugin_dht_get_key (void *cls,
+                         enum GNUNET_BLOCK_Type type,
+                         const void *block,
+                         size_t block_size,
+                         GNUNET_HashCode *key)
+{
+  const struct GNUNET_MessageHeader *msg;
+  const struct GNUNET_HELLO_Message *hello;
+  struct GNUNET_PeerIdentity *pid;
+
+  if (type != GNUNET_BLOCK_TYPE_DHT_HELLO)
+    return GNUNET_SYSERR;
+  if (block_size < sizeof (struct GNUNET_MessageHeader))
+    {
+      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
+                      "block-dht",
+                      _("Block not of type %u\n"),
+                      GNUNET_BLOCK_TYPE_DHT_HELLO);
+      return GNUNET_SYSERR;
+    }
+  msg = block;
+  if (block_size != ntohs (msg->size))
+    {
+      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
+                      "block-dht",
+                      _("Size mismatch for block\n"),
+                      GNUNET_BLOCK_TYPE_DHT_HELLO);
+      return GNUNET_SYSERR;
+    }
+  hello = block;
+  pid = (struct GNUNET_PeerIdentity*) key;
+  if (GNUNET_OK !=
+      GNUNET_HELLO_get_id (hello,
+                          pid))
+    {
+      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
+                      "block-dht",
+                      _("Block of type %u is malformed\n"),
+                      GNUNET_BLOCK_TYPE_DHT_HELLO);
+      return GNUNET_SYSERR;
+    }
+  return GNUNET_OK;
+}
+                                 
+
+/**
+ * Entry point for the plugin.
+ */
+void *
+gnunet_plugin_block_dht_init (void *cls)
+{
+  static enum GNUNET_BLOCK_Type types[] = 
+    {
+      GNUNET_BLOCK_TYPE_DHT_HELLO,
+      GNUNET_BLOCK_TYPE_ANY /* end of list */
+    };
+  struct GNUNET_BLOCK_PluginFunctions *api;
+
+  api = GNUNET_malloc (sizeof (struct GNUNET_BLOCK_PluginFunctions));
+  api->evaluate = &block_plugin_dht_evaluate;
+  api->get_key = &block_plugin_dht_get_key;
+  api->types = types;
+  return api;
+}
+
+
+/**
+ * Exit point from the plugin.
+ */
+void *
+gnunet_plugin_block_dht_done (void *cls)
+{
+  struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
+
+  GNUNET_free (api);
+  return NULL;
+}
+
+/* end of plugin_block_dht.c */

Modified: gnunet/src/block/plugin_block_fs.c
===================================================================
--- gnunet/src/block/plugin_block_fs.c  2010-09-18 05:17:21 UTC (rev 13023)
+++ gnunet/src/block/plugin_block_fs.c  2010-09-18 19:10:12 UTC (rev 13024)
@@ -74,8 +74,8 @@
 
   switch (type)
     {
-    case GNUNET_BLOCK_TYPE_DBLOCK:
-    case GNUNET_BLOCK_TYPE_IBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_DBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_IBLOCK:
       if (xquery_size != 0) 
        {
          GNUNET_break_op (0);
@@ -84,8 +84,8 @@
       if (reply_block == NULL)
        return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
       return GNUNET_BLOCK_EVALUATION_OK_LAST;
-    case GNUNET_BLOCK_TYPE_KBLOCK:
-    case GNUNET_BLOCK_TYPE_NBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_KBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_NBLOCK:
       if (xquery_size != 0) 
        {
          GNUNET_break_op (0);
@@ -111,7 +111,7 @@
        }
       GNUNET_CONTAINER_bloomfilter_add (*bf, &mhash);
       return GNUNET_BLOCK_EVALUATION_OK_MORE;
-    case GNUNET_BLOCK_TYPE_SBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_SBLOCK:
       if (xquery_size != sizeof (GNUNET_HashCode)) 
        {
          GNUNET_break_op (0);
@@ -133,8 +133,9 @@
                       &sh,
                       sizeof (GNUNET_HashCode)))
        {
-         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                     _("Reply mismatched in terms of namespace.  
Discarded.\n"));
+         GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
+                          "block-fs",
+                          _("Reply mismatched in terms of namespace.  
Discarded.\n"));
          return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
        }
       GNUNET_CRYPTO_hash (reply_block,
@@ -185,11 +186,11 @@
 
   switch (type)
     {
-    case GNUNET_BLOCK_TYPE_DBLOCK:
-    case GNUNET_BLOCK_TYPE_IBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_DBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_IBLOCK:
       GNUNET_CRYPTO_hash (block, block_size, key);
       return GNUNET_OK;
-    case GNUNET_BLOCK_TYPE_KBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_KBLOCK:
       if (block_size < sizeof (struct KBlock))
        {
          GNUNET_break_op (0);
@@ -218,7 +219,7 @@
                            sizeof (struct 
GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
                            key);
       return GNUNET_OK;
-    case GNUNET_BLOCK_TYPE_SBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_SBLOCK:
       if (block_size < sizeof (struct SBlock))
        {
          GNUNET_break_op (0);
@@ -243,7 +244,7 @@
       if (key != NULL)
        *key = sb->identifier;
       return GNUNET_OK;
-    case GNUNET_BLOCK_TYPE_NBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_NBLOCK:
       if (block_size < sizeof (struct NBlock))
        {
          GNUNET_break_op (0);
@@ -303,11 +304,11 @@
 {
   static enum GNUNET_BLOCK_Type types[] = 
     {
-      GNUNET_BLOCK_TYPE_DBLOCK,
-      GNUNET_BLOCK_TYPE_IBLOCK,
-      GNUNET_BLOCK_TYPE_KBLOCK,
-      GNUNET_BLOCK_TYPE_SBLOCK,
-      GNUNET_BLOCK_TYPE_NBLOCK,
+      GNUNET_BLOCK_TYPE_FS_DBLOCK,
+      GNUNET_BLOCK_TYPE_FS_IBLOCK,
+      GNUNET_BLOCK_TYPE_FS_KBLOCK,
+      GNUNET_BLOCK_TYPE_FS_SBLOCK,
+      GNUNET_BLOCK_TYPE_FS_NBLOCK,
       GNUNET_BLOCK_TYPE_ANY /* end of list */
     };
   struct GNUNET_BLOCK_PluginFunctions *api;

Added: gnunet/src/block/plugin_block_test.c
===================================================================
--- gnunet/src/block/plugin_block_test.c                                (rev 0)
+++ gnunet/src/block/plugin_block_test.c        2010-09-18 19:10:12 UTC (rev 
13024)
@@ -0,0 +1,154 @@
+/*
+     This file is part of GNUnet
+     (C) 2010 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file block/plugin_block_test.c
+ * @brief block plugin to test the DHT as a simple key-value store;
+ *        this plugin simply accepts any (new) response for any key
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include "plugin_block.h"
+
+#define DEBUG_TEST GNUNET_NO
+
+
+/**
+ * Number of bits we set per entry in the bloomfilter.
+ * Do not change!
+ */
+#define BLOOMFILTER_K 16
+
+/**
+ * Function called to validate a reply or a request.  For
+ * request evaluation, simply pass "NULL" for the reply_block.
+ *
+ * @param cls closure
+ * @param type block type
+ * @param query original query (hash)
+ * @param bf pointer to bloom filter associated with query; possibly updated 
(!)
+ * @param bf_mutator mutation value for bf
+ * @param xquery extrended query data (can be NULL, depending on type)
+ * @param xquery_size number of bytes in xquery
+ * @param reply_block response to validate
+ * @param reply_block_size number of bytes in reply block
+ * @return characterization of result
+ */
+static enum GNUNET_BLOCK_EvaluationResult
+block_plugin_test_evaluate (void *cls,
+                          enum GNUNET_BLOCK_Type type,
+                          const GNUNET_HashCode *query,
+                          struct GNUNET_CONTAINER_BloomFilter **bf,
+                          int32_t bf_mutator,
+                          const void *xquery,
+                          size_t xquery_size,
+                          const void *reply_block,
+                          size_t reply_block_size)
+{
+  GNUNET_HashCode chash;
+  GNUNET_HashCode mhash;
+
+  if (type != GNUNET_BLOCK_TYPE_TEST)  
+    return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED;
+  if (xquery_size != 0)
+    GNUNET_BLOCK_EVALUATION_REQUEST_INVALID;
+  if (reply_block_size == 0)
+    GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
+
+  GNUNET_CRYPTO_hash (reply_block,
+                     reply_block_size,
+                     &chash);
+  GNUNET_BLOCK_mingle_hash (&chash, bf_mutator, &mhash);
+  if (NULL != *bf)
+    {
+      if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (*bf,
+                                                          &mhash))
+       return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE;
+    }
+  else
+    {
+      *bf = GNUNET_CONTAINER_bloomfilter_init (NULL, 
+                                              8,
+                                              BLOOMFILTER_K);
+    }
+  GNUNET_CONTAINER_bloomfilter_add (*bf, &mhash);  
+  return GNUNET_BLOCK_EVALUATION_OK_MORE;
+}
+
+
+/**
+ * Function called to obtain the key for a block.
+ *
+ * @param cls closure
+ * @param type block type
+ * @param block block to get the key for
+ * @param block_size number of bytes in block
+ * @param key set to the key (query) for the given block
+ * @return GNUNET_OK on success, GNUNET_SYSERR if type not supported
+ *         (or if extracting a key from a block of this type does not work)
+ */
+static int
+block_plugin_test_get_key (void *cls,
+                         enum GNUNET_BLOCK_Type type,
+                         const void *block,
+                         size_t block_size,
+                         GNUNET_HashCode *key)
+{
+  /* always fails since there is no fixed relationship between
+     keys and values for test values */
+  return GNUNET_SYSERR;
+}
+                                 
+
+/**
+ * Entry point for the plugin.
+ */
+void *
+gnunet_plugin_block_test_init (void *cls)
+{
+  static enum GNUNET_BLOCK_Type types[] = 
+    {
+      GNUNET_BLOCK_TYPE_TEST,
+      GNUNET_BLOCK_TYPE_ANY /* end of list */
+    };
+  struct GNUNET_BLOCK_PluginFunctions *api;
+
+  api = GNUNET_malloc (sizeof (struct GNUNET_BLOCK_PluginFunctions));
+  api->evaluate = &block_plugin_test_evaluate;
+  api->get_key = &block_plugin_test_get_key;
+  api->types = types;
+  return api;
+}
+
+
+/**
+ * Exit point from the plugin.
+ */
+void *
+gnunet_plugin_block_test_done (void *cls)
+{
+  struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
+
+  GNUNET_free (api);
+  return NULL;
+}
+
+/* end of plugin_block_test.c */

Modified: gnunet/src/block/test_block.c
===================================================================
--- gnunet/src/block/test_block.c       2010-09-18 05:17:21 UTC (rev 13023)
+++ gnunet/src/block/test_block.c       2010-09-18 19:10:12 UTC (rev 13024)
@@ -38,14 +38,14 @@
   memset (block, 1, sizeof (block));
   if (GNUNET_OK !=
       GNUNET_BLOCK_get_key (ctx,
-                           GNUNET_BLOCK_TYPE_DBLOCK,
+                           GNUNET_BLOCK_TYPE_FS_DBLOCK,
                            block,
                            sizeof (block),
                            &key))
     return 1;
   if (GNUNET_BLOCK_EVALUATION_OK_LAST !=
       GNUNET_BLOCK_evaluate (ctx,
-                            GNUNET_BLOCK_TYPE_DBLOCK,
+                            GNUNET_BLOCK_TYPE_FS_DBLOCK,
                             &key,
                             NULL, 0,
                             NULL, 0,
@@ -53,7 +53,7 @@
     return 2;
   if (GNUNET_BLOCK_EVALUATION_REQUEST_VALID !=
       GNUNET_BLOCK_evaluate (ctx,
-                            GNUNET_BLOCK_TYPE_DBLOCK,
+                            GNUNET_BLOCK_TYPE_FS_DBLOCK,
                             &key,
                             NULL, 0,
                             NULL, 0,
@@ -62,7 +62,7 @@
   GNUNET_log_skip (1, GNUNET_NO);
   if (GNUNET_BLOCK_EVALUATION_REQUEST_INVALID  !=
       GNUNET_BLOCK_evaluate (ctx,
-                            GNUNET_BLOCK_TYPE_DBLOCK,
+                            GNUNET_BLOCK_TYPE_FS_DBLOCK,
                             &key,
                             NULL, 0,
                             "bogus", 5,

Modified: gnunet/src/datastore/gnunet-service-datastore.c
===================================================================
--- gnunet/src/datastore/gnunet-service-datastore.c     2010-09-18 05:17:21 UTC 
(rev 13023)
+++ gnunet/src/datastore/gnunet-service-datastore.c     2010-09-18 19:10:12 UTC 
(rev 13024)
@@ -1038,8 +1038,8 @@
       GNUNET_free (pc);
       return GNUNET_SYSERR;
     }
-  if ( (GNUNET_BLOCK_TYPE_DBLOCK == type) ||
-       (GNUNET_BLOCK_TYPE_IBLOCK == type) ||
+  if ( (GNUNET_BLOCK_TYPE_FS_DBLOCK == type) ||
+       (GNUNET_BLOCK_TYPE_FS_IBLOCK == type) ||
        ( (size == ntohl(dm->size)) &&
         (0 == memcmp (&dm[1],
                       data,

Modified: gnunet/src/dht/dht_api.c
===================================================================
--- gnunet/src/dht/dht_api.c    2010-09-18 05:17:21 UTC (rev 13023)
+++ gnunet/src/dht/dht_api.c    2010-09-18 19:10:12 UTC (rev 13024)
@@ -1132,7 +1132,7 @@
 struct GNUNET_DHT_GetHandle *
 GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle,
                       struct GNUNET_TIME_Relative timeout,
-                      uint32_t type,
+                      enum GNUNET_BLOCK_Type type,
                       const GNUNET_HashCode * key,
                       GNUNET_DHT_GetIterator iter,
                       void *iter_cls,
@@ -1366,7 +1366,7 @@
 void
 GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle,
                 const GNUNET_HashCode * key,
-                uint32_t type,
+                enum GNUNET_BLOCK_Type type,
                 uint32_t size,
                 const char *data,
                 struct GNUNET_TIME_Absolute exp,
@@ -1422,3 +1422,5 @@
 
   GNUNET_free (put_msg);
 }
+
+/* end of dht_api.c */

Modified: gnunet/src/fs/Makefile.am
===================================================================
--- gnunet/src/fs/Makefile.am   2010-09-18 05:17:21 UTC (rev 13023)
+++ gnunet/src/fs/Makefile.am   2010-09-18 19:10:12 UTC (rev 13024)
@@ -96,6 +96,7 @@
  gnunet-service-fs_indexing.c gnunet-service-fs_indexing.h 
 gnunet_service_fs_LDADD =  \
  $(top_builddir)/src/fs/libgnunetfs.la \
+ $(top_builddir)/src/dht/libgnunetdht.la \
  $(top_builddir)/src/block/libgnunetblock.la \
  $(top_builddir)/src/datastore/libgnunetdatastore.la \
  $(top_builddir)/src/statistics/libgnunetstatistics.la \

Modified: gnunet/src/fs/fs.h
===================================================================
--- gnunet/src/fs/fs.h  2010-09-18 05:17:21 UTC (rev 13023)
+++ gnunet/src/fs/fs.h  2010-09-18 19:10:12 UTC (rev 13024)
@@ -2222,6 +2222,32 @@
 };
 
 
+/**
+ * Message send by a peer that wants to be excluded
+ * from migration for a while.
+ */
+struct MigrationStopMessage
+{
+  /**
+   * Message type will be 
+   * GNUNET_MESSAGE_TYPE_FS_MIGRATION_STOP.
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * Always zero.
+   */
+  uint32_t reserved GNUNET_PACKED;
+
+  /**
+   * How long should the block last?
+   */
+  struct GNUNET_TIME_RelativeNBO duration;
+
+};
+
+
+
 #endif
 
 /* end of fs.h */

Modified: gnunet/src/fs/fs_download.c
===================================================================
--- gnunet/src/fs/fs_download.c 2010-09-18 05:17:21 UTC (rev 13023)
+++ gnunet/src/fs/fs_download.c 2010-09-18 19:10:12 UTC (rev 13024)
@@ -304,8 +304,8 @@
   prc.data = enc;
   prc.size = len;
   prc.type = (dc->treedepth == depth) 
-    ? GNUNET_BLOCK_TYPE_DBLOCK 
-    : GNUNET_BLOCK_TYPE_IBLOCK;
+    ? GNUNET_BLOCK_TYPE_FS_DBLOCK 
+    : GNUNET_BLOCK_TYPE_FS_IBLOCK;
   prc.query = chk->query;
   prc.do_store = do_store;
   process_result_with_request (&prc,
@@ -1423,9 +1423,9 @@
       else
        sm->options = htonl (0);      
       if (dc->pending->depth == dc->treedepth)
-       sm->type = htonl (GNUNET_BLOCK_TYPE_DBLOCK);
+       sm->type = htonl (GNUNET_BLOCK_TYPE_FS_DBLOCK);
       else
-       sm->type = htonl (GNUNET_BLOCK_TYPE_IBLOCK);
+       sm->type = htonl (GNUNET_BLOCK_TYPE_FS_IBLOCK);
       sm->anonymity_level = htonl (dc->anonymity);
       sm->target = dc->target.hashPubKey;
       sm->query = dc->pending->chk.query;

Modified: gnunet/src/fs/fs_namespace.c
===================================================================
--- gnunet/src/fs/fs_namespace.c        2010-09-18 05:17:21 UTC (rev 13023)
+++ gnunet/src/fs/fs_namespace.c        2010-09-18 19:10:12 UTC (rev 13024)
@@ -416,7 +416,7 @@
                        &query,
                        ac->pt_size + sizeof (struct NBlock),
                        ac->nb,
-                       GNUNET_BLOCK_TYPE_NBLOCK,
+                       GNUNET_BLOCK_TYPE_FS_NBLOCK,
                        ac->priority,
                        ac->anonymity,
                        ac->expiration,
@@ -982,7 +982,7 @@
                        &sb_enc->identifier,
                        size,
                        sb_enc,
-                       GNUNET_BLOCK_TYPE_SBLOCK, 
+                       GNUNET_BLOCK_TYPE_FS_SBLOCK, 
                        priority,
                        anonymity,
                        expirationTime,

Modified: gnunet/src/fs/fs_publish.c
===================================================================
--- gnunet/src/fs/fs_publish.c  2010-09-18 05:17:21 UTC (rev 13023)
+++ gnunet/src/fs/fs_publish.c  2010-09-18 19:10:12 UTC (rev 13024)
@@ -555,7 +555,7 @@
   dpc_cls->p = p;
   if ( (! p->is_directory) &&
        (GNUNET_YES == p->data.file.do_index) &&
-       (type == GNUNET_BLOCK_TYPE_DBLOCK) )
+       (type == GNUNET_BLOCK_TYPE_FS_DBLOCK) )
     {
 #if DEBUG_PUBLISH
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -571,7 +571,7 @@
                            query,
                            sizeof(struct OnDemandBlock),
                            &odb,
-                           GNUNET_BLOCK_TYPE_ONDEMAND,
+                           GNUNET_BLOCK_TYPE_FS_ONDEMAND,
                            p->priority,
                            p->anonymity,
                            p->expirationTime,
@@ -1596,7 +1596,7 @@
                        sizeof (struct KBlock) + 
                        pkc->slen,
                        pkc->cpy,
-                       GNUNET_BLOCK_TYPE_KBLOCK, 
+                       GNUNET_BLOCK_TYPE_FS_KBLOCK, 
                        pkc->priority,
                        pkc->anonymity,
                        pkc->expirationTime,

Modified: gnunet/src/fs/fs_search.c
===================================================================
--- gnunet/src/fs/fs_search.c   2010-09-18 05:17:21 UTC (rev 13023)
+++ gnunet/src/fs/fs_search.c   2010-09-18 19:10:12 UTC (rev 13024)
@@ -814,7 +814,7 @@
     }
   switch (type)
     {
-    case GNUNET_BLOCK_TYPE_KBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_KBLOCK:
       if (! GNUNET_FS_uri_test_ksk (sc->uri))
        {
          GNUNET_break (0);
@@ -827,7 +827,7 @@
        }
       process_kblock (sc, data, size);
       break;
-    case GNUNET_BLOCK_TYPE_SBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_SBLOCK:
       if (! GNUNET_FS_uri_test_sks (sc->uri))
        {
          GNUNET_break (0);
@@ -840,7 +840,7 @@
        }
       process_sblock (sc, data, size);
       break;
-    case GNUNET_BLOCK_TYPE_NBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_NBLOCK:
       if (! GNUNET_FS_uri_test_ksk (sc->uri))
        {
          GNUNET_break (0);
@@ -854,9 +854,9 @@
       process_nblock (sc, data, size);
       break;
     case GNUNET_BLOCK_TYPE_ANY:
-    case GNUNET_BLOCK_TYPE_DBLOCK:
-    case GNUNET_BLOCK_TYPE_ONDEMAND:
-    case GNUNET_BLOCK_TYPE_IBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_DBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_ONDEMAND:
+    case GNUNET_BLOCK_TYPE_FS_IBLOCK:
       GNUNET_break (0);
       break;
     default:
@@ -981,7 +981,7 @@
        sm->options = htonl (1);
       else
        sm->options = htonl (0);      
-      sm->type = htonl (GNUNET_BLOCK_TYPE_SBLOCK);
+      sm->type = htonl (GNUNET_BLOCK_TYPE_FS_SBLOCK);
       sm->anonymity_level = htonl (sc->anonymity);
       sm->target = sc->uri->data.sks.namespace;
       identifier = sc->uri->data.sks.identifier;

Modified: gnunet/src/fs/fs_tree.c
===================================================================
--- gnunet/src/fs/fs_tree.c     2010-09-18 05:17:21 UTC (rev 13023)
+++ gnunet/src/fs/fs_tree.c     2010-09-18 19:10:12 UTC (rev 13024)
@@ -385,8 +385,8 @@
              &mychk->query,
              te->publish_offset,
              (te->current_depth == te->chk_tree_depth) 
-             ? GNUNET_BLOCK_TYPE_DBLOCK 
-             : GNUNET_BLOCK_TYPE_IBLOCK,
+             ? GNUNET_BLOCK_TYPE_FS_DBLOCK 
+             : GNUNET_BLOCK_TYPE_FS_IBLOCK,
              enc,
              pt_size);
   if (NULL != te->progress)

Modified: gnunet/src/fs/fs_unindex.c
===================================================================
--- gnunet/src/fs/fs_unindex.c  2010-09-18 05:17:21 UTC (rev 13023)
+++ gnunet/src/fs/fs_unindex.c  2010-09-18 19:10:12 UTC (rev 13024)
@@ -207,7 +207,7 @@
   const void *data;
   struct OnDemandBlock odb;
 
-  if (type != GNUNET_BLOCK_TYPE_DBLOCK)
+  if (type != GNUNET_BLOCK_TYPE_FS_DBLOCK)
     {
       size = block_size;
       data = block;

Modified: gnunet/src/fs/gnunet-service-fs.c
===================================================================
--- gnunet/src/fs/gnunet-service-fs.c   2010-09-18 05:17:21 UTC (rev 13023)
+++ gnunet/src/fs/gnunet-service-fs.c   2010-09-18 19:10:12 UTC (rev 13024)
@@ -24,8 +24,9 @@
  * @author Christian Grothoff
  *
  * TODO:
+ * - track per-peer request latency (using new load API)
+ * - consider more precise latency estimation (per-peer & request) -- again 
load API?
  * - implement test_load_too_high, make decision priority-based, implement 
forwarding, etc.
- * - consider more precise latency estimation (per-peer & request)
  * - introduce random latency in processing
  * - tell other peers to stop migration if our PUTs fail (or if
  *   we don't support migration per configuration?)
@@ -35,7 +36,9 @@
 #include <float.h>
 #include "gnunet_constants.h"
 #include "gnunet_core_service.h"
+#include "gnunet_dht_service.h"
 #include "gnunet_datastore_service.h"
+#include "gnunet_load_lib.h"
 #include "gnunet_peer_lib.h"
 #include "gnunet_protocols.h"
 #include "gnunet_signatures.h"
@@ -52,6 +55,13 @@
 #define MAX_QUEUE_PER_PEER 16
 
 /**
+ * Size for the hash map for DHT requests from the FS
+ * service.  Should be about the number of concurrent
+ * DHT requests we plan to make.
+ */
+#define FS_DHT_HT_SIZE 1024
+
+/**
  * How often do we flush trust values to disk?
  */
 #define TRUST_FLUSH_FREQ GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_MINUTES, 5)
@@ -174,6 +184,12 @@
   struct GNUNET_TIME_Relative avg_delay;
 
   /**
+   * Point in time until which this peer does not want us to migrate content
+   * to it.
+   */
+  struct GNUNET_TIME_Absolute migration_blocked;
+
+  /**
    * Handle for an active request for transmission to this
    * peer, or NULL.
    */
@@ -709,6 +725,11 @@
 static struct GNUNET_TIME_Relative min_migration_delay;
 
 /**
+ * Handle for DHT operations.
+ */
+static struct GNUNET_DHT_Handle *dht_handle;
+
+/**
  * Size of the doubly-linked list of migration blocks.
  */
 static unsigned int mig_size;
@@ -731,6 +752,29 @@
 static double current_priorities;
 
 /**
+ * Datastore load tracking.
+ */
+static struct GNUNET_LOAD_Value *datastore_load;
+
+
+/**
+ * We've just now completed a datastore request.  Update our
+ * datastore load calculations.
+ *
+ * @param start time when the datastore request was issued
+ */
+static void
+update_datastore_delays (struct GNUNET_TIME_Absolute start)
+{
+  struct GNUNET_TIME_Relative delay;
+
+  delay = GNUNET_TIME_absolute_get_duration (start);
+  GNUNET_LOAD_update (datastore_load,
+                     delay.value);
+}
+
+
+/**
  * Get the filename under which we would store the GNUNET_HELLO_Message
  * for the given host and protocol.
  * @return filename of the form DIRECTORY/HOSTID
@@ -768,7 +812,6 @@
 
 /* ******************* clean up functions ************************ */
 
-
 /**
  * Delete the given migration block.
  *
@@ -831,6 +874,8 @@
   unsigned int repl;
   
   /* consider 'cp' as a migration target for mb */
+  if (GNUNET_TIME_absolute_get_remaining (cp->migration_blocked).value > 0)
+    return GNUNET_YES; /* peer has requested no migration! */
   if (mb != NULL)
     {
       GNUNET_PEER_resolve (cp->pid,
@@ -986,7 +1031,7 @@
        consider_migration_gathering ();
       return;
     }
-  if (type == GNUNET_BLOCK_TYPE_ONDEMAND)
+  if (type == GNUNET_BLOCK_TYPE_FS_ONDEMAND)
     {
       if (GNUNET_OK !=
          GNUNET_FS_handle_on_demand_block (key, size, data,
@@ -994,7 +1039,9 @@
                                            expiration, uid, 
                                            &process_migration_content,
                                            NULL))
-       GNUNET_DATASTORE_get_next (dsh, GNUNET_YES);
+       {
+         GNUNET_DATASTORE_get_next (dsh, GNUNET_YES);
+       }
       return;
     }
 #if DEBUG_FS
@@ -1587,6 +1634,10 @@
   while (mig_head != NULL)
     delete_migration_block (mig_head);
   GNUNET_assert (0 == mig_size);
+  GNUNET_DHT_disconnect (dht_handle);
+  dht_handle = NULL;
+  GNUNET_LOAD_value_free (datastore_load);
+  datastore_load = NULL;
   GNUNET_BLOCK_context_destroy (block_ctx);
   block_ctx = NULL;
   GNUNET_CONFIGURATION_destroy (block_cfg);
@@ -2297,6 +2348,21 @@
     }
   if (GNUNET_YES == pr->local_only)
     return; /* configured to not do P2P search */
+  /* (0) try DHT */
+  if (0 == pr->anonymity_level)
+    {
+#if 0      
+      /* DHT API needs fixing... */
+      pr->dht_get = GNUNET_DHT_get_start (dht_handle,
+                                         GNUNET_TIME_UNIT_FOREVER_REL,
+                                         pr->type,
+                                         &pr->query,
+                                         &process_dht_reply,
+                                         pr,
+                                         FIXME,
+                                         FIXME);
+#endif                                   
+    }
   /* (1) select target */
   psc.pr = pr;
   psc.target_score = -DBL_MAX;
@@ -2376,14 +2442,14 @@
   
   switch (pr->type)
     {
-    case GNUNET_BLOCK_TYPE_DBLOCK:
-    case GNUNET_BLOCK_TYPE_IBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_DBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_IBLOCK:
       /* only one reply expected, done with the request! */
       destroy_pending_request (pr);
       break;
     case GNUNET_BLOCK_TYPE_ANY:
-    case GNUNET_BLOCK_TYPE_KBLOCK:
-    case GNUNET_BLOCK_TYPE_SBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_KBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_SBLOCK:
       break;
     default:
       GNUNET_break (0);
@@ -2476,12 +2542,6 @@
   size_t size;
 
   /**
-   * Namespace that this reply belongs to
-   * (if it is of type SBLOCK).
-   */
-  GNUNET_HashCode namespace;
-
-  /**
    * Type of the block.
    */
   enum GNUNET_BLOCK_Type type;
@@ -2492,6 +2552,11 @@
   uint32_t priority;
 
   /**
+   * Evaluation result (returned).
+   */
+  enum GNUNET_BLOCK_EvaluationResult eval;
+
+  /**
    * Did we finish processing the associated request?
    */ 
   int finished;
@@ -2519,7 +2584,6 @@
   struct PutMessage *pm;
   struct ConnectedPeer *cp;
   struct GNUNET_TIME_Relative cur_delay;
-  enum GNUNET_BLOCK_EvaluationResult eval;
   size_t msize;
 
 #if DEBUG_FS
@@ -2565,15 +2629,15 @@
          GNUNET_SERVER_client_keep 
(pr->client_request_list->client_list->client);
        }
     }
-  eval = GNUNET_BLOCK_evaluate (block_ctx,
-                               prq->type,
-                               key,
-                               &pr->bf,
-                               pr->mingle,
-                               pr->namespace, (pr->namespace != NULL) ? sizeof 
(GNUNET_HashCode) : 0,
-                               prq->data,
-                               prq->size);
-  switch (eval)
+  prq->eval = GNUNET_BLOCK_evaluate (block_ctx,
+                                    prq->type,
+                                    key,
+                                    &pr->bf,
+                                    pr->mingle,
+                                    pr->namespace, (pr->namespace != NULL) ? 
sizeof (GNUNET_HashCode) : 0,
+                                    prq->data,
+                                    prq->size);
+  switch (prq->eval)
     {
     case GNUNET_BLOCK_EVALUATION_OK_MORE:
       break;
@@ -2636,8 +2700,21 @@
                          &pr->replies_seen[pr->replies_seen_off++]);         
       refresh_bloomfilter (pr);
     }
+  if (NULL == prq->sender)
+    {
+#if DEBUG_FS
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Found result for query `%s' in local datastore\n",
+                 GNUNET_h2s (key));
+#endif
+      GNUNET_STATISTICS_update (stats,
+                               gettext_noop ("# results found locally"),
+                               1,
+                               GNUNET_NO);      
+    }
   prq->priority += pr->remaining_priority;
   pr->remaining_priority = 0;
+  pr->results_found++;
   if (NULL != pr->client_request_list)
     {
       GNUNET_STATISTICS_update (stats,
@@ -2753,7 +2830,6 @@
   struct GNUNET_TIME_Absolute expiration;
   GNUNET_HashCode query;
   struct ProcessReplyClosure prq;
-  const struct SBlock *sb;
 
   msize = ntohs (message->size);
   if (msize < sizeof (struct PutMessage))
@@ -2766,7 +2842,7 @@
   type = ntohl (put->type);
   expiration = GNUNET_TIME_absolute_ntoh (put->expiration);
 
-  if (type == GNUNET_BLOCK_TYPE_ONDEMAND)
+  if (type == GNUNET_BLOCK_TYPE_FS_ONDEMAND)
     return GNUNET_SYSERR;
   if (GNUNET_OK !=
       GNUNET_BLOCK_get_key (block_ctx,
@@ -2778,14 +2854,6 @@
       GNUNET_break_op (0);
       return GNUNET_SYSERR;
     }
-  if (GNUNET_BLOCK_TYPE_SBLOCK == type)
-    { 
-      sb = (const struct SBlock*) &put[1];
-      GNUNET_CRYPTO_hash (&sb->subspace,
-                         sizeof (struct 
GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
-                         &prq.namespace);
-    }
-
 #if DEBUG_FS
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Received result for query `%s' from peer `%4s'\n",
@@ -2838,6 +2906,30 @@
 }
 
 
+/**
+ * Handle P2P "MIGRATION_STOP" message.
+ *
+ * @param cls closure, always NULL
+ * @param other the other peer involved (sender or receiver, NULL
+ *        for loopback messages where we are both sender and receiver)
+ * @param message the actual message
+ * @param latency reported latency of the connection with 'other'
+ * @param distance reported distance (DV) to 'other' 
+ * @return GNUNET_OK to keep the connection open,
+ *         GNUNET_SYSERR to close it (signal serious error)
+ */
+static int
+handle_p2p_migration_stop (void *cls,
+                          const struct GNUNET_PeerIdentity *other,
+                          const struct GNUNET_MessageHeader *message,
+                          struct GNUNET_TIME_Relative latency,
+                          uint32_t distance)
+{
+  // FIXME!
+}
+
+
+
 /* **************************** P2P GET Handling ************************ */
 
 
@@ -2923,10 +3015,8 @@
   struct PendingRequest *pr = cls;
   struct ProcessReplyClosure prq;
   struct CheckDuplicateRequestClosure cdrc;
-  const struct SBlock *sb;
-  GNUNET_HashCode dhash;
-  GNUNET_HashCode mhash;
   GNUNET_HashCode query;
+  unsigned int old_rf;
   
   if (NULL == key)
     {
@@ -2973,7 +3063,7 @@
              GNUNET_h2s (key),
              type);
 #endif
-  if (type == GNUNET_BLOCK_TYPE_ONDEMAND)
+  if (type == GNUNET_BLOCK_TYPE_FS_ONDEMAND)
     {
 #if DEBUG_FS
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2989,54 +3079,16 @@
                                            &process_local_reply,
                                            pr))
       if (pr->qe != NULL)
-       GNUNET_DATASTORE_get_next (dsh, GNUNET_YES);
+       {
+         GNUNET_DATASTORE_get_next (dsh, GNUNET_YES);
+       }
       return;
     }
-
-  /* FIXME: use block lib here! */
-  /* check for duplicates */
-  GNUNET_CRYPTO_hash (data, size, &dhash);
-  GNUNET_BLOCK_mingle_hash (&dhash, 
-                           pr->mingle,
-                           &mhash);
-  if ( (pr->bf != NULL) &&
-       (GNUNET_YES ==
-       GNUNET_CONTAINER_bloomfilter_test (pr->bf,
-                                          &mhash)) )
-    {      
-#if DEBUG_FS
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                 "Result from datastore filtered by bloomfilter 
(duplicate).\n");
-#endif
-      GNUNET_STATISTICS_update (stats,
-                               gettext_noop ("# results filtered by query 
bloomfilter"),
-                               1,
-                               GNUNET_NO);
-      if (pr->qe != NULL)
-       GNUNET_DATASTORE_get_next (dsh, GNUNET_YES);
-      return;
-    }
-#if DEBUG_FS
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Found result for query `%s' in local datastore\n",
-             GNUNET_h2s (key));
-#endif
-  GNUNET_STATISTICS_update (stats,
-                           gettext_noop ("# results found locally"),
-                           1,
-                           GNUNET_NO);
-  pr->results_found++;
+  old_rf = pr->results_found;
   memset (&prq, 0, sizeof (prq));
   prq.data = data;
   prq.expiration = expiration;
   prq.size = size;  
-  if (GNUNET_BLOCK_TYPE_SBLOCK == type)
-    { 
-      sb = (const struct SBlock*) data;
-      GNUNET_CRYPTO_hash (&sb->subspace,
-                         sizeof (struct 
GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
-                         &prq.namespace);
-    }
   if (GNUNET_OK != 
       GNUNET_BLOCK_get_key (block_ctx,
                            type,
@@ -3058,12 +3110,14 @@
   prq.priority = priority;  
   prq.finished = GNUNET_NO;
   process_reply (&prq, key, pr);
+  if ( (old_rf == 0) &&
+       (pr->results_found == 1) )
+    update_datastore_delays (pr->start_time);
   if (prq.finished == GNUNET_YES)
     return;
   if (pr->qe == NULL)
     return; /* done here */
-  if ( (type == GNUNET_BLOCK_TYPE_DBLOCK) ||
-       (type == GNUNET_BLOCK_TYPE_IBLOCK) ) 
+  if (prq.eval == GNUNET_BLOCK_EVALUATION_OK_LAST)
     {
       GNUNET_DATASTORE_get_next (dsh, GNUNET_NO);
       return;
@@ -3211,12 +3265,6 @@
   opt = (const GNUNET_HashCode*) &gm[1];
   bfsize = msize - sizeof (struct GetMessage) + bits * sizeof 
(GNUNET_HashCode);
   bm = ntohl (gm->hash_bitmap);
-  if ( (0 != (bm & GET_MESSAGE_BIT_SKS_NAMESPACE)) &&
-       (type != GNUNET_BLOCK_TYPE_SBLOCK) )
-    {
-      GNUNET_break_op (0);
-      return GNUNET_SYSERR;      
-    }
   bits = 0;
   cps = GNUNET_CONTAINER_multihashmap_get (connected_peers,
                                           &other->hashPubKey);
@@ -3297,7 +3345,6 @@
   pr->mingle = ntohl (gm->filter_mutator);
   if (0 != (bm & GET_MESSAGE_BIT_TRANSMIT_TO))
     pr->target_pid = GNUNET_PEER_intern ((const struct GNUNET_PeerIdentity*) 
&opt[bits++]);
-
   pr->anonymity_level = 1;
   pr->priority = bound_priority (ntohl (gm->priority), cps);
   pr->ttl = bound_ttl (ntohl (gm->ttl), pr->priority);
@@ -3402,7 +3449,7 @@
   /* calculate change in traffic preference */
   cps->inc_preference += pr->priority * 1000 + QUERY_BANDWIDTH_VALUE;
   /* process locally */
-  if (type == GNUNET_BLOCK_TYPE_DBLOCK)
+  if (type == GNUNET_BLOCK_TYPE_FS_DBLOCK)
     type = GNUNET_BLOCK_TYPE_ANY; /* to get on-demand as well */
   timeout = GNUNET_TIME_relative_multiply (BASIC_DATASTORE_REQUEST_DELAY,
                                           (pr->priority + 1)); 
@@ -3418,8 +3465,8 @@
   /* Are multiple results possible?  If so, start processing remotely now! */
   switch (pr->type)
     {
-    case GNUNET_BLOCK_TYPE_DBLOCK:
-    case GNUNET_BLOCK_TYPE_IBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_DBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_IBLOCK:
       /* only one result, wait for datastore */
       break;
     default:
@@ -3499,8 +3546,8 @@
       client_list = cl;
     }
   /* detect duplicate KBLOCK requests */
-  if ( (type == GNUNET_BLOCK_TYPE_KBLOCK) ||
-       (type == GNUNET_BLOCK_TYPE_NBLOCK) ||
+  if ( (type == GNUNET_BLOCK_TYPE_FS_KBLOCK) ||
+       (type == GNUNET_BLOCK_TYPE_FS_NBLOCK) ||
        (type == GNUNET_BLOCK_TYPE_ANY) )
     {
       crl = cl->rl_head;
@@ -3542,7 +3589,7 @@
                            1,
                            GNUNET_NO);
   pr = GNUNET_malloc (sizeof (struct PendingRequest) + 
-                     ((type == GNUNET_BLOCK_TYPE_SBLOCK) ? 
sizeof(GNUNET_HashCode) : 0));
+                     ((type == GNUNET_BLOCK_TYPE_FS_SBLOCK) ? 
sizeof(GNUNET_HashCode) : 0));
   crl = GNUNET_malloc (sizeof (struct ClientRequestList));
   memset (crl, 0, sizeof (struct ClientRequestList));
   crl->client_list = cl;
@@ -3560,6 +3607,7 @@
          sc * sizeof (GNUNET_HashCode));
   pr->replies_seen_off = sc;
   pr->anonymity_level = ntohl (sm->anonymity_level); 
+  pr->start_time = GNUNET_TIME_absolute_get ();
   refresh_bloomfilter (pr);
   pr->query = sm->query;
   if (0 == (1 & ntohl (sm->options)))
@@ -3568,14 +3616,14 @@
     pr->local_only = GNUNET_YES;
   switch (type)
     {
-    case GNUNET_BLOCK_TYPE_DBLOCK:
-    case GNUNET_BLOCK_TYPE_IBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_DBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_IBLOCK:
       if (0 != memcmp (&sm->target,
                       &all_zeros,
                       sizeof (GNUNET_HashCode)))
        pr->target_pid = GNUNET_PEER_intern ((const struct 
GNUNET_PeerIdentity*) &sm->target);
       break;
-    case GNUNET_BLOCK_TYPE_SBLOCK:
+    case GNUNET_BLOCK_TYPE_FS_SBLOCK:
       pr->namespace = (GNUNET_HashCode*) &pr[1];
       memcpy (&pr[1], &sm->target, sizeof (GNUNET_HashCode));
       break;
@@ -3587,7 +3635,7 @@
                                                   &sm->query,
                                                   pr,
                                                   
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
-  if (type == GNUNET_BLOCK_TYPE_DBLOCK)
+  if (type == GNUNET_BLOCK_TYPE_FS_DBLOCK)
     type = GNUNET_BLOCK_TYPE_ANY; /* get on-demand blocks too! */
   pr->qe = GNUNET_DATASTORE_get (dsh,
                                 &sm->query,
@@ -3619,6 +3667,9 @@
        GNUNET_MESSAGE_TYPE_FS_GET, 0 },
       { &handle_p2p_put, 
        GNUNET_MESSAGE_TYPE_FS_PUT, 0 },
+      { &handle_p2p_migration_stop, 
+       GNUNET_MESSAGE_TYPE_FS_MIGRATION_STOP,
+       sizeof (struct MigrationStopMessage) },
       { NULL, 0, 0 }
     };
   static const struct GNUNET_SERVER_MessageHandler handlers[] = {
@@ -3746,6 +3797,7 @@
       GNUNET_SCHEDULER_shutdown (sched);
       return;
     }
+  datastore_load = GNUNET_LOAD_value_init ();
   block_cfg = GNUNET_CONFIGURATION_create ();
   GNUNET_CONFIGURATION_set_value_string (block_cfg,
                                         "block",
@@ -3753,16 +3805,23 @@
                                         "fs");
   block_ctx = GNUNET_BLOCK_context_create (block_cfg);
   GNUNET_assert (NULL != block_ctx);
+  dht_handle = GNUNET_DHT_connect (sched,
+                                  cfg,
+                                  FS_DHT_HT_SIZE);
   if ( (GNUNET_OK != GNUNET_FS_indexing_init (sched, cfg, dsh)) ||
        (GNUNET_OK != main_init (sched, server, cfg)) )
     {    
       GNUNET_SCHEDULER_shutdown (sched);
       GNUNET_DATASTORE_disconnect (dsh, GNUNET_NO);
       dsh = NULL;
+      GNUNET_DHT_disconnect (dht_handle);
+      dht_handle = NULL;
       GNUNET_BLOCK_context_destroy (block_ctx);
       block_ctx = NULL;
       GNUNET_CONFIGURATION_destroy (block_cfg);
       block_cfg = NULL;
+      GNUNET_LOAD_value_free (datastore_load);
+      datastore_load = NULL;
       return;   
     }
 }

Modified: gnunet/src/fs/gnunet-service-fs_indexing.c
===================================================================
--- gnunet/src/fs/gnunet-service-fs_indexing.c  2010-09-18 05:17:21 UTC (rev 
13023)
+++ gnunet/src/fs/gnunet-service-fs_indexing.c  2010-09-18 19:10:12 UTC (rev 
13024)
@@ -682,7 +682,7 @@
        key,
        nsize,
        edata,
-       GNUNET_BLOCK_TYPE_DBLOCK,
+       GNUNET_BLOCK_TYPE_FS_DBLOCK,
        priority,
        anonymity,
        expiration,

Modified: gnunet/src/include/Makefile.am
===================================================================
--- gnunet/src/include/Makefile.am      2010-09-18 05:17:21 UTC (rev 13023)
+++ gnunet/src/include/Makefile.am      2010-09-18 19:10:12 UTC (rev 13024)
@@ -36,6 +36,7 @@
   gnunet_fs_service.h \
   gnunet_getopt_lib.h \
   gnunet_hello_lib.h \
+  gnunet_load_lib.h \
   gnunet_nat_lib.h \
   gnunet_network_lib.h \
   gnunet_os_lib.h \

Modified: gnunet/src/include/gnunet_block_lib.h
===================================================================
--- gnunet/src/include/gnunet_block_lib.h       2010-09-18 05:17:21 UTC (rev 
13023)
+++ gnunet/src/include/gnunet_block_lib.h       2010-09-18 19:10:12 UTC (rev 
13024)
@@ -50,41 +50,48 @@
     /**
      * Data block (leaf) in the CHK tree.
      */
-    GNUNET_BLOCK_TYPE_DBLOCK = 1,
+    GNUNET_BLOCK_TYPE_FS_DBLOCK = 1,
 
     /**
      * Inner block in the CHK tree.
      */
-    GNUNET_BLOCK_TYPE_IBLOCK = 2,
+    GNUNET_BLOCK_TYPE_FS_IBLOCK = 2,
 
     /**
      * Type of a block representing a keyword search result.
      */
-    GNUNET_BLOCK_TYPE_KBLOCK = 3,
+    GNUNET_BLOCK_TYPE_FS_KBLOCK = 3,
 
     /**
      * Type of a block that is used to advertise content in a namespace.
      */
-    GNUNET_BLOCK_TYPE_SBLOCK = 4,
+    GNUNET_BLOCK_TYPE_FS_SBLOCK = 4,
 
     /**
      * Type of a block representing a block to be encoded on demand from disk.
      * Should never appear on the network directly.
      */
-    GNUNET_BLOCK_TYPE_ONDEMAND = 5,
+    GNUNET_BLOCK_TYPE_FS_ONDEMAND = 5,
 
     /**
      * Type of a block that is used to advertise a namespace.  
      */
-    GNUNET_BLOCK_TYPE_NBLOCK = 6,
+    GNUNET_BLOCK_TYPE_FS_NBLOCK = 6,
 
-    GNUNET_BLOCK_TYPE_TEST = 9999
+    /**
+     * Type of a block that contains a HELLO for a peer (for
+     * DHT find-peer operations).
+     */
+    GNUNET_BLOCK_TYPE_DHT_HELLO = 7,
 
+    /**
+     * Block for testing.
+     */
+    GNUNET_BLOCK_TYPE_TEST = 8
+
   };
 
 
-
-
 /**
  * Possible ways for how a block may relate to a query.
  */

Modified: gnunet/src/include/gnunet_dht_service.h
===================================================================
--- gnunet/src/include/gnunet_dht_service.h     2010-09-18 05:17:21 UTC (rev 
13023)
+++ gnunet/src/include/gnunet_dht_service.h     2010-09-18 19:10:12 UTC (rev 
13024)
@@ -28,6 +28,7 @@
 #define GNUNET_DHT_SERVICE_H
 
 #include "gnunet_util_lib.h"
+#include "gnunet_block_lib.h"
 #include "gnunet_hello_lib.h"
 
 #ifdef __cplusplus
@@ -112,7 +113,7 @@
 void
 GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle,
                 const GNUNET_HashCode * key,
-                uint32_t type,
+                enum GNUNET_BLOCK_Type type,
                 uint32_t size,
                 const char *data,
                 struct GNUNET_TIME_Absolute exp,
@@ -133,11 +134,11 @@
  * @param data pointer to the result data
  */
 typedef void (*GNUNET_DHT_GetIterator)(void *cls,
-                                   struct GNUNET_TIME_Absolute exp,
-                                   const GNUNET_HashCode * key,
-                                   uint32_t type,
-                                   uint32_t size,
-                                   const void *data);
+                                      struct GNUNET_TIME_Absolute exp,
+                                      const GNUNET_HashCode * key,
+                                      enum GNUNET_BLOCK_Type type,
+                                      uint32_t size,
+                                      const void *data);
 
 
 
@@ -147,7 +148,7 @@
  * @param handle handle to the DHT service
  * @param timeout timeout for this request to be sent to the
  *        service (this is NOT a timeout for receiving responses)
- * @param type expected type of the response object (GNUNET_BLOCK_TYPE_*)
+ * @param type expected type of the response object (GNUNET_BLOCK_TYPE_FS_*)
  * @param key the key to look up
  * @param iter function to call on each result
  * @param iter_cls closure for iter
@@ -160,7 +161,7 @@
 struct GNUNET_DHT_GetHandle *
 GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle,
                       struct GNUNET_TIME_Relative timeout,
-                      uint32_t type,
+                      enum GNUNET_BLOCK_Type type,
                       const GNUNET_HashCode * key,
                       GNUNET_DHT_GetIterator iter,
                       void *iter_cls,

Added: gnunet/src/include/gnunet_load_lib.h
===================================================================
--- gnunet/src/include/gnunet_load_lib.h                                (rev 0)
+++ gnunet/src/include/gnunet_load_lib.h        2010-09-18 19:10:12 UTC (rev 
13024)
@@ -0,0 +1,106 @@
+/*
+     This file is part of GNUnet.
+     (C) 2010 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file include/gnunet_load_lib.h
+ * @brief functions related to load calculations
+ * @author Christian Grothoff
+ */
+
+#ifndef GNUNET_LOAD_LIB_H
+#define GNUNET_LOAD_LIB_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#if 0                           /* keep Emacsens' auto-indent happy */
+}
+#endif
+#endif
+
+#include "gnunet_common.h"
+#include "gnunet_time_lib.h"
+
+/**
+ * Opaque load handle.
+ */
+struct GNUNET_LOAD_Value;
+
+/**
+ * Create a new load value.
+ *
+ * @return the new load value
+ */
+struct GNUNET_LOAD_Value *
+GNUNET_LOAD_value_init (void);
+
+
+/**
+ * Free a load value.
+ *
+ * @param lv value to free
+ */
+#define GNUNET_LOAD_value_free(lv) GNUNET_free (lv)
+
+
+/**
+ * Get the current load.
+ *
+ * @param load load handle
+ * @return zero for below-average load, otherwise
+ *         number of std. devs we are above average;
+ *         100 if the latest updates were so large
+ *         that we could not do proper calculations
+ */
+double
+GNUNET_LOAD_get_load (const struct GNUNET_LOAD_Value *load);
+
+
+/**
+ * Get the average value given to update so far.
+ *
+ * @param load load handle
+ * @return zero if update was never called
+ */
+double
+GNUNET_LOAD_get_average (const struct GNUNET_LOAD_Value *load);
+
+
+/**
+ * Update the current load.
+ *
+ * @param load to update
+ * @param data latest measurement value (for example, delay)
+ */
+void
+GNUNET_LOAD_update (struct GNUNET_LOAD_Value *load,
+                   uint64_t data);
+
+
+#if 0                           /* keep Emacsens' auto-indent happy */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+/* ifndef GNUNET_LOAD_LIB_H */
+#endif
+/* end of gnunet_load_lib.h */

Modified: gnunet/src/include/gnunet_protocols.h
===================================================================
--- gnunet/src/include/gnunet_protocols.h       2010-09-18 05:17:21 UTC (rev 
13023)
+++ gnunet/src/include/gnunet_protocols.h       2010-09-18 19:10:12 UTC (rev 
13024)
@@ -514,7 +514,12 @@
  */
 #define GNUNET_MESSAGE_TYPE_FS_PUT 138
 
+/**
+ * Peer asks us to stop migrating content towards it for a while.
+ */
+#define GNUNET_MESSAGE_TYPE_FS_MIGRATION_STOP 139
 
+
 /**
  * DHT Message Types
  */

Modified: gnunet/src/util/Makefile.am
===================================================================
--- gnunet/src/util/Makefile.am 2010-09-18 05:17:21 UTC (rev 13023)
+++ gnunet/src/util/Makefile.am 2010-09-18 19:10:12 UTC (rev 13024)
@@ -48,6 +48,7 @@
   disk.h \
   getopt.c \
   getopt_helpers.c \
+  load.c \
   network.c \
   os_installation.c \
   os_load.c \

Added: gnunet/src/util/load.c
===================================================================
--- gnunet/src/util/load.c                              (rev 0)
+++ gnunet/src/util/load.c      2010-09-18 19:10:12 UTC (rev 13024)
@@ -0,0 +1,176 @@
+/*
+     This file is part of GNUnet.
+     (C) 2010 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file util/load.c
+ * @brief functions related to load calculations
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_load_lib.h"
+
+#define DEBUG_LOAD GNUNET_NO
+
+/**
+ * Values we track for load calculations.
+ */
+struct GNUNET_LOAD_Value 
+{
+
+  /**
+   * Sum of all datastore delays ever observed (in ms).  Note that
+   * delays above 64k ms are excluded (to avoid overflow within
+   * first 4 billion requests).
+   */
+  uint64_t cummulative_delay;
+  
+  /**
+   * Sum of squares of all datastore delays ever observed (in ms).   Note that
+   * delays above 64k ms are excluded (to avoid overflow within
+   * first 4 billion requests).
+   */
+  uint64_t cummulative_squared_delay;
+  
+  /**
+   * Total number of requests included in the cummulative datastore delay 
values.
+   */
+  uint64_t cummulative_request_count;
+  
+  /**
+   * Current running average datastore delay.  Its relation to the
+   * average datastore delay and it std. dev. (as calcualted from the
+   * cummulative values) tells us our current load.
+   */
+  double runavg_delay;
+
+  /**
+   * How high is the load?  0 for below average, otherwise
+   * the number of std. devs we are above average, or 100 if the
+   * load is so high that we currently cannot calculate it.
+   */
+  double load;
+
+};
+
+
+/**
+ * Create a new load value.
+ *
+ * @return the new load value
+ */
+struct GNUNET_LOAD_Value *
+GNUNET_LOAD_value_init ()
+{
+  return GNUNET_malloc (sizeof (struct GNUNET_LOAD_Value));
+}
+
+
+/**
+ * Get the current load.
+ *
+ * @param load load handle
+ * @return zero for below-average load, otherwise
+ *         number of std. devs we are above average;
+ *         100 if the latest updates were so large
+ *         that we could not do proper calculations
+ */
+double
+GNUNET_LOAD_get_load (const struct GNUNET_LOAD_Value *load)
+{
+  return load->load;
+}
+
+
+/**
+ * Get the average value given to update so far.
+ *
+ * @param load load handle
+ * @return zero if update was never called
+ */
+double
+GNUNET_LOAD_get_average (const struct GNUNET_LOAD_Value *load)
+{
+  double n;
+  double avg;
+  double sum_val_i;
+
+  if (load->cummulative_request_count == 0)
+    return 0.0;
+  n = ((double) load->cummulative_request_count);
+  sum_val_i = (double) load->cummulative_delay;
+  return sum_val_i / n;
+}
+
+
+/**
+ * Update the current load.
+ *
+ * @param load to update
+ * @param data latest measurement value (for example, delay)
+ */
+void
+GNUNET_LOAD_update (struct GNUNET_LOAD_Value *load,
+                   uint64_t data)
+{
+  uint32_t dv;
+  double stddev;
+  double avgdel;
+  double sum_val_i;
+  double n;
+  double nm1;
+
+  if (data > 64 * 1024)
+    {
+      /* very large */
+      load->load = 100.0;
+      return;
+    }
+  dv = (uint32_t) data;
+  load->cummulative_delay += dv;
+  load->cummulative_squared_delay += dv * dv; 
+  load->cummulative_request_count++;
+  load->runavg_delay = ((load->runavg_delay * 7.0) + dv) / 8.0;
+  if (load->cummulative_request_count > 1)
+    {
+      /* calcuate std dev of latency; we have for n values of "i" that:
+
+        avg = (sum val_i) / n
+        stddev = (sum (val_i - avg)^2) / (n-1)
+               = (sum (val_i^2 - 2 avg val_i + avg^2) / (n-1)
+                = (sum (val_i^2) - 2 avg sum (val_i) + n * avg^2) / (n-1)
+      */
+      sum_val_i = (double) load->cummulative_delay;
+      n = ((double) load->cummulative_request_count);
+      nm1 = n - 1.0;
+      avgdel = sum_val_i / n;
+      stddev = (((double) load->cummulative_squared_delay) - 2.0 * avgdel * 
sum_val_i + n * avgdel * avgdel) / nm1; 
+      if (stddev <= 0)
+       stddev = 0.01; /* must have been rounding error or zero; prevent 
division by zero */
+      /* now calculate load based on how far out we are from
+        std dev; or if we are below average, simply assume load zero */
+      if (load->runavg_delay < avgdel)
+       load->load = 0.0;
+      else
+       load->load = (load->runavg_delay - avgdel) / stddev;
+    }  
+}
+
+
+/* end of load.c */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]