aboutsummaryrefslogtreecommitdiff
path: root/src/namestore
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2015-08-11 14:41:03 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2015-08-11 14:41:03 +0000
commit7fe8782a2beffafb0fa3fadae43d4498335f4472 (patch)
tree1d5982382d50b31e3434f74df1c61fae9d8bb573 /src/namestore
parent7226997d96e7c2724d912553d1c7e613ee4cdd04 (diff)
downloadgnunet-7fe8782a2beffafb0fa3fadae43d4498335f4472.tar.gz
gnunet-7fe8782a2beffafb0fa3fadae43d4498335f4472.zip
- flat namestore plugin (experimental)
Diffstat (limited to 'src/namestore')
-rw-r--r--src/namestore/Makefile.am27
-rw-r--r--src/namestore/plugin_namestore_flat.c673
-rw-r--r--src/namestore/test_plugin_namestore.c4
-rw-r--r--src/namestore/test_plugin_namestore_flat.conf2
4 files changed, 704 insertions, 2 deletions
diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am
index 2f8c81425..221e88a91 100644
--- a/src/namestore/Makefile.am
+++ b/src/namestore/Makefile.am
@@ -20,6 +20,13 @@ if USE_COVERAGE
20 XLIBS = -lgcov 20 XLIBS = -lgcov
21endif 21endif
22 22
23if HAVE_EXPERIMENTAL
24FLAT_PLUGIN = libgnunet_plugin_namestore_flat.la
25if HAVE_TESTING
26FLAT_TESTS = test_plugin_namestore_flat
27endif
28endif
29
23if HAVE_SQLITE 30if HAVE_SQLITE
24SQLITE_PLUGIN = libgnunet_plugin_namestore_sqlite.la 31SQLITE_PLUGIN = libgnunet_plugin_namestore_sqlite.la
25if HAVE_TESTING 32if HAVE_TESTING
@@ -60,6 +67,7 @@ if HAVE_SQLITE
60check_PROGRAMS = \ 67check_PROGRAMS = \
61 $(SQLITE_TESTS) \ 68 $(SQLITE_TESTS) \
62 $(POSTGRES_TESTS) \ 69 $(POSTGRES_TESTS) \
70 $(FLAT_TESTS) \
63 $(TESTING_TESTS) 71 $(TESTING_TESTS)
64endif 72endif
65 73
@@ -150,8 +158,20 @@ gnunet_service_namestore_LDADD = \
150plugin_LTLIBRARIES = \ 158plugin_LTLIBRARIES = \
151 $(SQLITE_PLUGIN) \ 159 $(SQLITE_PLUGIN) \
152 $(POSTGRES_PLUGIN) \ 160 $(POSTGRES_PLUGIN) \
161 $(FLAT_PLUGIN) \
153 $(REST_PLUGIN) 162 $(REST_PLUGIN)
154 163
164libgnunet_plugin_namestore_flat_la_SOURCES = \
165 plugin_namestore_flat.c
166libgnunet_plugin_namestore_flat_la_LIBADD = \
167 $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
168 $(top_builddir)/src/statistics/libgnunetstatistics.la \
169 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
170 $(LTLIBINTL)
171libgnunet_plugin_namestore_flat_la_LDFLAGS = \
172 $(GN_PLUGIN_LDFLAGS)
173
174
155libgnunet_plugin_namestore_sqlite_la_SOURCES = \ 175libgnunet_plugin_namestore_sqlite_la_SOURCES = \
156 plugin_namestore_sqlite.c 176 plugin_namestore_sqlite.c
157libgnunet_plugin_namestore_sqlite_la_LIBADD = \ 177libgnunet_plugin_namestore_sqlite_la_LIBADD = \
@@ -307,6 +327,12 @@ test_namestore_api_zone_iteration_stop_LDADD = \
307 $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ 327 $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
308 libgnunetnamestore.la 328 libgnunetnamestore.la
309 329
330test_plugin_namestore_flat_SOURCES = \
331 test_plugin_namestore.c
332test_plugin_namestore_flat_LDADD = \
333 $(top_builddir)/src/testing/libgnunettesting.la \
334 $(top_builddir)/src/util/libgnunetutil.la
335
310test_plugin_namestore_sqlite_SOURCES = \ 336test_plugin_namestore_sqlite_SOURCES = \
311 test_plugin_namestore.c 337 test_plugin_namestore.c
312test_plugin_namestore_sqlite_LDADD = \ 338test_plugin_namestore_sqlite_LDADD = \
@@ -328,6 +354,7 @@ EXTRA_DIST = \
328 test_namestore_api.conf \ 354 test_namestore_api.conf \
329 test_plugin_namestore_sqlite.conf \ 355 test_plugin_namestore_sqlite.conf \
330 test_plugin_namestore_postgres.conf \ 356 test_plugin_namestore_postgres.conf \
357 test_plugin_namestore_flat.conf \
331 test_hostkey \ 358 test_hostkey \
332 zonefiles/S5I9DSGQVAB5FVV16T3B3CC5H1B2JGL3Q412JBKURME8EKU0600G.zkey \ 359 zonefiles/S5I9DSGQVAB5FVV16T3B3CC5H1B2JGL3Q412JBKURME8EKU0600G.zkey \
333 zonefiles/AQ835GVL939H4O8QJQ7GBLPTQC0QAAO91BN7QK01BA63MDSK6I4G.zkey \ 360 zonefiles/AQ835GVL939H4O8QJQ7GBLPTQC0QAAO91BN7QK01BA63MDSK6I4G.zkey \
diff --git a/src/namestore/plugin_namestore_flat.c b/src/namestore/plugin_namestore_flat.c
new file mode 100644
index 000000000..b2fd70d92
--- /dev/null
+++ b/src/namestore/plugin_namestore_flat.c
@@ -0,0 +1,673 @@
1 /*
2 * This file is part of GNUnet
3 * Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21/**
22 * @file namestore/plugin_namestore_flat.c
23 * @brief file-based namestore backend
24 * @author Martin Schanzenbach
25 */
26
27#include "platform.h"
28#include "gnunet_namestore_plugin.h"
29#include "gnunet_namestore_service.h"
30#include "gnunet_gnsrecord_lib.h"
31#include "namestore.h"
32
33/**
34 * Context for all functions in this plugin.
35 */
36struct Plugin
37{
38
39 const struct GNUNET_CONFIGURATION_Handle *cfg;
40
41 /**
42 * Database filename.
43 */
44 char *fn;
45
46 /**
47 * HashMap
48 */
49 struct GNUNET_CONTAINER_MultiHashMap *hm;
50
51 /**
52 * Offset
53 */
54 uint32_t offset;
55
56 /**
57 * Target Offset
58 */
59 uint32_t target_offset;
60
61 /**
62 * Iterator closure
63 */
64 void *iter_cls;
65
66 /**
67 * Iterator
68 */
69 GNUNET_NAMESTORE_RecordIterator iter;
70
71 /**
72 * Zone to iterate
73 */
74 const struct GNUNET_CRYPTO_EcdsaPrivateKey *iter_zone;
75
76 /**
77 * PKEY to look for in zone to name
78 */
79 struct GNUNET_CRYPTO_EcdsaPublicKey *iter_pkey;
80
81 /**
82 * Iteration result found
83 */
84 int iter_result_found;
85
86};
87
88struct FlatFileEntry
89{
90 /**
91 * Entry zone
92 */
93 struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key;
94
95 /**
96 * Entry zone pkey
97 */
98 struct GNUNET_CRYPTO_EcdsaPublicKey *pkey;
99
100 /**
101 * Record cound
102 */
103 uint32_t record_count;
104
105 /**
106 * Rvalue
107 */
108 uint64_t rvalue;
109
110 /**
111 * Record data
112 */
113 struct GNUNET_GNSRECORD_Data *record_data;
114
115 /**
116 * Label
117 */
118 char *label;
119
120
121};
122
123
124/**
125 * Initialize the database connections and associated
126 * data structures (create tables and indices
127 * as needed as well).
128 *
129 * @param plugin the plugin context (state for this module)
130 * @return #GNUNET_OK on success
131 */
132static int
133database_setup (struct Plugin *plugin)
134{
135 char *afsdir;
136 char *key_str;
137 char *record_data;
138 char *zone_private_key;
139 char *pkey;
140 char *record_data_b64;
141 char *buffer;
142 char *line;
143 char *label;
144 char *rvalue;
145 char *record_count;
146 size_t record_data_size;
147 size_t size;
148 struct GNUNET_HashCode hkey;
149 struct GNUNET_DISK_FileHandle *fh;
150 struct FlatFileEntry *entry;
151
152 if (GNUNET_OK !=
153 GNUNET_CONFIGURATION_get_value_filename (plugin->cfg,
154 "namestore-flat",
155 "FILENAME", &afsdir))
156 {
157 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
158 "namestore-flat", "FILENAME");
159 return GNUNET_SYSERR;
160 }
161 if (GNUNET_OK != GNUNET_DISK_file_test (afsdir))
162 {
163 if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir))
164 {
165 GNUNET_break (0);
166 GNUNET_free (afsdir);
167 return GNUNET_SYSERR;
168 }
169 }
170 /* afsdir should be UTF-8-encoded. If it isn't, it's a bug */
171 plugin->fn = afsdir;
172
173 /* Load data from file into hashmap */
174 plugin->hm = GNUNET_CONTAINER_multihashmap_create (10,
175 GNUNET_NO);
176 fh = GNUNET_DISK_file_open (afsdir,
177 GNUNET_DISK_OPEN_CREATE,
178 GNUNET_DISK_PERM_USER_WRITE |
179 GNUNET_DISK_PERM_USER_READ);
180 if (NULL == fh)
181 {
182 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
183 _("Unable to initialize file: %s.\n"),
184 afsdir);
185 return GNUNET_SYSERR;
186 }
187
188 if (GNUNET_SYSERR == GNUNET_DISK_file_size (afsdir,
189 &size,
190 GNUNET_YES,
191 GNUNET_YES))
192 {
193 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
194 _("Unable to get filesize: %s.\n"),
195 afsdir);
196 return GNUNET_SYSERR;
197 }
198
199 buffer = GNUNET_malloc (size);
200
201 if (GNUNET_SYSERR == GNUNET_DISK_file_read (fh,
202 buffer,
203 size))
204 {
205 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
206 _("Unable to read file: %s.\n"),
207 afsdir);
208 return GNUNET_SYSERR;
209 }
210
211 GNUNET_DISK_file_close (fh);
212
213 line = strtok ("\n", buffer);
214 while (line != NULL) {
215 zone_private_key = strtok (",", line);
216 pkey = strtok (NULL, line);
217 rvalue = strtok (NULL, line);
218 record_count = strtok (NULL, line);
219 record_data_b64 = strtok (NULL, line);
220 label = strtok (NULL, line);
221 line = strtok ("\n", buffer);
222 entry = GNUNET_malloc (sizeof (struct FlatFileEntry));
223 GNUNET_CRYPTO_ecdsa_public_key_from_string (pkey,
224 strlen (pkey),
225 entry->pkey);
226 sscanf (rvalue, "%lu", &entry->rvalue);
227 sscanf (record_count, "%u", &entry->record_count);
228 entry->label = GNUNET_strdup (label);
229 record_data_size = GNUNET_STRINGS_base64_decode (record_data_b64,
230 strlen (record_data_b64),
231 &record_data);
232 entry->record_data =
233 GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Data) * entry->record_count);
234 GNUNET_GNSRECORD_records_deserialize (record_data_size,
235 record_data,
236 entry->record_count,
237 entry->record_data);
238 GNUNET_free (record_data);
239 GNUNET_STRINGS_base64_decode (zone_private_key,
240 strlen (zone_private_key),
241 (char**)&entry->private_key);
242 key_str = GNUNET_malloc (strlen (label) + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
243 memcpy (key_str, label, strlen (label));
244 memcpy (key_str+strlen(label),
245 entry->private_key,
246 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
247 GNUNET_CRYPTO_hash (key_str,
248 strlen (key_str),
249 &hkey);
250 GNUNET_free (key_str);
251 if (GNUNET_OK !=
252 GNUNET_CONTAINER_multihashmap_put (plugin->hm,
253 &hkey,
254 entry,
255 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
256 {
257 GNUNET_free (entry);
258 GNUNET_break (0);
259 }
260 }
261 GNUNET_free (buffer);
262 return GNUNET_OK;
263}
264
265
266/**
267 * Store values in hashmap in file and free data
268 *
269 * @param plugin the plugin context
270 */
271static int
272store_and_free_entries (void *cls,
273 const struct GNUNET_HashCode *key,
274 void *value)
275{
276 struct GNUNET_DISK_FileHandle *fh = cls;
277 struct FlatFileEntry *entry = value;
278 char *line;
279 char *zone_private_key;
280 char *pkey;
281 char *rvalue;
282 char *record_count;
283 char *record_data_buf;
284 char *record_data_b64;
285 size_t record_data_len;
286
287 GNUNET_STRINGS_base64_encode ((char*)entry->private_key,
288 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey),
289 &zone_private_key);
290 pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (entry->pkey);
291 GNUNET_asprintf (&rvalue, "%hhu", entry->rvalue);
292 GNUNET_asprintf (&record_count, "%u", entry->record_count);
293
294 record_data_len = GNUNET_GNSRECORD_records_get_size (entry->record_count,
295 entry->record_data);
296
297 record_data_buf = GNUNET_malloc (record_data_len);
298 GNUNET_GNSRECORD_records_serialize (entry->record_count,
299 entry->record_data,
300 record_data_len,
301 record_data_buf);
302
303 GNUNET_STRINGS_base64_encode (record_data_buf,
304 strlen (record_data_buf),
305 &record_data_b64);
306
307 GNUNET_asprintf (&line,
308 "%s.%s.%s.%s.%s.%s\n",
309 zone_private_key,
310 pkey,
311 rvalue,
312 record_count,
313 record_data_b64,
314 entry->label);
315
316 GNUNET_free (rvalue);
317 GNUNET_free (record_count);
318 GNUNET_free (record_data_buf);
319 GNUNET_free (record_data_b64);
320
321 GNUNET_DISK_file_write (fh,
322 line,
323 strlen (line));
324
325 GNUNET_free (entry->private_key);
326 GNUNET_free (entry->pkey);
327 GNUNET_free (entry->label);
328 GNUNET_free (entry->record_data);
329 GNUNET_free (entry);
330 return GNUNET_YES;
331}
332
333/**
334 * Shutdown database connection and associate data
335 * structures.
336 * @param plugin the plugin context (state for this module)
337 */
338static void
339database_shutdown (struct Plugin *plugin)
340{
341 struct GNUNET_DISK_FileHandle *fh;
342 fh = GNUNET_DISK_file_open (plugin->fn,
343 GNUNET_DISK_OPEN_CREATE |
344 GNUNET_DISK_OPEN_TRUNCATE,
345 GNUNET_DISK_PERM_USER_WRITE |
346 GNUNET_DISK_PERM_USER_READ);
347 if (NULL == fh)
348 {
349 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
350 _("Unable to initialize file: %s.\n"),
351 plugin->fn);
352 return;
353 }
354
355 GNUNET_CONTAINER_multihashmap_iterate (plugin->hm,
356 &store_and_free_entries,
357 fh);
358 GNUNET_CONTAINER_multihashmap_destroy (plugin->hm);
359 GNUNET_DISK_file_close (fh);
360}
361
362
363/**
364 * Store a record in the datastore. Removes any existing record in the
365 * same zone with the same name.
366 *
367 * @param cls closure (internal context for the plugin)
368 * @param zone_key private key of the zone
369 * @param label name that is being mapped (at most 255 characters long)
370 * @param rd_count number of entries in @a rd array
371 * @param rd array of records with data to store
372 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
373 */
374static int
375namestore_store_records (void *cls,
376 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
377 const char *label,
378 unsigned int rd_count,
379 const struct GNUNET_GNSRECORD_Data *rd)
380{
381 struct Plugin *plugin = cls;
382 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
383 uint64_t rvalue;
384 size_t data_size;
385 unsigned int i;
386 char *key_str;
387 struct GNUNET_HashCode hkey;
388 struct FlatFileEntry *entry;
389
390 memset (&pkey, 0, sizeof (pkey));
391 for (i=0;i<rd_count;i++)
392 if (GNUNET_GNSRECORD_TYPE_PKEY == rd[i].record_type)
393 {
394 GNUNET_break (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) == rd[i].data_size);
395 memcpy (&pkey,
396 rd[i].data,
397 rd[i].data_size);
398 break;
399 }
400 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
401 data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
402 if (data_size > 64 * 65536)
403 {
404 GNUNET_break (0);
405 return GNUNET_SYSERR;
406 }
407 char data[data_size];
408
409 if (data_size != GNUNET_GNSRECORD_records_serialize (rd_count, rd,
410 data_size, data))
411 {
412 GNUNET_break (0);
413 return GNUNET_SYSERR;
414 }
415
416 key_str = GNUNET_malloc (strlen (label) + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
417 memcpy (key_str, label, strlen (label));
418 memcpy (key_str+strlen(label),
419 zone_key,
420 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
421 GNUNET_CRYPTO_hash (key_str,
422 strlen (key_str),
423 &hkey);
424
425 GNUNET_CONTAINER_multihashmap_remove_all (plugin->hm, &hkey);
426
427 if (0 != rd_count)
428 {
429 entry = GNUNET_malloc (sizeof (struct FlatFileEntry));
430 entry->private_key = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
431 memcpy (&entry->private_key,
432 zone_key,
433 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
434 entry->pkey = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
435 memcpy (entry->pkey,
436 &pkey,
437 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
438 entry->rvalue = rvalue;
439 entry->record_count = rd_count;
440 entry->record_data = GNUNET_malloc (data_size);
441 memcpy (&entry->record_data, data, data_size);
442 return GNUNET_CONTAINER_multihashmap_put (plugin->hm,
443 &hkey,
444 entry,
445 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
446 }
447 return GNUNET_NO;
448}
449
450
451/**
452 * Lookup records in the datastore for which we are the authority.
453 *
454 * @param cls closure (internal context for the plugin)
455 * @param zone private key of the zone
456 * @param label name of the record in the zone
457 * @param iter function to call with the result
458 * @param iter_cls closure for @a iter
459 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
460 */
461static int
462namestore_lookup_records (void *cls,
463 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
464 const char *label,
465 GNUNET_NAMESTORE_RecordIterator iter,
466 void *iter_cls)
467{
468 struct Plugin *plugin = cls;
469 struct FlatFileEntry *entry;
470 struct GNUNET_HashCode hkey;
471 char *key_str;
472
473 if (NULL == zone)
474 {
475 return GNUNET_SYSERR;
476 }
477 key_str = GNUNET_malloc (strlen (label) + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
478 memcpy (key_str, label, strlen (label));
479 memcpy (key_str+strlen(label),
480 zone,
481 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
482 GNUNET_CRYPTO_hash (key_str,
483 strlen (key_str),
484 &hkey);
485 GNUNET_free (key_str);
486
487 entry = GNUNET_CONTAINER_multihashmap_get (plugin->hm, &hkey);
488
489 if (NULL == entry)
490 return GNUNET_NO;
491 if (NULL != iter)
492 iter (iter_cls, entry->private_key, entry->label, entry->record_count, entry->record_data);
493 return GNUNET_YES;
494}
495
496
497static int
498iterate_zones (void *cls,
499 const struct GNUNET_HashCode *key,
500 void *value)
501{
502 struct Plugin *plugin = cls;
503 struct FlatFileEntry *entry = value;
504
505
506 if ((plugin->target_offset > plugin->offset) ||
507 (0 != memcmp (entry->private_key,
508 plugin->iter_zone,
509 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)))) {
510 plugin->offset++;
511 return GNUNET_YES;
512 }
513
514 plugin->iter (plugin->iter_cls,
515 entry->private_key,
516 entry->label,
517 entry->record_count,
518 entry->record_data);
519 plugin->iter_result_found = GNUNET_YES;
520 return GNUNET_NO;
521}
522
523/**
524 * Iterate over the results for a particular key and zone in the
525 * datastore. Will return at most one result to the iterator.
526 *
527 * @param cls closure (internal context for the plugin)
528 * @param zone hash of public key of the zone, NULL to iterate over all zones
529 * @param offset offset in the list of all matching records
530 * @param iter function to call with the result
531 * @param iter_cls closure for @a iter
532 * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
533 */
534static int
535namestore_iterate_records (void *cls,
536 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
537 uint64_t offset,
538 GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
539{
540 struct Plugin *plugin = cls;
541 plugin->target_offset = offset;
542 plugin->offset = 0;
543 plugin->iter = iter;
544 plugin->iter_cls = cls;
545 plugin->iter_zone = zone;
546 plugin->iter_result_found = GNUNET_NO;
547 GNUNET_CONTAINER_multihashmap_iterate (plugin->hm,
548 &iterate_zones,
549 plugin);
550 return plugin->iter_result_found;
551}
552
553static int
554zone_to_name (void *cls,
555 const struct GNUNET_HashCode *key,
556 void *value)
557{
558 struct Plugin *plugin = cls;
559 struct FlatFileEntry *entry = value;
560 int i;
561
562 if (0 != memcmp (entry->private_key,
563 plugin->iter_zone,
564 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)))
565 return GNUNET_YES;
566
567 for (i = 0; i < entry->record_count; i++) {
568 if (GNUNET_GNSRECORD_TYPE_PKEY != entry->record_data[i].record_type)
569 continue;
570 if (0 == memcmp (plugin->iter_pkey,
571 entry->record_data[i].data,
572 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
573 {
574 plugin->iter (plugin->iter_cls,
575 entry->private_key,
576 entry->label,
577 entry->record_count,
578 entry->record_data);
579 plugin->iter_result_found = GNUNET_YES;
580
581 }
582 }
583
584 return GNUNET_YES;
585}
586
587/**
588 * Look for an existing PKEY delegation record for a given public key.
589 * Returns at most one result to the iterator.
590 *
591 * @param cls closure (internal context for the plugin)
592 * @param zone private key of the zone to look up in, never NULL
593 * @param value_zone public key of the target zone (value), never NULL
594 * @param iter function to call with the result
595 * @param iter_cls closure for @a iter
596 * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
597 */
598static int
599namestore_zone_to_name (void *cls,
600 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
601 const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone,
602 GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
603{
604 struct Plugin *plugin = cls;
605
606 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
607 "Performing reverse lookup for `%s'\n",
608 GNUNET_GNSRECORD_z2s (value_zone));
609
610 GNUNET_CONTAINER_multihashmap_iterate (plugin->hm,
611 &zone_to_name,
612 plugin);
613
614
615 return plugin->iter_result_found;
616}
617
618
619/**
620 * Entry point for the plugin.
621 *
622 * @param cls the "struct GNUNET_NAMESTORE_PluginEnvironment*"
623 * @return NULL on error, otherwise the plugin context
624 */
625void *
626libgnunet_plugin_namestore_flat_init (void *cls)
627{
628 static struct Plugin plugin;
629 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
630 struct GNUNET_NAMESTORE_PluginFunctions *api;
631
632 if (NULL != plugin.cfg)
633 return NULL; /* can only initialize once! */
634 memset (&plugin, 0, sizeof (struct Plugin));
635 plugin.cfg = cfg;
636 if (GNUNET_OK != database_setup (&plugin))
637 {
638 database_shutdown (&plugin);
639 return NULL;
640 }
641 api = GNUNET_new (struct GNUNET_NAMESTORE_PluginFunctions);
642 api->cls = &plugin;
643 api->store_records = &namestore_store_records;
644 api->iterate_records = &namestore_iterate_records;
645 api->zone_to_name = &namestore_zone_to_name;
646 api->lookup_records = &namestore_lookup_records;
647 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
648 _("flat file database running\n"));
649 return api;
650}
651
652
653/**
654 * Exit point from the plugin.
655 *
656 * @param cls the plugin context (as returned by "init")
657 * @return always NULL
658 */
659void *
660libgnunet_plugin_namestore_flat_done (void *cls)
661{
662 struct GNUNET_NAMESTORE_PluginFunctions *api = cls;
663 struct Plugin *plugin = api->cls;
664
665 database_shutdown (plugin);
666 plugin->cfg = NULL;
667 GNUNET_free (api);
668 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
669 "flat file plugin is finished\n");
670 return NULL;
671}
672
673/* end of plugin_namestore_flat.c */
diff --git a/src/namestore/test_plugin_namestore.c b/src/namestore/test_plugin_namestore.c
index 4c98bdaa1..9c358abe8 100644
--- a/src/namestore/test_plugin_namestore.c
+++ b/src/namestore/test_plugin_namestore.c
@@ -182,7 +182,7 @@ main (int argc, char *argv[])
182 GNUNET_GETOPT_OPTION_END 182 GNUNET_GETOPT_OPTION_END
183 }; 183 };
184 184
185 GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-namestore-sqlite"); 185 //GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-namestore-sqlite");
186 GNUNET_log_setup ("test-plugin-namestore", 186 GNUNET_log_setup ("test-plugin-namestore",
187 "WARNING", 187 "WARNING",
188 NULL); 188 NULL);
@@ -193,7 +193,7 @@ main (int argc, char *argv[])
193 "test-plugin-namestore", "nohelp", options, &run, NULL); 193 "test-plugin-namestore", "nohelp", options, &run, NULL);
194 if (ok != 0) 194 if (ok != 0)
195 FPRINTF (stderr, "Missed some testcases: %d\n", ok); 195 FPRINTF (stderr, "Missed some testcases: %d\n", ok);
196 GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-namestore-sqlite"); 196 //GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-namestore-sqlite");
197 return ok; 197 return ok;
198} 198}
199 199
diff --git a/src/namestore/test_plugin_namestore_flat.conf b/src/namestore/test_plugin_namestore_flat.conf
new file mode 100644
index 000000000..2909d76e1
--- /dev/null
+++ b/src/namestore/test_plugin_namestore_flat.conf
@@ -0,0 +1,2 @@
1[namestore-flat]
2FILENAME = /tmp/gnunet-test-plugin-namestore-sqlite/flatdb