aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-dht_datacache.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-09-25 22:16:20 +0000
committerChristian Grothoff <christian@grothoff.org>2011-09-25 22:16:20 +0000
commit858f4546a0044b3ea9abdfbe6dda2e95d7c04dc1 (patch)
treeb0f0c65692214a9cf4c24f4bc1e03ec41247cfa6 /src/dht/gnunet-service-dht_datacache.c
parent1990307349dce4eda6b576097d516b9e0342d98d (diff)
downloadgnunet-858f4546a0044b3ea9abdfbe6dda2e95d7c04dc1.tar.gz
gnunet-858f4546a0044b3ea9abdfbe6dda2e95d7c04dc1.zip
wild hxing
Diffstat (limited to 'src/dht/gnunet-service-dht_datacache.c')
-rw-r--r--src/dht/gnunet-service-dht_datacache.c315
1 files changed, 315 insertions, 0 deletions
diff --git a/src/dht/gnunet-service-dht_datacache.c b/src/dht/gnunet-service-dht_datacache.c
new file mode 100644
index 000000000..b2dd05ac9
--- /dev/null
+++ b/src/dht/gnunet-service-dht_datacache.c
@@ -0,0 +1,315 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009, 2010, 2011 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 dht/gnunet-service-dht_datacache.c
23 * @brief GNUnet DHT service's datacache integration
24 * @author Christian Grothoff
25 * @author Nathan Evans
26 */
27#include "gnunet-service-dht_datacache.h"
28
29
30/**
31 * Handle to the datacache service (for inserting/retrieving data)
32 */
33static struct GNUNET_DATACACHE_Handle *datacache;
34
35
36/**
37 * Entry for inserting data into datacache from the DHT.
38 */
39struct DHTPutEntry
40{
41 /**
42 * Size of data.
43 */
44 uint16_t data_size;
45
46 /**
47 * Length of recorded path.
48 */
49 uint16_t path_length;
50
51 /* PATH ENTRIES */
52
53 /* PUT DATA */
54
55};
56
57
58/**
59 * Handle a datum we've received from another peer. Cache if
60 * possible.
61 *
62 * @param expiration when will the reply expire
63 * @param key the query this reply is for
64 * @param put_path_length number of peers in 'put_path'
65 * @param put_path path the reply took on put
66 * @param type type of the reply
67 * @param data_size number of bytes in 'data'
68 * @param data application payload data
69 */
70void
71GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
72 const GNUNET_HashCode *key,
73 unsigned int put_path_length,
74 const struct GNUNET_PeerIdentity *put_path,
75 uint32_t type,
76 size_t data_size,
77 const void *data)
78{
79 size_t plen = data_size + put_path_length * sizeof(struct GNUNET_PeerIdentity) + sizeof(struct DHTPutEntry);
80 char buf[plen];
81 struct DHTPutEntry *pe;
82 struct GNUNET_PeerIdentity *pp;
83 char *path_offset;
84
85 if (datacache == NULL)
86 {
87 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
88 "%s request received, but have no datacache!\n",
89 "PUT");
90 return;
91 }
92 if (data_size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
93 {
94 GNUNET_break (0);
95 return;
96 }
97 /* Put size is actual data size plus struct overhead plus path length (if any) */
98 pe = (struct DHTPutEntry *) buf;
99 pe->data_size = htons (data_size);
100 pe->path_length = htons ((uint16_t) put_path_length);
101 pp = (struct GNUNET_PeerIdentity *) &pe[1];
102 memcpy (pp, put_path, put_path_length * sizeof (struct GNUNET_PeerIdentity));
103 memcpy (&pp[put_path_length],
104 data, data_size);
105 (void) GNUNET_DATACACHE_put (datacache, key,
106 plen, (const char *) pe, type,
107 expiration);
108}
109
110
111/**
112 * Context containing information about a GET request.
113 */
114struct GetRequestContext
115{
116 /**
117 * extended query (see gnunet_block_lib.h).
118 */
119 const void *xquery;
120
121 /**
122 * Bloomfilter to filter out duplicate replies (updated)
123 */
124 struct GNUNET_CONTAINER_BloomFilter **reply_bf;
125
126 /**
127 * The key this request was about
128 */
129 GNUNET_HashCode key;
130
131 /**
132 * Number of bytes in xquery.
133 */
134 size_t xquery_size;
135
136 /**
137 * Mutator value for the reply_bf, see gnunet_block_lib.h
138 */
139 uint32_t reply_bf_mutator;
140
141};
142
143
144/**
145 * Iterator for local get request results,
146 *
147 * @param cls closure for iterator, a DatacacheGetContext
148 * @param exp when does this value expire?
149 * @param key the key this data is stored under
150 * @param size the size of the data identified by key
151 * @param data the actual data
152 * @param type the type of the data
153 *
154 * @return GNUNET_OK to continue iteration, anything else
155 * to stop iteration.
156 */
157static int
158datacache_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp,
159 const GNUNET_HashCode * key, size_t size,
160 const char *data, enum GNUNET_BLOCK_Type type)
161{
162 struct GetRequestContext *ctx = cls;
163 const struct DHTPutEntry *pe;
164 const struct GNUNET_PeerIdentity *pp;
165 const char *data;
166 size_t data_size;
167 uint16_t put_path_length;
168 enum GNUNET_BLOCK_EvaluationResult eval;
169
170 pe = (const struct DHTPutEntry *) data;
171 put_path_length = ntohs (pe->path_length);
172 data_size = ntohs (pe->data_size);
173
174 if (size !=
175 sizeof (struct DHTPutEntry) + data_size +
176 (put_path_length * sizeof (struct GNUNET_PeerIdentity)))
177 {
178 GNUNET_break (0);
179 return GNUNET_OK;
180 }
181 pp = (const struct GNUNET_PeerIdentity *) &pe[1];
182 data = (const char*) &pp[put_path_length];
183 eval =
184 GNUNET_BLOCK_evaluate (block_context, type, key,
185 ctx->reply_bf,
186 ctx->reply_bf_mutator,
187 ctx->xquery,
188 ctx->xquery_size,
189 data,
190 data_size);
191 switch (eval)
192 {
193 case GNUNET_BLOCK_EVALUATION_OK_LAST:
194 case GNUNET_BLOCK_EVALUATION_OK_MORE:
195 /* forward to local clients */
196 GDS_CLIENT_handle_reply (exp,
197 key,
198 0, NULL,
199 put_path_length, pp,
200 type, data_size, data);
201 /* forward to other peers */
202 GDS_NEIGHBOURS_handle_reply (type, exp,
203 key, put_path_length, pp,
204 0, NULL, data, data_size);
205 break;
206 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
207 break;
208 case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
209 break;
210 case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
211 GNUNET_break (0);
212 break;
213 case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
214 GNUNET_break_op (0);
215 return GNUNET_SYSERR;
216 case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
217 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
218 "Unsupported block type (%u) in local response!\n",
219 type);
220 break;
221 }
222 return GNUNET_OK;
223}
224
225
226/**
227 * Context containing information about a GET request.
228 */
229struct GetRequestContext
230{
231 /**
232 * extended query (see gnunet_block_lib.h).
233 */
234 const void *xquery;
235
236 /**
237 * Bloomfilter to filter out duplicate replies (updated)
238 */
239 struct GNUNET_CONTAINER_BloomFilter **reply_bf;
240
241 /**
242 * The key this request was about
243 */
244 GNUNET_HashCode key;
245
246 /**
247 * Number of bytes in xquery.
248 */
249 size_t xquery_size;
250
251 /**
252 * Mutator value for the reply_bf, see gnunet_block_lib.h
253 */
254 uint32_t reply_bf_mutator;
255
256};
257
258
259/**
260 * Handle a GET request we've received from another peer.
261 *
262 * @param key the query
263 * @param type requested data type
264 * @param xquery extended query
265 * @param xquery_size number of bytes in xquery
266 * @param reply_bf where the reply bf is (to be) stored, possibly updated, can be NULL
267 * @param reply_bf_mutator mutation value for reply_bf
268 */
269void
270GDS_DATACACHE_handle_get (const GNUNET_HashCode *key,
271 uint32_t type,
272 const void *xquery,
273 size_t xquery_size,
274 struct GNUNET_CONTAINER_BloomFilter **reply_bf,
275 uint32_t reply_bf_mutator)
276{
277 struct GetRequestContext ctx;
278
279 if (datacache == NULL)
280 return;
281 ctx.key = *key;
282 ctx.xquery = xquery;
283 ctx.xquery_size = xquery_size;
284 ctx.reply_bf = reply_bf;
285 ctx.reply_bf_mutator = reply_bf_mutator;
286 (void) GNUNET_DATACACHE_get (datacache, &msg_ctx->key, type,
287 &datacache_get_iterator, &ctx);
288}
289
290
291/**
292 * Initialize datacache subsystem.
293 */
294void
295GDS_DATACACHE_init ()
296{
297 datacache = GNUNET_DATACACHE_create (cfg, "dhtcache");
298}
299
300
301/**
302 * Shutdown datacache subsystem.
303 */
304void
305GDS_DATACACHE_done ()
306{
307 if (datacache != NULL)
308 {
309 GNUNET_DATACACHE_destroy (datacache);
310 datacache = NULL;
311 }
312}
313
314
315/* end of gnunet-service-dht_datacache.c */