aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO7
-rw-r--r--src/block/Makefile.am21
-rw-r--r--src/block/plugin_block_dht.c163
-rw-r--r--src/block/plugin_block_fs.c35
-rw-r--r--src/block/plugin_block_test.c154
-rw-r--r--src/block/test_block.c8
-rw-r--r--src/datastore/gnunet-service-datastore.c4
-rw-r--r--src/dht/dht_api.c6
-rw-r--r--src/fs/Makefile.am1
-rw-r--r--src/fs/fs.h26
-rw-r--r--src/fs/fs_download.c8
-rw-r--r--src/fs/fs_namespace.c4
-rw-r--r--src/fs/fs_publish.c6
-rw-r--r--src/fs/fs_search.c14
-rw-r--r--src/fs/fs_tree.c4
-rw-r--r--src/fs/fs_unindex.c2
-rw-r--r--src/fs/gnunet-service-fs.c257
-rw-r--r--src/fs/gnunet-service-fs_indexing.c2
-rw-r--r--src/include/Makefile.am1
-rw-r--r--src/include/gnunet_block_lib.h25
-rw-r--r--src/include/gnunet_dht_service.h17
-rw-r--r--src/include/gnunet_load_lib.h106
-rw-r--r--src/include/gnunet_protocols.h5
-rw-r--r--src/util/Makefile.am1
-rw-r--r--src/util/load.c176
25 files changed, 888 insertions, 165 deletions
diff --git a/TODO b/TODO
index e95522d87..04947882b 100644
--- a/TODO
+++ b/TODO
@@ -1,12 +1,13 @@
10.9.0pre2: 10.9.0pre2:
2 FS: 2 FS:
3 - move FS serivce to new block API
4 - integrate with DHT
5 - measure latencies (core, datastore) => trust economy 3 - measure latencies (core, datastore) => trust economy
6 - refuse content migration message (or solicit?) 4 - refuse content migration message (or solicit?)
7 - FS performance benchmarking 5 - FS performance benchmarking
6 - integrate with DHT (need DHT API to fit block API better first; also, get rid of the continuation!)
8* DHT: [Nate] 7* DHT: [Nate]
9 - use new block lib 8 - use new block lib in service
9 - provide block-lib compatible API in gnunet_dht_service.h
10 - eliminate continuations in DHT API (not needed, we have auto-retransmit!)
10* CORE: 11* CORE:
11 - derived key generation [Nils] 12 - derived key generation [Nils]
12 - Jun 27 11:51:54 core-7670 ERROR Assertion failed at gnunet-service-core.c:3616. 13 - Jun 27 11:51:54 core-7670 ERROR Assertion failed at gnunet-service-core.c:3616.
diff --git a/src/block/Makefile.am b/src/block/Makefile.am
index 2fc0c0081..b37c7705e 100644
--- a/src/block/Makefile.am
+++ b/src/block/Makefile.am
@@ -13,8 +13,19 @@ endif
13lib_LTLIBRARIES = libgnunetblock.la 13lib_LTLIBRARIES = libgnunetblock.la
14 14
15plugin_LTLIBRARIES = \ 15plugin_LTLIBRARIES = \
16 libgnunet_plugin_block_dht.la \
16 libgnunet_plugin_block_fs.la \ 17 libgnunet_plugin_block_fs.la \
17 libgnunet_plugin_block_template.la 18 libgnunet_plugin_block_template.la \
19 libgnunet_plugin_block_test.la
20
21libgnunet_plugin_block_dht_la_SOURCES = \
22 plugin_block_dht.c
23libgnunet_plugin_block_dht_la_LIBADD = \
24 $(top_builddir)/src/hello/libgnunethello.la \
25 $(top_builddir)/src/block/libgnunetblock.la \
26 $(top_builddir)/src/util/libgnunetutil.la
27libgnunet_plugin_block_dht_la_LDFLAGS = \
28 $(GN_PLUGIN_LDFLAGS)
18 29
19libgnunet_plugin_block_fs_la_SOURCES = \ 30libgnunet_plugin_block_fs_la_SOURCES = \
20 plugin_block_fs.c 31 plugin_block_fs.c
@@ -31,6 +42,14 @@ libgnunet_plugin_block_template_la_LIBADD = \
31libgnunet_plugin_block_template_la_LDFLAGS = \ 42libgnunet_plugin_block_template_la_LDFLAGS = \
32 $(GN_PLUGIN_LDFLAGS) 43 $(GN_PLUGIN_LDFLAGS)
33 44
45libgnunet_plugin_block_test_la_SOURCES = \
46 plugin_block_test.c
47libgnunet_plugin_block_test_la_LIBADD = \
48 $(top_builddir)/src/block/libgnunetblock.la \
49 $(top_builddir)/src/util/libgnunetutil.la
50libgnunet_plugin_block_test_la_LDFLAGS = \
51 $(GN_PLUGIN_LDFLAGS)
52
34 53
35libgnunetblock_la_SOURCES = \ 54libgnunetblock_la_SOURCES = \
36 block.c plugin_block.h 55 block.c plugin_block.h
diff --git a/src/block/plugin_block_dht.c b/src/block/plugin_block_dht.c
new file mode 100644
index 000000000..8312a69b5
--- /dev/null
+++ b/src/block/plugin_block_dht.c
@@ -0,0 +1,163 @@
1/*
2 This file is part of GNUnet
3 (C) 2010 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file block/plugin_block_dht.c
23 * @brief block plugin for DHT internals (right now, find-peer requests only);
24 * other plugins should be used to store "useful" data in the
25 * DHT (see fs block plugin)
26 * @author Christian Grothoff
27 */
28
29#include "platform.h"
30#include "gnunet_hello_lib.h"
31#include "plugin_block.h"
32
33#define DEBUG_DHT GNUNET_NO
34
35
36/**
37 * Function called to validate a reply or a request. For
38 * request evaluation, simply pass "NULL" for the reply_block.
39 *
40 * @param cls closure
41 * @param type block type
42 * @param query original query (hash)
43 * @param bf pointer to bloom filter associated with query; possibly updated (!)
44 * @param bf_mutator mutation value for bf
45 * @param xquery extrended query data (can be NULL, depending on type)
46 * @param xquery_size number of bytes in xquery
47 * @param reply_block response to validate
48 * @param reply_block_size number of bytes in reply block
49 * @return characterization of result
50 */
51static enum GNUNET_BLOCK_EvaluationResult
52block_plugin_dht_evaluate (void *cls,
53 enum GNUNET_BLOCK_Type type,
54 const GNUNET_HashCode *query,
55 struct GNUNET_CONTAINER_BloomFilter **bf,
56 int32_t bf_mutator,
57 const void *xquery,
58 size_t xquery_size,
59 const void *reply_block,
60 size_t reply_block_size)
61{
62 if (type != GNUNET_BLOCK_TYPE_DHT_HELLO)
63 return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED;
64 if (xquery_size != 0)
65 return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID;
66 if (reply_block_size == 0)
67 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
68 GNUNET_break (NULL == *bf);
69 return GNUNET_BLOCK_EVALUATION_OK_LAST;
70}
71
72
73/**
74 * Function called to obtain the key for a block.
75 *
76 * @param cls closure
77 * @param type block type
78 * @param block block to get the key for
79 * @param block_size number of bytes in block
80 * @param key set to the key (query) for the given block
81 * @return GNUNET_OK on success, GNUNET_SYSERR if type not supported
82 * (or if extracting a key from a block of this type does not work)
83 */
84static int
85block_plugin_dht_get_key (void *cls,
86 enum GNUNET_BLOCK_Type type,
87 const void *block,
88 size_t block_size,
89 GNUNET_HashCode *key)
90{
91 const struct GNUNET_MessageHeader *msg;
92 const struct GNUNET_HELLO_Message *hello;
93 struct GNUNET_PeerIdentity *pid;
94
95 if (type != GNUNET_BLOCK_TYPE_DHT_HELLO)
96 return GNUNET_SYSERR;
97 if (block_size < sizeof (struct GNUNET_MessageHeader))
98 {
99 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
100 "block-dht",
101 _("Block not of type %u\n"),
102 GNUNET_BLOCK_TYPE_DHT_HELLO);
103 return GNUNET_SYSERR;
104 }
105 msg = block;
106 if (block_size != ntohs (msg->size))
107 {
108 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
109 "block-dht",
110 _("Size mismatch for block\n"),
111 GNUNET_BLOCK_TYPE_DHT_HELLO);
112 return GNUNET_SYSERR;
113 }
114 hello = block;
115 pid = (struct GNUNET_PeerIdentity*) key;
116 if (GNUNET_OK !=
117 GNUNET_HELLO_get_id (hello,
118 pid))
119 {
120 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
121 "block-dht",
122 _("Block of type %u is malformed\n"),
123 GNUNET_BLOCK_TYPE_DHT_HELLO);
124 return GNUNET_SYSERR;
125 }
126 return GNUNET_OK;
127}
128
129
130/**
131 * Entry point for the plugin.
132 */
133void *
134gnunet_plugin_block_dht_init (void *cls)
135{
136 static enum GNUNET_BLOCK_Type types[] =
137 {
138 GNUNET_BLOCK_TYPE_DHT_HELLO,
139 GNUNET_BLOCK_TYPE_ANY /* end of list */
140 };
141 struct GNUNET_BLOCK_PluginFunctions *api;
142
143 api = GNUNET_malloc (sizeof (struct GNUNET_BLOCK_PluginFunctions));
144 api->evaluate = &block_plugin_dht_evaluate;
145 api->get_key = &block_plugin_dht_get_key;
146 api->types = types;
147 return api;
148}
149
150
151/**
152 * Exit point from the plugin.
153 */
154void *
155gnunet_plugin_block_dht_done (void *cls)
156{
157 struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
158
159 GNUNET_free (api);
160 return NULL;
161}
162
163/* end of plugin_block_dht.c */
diff --git a/src/block/plugin_block_fs.c b/src/block/plugin_block_fs.c
index 3ad15a0c6..d4e510abe 100644
--- a/src/block/plugin_block_fs.c
+++ b/src/block/plugin_block_fs.c
@@ -74,8 +74,8 @@ block_plugin_fs_evaluate (void *cls,
74 74
75 switch (type) 75 switch (type)
76 { 76 {
77 case GNUNET_BLOCK_TYPE_DBLOCK: 77 case GNUNET_BLOCK_TYPE_FS_DBLOCK:
78 case GNUNET_BLOCK_TYPE_IBLOCK: 78 case GNUNET_BLOCK_TYPE_FS_IBLOCK:
79 if (xquery_size != 0) 79 if (xquery_size != 0)
80 { 80 {
81 GNUNET_break_op (0); 81 GNUNET_break_op (0);
@@ -84,8 +84,8 @@ block_plugin_fs_evaluate (void *cls,
84 if (reply_block == NULL) 84 if (reply_block == NULL)
85 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; 85 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
86 return GNUNET_BLOCK_EVALUATION_OK_LAST; 86 return GNUNET_BLOCK_EVALUATION_OK_LAST;
87 case GNUNET_BLOCK_TYPE_KBLOCK: 87 case GNUNET_BLOCK_TYPE_FS_KBLOCK:
88 case GNUNET_BLOCK_TYPE_NBLOCK: 88 case GNUNET_BLOCK_TYPE_FS_NBLOCK:
89 if (xquery_size != 0) 89 if (xquery_size != 0)
90 { 90 {
91 GNUNET_break_op (0); 91 GNUNET_break_op (0);
@@ -111,7 +111,7 @@ block_plugin_fs_evaluate (void *cls,
111 } 111 }
112 GNUNET_CONTAINER_bloomfilter_add (*bf, &mhash); 112 GNUNET_CONTAINER_bloomfilter_add (*bf, &mhash);
113 return GNUNET_BLOCK_EVALUATION_OK_MORE; 113 return GNUNET_BLOCK_EVALUATION_OK_MORE;
114 case GNUNET_BLOCK_TYPE_SBLOCK: 114 case GNUNET_BLOCK_TYPE_FS_SBLOCK:
115 if (xquery_size != sizeof (GNUNET_HashCode)) 115 if (xquery_size != sizeof (GNUNET_HashCode))
116 { 116 {
117 GNUNET_break_op (0); 117 GNUNET_break_op (0);
@@ -133,8 +133,9 @@ block_plugin_fs_evaluate (void *cls,
133 &sh, 133 &sh,
134 sizeof (GNUNET_HashCode))) 134 sizeof (GNUNET_HashCode)))
135 { 135 {
136 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 136 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
137 _("Reply mismatched in terms of namespace. Discarded.\n")); 137 "block-fs",
138 _("Reply mismatched in terms of namespace. Discarded.\n"));
138 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; 139 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
139 } 140 }
140 GNUNET_CRYPTO_hash (reply_block, 141 GNUNET_CRYPTO_hash (reply_block,
@@ -185,11 +186,11 @@ block_plugin_fs_get_key (void *cls,
185 186
186 switch (type) 187 switch (type)
187 { 188 {
188 case GNUNET_BLOCK_TYPE_DBLOCK: 189 case GNUNET_BLOCK_TYPE_FS_DBLOCK:
189 case GNUNET_BLOCK_TYPE_IBLOCK: 190 case GNUNET_BLOCK_TYPE_FS_IBLOCK:
190 GNUNET_CRYPTO_hash (block, block_size, key); 191 GNUNET_CRYPTO_hash (block, block_size, key);
191 return GNUNET_OK; 192 return GNUNET_OK;
192 case GNUNET_BLOCK_TYPE_KBLOCK: 193 case GNUNET_BLOCK_TYPE_FS_KBLOCK:
193 if (block_size < sizeof (struct KBlock)) 194 if (block_size < sizeof (struct KBlock))
194 { 195 {
195 GNUNET_break_op (0); 196 GNUNET_break_op (0);
@@ -218,7 +219,7 @@ block_plugin_fs_get_key (void *cls,
218 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), 219 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
219 key); 220 key);
220 return GNUNET_OK; 221 return GNUNET_OK;
221 case GNUNET_BLOCK_TYPE_SBLOCK: 222 case GNUNET_BLOCK_TYPE_FS_SBLOCK:
222 if (block_size < sizeof (struct SBlock)) 223 if (block_size < sizeof (struct SBlock))
223 { 224 {
224 GNUNET_break_op (0); 225 GNUNET_break_op (0);
@@ -243,7 +244,7 @@ block_plugin_fs_get_key (void *cls,
243 if (key != NULL) 244 if (key != NULL)
244 *key = sb->identifier; 245 *key = sb->identifier;
245 return GNUNET_OK; 246 return GNUNET_OK;
246 case GNUNET_BLOCK_TYPE_NBLOCK: 247 case GNUNET_BLOCK_TYPE_FS_NBLOCK:
247 if (block_size < sizeof (struct NBlock)) 248 if (block_size < sizeof (struct NBlock))
248 { 249 {
249 GNUNET_break_op (0); 250 GNUNET_break_op (0);
@@ -303,11 +304,11 @@ libgnunet_plugin_block_fs_init (void *cls)
303{ 304{
304 static enum GNUNET_BLOCK_Type types[] = 305 static enum GNUNET_BLOCK_Type types[] =
305 { 306 {
306 GNUNET_BLOCK_TYPE_DBLOCK, 307 GNUNET_BLOCK_TYPE_FS_DBLOCK,
307 GNUNET_BLOCK_TYPE_IBLOCK, 308 GNUNET_BLOCK_TYPE_FS_IBLOCK,
308 GNUNET_BLOCK_TYPE_KBLOCK, 309 GNUNET_BLOCK_TYPE_FS_KBLOCK,
309 GNUNET_BLOCK_TYPE_SBLOCK, 310 GNUNET_BLOCK_TYPE_FS_SBLOCK,
310 GNUNET_BLOCK_TYPE_NBLOCK, 311 GNUNET_BLOCK_TYPE_FS_NBLOCK,
311 GNUNET_BLOCK_TYPE_ANY /* end of list */ 312 GNUNET_BLOCK_TYPE_ANY /* end of list */
312 }; 313 };
313 struct GNUNET_BLOCK_PluginFunctions *api; 314 struct GNUNET_BLOCK_PluginFunctions *api;
diff --git a/src/block/plugin_block_test.c b/src/block/plugin_block_test.c
new file mode 100644
index 000000000..1cf8c701d
--- /dev/null
+++ b/src/block/plugin_block_test.c
@@ -0,0 +1,154 @@
1/*
2 This file is part of GNUnet
3 (C) 2010 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file block/plugin_block_test.c
23 * @brief block plugin to test the DHT as a simple key-value store;
24 * this plugin simply accepts any (new) response for any key
25 * @author Christian Grothoff
26 */
27
28#include "platform.h"
29#include "plugin_block.h"
30
31#define DEBUG_TEST GNUNET_NO
32
33
34/**
35 * Number of bits we set per entry in the bloomfilter.
36 * Do not change!
37 */
38#define BLOOMFILTER_K 16
39
40/**
41 * Function called to validate a reply or a request. For
42 * request evaluation, simply pass "NULL" for the reply_block.
43 *
44 * @param cls closure
45 * @param type block type
46 * @param query original query (hash)
47 * @param bf pointer to bloom filter associated with query; possibly updated (!)
48 * @param bf_mutator mutation value for bf
49 * @param xquery extrended query data (can be NULL, depending on type)
50 * @param xquery_size number of bytes in xquery
51 * @param reply_block response to validate
52 * @param reply_block_size number of bytes in reply block
53 * @return characterization of result
54 */
55static enum GNUNET_BLOCK_EvaluationResult
56block_plugin_test_evaluate (void *cls,
57 enum GNUNET_BLOCK_Type type,
58 const GNUNET_HashCode *query,
59 struct GNUNET_CONTAINER_BloomFilter **bf,
60 int32_t bf_mutator,
61 const void *xquery,
62 size_t xquery_size,
63 const void *reply_block,
64 size_t reply_block_size)
65{
66 GNUNET_HashCode chash;
67 GNUNET_HashCode mhash;
68
69 if (type != GNUNET_BLOCK_TYPE_TEST)
70 return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED;
71 if (xquery_size != 0)
72 GNUNET_BLOCK_EVALUATION_REQUEST_INVALID;
73 if (reply_block_size == 0)
74 GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
75
76 GNUNET_CRYPTO_hash (reply_block,
77 reply_block_size,
78 &chash);
79 GNUNET_BLOCK_mingle_hash (&chash, bf_mutator, &mhash);
80 if (NULL != *bf)
81 {
82 if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (*bf,
83 &mhash))
84 return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE;
85 }
86 else
87 {
88 *bf = GNUNET_CONTAINER_bloomfilter_init (NULL,
89 8,
90 BLOOMFILTER_K);
91 }
92 GNUNET_CONTAINER_bloomfilter_add (*bf, &mhash);
93 return GNUNET_BLOCK_EVALUATION_OK_MORE;
94}
95
96
97/**
98 * Function called to obtain the key for a block.
99 *
100 * @param cls closure
101 * @param type block type
102 * @param block block to get the key for
103 * @param block_size number of bytes in block
104 * @param key set to the key (query) for the given block
105 * @return GNUNET_OK on success, GNUNET_SYSERR if type not supported
106 * (or if extracting a key from a block of this type does not work)
107 */
108static int
109block_plugin_test_get_key (void *cls,
110 enum GNUNET_BLOCK_Type type,
111 const void *block,
112 size_t block_size,
113 GNUNET_HashCode *key)
114{
115 /* always fails since there is no fixed relationship between
116 keys and values for test values */
117 return GNUNET_SYSERR;
118}
119
120
121/**
122 * Entry point for the plugin.
123 */
124void *
125gnunet_plugin_block_test_init (void *cls)
126{
127 static enum GNUNET_BLOCK_Type types[] =
128 {
129 GNUNET_BLOCK_TYPE_TEST,
130 GNUNET_BLOCK_TYPE_ANY /* end of list */
131 };
132 struct GNUNET_BLOCK_PluginFunctions *api;
133
134 api = GNUNET_malloc (sizeof (struct GNUNET_BLOCK_PluginFunctions));
135 api->evaluate = &block_plugin_test_evaluate;
136 api->get_key = &block_plugin_test_get_key;
137 api->types = types;
138 return api;
139}
140
141
142/**
143 * Exit point from the plugin.
144 */
145void *
146gnunet_plugin_block_test_done (void *cls)
147{
148 struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
149
150 GNUNET_free (api);
151 return NULL;
152}
153
154/* end of plugin_block_test.c */
diff --git a/src/block/test_block.c b/src/block/test_block.c
index 02719e5aa..bb9a1f01b 100644
--- a/src/block/test_block.c
+++ b/src/block/test_block.c
@@ -38,14 +38,14 @@ test_fs (struct GNUNET_BLOCK_Context *ctx)
38 memset (block, 1, sizeof (block)); 38 memset (block, 1, sizeof (block));
39 if (GNUNET_OK != 39 if (GNUNET_OK !=
40 GNUNET_BLOCK_get_key (ctx, 40 GNUNET_BLOCK_get_key (ctx,
41 GNUNET_BLOCK_TYPE_DBLOCK, 41 GNUNET_BLOCK_TYPE_FS_DBLOCK,
42 block, 42 block,
43 sizeof (block), 43 sizeof (block),
44 &key)) 44 &key))
45 return 1; 45 return 1;
46 if (GNUNET_BLOCK_EVALUATION_OK_LAST != 46 if (GNUNET_BLOCK_EVALUATION_OK_LAST !=
47 GNUNET_BLOCK_evaluate (ctx, 47 GNUNET_BLOCK_evaluate (ctx,
48 GNUNET_BLOCK_TYPE_DBLOCK, 48 GNUNET_BLOCK_TYPE_FS_DBLOCK,
49 &key, 49 &key,
50 NULL, 0, 50 NULL, 0,
51 NULL, 0, 51 NULL, 0,
@@ -53,7 +53,7 @@ test_fs (struct GNUNET_BLOCK_Context *ctx)
53 return 2; 53 return 2;
54 if (GNUNET_BLOCK_EVALUATION_REQUEST_VALID != 54 if (GNUNET_BLOCK_EVALUATION_REQUEST_VALID !=
55 GNUNET_BLOCK_evaluate (ctx, 55 GNUNET_BLOCK_evaluate (ctx,
56 GNUNET_BLOCK_TYPE_DBLOCK, 56 GNUNET_BLOCK_TYPE_FS_DBLOCK,
57 &key, 57 &key,
58 NULL, 0, 58 NULL, 0,
59 NULL, 0, 59 NULL, 0,
@@ -62,7 +62,7 @@ test_fs (struct GNUNET_BLOCK_Context *ctx)
62 GNUNET_log_skip (1, GNUNET_NO); 62 GNUNET_log_skip (1, GNUNET_NO);
63 if (GNUNET_BLOCK_EVALUATION_REQUEST_INVALID != 63 if (GNUNET_BLOCK_EVALUATION_REQUEST_INVALID !=
64 GNUNET_BLOCK_evaluate (ctx, 64 GNUNET_BLOCK_evaluate (ctx,
65 GNUNET_BLOCK_TYPE_DBLOCK, 65 GNUNET_BLOCK_TYPE_FS_DBLOCK,
66 &key, 66 &key,
67 NULL, 0, 67 NULL, 0,
68 "bogus", 5, 68 "bogus", 5,
diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c
index 3e9e2e480..8a896a7fb 100644
--- a/src/datastore/gnunet-service-datastore.c
+++ b/src/datastore/gnunet-service-datastore.c
@@ -1038,8 +1038,8 @@ check_present (void *cls,
1038 GNUNET_free (pc); 1038 GNUNET_free (pc);
1039 return GNUNET_SYSERR; 1039 return GNUNET_SYSERR;
1040 } 1040 }
1041 if ( (GNUNET_BLOCK_TYPE_DBLOCK == type) || 1041 if ( (GNUNET_BLOCK_TYPE_FS_DBLOCK == type) ||
1042 (GNUNET_BLOCK_TYPE_IBLOCK == type) || 1042 (GNUNET_BLOCK_TYPE_FS_IBLOCK == type) ||
1043 ( (size == ntohl(dm->size)) && 1043 ( (size == ntohl(dm->size)) &&
1044 (0 == memcmp (&dm[1], 1044 (0 == memcmp (&dm[1],
1045 data, 1045 data,
diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c
index 413ecb83a..15faba6c9 100644
--- a/src/dht/dht_api.c
+++ b/src/dht/dht_api.c
@@ -1132,7 +1132,7 @@ GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle,
1132struct GNUNET_DHT_GetHandle * 1132struct GNUNET_DHT_GetHandle *
1133GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle, 1133GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle,
1134 struct GNUNET_TIME_Relative timeout, 1134 struct GNUNET_TIME_Relative timeout,
1135 uint32_t type, 1135 enum GNUNET_BLOCK_Type type,
1136 const GNUNET_HashCode * key, 1136 const GNUNET_HashCode * key,
1137 GNUNET_DHT_GetIterator iter, 1137 GNUNET_DHT_GetIterator iter,
1138 void *iter_cls, 1138 void *iter_cls,
@@ -1366,7 +1366,7 @@ GNUNET_DHT_find_peer_stop (struct GNUNET_DHT_FindPeerHandle *find_peer_handle,
1366void 1366void
1367GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle, 1367GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle,
1368 const GNUNET_HashCode * key, 1368 const GNUNET_HashCode * key,
1369 uint32_t type, 1369 enum GNUNET_BLOCK_Type type,
1370 uint32_t size, 1370 uint32_t size,
1371 const char *data, 1371 const char *data,
1372 struct GNUNET_TIME_Absolute exp, 1372 struct GNUNET_TIME_Absolute exp,
@@ -1422,3 +1422,5 @@ GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle,
1422 1422
1423 GNUNET_free (put_msg); 1423 GNUNET_free (put_msg);
1424} 1424}
1425
1426/* end of dht_api.c */
diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am
index bcf5f460c..542c776f3 100644
--- a/src/fs/Makefile.am
+++ b/src/fs/Makefile.am
@@ -96,6 +96,7 @@ gnunet_service_fs_SOURCES = \
96 gnunet-service-fs_indexing.c gnunet-service-fs_indexing.h 96 gnunet-service-fs_indexing.c gnunet-service-fs_indexing.h
97gnunet_service_fs_LDADD = \ 97gnunet_service_fs_LDADD = \
98 $(top_builddir)/src/fs/libgnunetfs.la \ 98 $(top_builddir)/src/fs/libgnunetfs.la \
99 $(top_builddir)/src/dht/libgnunetdht.la \
99 $(top_builddir)/src/block/libgnunetblock.la \ 100 $(top_builddir)/src/block/libgnunetblock.la \
100 $(top_builddir)/src/datastore/libgnunetdatastore.la \ 101 $(top_builddir)/src/datastore/libgnunetdatastore.la \
101 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 102 $(top_builddir)/src/statistics/libgnunetstatistics.la \
diff --git a/src/fs/fs.h b/src/fs/fs.h
index 605e6c84b..edbde19da 100644
--- a/src/fs/fs.h
+++ b/src/fs/fs.h
@@ -2222,6 +2222,32 @@ struct PutMessage
2222}; 2222};
2223 2223
2224 2224
2225/**
2226 * Message send by a peer that wants to be excluded
2227 * from migration for a while.
2228 */
2229struct MigrationStopMessage
2230{
2231 /**
2232 * Message type will be
2233 * GNUNET_MESSAGE_TYPE_FS_MIGRATION_STOP.
2234 */
2235 struct GNUNET_MessageHeader header;
2236
2237 /**
2238 * Always zero.
2239 */
2240 uint32_t reserved GNUNET_PACKED;
2241
2242 /**
2243 * How long should the block last?
2244 */
2245 struct GNUNET_TIME_RelativeNBO duration;
2246
2247};
2248
2249
2250
2225#endif 2251#endif
2226 2252
2227/* end of fs.h */ 2253/* end of fs.h */
diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c
index 80758ebc7..847509358 100644
--- a/src/fs/fs_download.c
+++ b/src/fs/fs_download.c
@@ -304,8 +304,8 @@ encrypt_existing_match (struct GNUNET_FS_DownloadContext *dc,
304 prc.data = enc; 304 prc.data = enc;
305 prc.size = len; 305 prc.size = len;
306 prc.type = (dc->treedepth == depth) 306 prc.type = (dc->treedepth == depth)
307 ? GNUNET_BLOCK_TYPE_DBLOCK 307 ? GNUNET_BLOCK_TYPE_FS_DBLOCK
308 : GNUNET_BLOCK_TYPE_IBLOCK; 308 : GNUNET_BLOCK_TYPE_FS_IBLOCK;
309 prc.query = chk->query; 309 prc.query = chk->query;
310 prc.do_store = do_store; 310 prc.do_store = do_store;
311 process_result_with_request (&prc, 311 process_result_with_request (&prc,
@@ -1423,9 +1423,9 @@ transmit_download_request (void *cls,
1423 else 1423 else
1424 sm->options = htonl (0); 1424 sm->options = htonl (0);
1425 if (dc->pending->depth == dc->treedepth) 1425 if (dc->pending->depth == dc->treedepth)
1426 sm->type = htonl (GNUNET_BLOCK_TYPE_DBLOCK); 1426 sm->type = htonl (GNUNET_BLOCK_TYPE_FS_DBLOCK);
1427 else 1427 else
1428 sm->type = htonl (GNUNET_BLOCK_TYPE_IBLOCK); 1428 sm->type = htonl (GNUNET_BLOCK_TYPE_FS_IBLOCK);
1429 sm->anonymity_level = htonl (dc->anonymity); 1429 sm->anonymity_level = htonl (dc->anonymity);
1430 sm->target = dc->target.hashPubKey; 1430 sm->target = dc->target.hashPubKey;
1431 sm->query = dc->pending->chk.query; 1431 sm->query = dc->pending->chk.query;
diff --git a/src/fs/fs_namespace.c b/src/fs/fs_namespace.c
index 73cbc5f9e..5c1137eb7 100644
--- a/src/fs/fs_namespace.c
+++ b/src/fs/fs_namespace.c
@@ -416,7 +416,7 @@ advertisement_cont (void *cls,
416 &query, 416 &query,
417 ac->pt_size + sizeof (struct NBlock), 417 ac->pt_size + sizeof (struct NBlock),
418 ac->nb, 418 ac->nb,
419 GNUNET_BLOCK_TYPE_NBLOCK, 419 GNUNET_BLOCK_TYPE_FS_NBLOCK,
420 ac->priority, 420 ac->priority,
421 ac->anonymity, 421 ac->anonymity,
422 ac->expiration, 422 ac->expiration,
@@ -982,7 +982,7 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h,
982 &sb_enc->identifier, 982 &sb_enc->identifier,
983 size, 983 size,
984 sb_enc, 984 sb_enc,
985 GNUNET_BLOCK_TYPE_SBLOCK, 985 GNUNET_BLOCK_TYPE_FS_SBLOCK,
986 priority, 986 priority,
987 anonymity, 987 anonymity,
988 expirationTime, 988 expirationTime,
diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c
index 0b0617340..6262dc604 100644
--- a/src/fs/fs_publish.c
+++ b/src/fs/fs_publish.c
@@ -555,7 +555,7 @@ block_proc (void *cls,
555 dpc_cls->p = p; 555 dpc_cls->p = p;
556 if ( (! p->is_directory) && 556 if ( (! p->is_directory) &&
557 (GNUNET_YES == p->data.file.do_index) && 557 (GNUNET_YES == p->data.file.do_index) &&
558 (type == GNUNET_BLOCK_TYPE_DBLOCK) ) 558 (type == GNUNET_BLOCK_TYPE_FS_DBLOCK) )
559 { 559 {
560#if DEBUG_PUBLISH 560#if DEBUG_PUBLISH
561 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 561 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -571,7 +571,7 @@ block_proc (void *cls,
571 query, 571 query,
572 sizeof(struct OnDemandBlock), 572 sizeof(struct OnDemandBlock),
573 &odb, 573 &odb,
574 GNUNET_BLOCK_TYPE_ONDEMAND, 574 GNUNET_BLOCK_TYPE_FS_ONDEMAND,
575 p->priority, 575 p->priority,
576 p->anonymity, 576 p->anonymity,
577 p->expirationTime, 577 p->expirationTime,
@@ -1596,7 +1596,7 @@ publish_ksk_cont (void *cls,
1596 sizeof (struct KBlock) + 1596 sizeof (struct KBlock) +
1597 pkc->slen, 1597 pkc->slen,
1598 pkc->cpy, 1598 pkc->cpy,
1599 GNUNET_BLOCK_TYPE_KBLOCK, 1599 GNUNET_BLOCK_TYPE_FS_KBLOCK,
1600 pkc->priority, 1600 pkc->priority,
1601 pkc->anonymity, 1601 pkc->anonymity,
1602 pkc->expirationTime, 1602 pkc->expirationTime,
diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c
index a6418f786..f077bdac3 100644
--- a/src/fs/fs_search.c
+++ b/src/fs/fs_search.c
@@ -814,7 +814,7 @@ process_result (struct GNUNET_FS_SearchContext *sc,
814 } 814 }
815 switch (type) 815 switch (type)
816 { 816 {
817 case GNUNET_BLOCK_TYPE_KBLOCK: 817 case GNUNET_BLOCK_TYPE_FS_KBLOCK:
818 if (! GNUNET_FS_uri_test_ksk (sc->uri)) 818 if (! GNUNET_FS_uri_test_ksk (sc->uri))
819 { 819 {
820 GNUNET_break (0); 820 GNUNET_break (0);
@@ -827,7 +827,7 @@ process_result (struct GNUNET_FS_SearchContext *sc,
827 } 827 }
828 process_kblock (sc, data, size); 828 process_kblock (sc, data, size);
829 break; 829 break;
830 case GNUNET_BLOCK_TYPE_SBLOCK: 830 case GNUNET_BLOCK_TYPE_FS_SBLOCK:
831 if (! GNUNET_FS_uri_test_sks (sc->uri)) 831 if (! GNUNET_FS_uri_test_sks (sc->uri))
832 { 832 {
833 GNUNET_break (0); 833 GNUNET_break (0);
@@ -840,7 +840,7 @@ process_result (struct GNUNET_FS_SearchContext *sc,
840 } 840 }
841 process_sblock (sc, data, size); 841 process_sblock (sc, data, size);
842 break; 842 break;
843 case GNUNET_BLOCK_TYPE_NBLOCK: 843 case GNUNET_BLOCK_TYPE_FS_NBLOCK:
844 if (! GNUNET_FS_uri_test_ksk (sc->uri)) 844 if (! GNUNET_FS_uri_test_ksk (sc->uri))
845 { 845 {
846 GNUNET_break (0); 846 GNUNET_break (0);
@@ -854,9 +854,9 @@ process_result (struct GNUNET_FS_SearchContext *sc,
854 process_nblock (sc, data, size); 854 process_nblock (sc, data, size);
855 break; 855 break;
856 case GNUNET_BLOCK_TYPE_ANY: 856 case GNUNET_BLOCK_TYPE_ANY:
857 case GNUNET_BLOCK_TYPE_DBLOCK: 857 case GNUNET_BLOCK_TYPE_FS_DBLOCK:
858 case GNUNET_BLOCK_TYPE_ONDEMAND: 858 case GNUNET_BLOCK_TYPE_FS_ONDEMAND:
859 case GNUNET_BLOCK_TYPE_IBLOCK: 859 case GNUNET_BLOCK_TYPE_FS_IBLOCK:
860 GNUNET_break (0); 860 GNUNET_break (0);
861 break; 861 break;
862 default: 862 default:
@@ -981,7 +981,7 @@ transmit_search_request (void *cls,
981 sm->options = htonl (1); 981 sm->options = htonl (1);
982 else 982 else
983 sm->options = htonl (0); 983 sm->options = htonl (0);
984 sm->type = htonl (GNUNET_BLOCK_TYPE_SBLOCK); 984 sm->type = htonl (GNUNET_BLOCK_TYPE_FS_SBLOCK);
985 sm->anonymity_level = htonl (sc->anonymity); 985 sm->anonymity_level = htonl (sc->anonymity);
986 sm->target = sc->uri->data.sks.namespace; 986 sm->target = sc->uri->data.sks.namespace;
987 identifier = sc->uri->data.sks.identifier; 987 identifier = sc->uri->data.sks.identifier;
diff --git a/src/fs/fs_tree.c b/src/fs/fs_tree.c
index 760a7e039..55f7b0e09 100644
--- a/src/fs/fs_tree.c
+++ b/src/fs/fs_tree.c
@@ -385,8 +385,8 @@ void GNUNET_FS_tree_encoder_next (struct GNUNET_FS_TreeEncoder * te)
385 &mychk->query, 385 &mychk->query,
386 te->publish_offset, 386 te->publish_offset,
387 (te->current_depth == te->chk_tree_depth) 387 (te->current_depth == te->chk_tree_depth)
388 ? GNUNET_BLOCK_TYPE_DBLOCK 388 ? GNUNET_BLOCK_TYPE_FS_DBLOCK
389 : GNUNET_BLOCK_TYPE_IBLOCK, 389 : GNUNET_BLOCK_TYPE_FS_IBLOCK,
390 enc, 390 enc,
391 pt_size); 391 pt_size);
392 if (NULL != te->progress) 392 if (NULL != te->progress)
diff --git a/src/fs/fs_unindex.c b/src/fs/fs_unindex.c
index 375b833fb..e4ac4efd6 100644
--- a/src/fs/fs_unindex.c
+++ b/src/fs/fs_unindex.c
@@ -207,7 +207,7 @@ unindex_process (void *cls,
207 const void *data; 207 const void *data;
208 struct OnDemandBlock odb; 208 struct OnDemandBlock odb;
209 209
210 if (type != GNUNET_BLOCK_TYPE_DBLOCK) 210 if (type != GNUNET_BLOCK_TYPE_FS_DBLOCK)
211 { 211 {
212 size = block_size; 212 size = block_size;
213 data = block; 213 data = block;
diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c
index d40cdb744..9fce6478c 100644
--- a/src/fs/gnunet-service-fs.c
+++ b/src/fs/gnunet-service-fs.c
@@ -24,8 +24,9 @@
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * 25 *
26 * TODO: 26 * TODO:
27 * - track per-peer request latency (using new load API)
28 * - consider more precise latency estimation (per-peer & request) -- again load API?
27 * - implement test_load_too_high, make decision priority-based, implement forwarding, etc. 29 * - implement test_load_too_high, make decision priority-based, implement forwarding, etc.
28 * - consider more precise latency estimation (per-peer & request)
29 * - introduce random latency in processing 30 * - introduce random latency in processing
30 * - tell other peers to stop migration if our PUTs fail (or if 31 * - tell other peers to stop migration if our PUTs fail (or if
31 * we don't support migration per configuration?) 32 * we don't support migration per configuration?)
@@ -35,7 +36,9 @@
35#include <float.h> 36#include <float.h>
36#include "gnunet_constants.h" 37#include "gnunet_constants.h"
37#include "gnunet_core_service.h" 38#include "gnunet_core_service.h"
39#include "gnunet_dht_service.h"
38#include "gnunet_datastore_service.h" 40#include "gnunet_datastore_service.h"
41#include "gnunet_load_lib.h"
39#include "gnunet_peer_lib.h" 42#include "gnunet_peer_lib.h"
40#include "gnunet_protocols.h" 43#include "gnunet_protocols.h"
41#include "gnunet_signatures.h" 44#include "gnunet_signatures.h"
@@ -52,6 +55,13 @@
52#define MAX_QUEUE_PER_PEER 16 55#define MAX_QUEUE_PER_PEER 16
53 56
54/** 57/**
58 * Size for the hash map for DHT requests from the FS
59 * service. Should be about the number of concurrent
60 * DHT requests we plan to make.
61 */
62#define FS_DHT_HT_SIZE 1024
63
64/**
55 * How often do we flush trust values to disk? 65 * How often do we flush trust values to disk?
56 */ 66 */
57#define TRUST_FLUSH_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) 67#define TRUST_FLUSH_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
@@ -174,6 +184,12 @@ struct ConnectedPeer
174 struct GNUNET_TIME_Relative avg_delay; 184 struct GNUNET_TIME_Relative avg_delay;
175 185
176 /** 186 /**
187 * Point in time until which this peer does not want us to migrate content
188 * to it.
189 */
190 struct GNUNET_TIME_Absolute migration_blocked;
191
192 /**
177 * Handle for an active request for transmission to this 193 * Handle for an active request for transmission to this
178 * peer, or NULL. 194 * peer, or NULL.
179 */ 195 */
@@ -709,6 +725,11 @@ static GNUNET_SCHEDULER_TaskIdentifier mig_task;
709static struct GNUNET_TIME_Relative min_migration_delay; 725static struct GNUNET_TIME_Relative min_migration_delay;
710 726
711/** 727/**
728 * Handle for DHT operations.
729 */
730static struct GNUNET_DHT_Handle *dht_handle;
731
732/**
712 * Size of the doubly-linked list of migration blocks. 733 * Size of the doubly-linked list of migration blocks.
713 */ 734 */
714static unsigned int mig_size; 735static unsigned int mig_size;
@@ -731,6 +752,29 @@ static int active_migration;
731static double current_priorities; 752static double current_priorities;
732 753
733/** 754/**
755 * Datastore load tracking.
756 */
757static struct GNUNET_LOAD_Value *datastore_load;
758
759
760/**
761 * We've just now completed a datastore request. Update our
762 * datastore load calculations.
763 *
764 * @param start time when the datastore request was issued
765 */
766static void
767update_datastore_delays (struct GNUNET_TIME_Absolute start)
768{
769 struct GNUNET_TIME_Relative delay;
770
771 delay = GNUNET_TIME_absolute_get_duration (start);
772 GNUNET_LOAD_update (datastore_load,
773 delay.value);
774}
775
776
777/**
734 * Get the filename under which we would store the GNUNET_HELLO_Message 778 * Get the filename under which we would store the GNUNET_HELLO_Message
735 * for the given host and protocol. 779 * for the given host and protocol.
736 * @return filename of the form DIRECTORY/HOSTID 780 * @return filename of the form DIRECTORY/HOSTID
@@ -768,7 +812,6 @@ transmit_to_peer (void *cls,
768 812
769/* ******************* clean up functions ************************ */ 813/* ******************* clean up functions ************************ */
770 814
771
772/** 815/**
773 * Delete the given migration block. 816 * Delete the given migration block.
774 * 817 *
@@ -831,6 +874,8 @@ consider_migration (void *cls,
831 unsigned int repl; 874 unsigned int repl;
832 875
833 /* consider 'cp' as a migration target for mb */ 876 /* consider 'cp' as a migration target for mb */
877 if (GNUNET_TIME_absolute_get_remaining (cp->migration_blocked).value > 0)
878 return GNUNET_YES; /* peer has requested no migration! */
834 if (mb != NULL) 879 if (mb != NULL)
835 { 880 {
836 GNUNET_PEER_resolve (cp->pid, 881 GNUNET_PEER_resolve (cp->pid,
@@ -986,7 +1031,7 @@ process_migration_content (void *cls,
986 consider_migration_gathering (); 1031 consider_migration_gathering ();
987 return; 1032 return;
988 } 1033 }
989 if (type == GNUNET_BLOCK_TYPE_ONDEMAND) 1034 if (type == GNUNET_BLOCK_TYPE_FS_ONDEMAND)
990 { 1035 {
991 if (GNUNET_OK != 1036 if (GNUNET_OK !=
992 GNUNET_FS_handle_on_demand_block (key, size, data, 1037 GNUNET_FS_handle_on_demand_block (key, size, data,
@@ -994,7 +1039,9 @@ process_migration_content (void *cls,
994 expiration, uid, 1039 expiration, uid,
995 &process_migration_content, 1040 &process_migration_content,
996 NULL)) 1041 NULL))
997 GNUNET_DATASTORE_get_next (dsh, GNUNET_YES); 1042 {
1043 GNUNET_DATASTORE_get_next (dsh, GNUNET_YES);
1044 }
998 return; 1045 return;
999 } 1046 }
1000#if DEBUG_FS 1047#if DEBUG_FS
@@ -1587,6 +1634,10 @@ shutdown_task (void *cls,
1587 while (mig_head != NULL) 1634 while (mig_head != NULL)
1588 delete_migration_block (mig_head); 1635 delete_migration_block (mig_head);
1589 GNUNET_assert (0 == mig_size); 1636 GNUNET_assert (0 == mig_size);
1637 GNUNET_DHT_disconnect (dht_handle);
1638 dht_handle = NULL;
1639 GNUNET_LOAD_value_free (datastore_load);
1640 datastore_load = NULL;
1590 GNUNET_BLOCK_context_destroy (block_ctx); 1641 GNUNET_BLOCK_context_destroy (block_ctx);
1591 block_ctx = NULL; 1642 block_ctx = NULL;
1592 GNUNET_CONFIGURATION_destroy (block_cfg); 1643 GNUNET_CONFIGURATION_destroy (block_cfg);
@@ -2297,6 +2348,21 @@ forward_request_task (void *cls,
2297 } 2348 }
2298 if (GNUNET_YES == pr->local_only) 2349 if (GNUNET_YES == pr->local_only)
2299 return; /* configured to not do P2P search */ 2350 return; /* configured to not do P2P search */
2351 /* (0) try DHT */
2352 if (0 == pr->anonymity_level)
2353 {
2354#if 0
2355 /* DHT API needs fixing... */
2356 pr->dht_get = GNUNET_DHT_get_start (dht_handle,
2357 GNUNET_TIME_UNIT_FOREVER_REL,
2358 pr->type,
2359 &pr->query,
2360 &process_dht_reply,
2361 pr,
2362 FIXME,
2363 FIXME);
2364#endif
2365 }
2300 /* (1) select target */ 2366 /* (1) select target */
2301 psc.pr = pr; 2367 psc.pr = pr;
2302 psc.target_score = -DBL_MAX; 2368 psc.target_score = -DBL_MAX;
@@ -2376,14 +2442,14 @@ transmit_reply_continuation (void *cls,
2376 2442
2377 switch (pr->type) 2443 switch (pr->type)
2378 { 2444 {
2379 case GNUNET_BLOCK_TYPE_DBLOCK: 2445 case GNUNET_BLOCK_TYPE_FS_DBLOCK:
2380 case GNUNET_BLOCK_TYPE_IBLOCK: 2446 case GNUNET_BLOCK_TYPE_FS_IBLOCK:
2381 /* only one reply expected, done with the request! */ 2447 /* only one reply expected, done with the request! */
2382 destroy_pending_request (pr); 2448 destroy_pending_request (pr);
2383 break; 2449 break;
2384 case GNUNET_BLOCK_TYPE_ANY: 2450 case GNUNET_BLOCK_TYPE_ANY:
2385 case GNUNET_BLOCK_TYPE_KBLOCK: 2451 case GNUNET_BLOCK_TYPE_FS_KBLOCK:
2386 case GNUNET_BLOCK_TYPE_SBLOCK: 2452 case GNUNET_BLOCK_TYPE_FS_SBLOCK:
2387 break; 2453 break;
2388 default: 2454 default:
2389 GNUNET_break (0); 2455 GNUNET_break (0);
@@ -2476,12 +2542,6 @@ struct ProcessReplyClosure
2476 size_t size; 2542 size_t size;
2477 2543
2478 /** 2544 /**
2479 * Namespace that this reply belongs to
2480 * (if it is of type SBLOCK).
2481 */
2482 GNUNET_HashCode namespace;
2483
2484 /**
2485 * Type of the block. 2545 * Type of the block.
2486 */ 2546 */
2487 enum GNUNET_BLOCK_Type type; 2547 enum GNUNET_BLOCK_Type type;
@@ -2492,6 +2552,11 @@ struct ProcessReplyClosure
2492 uint32_t priority; 2552 uint32_t priority;
2493 2553
2494 /** 2554 /**
2555 * Evaluation result (returned).
2556 */
2557 enum GNUNET_BLOCK_EvaluationResult eval;
2558
2559 /**
2495 * Did we finish processing the associated request? 2560 * Did we finish processing the associated request?
2496 */ 2561 */
2497 int finished; 2562 int finished;
@@ -2519,7 +2584,6 @@ process_reply (void *cls,
2519 struct PutMessage *pm; 2584 struct PutMessage *pm;
2520 struct ConnectedPeer *cp; 2585 struct ConnectedPeer *cp;
2521 struct GNUNET_TIME_Relative cur_delay; 2586 struct GNUNET_TIME_Relative cur_delay;
2522 enum GNUNET_BLOCK_EvaluationResult eval;
2523 size_t msize; 2587 size_t msize;
2524 2588
2525#if DEBUG_FS 2589#if DEBUG_FS
@@ -2565,15 +2629,15 @@ process_reply (void *cls,
2565 GNUNET_SERVER_client_keep (pr->client_request_list->client_list->client); 2629 GNUNET_SERVER_client_keep (pr->client_request_list->client_list->client);
2566 } 2630 }
2567 } 2631 }
2568 eval = GNUNET_BLOCK_evaluate (block_ctx, 2632 prq->eval = GNUNET_BLOCK_evaluate (block_ctx,
2569 prq->type, 2633 prq->type,
2570 key, 2634 key,
2571 &pr->bf, 2635 &pr->bf,
2572 pr->mingle, 2636 pr->mingle,
2573 pr->namespace, (pr->namespace != NULL) ? sizeof (GNUNET_HashCode) : 0, 2637 pr->namespace, (pr->namespace != NULL) ? sizeof (GNUNET_HashCode) : 0,
2574 prq->data, 2638 prq->data,
2575 prq->size); 2639 prq->size);
2576 switch (eval) 2640 switch (prq->eval)
2577 { 2641 {
2578 case GNUNET_BLOCK_EVALUATION_OK_MORE: 2642 case GNUNET_BLOCK_EVALUATION_OK_MORE:
2579 break; 2643 break;
@@ -2636,8 +2700,21 @@ process_reply (void *cls,
2636 &pr->replies_seen[pr->replies_seen_off++]); 2700 &pr->replies_seen[pr->replies_seen_off++]);
2637 refresh_bloomfilter (pr); 2701 refresh_bloomfilter (pr);
2638 } 2702 }
2703 if (NULL == prq->sender)
2704 {
2705#if DEBUG_FS
2706 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2707 "Found result for query `%s' in local datastore\n",
2708 GNUNET_h2s (key));
2709#endif
2710 GNUNET_STATISTICS_update (stats,
2711 gettext_noop ("# results found locally"),
2712 1,
2713 GNUNET_NO);
2714 }
2639 prq->priority += pr->remaining_priority; 2715 prq->priority += pr->remaining_priority;
2640 pr->remaining_priority = 0; 2716 pr->remaining_priority = 0;
2717 pr->results_found++;
2641 if (NULL != pr->client_request_list) 2718 if (NULL != pr->client_request_list)
2642 { 2719 {
2643 GNUNET_STATISTICS_update (stats, 2720 GNUNET_STATISTICS_update (stats,
@@ -2753,7 +2830,6 @@ handle_p2p_put (void *cls,
2753 struct GNUNET_TIME_Absolute expiration; 2830 struct GNUNET_TIME_Absolute expiration;
2754 GNUNET_HashCode query; 2831 GNUNET_HashCode query;
2755 struct ProcessReplyClosure prq; 2832 struct ProcessReplyClosure prq;
2756 const struct SBlock *sb;
2757 2833
2758 msize = ntohs (message->size); 2834 msize = ntohs (message->size);
2759 if (msize < sizeof (struct PutMessage)) 2835 if (msize < sizeof (struct PutMessage))
@@ -2766,7 +2842,7 @@ handle_p2p_put (void *cls,
2766 type = ntohl (put->type); 2842 type = ntohl (put->type);
2767 expiration = GNUNET_TIME_absolute_ntoh (put->expiration); 2843 expiration = GNUNET_TIME_absolute_ntoh (put->expiration);
2768 2844
2769 if (type == GNUNET_BLOCK_TYPE_ONDEMAND) 2845 if (type == GNUNET_BLOCK_TYPE_FS_ONDEMAND)
2770 return GNUNET_SYSERR; 2846 return GNUNET_SYSERR;
2771 if (GNUNET_OK != 2847 if (GNUNET_OK !=
2772 GNUNET_BLOCK_get_key (block_ctx, 2848 GNUNET_BLOCK_get_key (block_ctx,
@@ -2778,14 +2854,6 @@ handle_p2p_put (void *cls,
2778 GNUNET_break_op (0); 2854 GNUNET_break_op (0);
2779 return GNUNET_SYSERR; 2855 return GNUNET_SYSERR;
2780 } 2856 }
2781 if (GNUNET_BLOCK_TYPE_SBLOCK == type)
2782 {
2783 sb = (const struct SBlock*) &put[1];
2784 GNUNET_CRYPTO_hash (&sb->subspace,
2785 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
2786 &prq.namespace);
2787 }
2788
2789#if DEBUG_FS 2857#if DEBUG_FS
2790 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2858 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2791 "Received result for query `%s' from peer `%4s'\n", 2859 "Received result for query `%s' from peer `%4s'\n",
@@ -2838,6 +2906,30 @@ handle_p2p_put (void *cls,
2838} 2906}
2839 2907
2840 2908
2909/**
2910 * Handle P2P "MIGRATION_STOP" message.
2911 *
2912 * @param cls closure, always NULL
2913 * @param other the other peer involved (sender or receiver, NULL
2914 * for loopback messages where we are both sender and receiver)
2915 * @param message the actual message
2916 * @param latency reported latency of the connection with 'other'
2917 * @param distance reported distance (DV) to 'other'
2918 * @return GNUNET_OK to keep the connection open,
2919 * GNUNET_SYSERR to close it (signal serious error)
2920 */
2921static int
2922handle_p2p_migration_stop (void *cls,
2923 const struct GNUNET_PeerIdentity *other,
2924 const struct GNUNET_MessageHeader *message,
2925 struct GNUNET_TIME_Relative latency,
2926 uint32_t distance)
2927{
2928 // FIXME!
2929}
2930
2931
2932
2841/* **************************** P2P GET Handling ************************ */ 2933/* **************************** P2P GET Handling ************************ */
2842 2934
2843 2935
@@ -2923,10 +3015,8 @@ process_local_reply (void *cls,
2923 struct PendingRequest *pr = cls; 3015 struct PendingRequest *pr = cls;
2924 struct ProcessReplyClosure prq; 3016 struct ProcessReplyClosure prq;
2925 struct CheckDuplicateRequestClosure cdrc; 3017 struct CheckDuplicateRequestClosure cdrc;
2926 const struct SBlock *sb;
2927 GNUNET_HashCode dhash;
2928 GNUNET_HashCode mhash;
2929 GNUNET_HashCode query; 3018 GNUNET_HashCode query;
3019 unsigned int old_rf;
2930 3020
2931 if (NULL == key) 3021 if (NULL == key)
2932 { 3022 {
@@ -2973,7 +3063,7 @@ process_local_reply (void *cls,
2973 GNUNET_h2s (key), 3063 GNUNET_h2s (key),
2974 type); 3064 type);
2975#endif 3065#endif
2976 if (type == GNUNET_BLOCK_TYPE_ONDEMAND) 3066 if (type == GNUNET_BLOCK_TYPE_FS_ONDEMAND)
2977 { 3067 {
2978#if DEBUG_FS 3068#if DEBUG_FS
2979 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3069 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2989,54 +3079,16 @@ process_local_reply (void *cls,
2989 &process_local_reply, 3079 &process_local_reply,
2990 pr)) 3080 pr))
2991 if (pr->qe != NULL) 3081 if (pr->qe != NULL)
2992 GNUNET_DATASTORE_get_next (dsh, GNUNET_YES); 3082 {
2993 return; 3083 GNUNET_DATASTORE_get_next (dsh, GNUNET_YES);
2994 } 3084 }
2995
2996 /* FIXME: use block lib here! */
2997 /* check for duplicates */
2998 GNUNET_CRYPTO_hash (data, size, &dhash);
2999 GNUNET_BLOCK_mingle_hash (&dhash,
3000 pr->mingle,
3001 &mhash);
3002 if ( (pr->bf != NULL) &&
3003 (GNUNET_YES ==
3004 GNUNET_CONTAINER_bloomfilter_test (pr->bf,
3005 &mhash)) )
3006 {
3007#if DEBUG_FS
3008 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3009 "Result from datastore filtered by bloomfilter (duplicate).\n");
3010#endif
3011 GNUNET_STATISTICS_update (stats,
3012 gettext_noop ("# results filtered by query bloomfilter"),
3013 1,
3014 GNUNET_NO);
3015 if (pr->qe != NULL)
3016 GNUNET_DATASTORE_get_next (dsh, GNUNET_YES);
3017 return; 3085 return;
3018 } 3086 }
3019#if DEBUG_FS 3087 old_rf = pr->results_found;
3020 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3021 "Found result for query `%s' in local datastore\n",
3022 GNUNET_h2s (key));
3023#endif
3024 GNUNET_STATISTICS_update (stats,
3025 gettext_noop ("# results found locally"),
3026 1,
3027 GNUNET_NO);
3028 pr->results_found++;
3029 memset (&prq, 0, sizeof (prq)); 3088 memset (&prq, 0, sizeof (prq));
3030 prq.data = data; 3089 prq.data = data;
3031 prq.expiration = expiration; 3090 prq.expiration = expiration;
3032 prq.size = size; 3091 prq.size = size;
3033 if (GNUNET_BLOCK_TYPE_SBLOCK == type)
3034 {
3035 sb = (const struct SBlock*) data;
3036 GNUNET_CRYPTO_hash (&sb->subspace,
3037 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
3038 &prq.namespace);
3039 }
3040 if (GNUNET_OK != 3092 if (GNUNET_OK !=
3041 GNUNET_BLOCK_get_key (block_ctx, 3093 GNUNET_BLOCK_get_key (block_ctx,
3042 type, 3094 type,
@@ -3058,12 +3110,14 @@ process_local_reply (void *cls,
3058 prq.priority = priority; 3110 prq.priority = priority;
3059 prq.finished = GNUNET_NO; 3111 prq.finished = GNUNET_NO;
3060 process_reply (&prq, key, pr); 3112 process_reply (&prq, key, pr);
3113 if ( (old_rf == 0) &&
3114 (pr->results_found == 1) )
3115 update_datastore_delays (pr->start_time);
3061 if (prq.finished == GNUNET_YES) 3116 if (prq.finished == GNUNET_YES)
3062 return; 3117 return;
3063 if (pr->qe == NULL) 3118 if (pr->qe == NULL)
3064 return; /* done here */ 3119 return; /* done here */
3065 if ( (type == GNUNET_BLOCK_TYPE_DBLOCK) || 3120 if (prq.eval == GNUNET_BLOCK_EVALUATION_OK_LAST)
3066 (type == GNUNET_BLOCK_TYPE_IBLOCK) )
3067 { 3121 {
3068 GNUNET_DATASTORE_get_next (dsh, GNUNET_NO); 3122 GNUNET_DATASTORE_get_next (dsh, GNUNET_NO);
3069 return; 3123 return;
@@ -3211,12 +3265,6 @@ handle_p2p_get (void *cls,
3211 opt = (const GNUNET_HashCode*) &gm[1]; 3265 opt = (const GNUNET_HashCode*) &gm[1];
3212 bfsize = msize - sizeof (struct GetMessage) + bits * sizeof (GNUNET_HashCode); 3266 bfsize = msize - sizeof (struct GetMessage) + bits * sizeof (GNUNET_HashCode);
3213 bm = ntohl (gm->hash_bitmap); 3267 bm = ntohl (gm->hash_bitmap);
3214 if ( (0 != (bm & GET_MESSAGE_BIT_SKS_NAMESPACE)) &&
3215 (type != GNUNET_BLOCK_TYPE_SBLOCK) )
3216 {
3217 GNUNET_break_op (0);
3218 return GNUNET_SYSERR;
3219 }
3220 bits = 0; 3268 bits = 0;
3221 cps = GNUNET_CONTAINER_multihashmap_get (connected_peers, 3269 cps = GNUNET_CONTAINER_multihashmap_get (connected_peers,
3222 &other->hashPubKey); 3270 &other->hashPubKey);
@@ -3297,7 +3345,6 @@ handle_p2p_get (void *cls,
3297 pr->mingle = ntohl (gm->filter_mutator); 3345 pr->mingle = ntohl (gm->filter_mutator);
3298 if (0 != (bm & GET_MESSAGE_BIT_TRANSMIT_TO)) 3346 if (0 != (bm & GET_MESSAGE_BIT_TRANSMIT_TO))
3299 pr->target_pid = GNUNET_PEER_intern ((const struct GNUNET_PeerIdentity*) &opt[bits++]); 3347 pr->target_pid = GNUNET_PEER_intern ((const struct GNUNET_PeerIdentity*) &opt[bits++]);
3300
3301 pr->anonymity_level = 1; 3348 pr->anonymity_level = 1;
3302 pr->priority = bound_priority (ntohl (gm->priority), cps); 3349 pr->priority = bound_priority (ntohl (gm->priority), cps);
3303 pr->ttl = bound_ttl (ntohl (gm->ttl), pr->priority); 3350 pr->ttl = bound_ttl (ntohl (gm->ttl), pr->priority);
@@ -3402,7 +3449,7 @@ handle_p2p_get (void *cls,
3402 /* calculate change in traffic preference */ 3449 /* calculate change in traffic preference */
3403 cps->inc_preference += pr->priority * 1000 + QUERY_BANDWIDTH_VALUE; 3450 cps->inc_preference += pr->priority * 1000 + QUERY_BANDWIDTH_VALUE;
3404 /* process locally */ 3451 /* process locally */
3405 if (type == GNUNET_BLOCK_TYPE_DBLOCK) 3452 if (type == GNUNET_BLOCK_TYPE_FS_DBLOCK)
3406 type = GNUNET_BLOCK_TYPE_ANY; /* to get on-demand as well */ 3453 type = GNUNET_BLOCK_TYPE_ANY; /* to get on-demand as well */
3407 timeout = GNUNET_TIME_relative_multiply (BASIC_DATASTORE_REQUEST_DELAY, 3454 timeout = GNUNET_TIME_relative_multiply (BASIC_DATASTORE_REQUEST_DELAY,
3408 (pr->priority + 1)); 3455 (pr->priority + 1));
@@ -3418,8 +3465,8 @@ handle_p2p_get (void *cls,
3418 /* Are multiple results possible? If so, start processing remotely now! */ 3465 /* Are multiple results possible? If so, start processing remotely now! */
3419 switch (pr->type) 3466 switch (pr->type)
3420 { 3467 {
3421 case GNUNET_BLOCK_TYPE_DBLOCK: 3468 case GNUNET_BLOCK_TYPE_FS_DBLOCK:
3422 case GNUNET_BLOCK_TYPE_IBLOCK: 3469 case GNUNET_BLOCK_TYPE_FS_IBLOCK:
3423 /* only one result, wait for datastore */ 3470 /* only one result, wait for datastore */
3424 break; 3471 break;
3425 default: 3472 default:
@@ -3499,8 +3546,8 @@ handle_start_search (void *cls,
3499 client_list = cl; 3546 client_list = cl;
3500 } 3547 }
3501 /* detect duplicate KBLOCK requests */ 3548 /* detect duplicate KBLOCK requests */
3502 if ( (type == GNUNET_BLOCK_TYPE_KBLOCK) || 3549 if ( (type == GNUNET_BLOCK_TYPE_FS_KBLOCK) ||
3503 (type == GNUNET_BLOCK_TYPE_NBLOCK) || 3550 (type == GNUNET_BLOCK_TYPE_FS_NBLOCK) ||
3504 (type == GNUNET_BLOCK_TYPE_ANY) ) 3551 (type == GNUNET_BLOCK_TYPE_ANY) )
3505 { 3552 {
3506 crl = cl->rl_head; 3553 crl = cl->rl_head;
@@ -3542,7 +3589,7 @@ handle_start_search (void *cls,
3542 1, 3589 1,
3543 GNUNET_NO); 3590 GNUNET_NO);
3544 pr = GNUNET_malloc (sizeof (struct PendingRequest) + 3591 pr = GNUNET_malloc (sizeof (struct PendingRequest) +
3545 ((type == GNUNET_BLOCK_TYPE_SBLOCK) ? sizeof(GNUNET_HashCode) : 0)); 3592 ((type == GNUNET_BLOCK_TYPE_FS_SBLOCK) ? sizeof(GNUNET_HashCode) : 0));
3546 crl = GNUNET_malloc (sizeof (struct ClientRequestList)); 3593 crl = GNUNET_malloc (sizeof (struct ClientRequestList));
3547 memset (crl, 0, sizeof (struct ClientRequestList)); 3594 memset (crl, 0, sizeof (struct ClientRequestList));
3548 crl->client_list = cl; 3595 crl->client_list = cl;
@@ -3560,6 +3607,7 @@ handle_start_search (void *cls,
3560 sc * sizeof (GNUNET_HashCode)); 3607 sc * sizeof (GNUNET_HashCode));
3561 pr->replies_seen_off = sc; 3608 pr->replies_seen_off = sc;
3562 pr->anonymity_level = ntohl (sm->anonymity_level); 3609 pr->anonymity_level = ntohl (sm->anonymity_level);
3610 pr->start_time = GNUNET_TIME_absolute_get ();
3563 refresh_bloomfilter (pr); 3611 refresh_bloomfilter (pr);
3564 pr->query = sm->query; 3612 pr->query = sm->query;
3565 if (0 == (1 & ntohl (sm->options))) 3613 if (0 == (1 & ntohl (sm->options)))
@@ -3568,14 +3616,14 @@ handle_start_search (void *cls,
3568 pr->local_only = GNUNET_YES; 3616 pr->local_only = GNUNET_YES;
3569 switch (type) 3617 switch (type)
3570 { 3618 {
3571 case GNUNET_BLOCK_TYPE_DBLOCK: 3619 case GNUNET_BLOCK_TYPE_FS_DBLOCK:
3572 case GNUNET_BLOCK_TYPE_IBLOCK: 3620 case GNUNET_BLOCK_TYPE_FS_IBLOCK:
3573 if (0 != memcmp (&sm->target, 3621 if (0 != memcmp (&sm->target,
3574 &all_zeros, 3622 &all_zeros,
3575 sizeof (GNUNET_HashCode))) 3623 sizeof (GNUNET_HashCode)))
3576 pr->target_pid = GNUNET_PEER_intern ((const struct GNUNET_PeerIdentity*) &sm->target); 3624 pr->target_pid = GNUNET_PEER_intern ((const struct GNUNET_PeerIdentity*) &sm->target);
3577 break; 3625 break;
3578 case GNUNET_BLOCK_TYPE_SBLOCK: 3626 case GNUNET_BLOCK_TYPE_FS_SBLOCK:
3579 pr->namespace = (GNUNET_HashCode*) &pr[1]; 3627 pr->namespace = (GNUNET_HashCode*) &pr[1];
3580 memcpy (&pr[1], &sm->target, sizeof (GNUNET_HashCode)); 3628 memcpy (&pr[1], &sm->target, sizeof (GNUNET_HashCode));
3581 break; 3629 break;
@@ -3587,7 +3635,7 @@ handle_start_search (void *cls,
3587 &sm->query, 3635 &sm->query,
3588 pr, 3636 pr,
3589 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); 3637 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
3590 if (type == GNUNET_BLOCK_TYPE_DBLOCK) 3638 if (type == GNUNET_BLOCK_TYPE_FS_DBLOCK)
3591 type = GNUNET_BLOCK_TYPE_ANY; /* get on-demand blocks too! */ 3639 type = GNUNET_BLOCK_TYPE_ANY; /* get on-demand blocks too! */
3592 pr->qe = GNUNET_DATASTORE_get (dsh, 3640 pr->qe = GNUNET_DATASTORE_get (dsh,
3593 &sm->query, 3641 &sm->query,
@@ -3619,6 +3667,9 @@ main_init (struct GNUNET_SCHEDULER_Handle *s,
3619 GNUNET_MESSAGE_TYPE_FS_GET, 0 }, 3667 GNUNET_MESSAGE_TYPE_FS_GET, 0 },
3620 { &handle_p2p_put, 3668 { &handle_p2p_put,
3621 GNUNET_MESSAGE_TYPE_FS_PUT, 0 }, 3669 GNUNET_MESSAGE_TYPE_FS_PUT, 0 },
3670 { &handle_p2p_migration_stop,
3671 GNUNET_MESSAGE_TYPE_FS_MIGRATION_STOP,
3672 sizeof (struct MigrationStopMessage) },
3622 { NULL, 0, 0 } 3673 { NULL, 0, 0 }
3623 }; 3674 };
3624 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 3675 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
@@ -3746,6 +3797,7 @@ run (void *cls,
3746 GNUNET_SCHEDULER_shutdown (sched); 3797 GNUNET_SCHEDULER_shutdown (sched);
3747 return; 3798 return;
3748 } 3799 }
3800 datastore_load = GNUNET_LOAD_value_init ();
3749 block_cfg = GNUNET_CONFIGURATION_create (); 3801 block_cfg = GNUNET_CONFIGURATION_create ();
3750 GNUNET_CONFIGURATION_set_value_string (block_cfg, 3802 GNUNET_CONFIGURATION_set_value_string (block_cfg,
3751 "block", 3803 "block",
@@ -3753,16 +3805,23 @@ run (void *cls,
3753 "fs"); 3805 "fs");
3754 block_ctx = GNUNET_BLOCK_context_create (block_cfg); 3806 block_ctx = GNUNET_BLOCK_context_create (block_cfg);
3755 GNUNET_assert (NULL != block_ctx); 3807 GNUNET_assert (NULL != block_ctx);
3808 dht_handle = GNUNET_DHT_connect (sched,
3809 cfg,
3810 FS_DHT_HT_SIZE);
3756 if ( (GNUNET_OK != GNUNET_FS_indexing_init (sched, cfg, dsh)) || 3811 if ( (GNUNET_OK != GNUNET_FS_indexing_init (sched, cfg, dsh)) ||
3757 (GNUNET_OK != main_init (sched, server, cfg)) ) 3812 (GNUNET_OK != main_init (sched, server, cfg)) )
3758 { 3813 {
3759 GNUNET_SCHEDULER_shutdown (sched); 3814 GNUNET_SCHEDULER_shutdown (sched);
3760 GNUNET_DATASTORE_disconnect (dsh, GNUNET_NO); 3815 GNUNET_DATASTORE_disconnect (dsh, GNUNET_NO);
3761 dsh = NULL; 3816 dsh = NULL;
3817 GNUNET_DHT_disconnect (dht_handle);
3818 dht_handle = NULL;
3762 GNUNET_BLOCK_context_destroy (block_ctx); 3819 GNUNET_BLOCK_context_destroy (block_ctx);
3763 block_ctx = NULL; 3820 block_ctx = NULL;
3764 GNUNET_CONFIGURATION_destroy (block_cfg); 3821 GNUNET_CONFIGURATION_destroy (block_cfg);
3765 block_cfg = NULL; 3822 block_cfg = NULL;
3823 GNUNET_LOAD_value_free (datastore_load);
3824 datastore_load = NULL;
3766 return; 3825 return;
3767 } 3826 }
3768} 3827}
diff --git a/src/fs/gnunet-service-fs_indexing.c b/src/fs/gnunet-service-fs_indexing.c
index 20350f8fc..99b5da102 100644
--- a/src/fs/gnunet-service-fs_indexing.c
+++ b/src/fs/gnunet-service-fs_indexing.c
@@ -682,7 +682,7 @@ GNUNET_FS_handle_on_demand_block (const GNUNET_HashCode * key,
682 key, 682 key,
683 nsize, 683 nsize,
684 edata, 684 edata,
685 GNUNET_BLOCK_TYPE_DBLOCK, 685 GNUNET_BLOCK_TYPE_FS_DBLOCK,
686 priority, 686 priority,
687 anonymity, 687 anonymity,
688 expiration, 688 expiration,
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index 4e7fb8b7b..70fd97bd0 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -36,6 +36,7 @@ gnunetinclude_HEADERS = \
36 gnunet_fs_service.h \ 36 gnunet_fs_service.h \
37 gnunet_getopt_lib.h \ 37 gnunet_getopt_lib.h \
38 gnunet_hello_lib.h \ 38 gnunet_hello_lib.h \
39 gnunet_load_lib.h \
39 gnunet_nat_lib.h \ 40 gnunet_nat_lib.h \
40 gnunet_network_lib.h \ 41 gnunet_network_lib.h \
41 gnunet_os_lib.h \ 42 gnunet_os_lib.h \
diff --git a/src/include/gnunet_block_lib.h b/src/include/gnunet_block_lib.h
index 5154a3c08..bdbaeade5 100644
--- a/src/include/gnunet_block_lib.h
+++ b/src/include/gnunet_block_lib.h
@@ -50,39 +50,46 @@ enum GNUNET_BLOCK_Type
50 /** 50 /**
51 * Data block (leaf) in the CHK tree. 51 * Data block (leaf) in the CHK tree.
52 */ 52 */
53 GNUNET_BLOCK_TYPE_DBLOCK = 1, 53 GNUNET_BLOCK_TYPE_FS_DBLOCK = 1,
54 54
55 /** 55 /**
56 * Inner block in the CHK tree. 56 * Inner block in the CHK tree.
57 */ 57 */
58 GNUNET_BLOCK_TYPE_IBLOCK = 2, 58 GNUNET_BLOCK_TYPE_FS_IBLOCK = 2,
59 59
60 /** 60 /**
61 * Type of a block representing a keyword search result. 61 * Type of a block representing a keyword search result.
62 */ 62 */
63 GNUNET_BLOCK_TYPE_KBLOCK = 3, 63 GNUNET_BLOCK_TYPE_FS_KBLOCK = 3,
64 64
65 /** 65 /**
66 * Type of a block that is used to advertise content in a namespace. 66 * Type of a block that is used to advertise content in a namespace.
67 */ 67 */
68 GNUNET_BLOCK_TYPE_SBLOCK = 4, 68 GNUNET_BLOCK_TYPE_FS_SBLOCK = 4,
69 69
70 /** 70 /**
71 * Type of a block representing a block to be encoded on demand from disk. 71 * Type of a block representing a block to be encoded on demand from disk.
72 * Should never appear on the network directly. 72 * Should never appear on the network directly.
73 */ 73 */
74 GNUNET_BLOCK_TYPE_ONDEMAND = 5, 74 GNUNET_BLOCK_TYPE_FS_ONDEMAND = 5,
75 75
76 /** 76 /**
77 * Type of a block that is used to advertise a namespace. 77 * Type of a block that is used to advertise a namespace.
78 */ 78 */
79 GNUNET_BLOCK_TYPE_NBLOCK = 6, 79 GNUNET_BLOCK_TYPE_FS_NBLOCK = 6,
80 80
81 GNUNET_BLOCK_TYPE_TEST = 9999 81 /**
82 82 * Type of a block that contains a HELLO for a peer (for
83 }; 83 * DHT find-peer operations).
84 */
85 GNUNET_BLOCK_TYPE_DHT_HELLO = 7,
84 86
87 /**
88 * Block for testing.
89 */
90 GNUNET_BLOCK_TYPE_TEST = 8
85 91
92 };
86 93
87 94
88/** 95/**
diff --git a/src/include/gnunet_dht_service.h b/src/include/gnunet_dht_service.h
index ca1bebe09..a95cfafe6 100644
--- a/src/include/gnunet_dht_service.h
+++ b/src/include/gnunet_dht_service.h
@@ -28,6 +28,7 @@
28#define GNUNET_DHT_SERVICE_H 28#define GNUNET_DHT_SERVICE_H
29 29
30#include "gnunet_util_lib.h" 30#include "gnunet_util_lib.h"
31#include "gnunet_block_lib.h"
31#include "gnunet_hello_lib.h" 32#include "gnunet_hello_lib.h"
32 33
33#ifdef __cplusplus 34#ifdef __cplusplus
@@ -112,7 +113,7 @@ GNUNET_DHT_disconnect (struct GNUNET_DHT_Handle *handle);
112void 113void
113GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle, 114GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle,
114 const GNUNET_HashCode * key, 115 const GNUNET_HashCode * key,
115 uint32_t type, 116 enum GNUNET_BLOCK_Type type,
116 uint32_t size, 117 uint32_t size,
117 const char *data, 118 const char *data,
118 struct GNUNET_TIME_Absolute exp, 119 struct GNUNET_TIME_Absolute exp,
@@ -133,11 +134,11 @@ GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle,
133 * @param data pointer to the result data 134 * @param data pointer to the result data
134 */ 135 */
135typedef void (*GNUNET_DHT_GetIterator)(void *cls, 136typedef void (*GNUNET_DHT_GetIterator)(void *cls,
136 struct GNUNET_TIME_Absolute exp, 137 struct GNUNET_TIME_Absolute exp,
137 const GNUNET_HashCode * key, 138 const GNUNET_HashCode * key,
138 uint32_t type, 139 enum GNUNET_BLOCK_Type type,
139 uint32_t size, 140 uint32_t size,
140 const void *data); 141 const void *data);
141 142
142 143
143 144
@@ -147,7 +148,7 @@ typedef void (*GNUNET_DHT_GetIterator)(void *cls,
147 * @param handle handle to the DHT service 148 * @param handle handle to the DHT service
148 * @param timeout timeout for this request to be sent to the 149 * @param timeout timeout for this request to be sent to the
149 * service (this is NOT a timeout for receiving responses) 150 * service (this is NOT a timeout for receiving responses)
150 * @param type expected type of the response object (GNUNET_BLOCK_TYPE_*) 151 * @param type expected type of the response object (GNUNET_BLOCK_TYPE_FS_*)
151 * @param key the key to look up 152 * @param key the key to look up
152 * @param iter function to call on each result 153 * @param iter function to call on each result
153 * @param iter_cls closure for iter 154 * @param iter_cls closure for iter
@@ -160,7 +161,7 @@ typedef void (*GNUNET_DHT_GetIterator)(void *cls,
160struct GNUNET_DHT_GetHandle * 161struct GNUNET_DHT_GetHandle *
161GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle, 162GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle,
162 struct GNUNET_TIME_Relative timeout, 163 struct GNUNET_TIME_Relative timeout,
163 uint32_t type, 164 enum GNUNET_BLOCK_Type type,
164 const GNUNET_HashCode * key, 165 const GNUNET_HashCode * key,
165 GNUNET_DHT_GetIterator iter, 166 GNUNET_DHT_GetIterator iter,
166 void *iter_cls, 167 void *iter_cls,
diff --git a/src/include/gnunet_load_lib.h b/src/include/gnunet_load_lib.h
new file mode 100644
index 000000000..7af00ccd3
--- /dev/null
+++ b/src/include/gnunet_load_lib.h
@@ -0,0 +1,106 @@
1/*
2 This file is part of GNUnet.
3 (C) 2010 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file include/gnunet_load_lib.h
23 * @brief functions related to load calculations
24 * @author Christian Grothoff
25 */
26
27#ifndef GNUNET_LOAD_LIB_H
28#define GNUNET_LOAD_LIB_H
29
30#ifdef __cplusplus
31extern "C"
32{
33#if 0 /* keep Emacsens' auto-indent happy */
34}
35#endif
36#endif
37
38#include "gnunet_common.h"
39#include "gnunet_time_lib.h"
40
41/**
42 * Opaque load handle.
43 */
44struct GNUNET_LOAD_Value;
45
46/**
47 * Create a new load value.
48 *
49 * @return the new load value
50 */
51struct GNUNET_LOAD_Value *
52GNUNET_LOAD_value_init (void);
53
54
55/**
56 * Free a load value.
57 *
58 * @param lv value to free
59 */
60#define GNUNET_LOAD_value_free(lv) GNUNET_free (lv)
61
62
63/**
64 * Get the current load.
65 *
66 * @param load load handle
67 * @return zero for below-average load, otherwise
68 * number of std. devs we are above average;
69 * 100 if the latest updates were so large
70 * that we could not do proper calculations
71 */
72double
73GNUNET_LOAD_get_load (const struct GNUNET_LOAD_Value *load);
74
75
76/**
77 * Get the average value given to update so far.
78 *
79 * @param load load handle
80 * @return zero if update was never called
81 */
82double
83GNUNET_LOAD_get_average (const struct GNUNET_LOAD_Value *load);
84
85
86/**
87 * Update the current load.
88 *
89 * @param load to update
90 * @param data latest measurement value (for example, delay)
91 */
92void
93GNUNET_LOAD_update (struct GNUNET_LOAD_Value *load,
94 uint64_t data);
95
96
97#if 0 /* keep Emacsens' auto-indent happy */
98{
99#endif
100#ifdef __cplusplus
101}
102#endif
103
104/* ifndef GNUNET_LOAD_LIB_H */
105#endif
106/* end of gnunet_load_lib.h */
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 611c56b61..784964b49 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -514,6 +514,11 @@ extern "C"
514 */ 514 */
515#define GNUNET_MESSAGE_TYPE_FS_PUT 138 515#define GNUNET_MESSAGE_TYPE_FS_PUT 138
516 516
517/**
518 * Peer asks us to stop migrating content towards it for a while.
519 */
520#define GNUNET_MESSAGE_TYPE_FS_MIGRATION_STOP 139
521
517 522
518/** 523/**
519 * DHT Message Types 524 * DHT Message Types
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 6d88537e5..2f7edd301 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -48,6 +48,7 @@ libgnunetutil_la_SOURCES = \
48 disk.h \ 48 disk.h \
49 getopt.c \ 49 getopt.c \
50 getopt_helpers.c \ 50 getopt_helpers.c \
51 load.c \
51 network.c \ 52 network.c \
52 os_installation.c \ 53 os_installation.c \
53 os_load.c \ 54 os_load.c \
diff --git a/src/util/load.c b/src/util/load.c
new file mode 100644
index 000000000..451aca295
--- /dev/null
+++ b/src/util/load.c
@@ -0,0 +1,176 @@
1/*
2 This file is part of GNUnet.
3 (C) 2010 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file util/load.c
23 * @brief functions related to load calculations
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_load_lib.h"
28
29#define DEBUG_LOAD GNUNET_NO
30
31/**
32 * Values we track for load calculations.
33 */
34struct GNUNET_LOAD_Value
35{
36
37 /**
38 * Sum of all datastore delays ever observed (in ms). Note that
39 * delays above 64k ms are excluded (to avoid overflow within
40 * first 4 billion requests).
41 */
42 uint64_t cummulative_delay;
43
44 /**
45 * Sum of squares of all datastore delays ever observed (in ms). Note that
46 * delays above 64k ms are excluded (to avoid overflow within
47 * first 4 billion requests).
48 */
49 uint64_t cummulative_squared_delay;
50
51 /**
52 * Total number of requests included in the cummulative datastore delay values.
53 */
54 uint64_t cummulative_request_count;
55
56 /**
57 * Current running average datastore delay. Its relation to the
58 * average datastore delay and it std. dev. (as calcualted from the
59 * cummulative values) tells us our current load.
60 */
61 double runavg_delay;
62
63 /**
64 * How high is the load? 0 for below average, otherwise
65 * the number of std. devs we are above average, or 100 if the
66 * load is so high that we currently cannot calculate it.
67 */
68 double load;
69
70};
71
72
73/**
74 * Create a new load value.
75 *
76 * @return the new load value
77 */
78struct GNUNET_LOAD_Value *
79GNUNET_LOAD_value_init ()
80{
81 return GNUNET_malloc (sizeof (struct GNUNET_LOAD_Value));
82}
83
84
85/**
86 * Get the current load.
87 *
88 * @param load load handle
89 * @return zero for below-average load, otherwise
90 * number of std. devs we are above average;
91 * 100 if the latest updates were so large
92 * that we could not do proper calculations
93 */
94double
95GNUNET_LOAD_get_load (const struct GNUNET_LOAD_Value *load)
96{
97 return load->load;
98}
99
100
101/**
102 * Get the average value given to update so far.
103 *
104 * @param load load handle
105 * @return zero if update was never called
106 */
107double
108GNUNET_LOAD_get_average (const struct GNUNET_LOAD_Value *load)
109{
110 double n;
111 double avg;
112 double sum_val_i;
113
114 if (load->cummulative_request_count == 0)
115 return 0.0;
116 n = ((double) load->cummulative_request_count);
117 sum_val_i = (double) load->cummulative_delay;
118 return sum_val_i / n;
119}
120
121
122/**
123 * Update the current load.
124 *
125 * @param load to update
126 * @param data latest measurement value (for example, delay)
127 */
128void
129GNUNET_LOAD_update (struct GNUNET_LOAD_Value *load,
130 uint64_t data)
131{
132 uint32_t dv;
133 double stddev;
134 double avgdel;
135 double sum_val_i;
136 double n;
137 double nm1;
138
139 if (data > 64 * 1024)
140 {
141 /* very large */
142 load->load = 100.0;
143 return;
144 }
145 dv = (uint32_t) data;
146 load->cummulative_delay += dv;
147 load->cummulative_squared_delay += dv * dv;
148 load->cummulative_request_count++;
149 load->runavg_delay = ((load->runavg_delay * 7.0) + dv) / 8.0;
150 if (load->cummulative_request_count > 1)
151 {
152 /* calcuate std dev of latency; we have for n values of "i" that:
153
154 avg = (sum val_i) / n
155 stddev = (sum (val_i - avg)^2) / (n-1)
156 = (sum (val_i^2 - 2 avg val_i + avg^2) / (n-1)
157 = (sum (val_i^2) - 2 avg sum (val_i) + n * avg^2) / (n-1)
158 */
159 sum_val_i = (double) load->cummulative_delay;
160 n = ((double) load->cummulative_request_count);
161 nm1 = n - 1.0;
162 avgdel = sum_val_i / n;
163 stddev = (((double) load->cummulative_squared_delay) - 2.0 * avgdel * sum_val_i + n * avgdel * avgdel) / nm1;
164 if (stddev <= 0)
165 stddev = 0.01; /* must have been rounding error or zero; prevent division by zero */
166 /* now calculate load based on how far out we are from
167 std dev; or if we are below average, simply assume load zero */
168 if (load->runavg_delay < avgdel)
169 load->load = 0.0;
170 else
171 load->load = (load->runavg_delay - avgdel) / stddev;
172 }
173}
174
175
176/* end of load.c */