2 This file is part of GNUnet.
3 (C) 2009 Christian Grothoff (and other contributing authors)
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.
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.
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.
22 * @file namestore/gnunet-service-namestore.c
23 * @brief namestore for the GNUnet naming system
24 * @author Matthias Wachs
27 #include "gnunet_getopt_lib.h"
28 #include "gnunet_service_lib.h"
29 #include "gnunet_namestore_service.h"
30 #include "gnunet_namestore_plugin.h"
31 #include "gnunet_signatures.h"
32 #include "namestore.h"
34 #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
37 * A namestore operation.
39 struct GNUNET_NAMESTORE_ZoneIteration
42 * Next element in the DLL
44 struct GNUNET_NAMESTORE_ZoneIteration *next;
47 * Previous element in the DLL
49 struct GNUNET_NAMESTORE_ZoneIteration *prev;
52 * Namestore client which intiated this zone iteration
54 struct GNUNET_NAMESTORE_Client * client;
57 * GNUNET_YES if we iterate over a specific zone
58 * GNUNET_NO if we iterate over all zones
63 * Hash of the specific zone if 'has_zone' is GNUNET_YES,
64 * othwerwise set to '\0'
66 struct GNUNET_CRYPTO_ShortHashCode zone;
69 * The operation id fot the zone iteration in the response for the client
74 * Offset of the zone iteration used to address next result of the zone
75 * iteration in the store
77 * Initialy set to 0 in handle_iteration_start
78 * Incremented with by every call to handle_iteration_next
84 * Which flags must be included
86 uint16_t must_have_flags;
89 * Which flags must not be included
91 uint16_t must_not_have_flags;
98 struct GNUNET_NAMESTORE_Client
101 * Next element in the DLL
103 struct GNUNET_NAMESTORE_Client *next;
106 * Previous element in the DLL
108 struct GNUNET_NAMESTORE_Client *prev;
113 struct GNUNET_SERVER_Client * client;
117 * Zone iteration operations in progress initiated by this client
119 struct GNUNET_NAMESTORE_ZoneIteration *op_head;
123 * Zone iteration operations in progress initiated by this client
125 struct GNUNET_NAMESTORE_ZoneIteration *op_tail;
130 * A container struct to store information belonging to a zone crypto key pair
132 struct GNUNET_NAMESTORE_CryptoContainer
135 * Filename where to store the container
140 * Short hash of the zone's public key
142 struct GNUNET_CRYPTO_ShortHashCode zone;
147 struct GNUNET_CRYPTO_RsaPrivateKey *privkey;
152 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey;
157 * Configuration handle.
159 const struct GNUNET_CONFIGURATION_Handle *GSN_cfg;
164 struct GNUNET_NAMESTORE_PluginFunctions *GSN_database;
169 static char *zonefile_directory;
172 * Name of the database plugin
174 static char *db_lib_name;
178 * Our notification context.
180 static struct GNUNET_SERVER_NotificationContext *snc;
183 * Head of the Client DLL
185 static struct GNUNET_NAMESTORE_Client *client_head;
188 * Tail of the Client DLL
190 static struct GNUNET_NAMESTORE_Client *client_tail;
193 * Hashmap containing the zone keys this namestore has is authoritative for
195 * Keys are the GNUNET_CRYPTO_HashCode of the GNUNET_CRYPTO_ShortHashCode
196 * The values are 'struct GNUNET_NAMESTORE_CryptoContainer *'
198 struct GNUNET_CONTAINER_MultiHashMap *zonekeys;
202 * Write zonefile to disk
203 * @param filename where to write
204 * @param c the crypto container
206 * @return GNUNET_OK on success, GNUNET_SYSERR on fail
210 write_key_to_file (const char *filename, struct GNUNET_NAMESTORE_CryptoContainer *c)
212 struct GNUNET_CRYPTO_RsaPrivateKey *ret = c->privkey;
213 struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *enc;
214 struct GNUNET_DISK_FileHandle *fd;
216 if (GNUNET_YES == GNUNET_DISK_file_test (filename))
218 struct GNUNET_CRYPTO_ShortHashCode zone;
219 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
220 struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
222 privkey = GNUNET_CRYPTO_rsa_key_create_from_file(filename);
225 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
226 _("File zone `%s' but corrupt content already exists, failed to write! \n"), GNUNET_short_h2s (&zone));
227 return GNUNET_SYSERR;
230 GNUNET_CRYPTO_rsa_key_get_public (privkey, &pubkey);
231 GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone);
232 GNUNET_CRYPTO_rsa_key_free (privkey);
234 if (0 == memcmp (&zone, &c->zone, sizeof(zone)))
236 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
237 _("File zone `%s' containing this key already exists\n"), GNUNET_short_h2s (&zone));
242 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
243 _("File zone `%s' but different zone key already exists, failed to write! \n"), GNUNET_short_h2s (&zone));
247 fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_FAILIFEXISTS, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
252 if (GNUNET_YES != GNUNET_DISK_file_test (filename))
254 /* must exist but not be accessible, fail for good! */
255 if (0 != ACCESS (filename, R_OK))
256 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", filename);
258 GNUNET_break (0); /* what is going on!? */
259 return GNUNET_SYSERR;
262 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename);
263 return GNUNET_SYSERR;
266 if (GNUNET_YES != GNUNET_DISK_file_lock (fd, 0, sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded), GNUNET_YES))
268 GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
269 return GNUNET_SYSERR;
271 enc = GNUNET_CRYPTO_rsa_encode_key (ret);
272 GNUNET_assert (enc != NULL);
273 GNUNET_assert (ntohs (enc->len) == GNUNET_DISK_file_write (fd, enc, ntohs (enc->len)));
275 GNUNET_DISK_file_sync (fd);
276 if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded)))
277 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
278 GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
280 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
281 _("Stored zonekey for zone `%s' in file `%s'\n"), GNUNET_short_h2s(&c->zone), c->filename);
285 int zone_to_disk_it (void *cls,
286 const struct GNUNET_HashCode *key,
289 struct GNUNET_NAMESTORE_CryptoContainer * c = value;
290 if (c->filename != NULL)
291 write_key_to_file(c->filename, c);
294 GNUNET_asprintf(&c->filename, "%s/%s.zkey", zonefile_directory, GNUNET_short_h2s (&c->zone));
295 write_key_to_file(c->filename, c);
299 GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (zonekeys, key, value));
300 GNUNET_CRYPTO_rsa_key_free (c->privkey);
301 GNUNET_free (c->pubkey);
302 GNUNET_free (c->filename);
309 struct GNUNET_TIME_Absolute
310 get_block_expiration_time (unsigned int rd_count, const struct GNUNET_NAMESTORE_RecordData *rd)
313 struct GNUNET_TIME_Absolute expire = GNUNET_TIME_UNIT_FOREVER_ABS;
314 struct GNUNET_TIME_Absolute at;
315 struct GNUNET_TIME_Relative rt;
318 return GNUNET_TIME_UNIT_ZERO_ABS;
319 for (c = 0; c < rd_count; c++)
321 if (0 != (rd[c].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION))
323 rt.rel_value = rd[c].expiration_time;
324 at = GNUNET_TIME_relative_to_absolute (rt);
328 at.abs_value = rd[c].expiration_time;
330 expire = GNUNET_TIME_absolute_min (at, expire);
336 * Task run during shutdown.
342 cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
344 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n");
345 struct GNUNET_NAMESTORE_ZoneIteration * no;
346 struct GNUNET_NAMESTORE_ZoneIteration * tmp;
347 struct GNUNET_NAMESTORE_Client * nc;
348 struct GNUNET_NAMESTORE_Client * next;
352 GNUNET_SERVER_notification_context_destroy (snc);
355 GNUNET_CONTAINER_multihashmap_iterate(zonekeys, &zone_to_disk_it, NULL);
356 GNUNET_CONTAINER_multihashmap_destroy(zonekeys);
358 for (nc = client_head; nc != NULL; nc = next)
361 for (no = nc->op_head; no != NULL; no = tmp)
363 GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no);
367 GNUNET_SERVER_client_drop(nc->client);
368 GNUNET_CONTAINER_DLL_remove (client_head, client_tail, nc);
372 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, GSN_database));
373 GNUNET_free (db_lib_name);
374 GNUNET_free_non_null(zonefile_directory);
377 static struct GNUNET_NAMESTORE_Client *
378 client_lookup (struct GNUNET_SERVER_Client *client)
380 struct GNUNET_NAMESTORE_Client * nc;
382 GNUNET_assert (NULL != client);
384 for (nc = client_head; nc != NULL; nc = nc->next)
386 if (client == nc->client)
393 * Called whenever a client is disconnected. Frees our
394 * resources associated with that client.
397 * @param client identification of the client
400 client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client)
402 struct GNUNET_NAMESTORE_ZoneIteration * no;
403 struct GNUNET_NAMESTORE_Client * nc;
407 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected \n", client);
409 nc = client_lookup (client);
411 if ((NULL == client) || (NULL == nc))
417 GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no);
422 GNUNET_SERVER_client_drop(nc->client);
423 GNUNET_CONTAINER_DLL_remove (client_head, client_tail, nc);
430 static void handle_start (void *cls,
431 struct GNUNET_SERVER_Client * client,
432 const struct GNUNET_MessageHeader * message)
434 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
436 struct GNUNET_NAMESTORE_Client * nc = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_Client));
438 GNUNET_SERVER_notification_context_add (snc, client);
439 GNUNET_CONTAINER_DLL_insert(client_head, client_tail, nc);
440 GNUNET_SERVER_client_keep (client);
441 GNUNET_SERVER_receive_done (client, GNUNET_OK);
444 struct LookupNameContext
446 struct GNUNET_NAMESTORE_Client *nc;
448 uint32_t record_type;
449 struct GNUNET_CRYPTO_ShortHashCode *zone;
453 void drop_iterator (void *cls,
454 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
455 struct GNUNET_TIME_Absolute expire,
458 const struct GNUNET_NAMESTORE_RecordData *rd,
459 const struct GNUNET_CRYPTO_RsaSignature *signature)
461 struct GNUNET_CRYPTO_ShortHashCode zone_hash;
463 if (NULL != zone_key)
465 GNUNET_CRYPTO_short_hash(zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone_hash);
466 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting zone `%s'\n", GNUNET_short_h2s (&zone_hash));
467 GSN_database->delete_zone (GSN_database->cls, &zone_hash);
471 (*stop) = GNUNET_YES;
477 handle_lookup_name_it (void *cls,
478 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
479 struct GNUNET_TIME_Absolute expire,
481 unsigned int rd_count,
482 const struct GNUNET_NAMESTORE_RecordData *rd,
483 const struct GNUNET_CRYPTO_RsaSignature *signature)
486 struct LookupNameContext *lnc = cls;
487 struct LookupNameResponseMessage *lnr_msg;
488 struct GNUNET_NAMESTORE_RecordData *rd_selected = NULL;
489 struct GNUNET_NAMESTORE_CryptoContainer *cc;
490 struct GNUNET_CRYPTO_RsaSignature *signature_new = NULL;
491 struct GNUNET_TIME_Absolute e;
492 struct GNUNET_CRYPTO_ShortHashCode zone_key_hash;
493 struct GNUNET_HashCode long_hash;
500 int copied_elements = 0;
501 int contains_signature = GNUNET_NO;
502 int authoritative = GNUNET_NO;
506 name_len = strlen(name) + 1;
508 /* count records to copy */
511 if (lnc->record_type != 0)
513 /* special record type needed */
514 for (c = 0; c < rd_count; c ++)
515 if (rd[c].record_type == lnc->record_type)
516 copied_elements++; /* found matching record */
517 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u records with type %u for name `%s' in zone `%s'\n",
518 copied_elements, lnc->record_type, lnc->name, GNUNET_short_h2s(lnc->zone));
519 rd_selected = GNUNET_malloc (copied_elements * sizeof (struct GNUNET_NAMESTORE_RecordData));
521 for (c = 0; c < rd_count; c ++)
523 if (rd[c].record_type == lnc->record_type)
525 /* found matching record */
526 memcpy (&rd_selected[copied_elements], &rd[c], sizeof (struct GNUNET_NAMESTORE_RecordData));
533 copied_elements = rd_count;
534 rd_selected = (struct GNUNET_NAMESTORE_RecordData *) rd;
542 expire = GNUNET_TIME_UNIT_ZERO_ABS;
545 rd_ser_len = GNUNET_NAMESTORE_records_get_size(copied_elements, rd_selected);
546 char rd_ser[rd_ser_len];
547 GNUNET_NAMESTORE_records_serialize(copied_elements, rd_selected, rd_ser_len, rd_ser);
549 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u records for name `%s' in zone `%s'\n",
550 copied_elements, lnc->name, GNUNET_short_h2s(lnc->zone));
552 if ((copied_elements == rd_count) && (NULL != signature))
553 contains_signature = GNUNET_YES; /* returning all records, so include signature */
555 contains_signature = GNUNET_NO; /* returning not all records, so do not include signature */
558 if ((NULL != zone_key) && (copied_elements == rd_count))
560 GNUNET_CRYPTO_short_hash(zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone_key_hash);
561 GNUNET_CRYPTO_short_hash_double (&zone_key_hash, &long_hash);
562 if (GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash))
564 cc = GNUNET_CONTAINER_multihashmap_get(zonekeys, &long_hash);
565 e = get_block_expiration_time(rd_count, rd);
566 signature_new = GNUNET_NAMESTORE_create_signature(cc->privkey, e, name, rd, rd_count);
567 GNUNET_assert (signature_new != NULL);
568 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating signature for name `%s' with %u records in zone `%s'\n",name, copied_elements, GNUNET_short_h2s(&zone_key_hash));
569 authoritative = GNUNET_YES;
572 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "I am not authoritative for name `%s' in zone `%s'\n",name, GNUNET_short_h2s(&zone_key_hash));
575 r_size = sizeof (struct LookupNameResponseMessage) +
576 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) +
580 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "NAMESTORE_LOOKUP_NAME_RESPONSE");
581 lnr_msg = GNUNET_malloc (r_size);
582 lnr_msg->gns_header.header.type = ntohs (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE);
583 lnr_msg->gns_header.header.size = ntohs (r_size);
584 lnr_msg->gns_header.r_id = htonl (lnc->request_id);
585 lnr_msg->rd_count = htons (copied_elements);
586 lnr_msg->rd_len = htons (rd_ser_len);
587 lnr_msg->name_len = htons (name_len);
588 lnr_msg->expire = GNUNET_TIME_absolute_hton(get_block_expiration_time(copied_elements, rd_selected));
590 if (rd_selected != rd)
591 GNUNET_free (rd_selected);
593 if (zone_key != NULL)
594 lnr_msg->public_key = (*zone_key);
596 memset(&lnr_msg->public_key, '\0', sizeof (lnr_msg->public_key));
598 if (GNUNET_YES == authoritative)
599 { /* use new created signature */
600 lnr_msg->contains_sig = htons (GNUNET_YES);
601 GNUNET_assert (signature_new != NULL);
602 lnr_msg->signature = *signature_new;
603 GNUNET_free (signature_new);
605 else if (GNUNET_YES == contains_signature)
607 /* use existing signature */
608 lnr_msg->contains_sig = htons (GNUNET_YES);
609 GNUNET_assert (signature != NULL);
610 lnr_msg->signature = *signature;
614 /* use no signature */
615 memset (&lnr_msg->signature, '\0', sizeof (lnr_msg->signature));
618 name_tmp = (char *) &lnr_msg[1];
619 rd_tmp = &name_tmp[name_len];
621 memcpy (name_tmp, name, name_len);
622 memcpy (rd_tmp, rd_ser, rd_ser_len);
624 GNUNET_SERVER_notification_context_unicast (snc, lnc->nc->client, (const struct GNUNET_MessageHeader *) lnr_msg, GNUNET_NO);
625 GNUNET_free (lnr_msg);
628 static void handle_lookup_name (void *cls,
629 struct GNUNET_SERVER_Client * client,
630 const struct GNUNET_MessageHeader * message)
632 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_LOOKUP_NAME");
633 struct LookupNameContext lnc;
634 struct GNUNET_NAMESTORE_Client *nc;
640 if (ntohs (message->size) < sizeof (struct LookupNameMessage))
643 GNUNET_SERVER_receive_done (client, GNUNET_OK);
647 nc = client_lookup(client);
651 GNUNET_SERVER_receive_done (client, GNUNET_OK);
655 struct LookupNameMessage * ln_msg = (struct LookupNameMessage *) message;
656 rid = ntohl (ln_msg->gns_header.r_id);
657 name_len = ntohl (ln_msg->name_len);
658 type = ntohl (ln_msg->record_type);
660 if ((name_len == 0) || (name_len > 256))
663 GNUNET_SERVER_receive_done (client, GNUNET_OK);
667 name = (char *) &ln_msg[1];
668 if (name[name_len -1] != '\0')
671 GNUNET_SERVER_receive_done (client, GNUNET_OK);
676 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up all records for name `%s' in zone `%s'\n", name, GNUNET_short_h2s(&ln_msg->zone));
678 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up records with type %u for name `%s' in zone `%s'\n", type, name, GNUNET_short_h2s(&ln_msg->zone));
680 /* do the actual lookup */
681 lnc.request_id = rid;
683 lnc.record_type = type;
685 lnc.zone = &ln_msg->zone;
686 GSN_database->iterate_records(GSN_database->cls, &ln_msg->zone, name, 0, &handle_lookup_name_it, &lnc);
688 GNUNET_SERVER_receive_done (client, GNUNET_OK);
691 static void handle_record_put (void *cls,
692 struct GNUNET_SERVER_Client * client,
693 const struct GNUNET_MessageHeader * message)
695 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_RECORD_PUT");
696 struct GNUNET_NAMESTORE_Client *nc;
697 struct GNUNET_TIME_Absolute expire;
698 struct GNUNET_CRYPTO_RsaSignature *signature;
699 struct RecordPutResponseMessage rpr_msg;
708 int res = GNUNET_SYSERR;
710 if (ntohs (message->size) < sizeof (struct RecordPutMessage))
713 GNUNET_SERVER_receive_done (client, GNUNET_OK);
717 nc = client_lookup (client);
721 GNUNET_SERVER_receive_done (client, GNUNET_OK);
725 struct RecordPutMessage * rp_msg = (struct RecordPutMessage *) message;
727 rid = ntohl (rp_msg->gns_header.r_id);
728 msg_size = ntohs (rp_msg->gns_header.header.size);
729 name_len = ntohs (rp_msg->name_len);
730 rd_count = ntohs (rp_msg->rd_count);
731 rd_ser_len = ntohs(rp_msg->rd_len);
733 if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
736 GNUNET_SERVER_receive_done (client, GNUNET_OK);
740 if ((rd_count < 1) || (rd_ser_len < 1) || (name_len >=256) || (name_len == 0))
743 GNUNET_SERVER_receive_done (client, GNUNET_OK);
747 msg_size_exp = sizeof (struct RecordPutMessage) + name_len + rd_ser_len;
748 if (msg_size != msg_size_exp)
750 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expected message %u size but message size is %u \n", msg_size_exp, msg_size);
752 GNUNET_SERVER_receive_done (client, GNUNET_OK);
755 if ((name_len == 0) || (name_len > 256))
758 GNUNET_SERVER_receive_done (client, GNUNET_OK);
762 name = (char *) &rp_msg[1];
764 if (name[name_len -1] != '\0')
767 GNUNET_SERVER_receive_done (client, GNUNET_OK);
771 expire = GNUNET_TIME_absolute_ntoh(rp_msg->expire);
772 signature = (struct GNUNET_CRYPTO_RsaSignature *) &rp_msg->signature;
774 rd_ser = &name[name_len];
775 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
776 res = GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_ser, rd_count, rd);
777 if (res != GNUNET_OK)
783 struct GNUNET_CRYPTO_ShortHashCode zone_hash;
784 GNUNET_CRYPTO_short_hash (&rp_msg->public_key, sizeof (rp_msg->public_key), &zone_hash);
786 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Putting %u record for name `%s' in zone `%s'\n", rd_count, name, GNUNET_short_h2s(&zone_hash));
788 /* Database operation */
789 res = GSN_database->put_records(GSN_database->cls,
796 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Putting record for name `%s': %s\n",
797 name, (res == GNUNET_OK) ? "OK" : "FAIL");
801 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_PUT_RESPONSE");
802 rpr_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE);
803 rpr_msg.gns_header.header.size = htons (sizeof (struct RecordPutResponseMessage));
804 rpr_msg.gns_header.r_id = htonl (rid);
805 rpr_msg.op_result = htonl (res);
806 GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &rpr_msg, GNUNET_NO);
808 GNUNET_SERVER_receive_done (client, GNUNET_OK);
811 struct CreateRecordContext
813 struct GNUNET_NAMESTORE_RecordData *rd;
814 struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
815 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey;
816 struct GNUNET_TIME_Absolute expire;
823 handle_create_record_it (void *cls,
824 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey,
825 struct GNUNET_TIME_Absolute expire,
827 unsigned int rd_count,
828 const struct GNUNET_NAMESTORE_RecordData *rd,
829 const struct GNUNET_CRYPTO_RsaSignature *signature)
831 struct CreateRecordContext * crc = cls;
832 struct GNUNET_NAMESTORE_RecordData *rd_new = NULL;
833 struct GNUNET_CRYPTO_RsaSignature dummy_signature;
834 struct GNUNET_TIME_Absolute block_expiration;
836 int exist = GNUNET_SYSERR;
837 int update = GNUNET_NO;
839 int rd_count_new = 0;
841 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u existing records for `%s'\n", rd_count, crc->name);
842 for (c = 0; c < rd_count; c++)
844 if ( (crc->rd->record_type == GNUNET_NAMESTORE_TYPE_PKEY) &&
845 (rd[c].record_type == GNUNET_NAMESTORE_TYPE_PKEY))
847 /* Update unique PKEY */
852 if ( (crc->rd->record_type == GNUNET_NAMESTORE_TYPE_PSEU) &&
853 (rd[c].record_type == GNUNET_NAMESTORE_TYPE_PSEU))
855 /* Update unique PSEU */
860 if ((crc->rd->record_type == rd[c].record_type) &&
861 (crc->rd->data_size == rd[c].data_size) &&
862 (0 == memcmp (crc->rd->data, rd[c].data, rd[c].data_size)))
864 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
865 "Found existing records for `%s' to update expiration date!\n",
868 if ( (crc->rd->expiration_time != rd[c].expiration_time) &&
869 ((crc->rd->flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION)
870 == (rd[c].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION) ) )
876 if (exist == GNUNET_SYSERR)
878 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
879 "No existing record for name `%s'!\n",
881 rd_new = GNUNET_malloc ((rd_count+1) * sizeof (struct GNUNET_NAMESTORE_RecordData));
882 memcpy (rd_new, rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
883 rd_count_new = rd_count + 1;
884 rd_new[rd_count] = *(crc->rd);
886 else if (update == GNUNET_NO)
888 /* Exact same record already exists */
889 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
890 "Matching record for %s' exists, no change required!\n",
898 GNUNET_assert (GNUNET_YES == update);
899 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
900 "Updating existing records for `%s'!\n",
902 rd_new = GNUNET_malloc ((rd_count) * sizeof (struct GNUNET_NAMESTORE_RecordData));
903 memcpy (rd_new, rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
904 rd_count_new = rd_count;
905 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
906 (0 == (crc->rd->flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION))
907 ? "Updating absolute expiration from %llu to %llu!\n"
908 : "Updating relative expiration from %llu to %llu!\n",
909 rd_new[exist].expiration_time, crc->rd->expiration_time);
910 rd_new[exist] = *(crc->rd);
913 block_expiration = GNUNET_TIME_absolute_max(crc->expire, expire);
914 if (block_expiration.abs_value != expire.abs_value)
915 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
916 "Updated block expiration time\n");
918 memset (&dummy_signature, '\0', sizeof (dummy_signature));
920 /* Database operation */
921 GNUNET_assert ((rd_new != NULL) && (rd_count_new > 0));
922 res = GSN_database->put_records(GSN_database->cls,
923 (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) crc->pubkey,
926 rd_count_new, rd_new,
928 GNUNET_break (GNUNET_OK == res);
929 if (res == GNUNET_OK)
930 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully put record for `%s' in database \n", crc->name);
932 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to put record for `%s' in database \n", crc->name);
936 GNUNET_free_non_null (rd_new);
940 /* failed to create the record */
941 crc->res = GNUNET_SYSERR;
944 /* database operations OK */
945 if (GNUNET_YES == update)
947 /* we updated an existing record */
948 crc->res = GNUNET_NO;
952 /* we created a new record */
953 crc->res = GNUNET_YES;
957 /* identical entry existed, so we did nothing */
958 crc->res = GNUNET_NO;
964 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Update result for name `%s' %u\n", crc->name, res);
968 static void handle_record_create (void *cls,
969 struct GNUNET_SERVER_Client * client,
970 const struct GNUNET_MessageHeader * message)
972 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_RECORD_CREATE");
973 struct GNUNET_NAMESTORE_Client *nc;
974 struct GNUNET_NAMESTORE_CryptoContainer *cc;
975 struct CreateRecordContext crc;
976 struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
977 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
978 struct RecordCreateResponseMessage rcr_msg;
979 struct GNUNET_CRYPTO_ShortHashCode pubkey_hash;
980 struct GNUNET_HashCode long_hash;
992 int res = GNUNET_SYSERR;
993 crc.res = GNUNET_SYSERR;
995 if (ntohs (message->size) < sizeof (struct RecordCreateMessage))
998 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1002 nc = client_lookup(client);
1005 GNUNET_break_op (0);
1006 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1010 struct RecordCreateMessage * rp_msg = (struct RecordCreateMessage *) message;
1011 rid = ntohl (rp_msg->gns_header.r_id);
1012 name_len = ntohs (rp_msg->name_len);
1013 msg_size = ntohs (message->size);
1014 rd_count = ntohs (rp_msg->rd_count);
1015 rd_ser_len = ntohs (rp_msg->rd_len);
1016 key_len = ntohs (rp_msg->pkey_len);
1017 msg_size_exp = sizeof (struct RecordCreateMessage) + key_len + name_len + rd_ser_len;
1019 if (msg_size != msg_size_exp)
1021 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expected message %u size but message size is %u \n", msg_size_exp, msg_size);
1022 GNUNET_break_op (0);
1023 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1027 if ((name_len == 0) || (name_len > 256))
1029 GNUNET_break_op (0);
1030 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1034 pkey_tmp = (char *) &rp_msg[1];
1035 name_tmp = &pkey_tmp[key_len];
1036 rd_ser = &name_tmp[name_len];
1038 if (name_tmp[name_len -1] != '\0')
1040 GNUNET_break_op (0);
1041 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1045 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
1047 res = GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_ser, rd_count, rd);
1048 if ((res != GNUNET_OK) || (rd_count != 1))
1050 GNUNET_break_op (0);
1053 /* Extracting and converting private key */
1054 pkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len);
1055 GNUNET_assert (pkey != NULL);
1056 GNUNET_CRYPTO_rsa_key_get_public(pkey, &pub);
1057 GNUNET_CRYPTO_short_hash (&pub, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pubkey_hash);
1058 GNUNET_CRYPTO_short_hash_double (&pubkey_hash, &long_hash);
1060 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash))
1062 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received new private key for zone `%s'\n",GNUNET_short_h2s(&pubkey_hash));
1064 cc = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_CryptoContainer));
1065 cc->privkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len);
1066 cc->pubkey = GNUNET_malloc(sizeof (pub));
1067 memcpy (cc->pubkey, &pub, sizeof(pub));
1068 cc->zone = pubkey_hash;
1069 GNUNET_CONTAINER_multihashmap_put(zonekeys, &long_hash, cc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1072 crc.expire = GNUNET_TIME_absolute_ntoh(rp_msg->expire);
1073 crc.res = GNUNET_SYSERR;
1077 crc.name = name_tmp;
1079 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating record for name `%s' in zone `%s'\n", name_tmp, GNUNET_short_h2s(&pubkey_hash));
1081 /* Get existing records for name */
1082 res = GSN_database->iterate_records(GSN_database->cls, &pubkey_hash, name_tmp, 0, &handle_create_record_it, &crc);
1083 if (res != GNUNET_SYSERR)
1085 GNUNET_CRYPTO_rsa_key_free(pkey);
1090 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_CREATE_RESPONSE");
1091 rcr_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE);
1092 rcr_msg.gns_header.header.size = htons (sizeof (struct RecordCreateResponseMessage));
1093 rcr_msg.gns_header.r_id = htonl (rid);
1094 if ((GNUNET_OK == res) && (crc.res == GNUNET_YES))
1095 rcr_msg.op_result = htonl (GNUNET_YES);
1096 else if ((GNUNET_OK == res) && (crc.res == GNUNET_NO))
1097 rcr_msg.op_result = htonl (GNUNET_NO);
1099 rcr_msg.op_result = htonl (GNUNET_SYSERR);
1100 GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &rcr_msg, GNUNET_NO);
1102 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1106 struct RemoveRecordContext
1108 struct GNUNET_NAMESTORE_RecordData *rd;
1109 struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
1115 handle_record_remove_it (void *cls,
1116 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
1117 struct GNUNET_TIME_Absolute expire,
1119 unsigned int rd_count,
1120 const struct GNUNET_NAMESTORE_RecordData *rd,
1121 const struct GNUNET_CRYPTO_RsaSignature *signature)
1123 struct RemoveRecordContext *rrc = cls;
1127 unsigned int rd_count_new;
1129 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name `%s 'currently has %u records\n", name, rd_count);
1133 /* Could not find record to remove */
1138 /* Find record to remove */
1139 found = GNUNET_SYSERR;
1140 for (c = 0; c < rd_count; c++)
1143 if (rd[c].flags != rrc->rd->flags)
1145 if (rd[c].record_type != rrc->rd->record_type)
1148 if (rd[c].data_size != rrc->rd->data_size)
1151 if (0 != memcmp (rd[c].data, rrc->rd->data, rrc->rd->data_size))
1154 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found record to remove!\n", rd_count);
1158 if (GNUNET_SYSERR == found)
1160 /* Could not find record to remove */
1165 if (rd_count-1 == 0)
1167 struct GNUNET_CRYPTO_ShortHashCode pubkey_hash;
1168 GNUNET_CRYPTO_short_hash (zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pubkey_hash);
1169 res = GSN_database->remove_records (GSN_database->cls,
1172 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1173 "No records left for name `%s', removing name\n",
1175 if (GNUNET_OK != res)
1177 /* Could put records into database */
1185 rd_count_new = rd_count -1;
1186 struct GNUNET_NAMESTORE_RecordData rd_new[rd_count_new];
1188 unsigned int c2 = 0;
1189 for (c = 0; c < rd_count; c++)
1193 GNUNET_assert (c2 < rd_count_new);
1199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name `%s' now has %u records\n", name, rd_count_new);
1201 /* Create dummy signature */
1202 struct GNUNET_CRYPTO_RsaSignature dummy_signature;
1203 memset (&dummy_signature, '\0', sizeof (dummy_signature));
1207 res = GSN_database->put_records(GSN_database->cls,
1211 rd_count_new, rd_new,
1213 if (GNUNET_OK != res)
1215 /* Could put records into database */
1225 handle_record_remove (void *cls,
1226 struct GNUNET_SERVER_Client * client,
1227 const struct GNUNET_MessageHeader * message)
1229 struct GNUNET_NAMESTORE_Client *nc;
1230 const struct RecordRemoveMessage * rr_msg;
1231 struct RecordRemoveResponseMessage rrr_msg;
1232 struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
1233 struct GNUNET_NAMESTORE_CryptoContainer *cc;
1234 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
1235 struct GNUNET_CRYPTO_ShortHashCode pubkey_hash;
1236 struct GNUNET_HashCode long_hash;
1237 const char * pkey_tmp;
1238 const char * name_tmp;
1239 const char * rd_ser;
1244 size_t msg_size_exp = 0;
1248 int res = GNUNET_SYSERR;
1250 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_RECORD_REMOVE");
1251 if (ntohs (message->size) < sizeof (struct RecordRemoveMessage))
1253 GNUNET_break_op (0);
1254 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1258 nc = client_lookup(client);
1261 GNUNET_break_op (0);
1262 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1266 rr_msg = (const struct RecordRemoveMessage *) message;
1267 rid = ntohl (rr_msg->gns_header.r_id);
1268 name_len = ntohs (rr_msg->name_len);
1269 rd_ser_len = ntohs (rr_msg->rd_len);
1270 rd_count = ntohs (rr_msg->rd_count);
1271 key_len = ntohs (rr_msg->pkey_len);
1272 msg_size = ntohs (message->size);
1274 if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
1276 GNUNET_break_op (0);
1277 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1281 if ((name_len >=256) || (name_len == 0))
1283 GNUNET_break_op (0);
1284 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1288 msg_size_exp = sizeof (struct RecordRemoveMessage) + key_len + name_len + rd_ser_len;
1289 if (msg_size != msg_size_exp)
1291 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expected message %u size but message size is %u \n", msg_size_exp, msg_size);
1292 GNUNET_break_op (0);
1293 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1297 pkey_tmp = (const char *) &rr_msg[1];
1298 name_tmp = &pkey_tmp[key_len];
1299 rd_ser = &name_tmp[name_len];
1302 if ((name_len == 0) || (name_len > 256))
1304 GNUNET_break_op (0);
1305 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1309 if (name_tmp[name_len -1] != '\0')
1311 GNUNET_break_op (0);
1312 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1316 /* Extracting and converting private key */
1317 pkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len);
1318 GNUNET_assert (pkey != NULL);
1319 GNUNET_CRYPTO_rsa_key_get_public(pkey, &pub);
1320 GNUNET_CRYPTO_short_hash (&pub, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pubkey_hash);
1321 GNUNET_CRYPTO_short_hash_double (&pubkey_hash, &long_hash);
1323 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash))
1325 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1326 "Received new private key for zone `%s'\n",
1327 GNUNET_short_h2s(&pubkey_hash));
1328 cc = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_CryptoContainer));
1329 cc->privkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len);
1330 cc->pubkey = GNUNET_malloc(sizeof (pub));
1331 memcpy (cc->pubkey, &pub, sizeof(pub));
1332 cc->zone = pubkey_hash;
1334 GNUNET_CONTAINER_multihashmap_put(zonekeys, &long_hash, cc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1338 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
1339 res = GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_ser, rd_count, rd);
1340 if ((res != GNUNET_OK) || (rd_count > 1))
1342 GNUNET_break_op (0);
1348 /* remove the whole name and all records */
1349 /* Database operation */
1350 res = GSN_database->remove_records (GSN_database->cls,
1353 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing name `%s': %s\n",
1354 name_tmp, (GNUNET_OK == res) ? "OK" : "FAIL");
1356 if (GNUNET_OK != res)
1357 /* Could not remove entry from database */
1364 /* remove a single record */
1365 struct RemoveRecordContext rrc;
1369 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing record for name `%s' in zone `%s'\n", name_tmp, GNUNET_short_h2s(&pubkey_hash));
1371 /* Database operation */
1372 res = GSN_database->iterate_records (GSN_database->cls,
1376 handle_record_remove_it, &rrc);
1378 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing record for name `%s': %s\n",
1379 name_tmp, (rrc.op_res == 0) ? "OK" : "FAIL");
1384 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_REMOVE_RESPONSE");
1385 rrr_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE);
1386 rrr_msg.gns_header.header.size = htons (sizeof (struct RecordRemoveResponseMessage));
1387 rrr_msg.gns_header.r_id = htonl (rid);
1388 rrr_msg.op_result = htonl (res);
1389 GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &rrr_msg, GNUNET_NO);
1391 GNUNET_CRYPTO_rsa_key_free (pkey);
1393 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1397 struct ZoneToNameCtx
1399 struct GNUNET_NAMESTORE_Client *nc;
1404 handle_zone_to_name_it (void *cls,
1405 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
1406 struct GNUNET_TIME_Absolute expire,
1408 unsigned int rd_count,
1409 const struct GNUNET_NAMESTORE_RecordData *rd,
1410 const struct GNUNET_CRYPTO_RsaSignature *signature)
1412 struct ZoneToNameCtx * ztn_ctx = cls;
1413 struct ZoneToNameResponseMessage *ztnr_msg;
1414 int16_t res = GNUNET_SYSERR;
1415 uint16_t name_len = 0;
1416 uint16_t rd_ser_len = 0 ;
1417 int32_t contains_sig = 0;
1418 size_t msg_size = 0;
1420 char *rd_ser = NULL;
1425 if ((zone_key != NULL) && (name != NULL))
1428 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found results: name is `%s', has %u records\n", name, rd_count);
1430 name_len = strlen (name) +1;
1434 /* no result found */
1435 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found no results\n");
1442 rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
1443 rd_ser = GNUNET_malloc (rd_ser_len);
1444 GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser);
1449 if (signature != NULL)
1450 contains_sig = GNUNET_YES;
1452 contains_sig = GNUNET_NO;
1456 msg_size = sizeof (struct ZoneToNameResponseMessage) + name_len + rd_ser_len + contains_sig * sizeof (struct GNUNET_CRYPTO_RsaSignature);
1457 ztnr_msg = GNUNET_malloc (msg_size);
1459 name_tmp = (char *) &ztnr_msg[1];
1460 rd_tmp = &name_tmp[name_len];
1461 sig_tmp = &rd_tmp[rd_ser_len];
1463 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "ZONE_TO_NAME_RESPONSE");
1464 ztnr_msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE);
1465 ztnr_msg->gns_header.header.size = htons (msg_size);
1466 ztnr_msg->gns_header.r_id = htonl (ztn_ctx->rid);
1467 ztnr_msg->res = htons (res);
1468 ztnr_msg->rd_len = htons (rd_ser_len);
1469 ztnr_msg->rd_count = htons (rd_count);
1470 ztnr_msg->name_len = htons (name_len);
1471 ztnr_msg->expire = GNUNET_TIME_absolute_hton(expire);
1472 if (zone_key != NULL)
1473 ztnr_msg->zone_key = *zone_key;
1475 memset (&ztnr_msg->zone_key, '\0', sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
1477 if ((name_len > 0) && (name != NULL))
1478 memcpy (name_tmp, name, name_len);
1480 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name is `%s', has %u records, rd ser len %u msg_size %u\n", name, rd_count, rd_ser_len, msg_size);
1481 if ((rd_ser_len > 0) && (rd_ser != NULL))
1482 memcpy (rd_tmp, rd_ser, rd_ser_len);
1483 if ((GNUNET_YES == contains_sig) && (signature != NULL))
1484 memcpy (sig_tmp, signature, contains_sig * sizeof (struct GNUNET_CRYPTO_RsaSignature));
1486 GNUNET_SERVER_notification_context_unicast (snc, ztn_ctx->nc->client, (const struct GNUNET_MessageHeader *) ztnr_msg, GNUNET_NO);
1487 GNUNET_free (ztnr_msg);
1488 GNUNET_free_non_null (rd_ser);
1492 static void handle_zone_to_name (void *cls,
1493 struct GNUNET_SERVER_Client * client,
1494 const struct GNUNET_MessageHeader * message)
1496 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "ZONE_TO_NAME");
1497 struct GNUNET_NAMESTORE_Client *nc;
1498 struct ZoneToNameCtx ztn_ctx;
1499 size_t msg_size = 0;
1502 if (ntohs (message->size) != sizeof (struct ZoneToNameMessage))
1504 GNUNET_break_op (0);
1505 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1509 nc = client_lookup(client);
1512 GNUNET_break_op (0);
1513 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1517 struct ZoneToNameMessage *ztn_msg = (struct ZoneToNameMessage *) message;
1519 if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
1521 GNUNET_break_op (0);
1522 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1526 rid = ntohl (ztn_msg->gns_header.r_id);
1531 struct GNUNET_CRYPTO_ShortHashAsciiEncoded z_tmp;
1532 GNUNET_CRYPTO_short_hash_to_enc(&ztn_msg->zone, &z_tmp);
1533 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up name for zone `%s' in zone `%s'\n",
1535 GNUNET_short_h2s (&ztn_msg->value_zone));
1537 GSN_database->zone_to_name (GSN_database->cls, &ztn_msg->zone, &ztn_msg->value_zone, &handle_zone_to_name_it, &ztn_ctx);
1539 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1544 * Copy record, data has to be free separetely
1547 copy_record (const struct GNUNET_NAMESTORE_RecordData *src, struct GNUNET_NAMESTORE_RecordData *dest)
1550 memcpy (dest, src, sizeof (struct GNUNET_NAMESTORE_RecordData));
1551 dest->data = GNUNET_malloc (src->data_size);
1552 memcpy ((void *) dest->data, src->data, src->data_size);
1555 struct ZoneIterationProcResult
1557 struct GNUNET_NAMESTORE_ZoneIteration *zi;
1559 int res_iteration_finished;
1560 int records_included;
1564 struct GNUNET_CRYPTO_ShortHashCode zone_hash;
1565 struct GNUNET_NAMESTORE_RecordData *rd;
1566 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded zone_key;
1567 struct GNUNET_CRYPTO_RsaSignature signature;
1568 struct GNUNET_TIME_Absolute expire;
1572 void zone_iteraterate_proc (void *cls,
1573 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
1574 struct GNUNET_TIME_Absolute expire,
1576 unsigned int rd_count,
1577 const struct GNUNET_NAMESTORE_RecordData *rd,
1578 const struct GNUNET_CRYPTO_RsaSignature *signature)
1580 struct ZoneIterationProcResult *proc = cls;
1581 struct GNUNET_NAMESTORE_RecordData *rd_filtered;
1582 struct GNUNET_CRYPTO_RsaSignature * new_signature;
1583 struct GNUNET_NAMESTORE_CryptoContainer *cc;
1584 struct GNUNET_CRYPTO_ShortHashCode hash;
1585 struct GNUNET_HashCode long_hash;
1586 struct GNUNET_TIME_Absolute e;
1587 unsigned int rd_count_filtered = 0;
1591 proc->res_iteration_finished = GNUNET_NO;
1592 proc->records_included = 0;
1594 if ((zone_key == NULL) && (name == NULL))
1596 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
1597 proc->res_iteration_finished = GNUNET_YES;
1601 else if ((zone_key != NULL) && (name != NULL)) /* just a safety check */
1603 rd_filtered = GNUNET_malloc (rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
1604 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received result for zone iteration: `%s'\n", name);
1605 for (c = 0; c < rd_count; c++)
1607 include = GNUNET_YES;
1608 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: 0x%x must have 0x%x \n",
1609 c, rd[c].flags, proc->zi->must_have_flags);
1610 /* Checking must have flags */
1611 if ((rd[c].flags & proc->zi->must_have_flags) == proc->zi->must_have_flags)
1614 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Include \n", c);
1618 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Not include \n", c);
1619 include = GNUNET_NO;
1622 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: 0x%x must not have 0x%x\n",
1623 c, rd[c].flags, proc->zi->must_not_have_flags);
1624 if ((rd[c].flags & proc->zi->must_not_have_flags) != 0)
1626 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Not include \n", c);
1627 include = GNUNET_NO;
1632 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Include \n", c);
1634 if (GNUNET_YES == include)
1636 copy_record (&rd[c], &rd_filtered[rd_count_filtered]);
1637 rd_count_filtered++;
1641 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Included %i of %i records \n", rd_count_filtered, rd_count);
1643 proc->records_included = rd_count_filtered;
1644 if (0 == rd_count_filtered)
1646 GNUNET_free (rd_filtered);
1649 proc->rd = rd_filtered;
1650 proc->name = GNUNET_strdup(name);
1651 memcpy (&proc->zone_key, zone_key, sizeof (proc->zone_key));
1654 proc->has_signature = GNUNET_NO;
1655 GNUNET_CRYPTO_short_hash (zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &hash);
1656 GNUNET_CRYPTO_short_hash_double(&hash, &long_hash);
1657 proc->zone_hash = hash;
1659 if (GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash))
1661 cc = GNUNET_CONTAINER_multihashmap_get(zonekeys, &long_hash);
1662 e = get_block_expiration_time(rd_count_filtered, rd_filtered);
1664 new_signature = GNUNET_NAMESTORE_create_signature(cc->privkey, e, name, rd_filtered, rd_count_filtered);
1665 GNUNET_assert (signature != NULL);
1666 proc->signature = (*new_signature);
1667 GNUNET_free (new_signature);
1668 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating signature for `%s' in zone `%s' with %u records and expiration %llu\n",
1669 name, GNUNET_short_h2s(&hash), rd_count_filtered, e.abs_value);
1670 proc->has_signature = GNUNET_YES;
1672 else if (rd_count_filtered == rd_count)
1674 proc->expire = expire;
1675 if (NULL != signature)
1677 proc->signature = (*signature);
1678 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using provided signature for `%s' in zone `%s' with %u records and expiration %llu\n",
1679 name, GNUNET_short_h2s(&hash), rd_count_filtered, expire.abs_value);
1680 proc->has_signature = GNUNET_YES;
1684 memset (&proc->signature, '\0', sizeof (proc->signature));
1685 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No signature provided for `%s'\n", name);
1697 void find_next_zone_iteration_result (struct ZoneIterationProcResult *proc)
1700 struct GNUNET_CRYPTO_ShortHashCode *zone;
1702 if (GNUNET_YES == proc->zi->has_zone)
1703 zone = &proc->zi->zone;
1709 GSN_database->iterate_records (GSN_database->cls, zone , NULL, proc->zi->offset, &zone_iteraterate_proc, proc);
1712 while ((proc->records_included == 0) && (GNUNET_NO == proc->res_iteration_finished));
1716 void send_zone_iteration_result (struct ZoneIterationProcResult *proc)
1718 struct GNUNET_NAMESTORE_ZoneIteration *zi = proc->zi;
1720 if (GNUNET_YES == proc->res_iteration_finished)
1722 struct ZoneIterationResponseMessage zir_msg;
1723 if (zi->has_zone == GNUNET_YES)
1724 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No more results for zone `%s'\n", GNUNET_short_h2s(&zi->zone));
1726 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No more results for all zones\n");
1728 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending empty `%s' message\n", "ZONE_ITERATION_RESPONSE");
1729 zir_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE);
1730 zir_msg.gns_header.header.size = htons (sizeof (struct ZoneIterationResponseMessage));
1731 zir_msg.gns_header.r_id = htonl(zi->request_id);
1732 zir_msg.expire = GNUNET_TIME_absolute_hton(GNUNET_TIME_UNIT_ZERO_ABS);
1733 zir_msg.name_len = htons (0);
1734 zir_msg.reserved = htons (0);
1735 zir_msg.rd_count = htons (0);
1736 zir_msg.rd_len = htons (0);
1737 memset (&zir_msg.public_key, '\0', sizeof (zir_msg.public_key));
1738 memset (&zir_msg.signature, '\0', sizeof (zir_msg.signature));
1739 GNUNET_SERVER_notification_context_unicast (snc, zi->client->client, (const struct GNUNET_MessageHeader *) &zir_msg, GNUNET_NO);
1741 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing zone iterator\n");
1742 GNUNET_CONTAINER_DLL_remove (zi->client->op_head, zi->client->op_tail, zi);
1748 GNUNET_assert (proc->records_included > 0);
1750 struct ZoneIterationResponseMessage *zir_msg;
1751 if (zi->has_zone == GNUNET_YES)
1752 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending name `%s' for iteration over zone `%s'\n",
1753 proc->name, GNUNET_short_h2s(&zi->zone));
1754 if (zi->has_zone == GNUNET_NO)
1755 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending name `%s' for iteration over all zones\n",
1763 name_len = strlen (proc->name) +1;
1765 rd_ser_len = GNUNET_NAMESTORE_records_get_size(proc->records_included, proc->rd);
1766 char rd_ser[rd_ser_len];
1767 GNUNET_NAMESTORE_records_serialize(proc->records_included, proc->rd, rd_ser_len, rd_ser);
1768 msg_size = sizeof (struct ZoneIterationResponseMessage) + name_len + rd_ser_len;
1769 zir_msg = GNUNET_malloc(msg_size);
1771 name_tmp = (char *) &zir_msg[1];
1772 rd_tmp = &name_tmp[name_len];
1774 zir_msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE);
1775 zir_msg->gns_header.header.size = htons (msg_size);
1776 zir_msg->gns_header.r_id = htonl(zi->request_id);
1777 zir_msg->expire = GNUNET_TIME_absolute_hton(proc->expire);
1778 zir_msg->reserved = htons (0);
1779 zir_msg->name_len = htons (name_len);
1780 zir_msg->rd_count = htons (proc->records_included);
1781 zir_msg->rd_len = htons (rd_ser_len);
1782 zir_msg->signature = proc->signature;
1783 zir_msg->public_key = proc->zone_key;
1784 memcpy (name_tmp, proc->name, name_len);
1785 memcpy (rd_tmp, rd_ser, rd_ser_len);
1787 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message with size %u\n", "ZONE_ITERATION_RESPONSE", msg_size);
1788 GNUNET_SERVER_notification_context_unicast (snc, zi->client->client, (const struct GNUNET_MessageHeader *) zir_msg, GNUNET_NO);
1789 GNUNET_free (zir_msg);
1793 void clean_up_zone_iteration_result (struct ZoneIterationProcResult *proc)
1796 GNUNET_free_non_null (proc->name);
1797 for (c = 0; c < proc->records_included; c++)
1799 GNUNET_free ((void *) proc->rd[c].data);
1801 GNUNET_free_non_null (proc->rd);
1806 static void handle_iteration_start (void *cls,
1807 struct GNUNET_SERVER_Client * client,
1808 const struct GNUNET_MessageHeader * message)
1810 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "ZONE_ITERATION_START");
1812 struct ZoneIterationStartMessage * zis_msg = (struct ZoneIterationStartMessage *) message;
1813 struct GNUNET_NAMESTORE_Client *nc;
1814 struct GNUNET_NAMESTORE_ZoneIteration *zi;
1816 nc = client_lookup(client);
1819 GNUNET_break_op (0);
1820 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1824 zi = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_ZoneIteration));
1825 zi->request_id = ntohl (zis_msg->gns_header.r_id);
1828 zi->must_have_flags = ntohs (zis_msg->must_have_flags);
1829 zi->must_not_have_flags = ntohs (zis_msg->must_not_have_flags);
1831 struct GNUNET_CRYPTO_ShortHashCode dummy;
1832 memset (&dummy, '\0', sizeof (dummy));
1833 if (0 == memcmp (&dummy, &zis_msg->zone, sizeof (dummy)))
1835 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting to iterate over all zones\n");
1836 zi->zone = zis_msg->zone;
1837 zi->has_zone = GNUNET_NO;
1841 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting to iterate over zone `%s'\n", GNUNET_short_h2s (&zis_msg->zone));
1842 zi->zone = zis_msg->zone;
1843 zi->has_zone = GNUNET_YES;
1846 GNUNET_CONTAINER_DLL_insert (nc->op_head, nc->op_tail, zi);
1848 struct ZoneIterationProcResult proc;
1851 find_next_zone_iteration_result (&proc);
1852 if (GNUNET_YES == proc.res_iteration_finished)
1854 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration done\n");
1856 else if (proc.records_included != 0)
1858 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration return %u records\n", proc.records_included);
1860 send_zone_iteration_result (&proc);
1861 clean_up_zone_iteration_result (&proc);
1863 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1866 static void handle_iteration_stop (void *cls,
1867 struct GNUNET_SERVER_Client * client,
1868 const struct GNUNET_MessageHeader * message)
1870 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "ZONE_ITERATION_STOP");
1872 struct GNUNET_NAMESTORE_Client *nc;
1873 struct GNUNET_NAMESTORE_ZoneIteration *zi;
1874 struct ZoneIterationStopMessage * zis_msg = (struct ZoneIterationStopMessage *) message;
1877 nc = client_lookup(client);
1880 GNUNET_break_op (0);
1881 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1885 rid = ntohl (zis_msg->gns_header.r_id);
1886 for (zi = nc->op_head; zi != NULL; zi = zi->next)
1888 if (zi->request_id == rid)
1893 GNUNET_break_op (0);
1894 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1898 GNUNET_CONTAINER_DLL_remove(nc->op_head, nc->op_tail, zi);
1899 if (GNUNET_YES == zi->has_zone)
1900 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopped zone iteration for zone `%s'\n", GNUNET_short_h2s (&zi->zone));
1902 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopped zone iteration all zones\n");
1905 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1908 static void handle_iteration_next (void *cls,
1909 struct GNUNET_SERVER_Client * client,
1910 const struct GNUNET_MessageHeader * message)
1912 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "ZONE_ITERATION_NEXT");
1914 struct GNUNET_NAMESTORE_Client *nc;
1915 struct GNUNET_NAMESTORE_ZoneIteration *zi;
1916 struct ZoneIterationStopMessage * zis_msg = (struct ZoneIterationStopMessage *) message;
1919 nc = client_lookup(client);
1922 GNUNET_break_op (0);
1923 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1927 rid = ntohl (zis_msg->gns_header.r_id);
1928 for (zi = nc->op_head; zi != NULL; zi = zi->next)
1930 if (zi->request_id == rid)
1935 GNUNET_break_op (0);
1936 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1940 struct ZoneIterationProcResult proc;
1943 find_next_zone_iteration_result (&proc);
1944 if (GNUNET_YES == proc.res_iteration_finished)
1946 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration done\n");
1948 else if (proc.records_included != 0)
1950 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration return %u records\n", proc.records_included);
1952 send_zone_iteration_result (&proc);
1953 clean_up_zone_iteration_result (&proc);
1955 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1958 int zonekey_file_it (void *cls, const char *filename)
1960 struct GNUNET_HashCode long_hash;
1962 if ((filename != NULL) && (NULL != strstr(filename, ".zkey")))
1964 struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
1965 struct GNUNET_NAMESTORE_CryptoContainer *c;
1966 privkey = GNUNET_CRYPTO_rsa_key_create_from_file(filename);
1967 if (privkey == NULL)
1970 c = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_CryptoContainer));
1971 c->pubkey = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
1972 c->privkey = privkey;
1973 GNUNET_CRYPTO_rsa_key_get_public(privkey, c->pubkey);
1974 GNUNET_CRYPTO_short_hash(c->pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &c->zone);
1976 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found zonefile for zone `%s'\n", GNUNET_short_h2s (&c->zone));
1977 GNUNET_CRYPTO_short_hash_double (&c->zone, &long_hash);
1978 GNUNET_CONTAINER_multihashmap_put(zonekeys, &long_hash, c, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1986 * Process template requests.
1988 * @param cls closure
1989 * @param server the initialized server
1990 * @param cfg configuration to use
1993 run (void *cls, struct GNUNET_SERVER_Handle *server,
1994 const struct GNUNET_CONFIGURATION_Handle *cfg)
1998 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n");
2000 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
2001 {&handle_start, NULL,
2002 GNUNET_MESSAGE_TYPE_NAMESTORE_START, sizeof (struct StartMessage)},
2003 {&handle_lookup_name, NULL,
2004 GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME, 0},
2005 {&handle_record_put, NULL,
2006 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT, 0},
2007 {&handle_record_create, NULL,
2008 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE, 0},
2009 {&handle_record_remove, NULL,
2010 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE, 0},
2011 {&handle_zone_to_name, NULL,
2012 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME, 0},
2013 {&handle_iteration_start, NULL,
2014 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START, sizeof (struct ZoneIterationStartMessage)},
2015 {&handle_iteration_next, NULL,
2016 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT, 0},
2017 {&handle_iteration_stop, NULL,
2018 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP, 0},
2024 /* Load private keys from disk */
2026 GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore", "zonefile_directory",
2027 &zonefile_directory))
2029 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("No directory to load zonefiles specified in configuration\n"));
2030 GNUNET_SCHEDULER_add_now (&cleanup_task, NULL);
2034 if (GNUNET_NO == GNUNET_DISK_file_test (zonefile_directory))
2036 if (GNUNET_SYSERR == GNUNET_DISK_directory_create (zonefile_directory))
2038 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Creating directory `%s' for zone files failed!\n"), zonefile_directory);
2039 GNUNET_SCHEDULER_add_now (&cleanup_task, NULL);
2042 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created directory `%s' for zone files\n", zonefile_directory);
2045 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scanning directory `%s' for zone files\n", zonefile_directory);
2046 zonekeys = GNUNET_CONTAINER_multihashmap_create (10);
2047 GNUNET_DISK_directory_scan (zonefile_directory, zonekey_file_it, &counter);
2048 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u zone files\n", counter);
2050 /* Loading database plugin */
2052 GNUNET_CONFIGURATION_get_value_string (cfg, "namestore", "database",
2054 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
2056 GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database);
2057 GSN_database = GNUNET_PLUGIN_load (db_lib_name, (void *) GSN_cfg);
2058 GNUNET_free (database);
2059 if (GSN_database == NULL)
2061 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not load database backend `%s'\n",
2063 GNUNET_SCHEDULER_add_now (&cleanup_task, NULL);
2067 /* Configuring server handles */
2068 GNUNET_SERVER_add_handlers (server, handlers);
2069 snc = GNUNET_SERVER_notification_context_create (server, 16);
2070 GNUNET_SERVER_disconnect_notify (server,
2071 &client_disconnect_notification,
2074 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task,
2081 * The main function for the template service.
2083 * @param argc number of arguments from the command line
2084 * @param argv command line arguments
2085 * @return 0 ok, 1 on error
2088 main (int argc, char *const *argv)
2090 return (GNUNET_OK ==
2091 GNUNET_SERVICE_run (argc, argv, "namestore",
2092 GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1;
2095 /* end of gnunet-service-namestore.c */