aboutsummaryrefslogtreecommitdiff
path: root/src/dht/plugin_block_dht.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dht/plugin_block_dht.c')
-rw-r--r--src/dht/plugin_block_dht.c181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/dht/plugin_block_dht.c b/src/dht/plugin_block_dht.c
new file mode 100644
index 000000000..f574e6d06
--- /dev/null
+++ b/src/dht/plugin_block_dht.c
@@ -0,0 +1,181 @@
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_constants.h"
31#include "gnunet_hello_lib.h"
32#include "gnunet_block_plugin.h"
33
34#define DEBUG_DHT GNUNET_EXTRA_LOGGING
35
36
37/**
38 * Function called to validate a reply or a request. For
39 * request evaluation, simply pass "NULL" for the reply_block.
40 *
41 * @param cls closure
42 * @param type block type
43 * @param query original query (hash)
44 * @param bf pointer to bloom filter associated with query; possibly updated (!)
45 * @param bf_mutator mutation value for bf
46 * @param xquery extended query data (can be NULL, depending on type)
47 * @param xquery_size number of bytes in xquery
48 * @param reply_block response to validate
49 * @param reply_block_size number of bytes in reply block
50 * @return characterization of result
51 */
52static enum GNUNET_BLOCK_EvaluationResult
53block_plugin_dht_evaluate (void *cls, enum GNUNET_BLOCK_Type type,
54 const GNUNET_HashCode * query,
55 struct GNUNET_CONTAINER_BloomFilter **bf,
56 int32_t bf_mutator, const void *xquery,
57 size_t xquery_size, const void *reply_block,
58 size_t reply_block_size)
59{
60 GNUNET_HashCode mhash;
61 const struct GNUNET_HELLO_Message *hello;
62 struct GNUNET_PeerIdentity pid;
63 const struct GNUNET_MessageHeader *msg;
64
65 if (type != GNUNET_BLOCK_TYPE_DHT_HELLO)
66 return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED;
67 if (xquery_size != 0)
68 return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID;
69 if (reply_block_size == 0)
70 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
71 if (reply_block_size < sizeof (struct GNUNET_MessageHeader))
72 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
73 msg = reply_block;
74 if (reply_block_size != ntohs (msg->size))
75 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
76 hello = reply_block;
77 if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &pid))
78 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
79 if (NULL != bf)
80 {
81 GNUNET_BLOCK_mingle_hash (&pid.hashPubKey, bf_mutator, &mhash);
82 if (NULL != *bf)
83 {
84 if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (*bf, &mhash))
85 return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE;
86 }
87 else
88 {
89 *bf =
90 GNUNET_CONTAINER_bloomfilter_init (NULL, 8,
91 GNUNET_CONSTANTS_BLOOMFILTER_K);
92 }
93 GNUNET_CONTAINER_bloomfilter_add (*bf, &mhash);
94 }
95 return GNUNET_BLOCK_EVALUATION_OK_MORE;
96}
97
98
99/**
100 * Function called to obtain the key for a block.
101 *
102 * @param cls closure
103 * @param type block type
104 * @param block block to get the key for
105 * @param block_size number of bytes in block
106 * @param key set to the key (query) for the given block
107 * @return GNUNET_OK on success, GNUNET_SYSERR if type not supported
108 * (or if extracting a key from a block of this type does not work)
109 */
110static int
111block_plugin_dht_get_key (void *cls, enum GNUNET_BLOCK_Type type,
112 const void *block, size_t block_size,
113 GNUNET_HashCode * key)
114{
115 const struct GNUNET_MessageHeader *msg;
116 const struct GNUNET_HELLO_Message *hello;
117 struct GNUNET_PeerIdentity *pid;
118
119 if (type != GNUNET_BLOCK_TYPE_DHT_HELLO)
120 return GNUNET_SYSERR;
121 if (block_size < sizeof (struct GNUNET_MessageHeader))
122 {
123 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "block-dht",
124 _("Block not of type %u\n"), GNUNET_BLOCK_TYPE_DHT_HELLO);
125 return GNUNET_NO;
126 }
127 msg = block;
128 if (block_size != ntohs (msg->size))
129 {
130 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "block-dht",
131 _("Size mismatch for block\n"),
132 GNUNET_BLOCK_TYPE_DHT_HELLO);
133 return GNUNET_NO;
134 }
135 hello = block;
136 pid = (struct GNUNET_PeerIdentity *) key;
137 if (GNUNET_OK != GNUNET_HELLO_get_id (hello, pid))
138 {
139 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "block-dht",
140 _("Block of type %u is malformed\n"),
141 GNUNET_BLOCK_TYPE_DHT_HELLO);
142 return GNUNET_NO;
143 }
144 return GNUNET_OK;
145}
146
147
148/**
149 * Entry point for the plugin.
150 */
151void *
152libgnunet_plugin_block_dht_init (void *cls)
153{
154 static enum GNUNET_BLOCK_Type types[] =
155 {
156 GNUNET_BLOCK_TYPE_DHT_HELLO,
157 GNUNET_BLOCK_TYPE_ANY /* end of list */
158 };
159 struct GNUNET_BLOCK_PluginFunctions *api;
160
161 api = GNUNET_malloc (sizeof (struct GNUNET_BLOCK_PluginFunctions));
162 api->evaluate = &block_plugin_dht_evaluate;
163 api->get_key = &block_plugin_dht_get_key;
164 api->types = types;
165 return api;
166}
167
168
169/**
170 * Exit point from the plugin.
171 */
172void *
173libgnunet_plugin_block_dht_done (void *cls)
174{
175 struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
176
177 GNUNET_free (api);
178 return NULL;
179}
180
181/* end of plugin_block_dht.c */