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 * Writes the encrypted private key of a zone in a file
204 * @param filename where to store the zone
205 * @param c the crypto container containing private key of the zone
206 * @return GNUNET_OK on success, GNUNET_SYSERR on fail
209 write_key_to_file (const char *filename, struct GNUNET_NAMESTORE_CryptoContainer *c)
211 struct GNUNET_CRYPTO_RsaPrivateKey *ret = c->privkey;
212 struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *enc;
213 struct GNUNET_DISK_FileHandle *fd;
215 if (GNUNET_YES == GNUNET_DISK_file_test (filename))
217 struct GNUNET_CRYPTO_ShortHashCode zone;
218 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
219 struct GNUNET_CRYPTO_RsaPrivateKey *privkey;
221 privkey = GNUNET_CRYPTO_rsa_key_create_from_file(filename);
224 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
225 _("File zone `%s' but corrupt content already exists, failed to write! \n"), GNUNET_short_h2s (&zone));
226 return GNUNET_SYSERR;
229 GNUNET_CRYPTO_rsa_key_get_public (privkey, &pubkey);
230 GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone);
231 GNUNET_CRYPTO_rsa_key_free (privkey);
233 if (0 == memcmp (&zone, &c->zone, sizeof(zone)))
235 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
236 _("File zone `%s' containing this key already exists\n"), GNUNET_short_h2s (&zone));
241 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
242 _("File zone `%s' but different zone key already exists, failed to write! \n"), GNUNET_short_h2s (&zone));
246 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);
251 if (GNUNET_YES != GNUNET_DISK_file_test (filename))
253 /* must exist but not be accessible, fail for good! */
254 if (0 != ACCESS (filename, R_OK))
255 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", filename);
257 GNUNET_break (0); /* what is going on!? */
258 return GNUNET_SYSERR;
261 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename);
262 return GNUNET_SYSERR;
265 if (GNUNET_YES != GNUNET_DISK_file_lock (fd, 0, sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded), GNUNET_YES))
267 GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
268 return GNUNET_SYSERR;
270 enc = GNUNET_CRYPTO_rsa_encode_key (ret);
271 GNUNET_assert (enc != NULL);
272 GNUNET_assert (ntohs (enc->len) == GNUNET_DISK_file_write (fd, enc, ntohs (enc->len)));
274 GNUNET_DISK_file_sync (fd);
275 if (GNUNET_YES != GNUNET_DISK_file_unlock (fd, 0, sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded)))
276 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
277 GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
279 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
280 _("Stored zonekey for zone `%s' in file `%s'\n"), GNUNET_short_h2s(&c->zone), c->filename);
286 * Write all zone keys to disk.
287 * Iterates over all entries of the hashmap 'zonekeys'
290 * @param key zone key
291 * @param value 'struct GNUNET_NAMESTORE_CryptoContainer' containing the private
293 * @return GNUNET_OK to continue iteration
296 zone_to_disk_it (void *cls,
297 const struct GNUNET_HashCode *key,
300 struct GNUNET_NAMESTORE_CryptoContainer *c = value;
301 if (c->filename != NULL)
302 write_key_to_file(c->filename, c);
305 GNUNET_asprintf(&c->filename, "%s/%s.zkey", zonefile_directory, GNUNET_short_h2s (&c->zone));
306 write_key_to_file(c->filename, c);
309 GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (zonekeys, key, value));
310 GNUNET_CRYPTO_rsa_key_free (c->privkey);
311 GNUNET_free (c->pubkey);
312 GNUNET_free (c->filename);
320 * Returns the expiration time of the given block of records
321 * The block expiration time is the expiration time of the block with smallest
324 * @param rd_count number of records given in 'rd'
325 * @param rd array of records
326 * @return absolute expiration time
328 struct GNUNET_TIME_Absolute
329 get_block_expiration_time (unsigned int rd_count, const struct GNUNET_NAMESTORE_RecordData *rd)
332 struct GNUNET_TIME_Absolute expire = GNUNET_TIME_UNIT_FOREVER_ABS;
333 struct GNUNET_TIME_Absolute at;
334 struct GNUNET_TIME_Relative rt;
337 return GNUNET_TIME_UNIT_ZERO_ABS;
338 for (c = 0; c < rd_count; c++)
340 if (0 != (rd[c].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION))
342 rt.rel_value = rd[c].expiration_time;
343 at = GNUNET_TIME_relative_to_absolute (rt);
347 at.abs_value = rd[c].expiration_time;
349 expire = GNUNET_TIME_absolute_min (at, expire);
355 * Task run during shutdown.
361 cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
363 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n");
364 struct GNUNET_NAMESTORE_ZoneIteration *no;
365 struct GNUNET_NAMESTORE_ZoneIteration *tmp;
366 struct GNUNET_NAMESTORE_Client *nc;
367 struct GNUNET_NAMESTORE_Client *next;
371 GNUNET_SERVER_notification_context_destroy (snc);
374 GNUNET_CONTAINER_multihashmap_iterate(zonekeys, &zone_to_disk_it, NULL);
375 GNUNET_CONTAINER_multihashmap_destroy(zonekeys);
377 for (nc = client_head; nc != NULL; nc = next)
380 for (no = nc->op_head; no != NULL; no = tmp)
382 GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no);
386 GNUNET_SERVER_client_drop(nc->client);
387 GNUNET_CONTAINER_DLL_remove (client_head, client_tail, nc);
391 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, GSN_database));
392 GNUNET_free (db_lib_name);
393 GNUNET_free_non_null(zonefile_directory);
396 static struct GNUNET_NAMESTORE_Client *
397 client_lookup (struct GNUNET_SERVER_Client *client)
399 struct GNUNET_NAMESTORE_Client *nc;
401 GNUNET_assert (NULL != client);
403 for (nc = client_head; nc != NULL; nc = nc->next)
405 if (client == nc->client)
412 * Called whenever a client is disconnected.
413 * Frees our resources associated with that client.
416 * @param client identification of the client
419 client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client)
421 struct GNUNET_NAMESTORE_ZoneIteration *no;
422 struct GNUNET_NAMESTORE_Client *nc;
426 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected \n", client);
428 nc = client_lookup (client);
430 if ((NULL == client) || (NULL == nc))
436 GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no);
441 GNUNET_SERVER_client_drop(nc->client);
442 GNUNET_CONTAINER_DLL_remove (client_head, client_tail, nc);
448 * Handles a 'GNUNET_MESSAGE_TYPE_NAMESTORE_START' message
451 * @param client GNUNET_SERVER_Client sending the message
452 * @param message unused
455 handle_start (void *cls,
456 struct GNUNET_SERVER_Client *client,
457 const struct GNUNET_MessageHeader *message)
459 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
461 struct GNUNET_NAMESTORE_Client *nc = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_Client));
463 GNUNET_SERVER_notification_context_add (snc, client);
464 GNUNET_CONTAINER_DLL_insert(client_head, client_tail, nc);
465 GNUNET_SERVER_client_keep (client);
466 GNUNET_SERVER_receive_done (client, GNUNET_OK);
470 struct LookupNameContext
473 struct GNUNET_NAMESTORE_Client *nc;
475 uint32_t record_type;
476 struct GNUNET_CRYPTO_ShortHashCode *zone;
482 handle_lookup_name_it (void *cls,
483 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
484 struct GNUNET_TIME_Absolute expire,
486 unsigned int rd_count,
487 const struct GNUNET_NAMESTORE_RecordData *rd,
488 const struct GNUNET_CRYPTO_RsaSignature *signature)
491 struct LookupNameContext *lnc = cls;
492 struct LookupNameResponseMessage *lnr_msg;
493 struct GNUNET_NAMESTORE_RecordData *rd_selected = NULL;
494 struct GNUNET_NAMESTORE_CryptoContainer *cc;
495 struct GNUNET_CRYPTO_RsaSignature *signature_new = NULL;
496 struct GNUNET_TIME_Absolute e;
497 struct GNUNET_CRYPTO_ShortHashCode zone_key_hash;
498 struct GNUNET_HashCode long_hash;
505 int copied_elements = 0;
506 int contains_signature = GNUNET_NO;
507 int authoritative = GNUNET_NO;
511 name_len = strlen(name) + 1;
513 /* count records to copy */
516 if (lnc->record_type != 0)
518 /* special record type needed */
519 for (c = 0; c < rd_count; c ++)
520 if (rd[c].record_type == lnc->record_type)
521 copied_elements++; /* found matching record */
522 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u records with type %u for name `%s' in zone `%s'\n",
523 copied_elements, lnc->record_type, lnc->name, GNUNET_short_h2s(lnc->zone));
524 rd_selected = GNUNET_malloc (copied_elements * sizeof (struct GNUNET_NAMESTORE_RecordData));
526 for (c = 0; c < rd_count; c ++)
528 if (rd[c].record_type == lnc->record_type)
530 /* found matching record */
531 memcpy (&rd_selected[copied_elements], &rd[c], sizeof (struct GNUNET_NAMESTORE_RecordData));
538 copied_elements = rd_count;
539 rd_selected = (struct GNUNET_NAMESTORE_RecordData *) rd;
547 expire = GNUNET_TIME_UNIT_ZERO_ABS;
550 rd_ser_len = GNUNET_NAMESTORE_records_get_size(copied_elements, rd_selected);
551 char rd_ser[rd_ser_len];
552 GNUNET_NAMESTORE_records_serialize(copied_elements, rd_selected, rd_ser_len, rd_ser);
554 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u records for name `%s' in zone `%s'\n",
555 copied_elements, lnc->name, GNUNET_short_h2s(lnc->zone));
557 if ((copied_elements == rd_count) && (NULL != signature))
558 contains_signature = GNUNET_YES; /* returning all records, so include signature */
560 contains_signature = GNUNET_NO; /* returning not all records, so do not include signature */
563 if ((NULL != zone_key) && (copied_elements == rd_count))
565 GNUNET_CRYPTO_short_hash(zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone_key_hash);
566 GNUNET_CRYPTO_short_hash_double (&zone_key_hash, &long_hash);
567 if (GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash))
569 cc = GNUNET_CONTAINER_multihashmap_get(zonekeys, &long_hash);
570 e = get_block_expiration_time(rd_count, rd);
571 signature_new = GNUNET_NAMESTORE_create_signature(cc->privkey, e, name, rd, rd_count);
572 GNUNET_assert (signature_new != NULL);
573 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));
574 authoritative = GNUNET_YES;
577 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "I am not authoritative for name `%s' in zone `%s'\n",name, GNUNET_short_h2s(&zone_key_hash));
580 r_size = sizeof (struct LookupNameResponseMessage) +
581 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) +
585 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "NAMESTORE_LOOKUP_NAME_RESPONSE");
586 lnr_msg = GNUNET_malloc (r_size);
587 lnr_msg->gns_header.header.type = ntohs (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE);
588 lnr_msg->gns_header.header.size = ntohs (r_size);
589 lnr_msg->gns_header.r_id = htonl (lnc->request_id);
590 lnr_msg->rd_count = htons (copied_elements);
591 lnr_msg->rd_len = htons (rd_ser_len);
592 lnr_msg->name_len = htons (name_len);
593 lnr_msg->expire = GNUNET_TIME_absolute_hton(get_block_expiration_time(copied_elements, rd_selected));
595 if (rd_selected != rd)
596 GNUNET_free (rd_selected);
598 if (zone_key != NULL)
599 lnr_msg->public_key = (*zone_key);
601 memset(&lnr_msg->public_key, '\0', sizeof (lnr_msg->public_key));
603 if (GNUNET_YES == authoritative)
604 { /* use new created signature */
605 lnr_msg->contains_sig = htons (GNUNET_YES);
606 GNUNET_assert (signature_new != NULL);
607 lnr_msg->signature = *signature_new;
608 GNUNET_free (signature_new);
610 else if (GNUNET_YES == contains_signature)
612 /* use existing signature */
613 lnr_msg->contains_sig = htons (GNUNET_YES);
614 GNUNET_assert (signature != NULL);
615 lnr_msg->signature = *signature;
619 /* use no signature */
620 memset (&lnr_msg->signature, '\0', sizeof (lnr_msg->signature));
623 name_tmp = (char *) &lnr_msg[1];
624 rd_tmp = &name_tmp[name_len];
626 memcpy (name_tmp, name, name_len);
627 memcpy (rd_tmp, rd_ser, rd_ser_len);
629 GNUNET_SERVER_notification_context_unicast (snc, lnc->nc->client, (const struct GNUNET_MessageHeader *) lnr_msg, GNUNET_NO);
630 GNUNET_free (lnr_msg);
634 * Handles a 'GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME' message
637 * @param client GNUNET_SERVER_Client sending the message
638 * @param message message of type 'struct LookupNameMessage'
641 handle_lookup_name (void *cls,
642 struct GNUNET_SERVER_Client *client,
643 const struct GNUNET_MessageHeader *message)
645 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_LOOKUP_NAME");
646 struct LookupNameContext lnc;
647 struct GNUNET_NAMESTORE_Client *nc;
653 if (ntohs (message->size) < sizeof (struct LookupNameMessage))
656 GNUNET_SERVER_receive_done (client, GNUNET_OK);
660 nc = client_lookup(client);
664 GNUNET_SERVER_receive_done (client, GNUNET_OK);
668 struct LookupNameMessage *ln_msg = (struct LookupNameMessage *) message;
669 rid = ntohl (ln_msg->gns_header.r_id);
670 name_len = ntohl (ln_msg->name_len);
671 type = ntohl (ln_msg->record_type);
673 if ((name_len == 0) || (name_len > 256))
676 GNUNET_SERVER_receive_done (client, GNUNET_OK);
680 name = (char *) &ln_msg[1];
681 if (name[name_len -1] != '\0')
684 GNUNET_SERVER_receive_done (client, GNUNET_OK);
689 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up all records for name `%s' in zone `%s'\n", name, GNUNET_short_h2s(&ln_msg->zone));
691 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));
693 /* do the actual lookup */
694 lnc.request_id = rid;
696 lnc.record_type = type;
698 lnc.zone = &ln_msg->zone;
699 GSN_database->iterate_records(GSN_database->cls, &ln_msg->zone, name, 0, &handle_lookup_name_it, &lnc);
701 GNUNET_SERVER_receive_done (client, GNUNET_OK);
706 * Handles a 'GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT' message
709 * @param client GNUNET_SERVER_Client sending the message
710 * @param message message of type 'struct RecordPutMessage'
713 handle_record_put (void *cls,
714 struct GNUNET_SERVER_Client *client,
715 const struct GNUNET_MessageHeader *message)
717 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_RECORD_PUT");
718 struct GNUNET_NAMESTORE_Client *nc;
719 struct RecordPutMessage *rp_msg;
720 struct GNUNET_TIME_Absolute expire;
721 struct GNUNET_CRYPTO_RsaSignature *signature;
722 struct RecordPutResponseMessage rpr_msg;
731 int res = GNUNET_SYSERR;
733 if (ntohs (message->size) < sizeof (struct RecordPutMessage))
736 GNUNET_SERVER_receive_done (client, GNUNET_OK);
740 nc = client_lookup (client);
744 GNUNET_SERVER_receive_done (client, GNUNET_OK);
748 rp_msg = (struct RecordPutMessage *) message;
749 rid = ntohl (rp_msg->gns_header.r_id);
750 msg_size = ntohs (rp_msg->gns_header.header.size);
751 name_len = ntohs (rp_msg->name_len);
752 rd_count = ntohs (rp_msg->rd_count);
753 rd_ser_len = ntohs(rp_msg->rd_len);
755 if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
758 GNUNET_SERVER_receive_done (client, GNUNET_OK);
762 if ((rd_count < 1) || (rd_ser_len < 1) || (name_len >=256) || (name_len == 0))
765 GNUNET_SERVER_receive_done (client, GNUNET_OK);
769 msg_size_exp = sizeof (struct RecordPutMessage) + name_len + rd_ser_len;
770 if (msg_size != msg_size_exp)
772 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expected message %u size but message size is %u \n", msg_size_exp, msg_size);
774 GNUNET_SERVER_receive_done (client, GNUNET_OK);
777 if ((name_len == 0) || (name_len > 256))
780 GNUNET_SERVER_receive_done (client, GNUNET_OK);
784 name = (char *) &rp_msg[1];
786 if (name[name_len -1] != '\0')
789 GNUNET_SERVER_receive_done (client, GNUNET_OK);
793 expire = GNUNET_TIME_absolute_ntoh(rp_msg->expire);
794 signature = (struct GNUNET_CRYPTO_RsaSignature *) &rp_msg->signature;
796 rd_ser = &name[name_len];
797 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
798 res = GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_ser, rd_count, rd);
799 if (res != GNUNET_OK)
805 struct GNUNET_CRYPTO_ShortHashCode zone_hash;
806 GNUNET_CRYPTO_short_hash (&rp_msg->public_key, sizeof (rp_msg->public_key), &zone_hash);
808 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Putting %u record for name `%s' in zone `%s'\n", rd_count, name, GNUNET_short_h2s(&zone_hash));
810 /* Database operation */
811 res = GSN_database->put_records(GSN_database->cls,
818 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Putting record for name `%s': %s\n",
819 name, (res == GNUNET_OK) ? "OK" : "FAIL");
823 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_PUT_RESPONSE");
824 rpr_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE);
825 rpr_msg.gns_header.header.size = htons (sizeof (struct RecordPutResponseMessage));
826 rpr_msg.gns_header.r_id = htonl (rid);
827 rpr_msg.op_result = htonl (res);
828 GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &rpr_msg, GNUNET_NO);
830 GNUNET_SERVER_receive_done (client, GNUNET_OK);
833 struct CreateRecordContext
835 struct GNUNET_NAMESTORE_RecordData *rd;
836 struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
837 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey;
838 struct GNUNET_TIME_Absolute expire;
845 handle_create_record_it (void *cls,
846 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey,
847 struct GNUNET_TIME_Absolute expire,
849 unsigned int rd_count,
850 const struct GNUNET_NAMESTORE_RecordData *rd,
851 const struct GNUNET_CRYPTO_RsaSignature *signature)
853 struct CreateRecordContext *crc = cls;
854 struct GNUNET_NAMESTORE_RecordData *rd_new = NULL;
855 struct GNUNET_CRYPTO_RsaSignature dummy_signature;
856 struct GNUNET_TIME_Absolute block_expiration;
858 int exist = GNUNET_SYSERR;
859 int update = GNUNET_NO;
861 int rd_count_new = 0;
863 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u existing records for `%s'\n", rd_count, crc->name);
864 for (c = 0; c < rd_count; c++)
866 if ( (crc->rd->record_type == GNUNET_NAMESTORE_TYPE_PKEY) &&
867 (rd[c].record_type == GNUNET_NAMESTORE_TYPE_PKEY))
869 /* Update unique PKEY */
874 if ( (crc->rd->record_type == GNUNET_NAMESTORE_TYPE_PSEU) &&
875 (rd[c].record_type == GNUNET_NAMESTORE_TYPE_PSEU))
877 /* Update unique PSEU */
882 if ((crc->rd->record_type == rd[c].record_type) &&
883 (crc->rd->data_size == rd[c].data_size) &&
884 (0 == memcmp (crc->rd->data, rd[c].data, rd[c].data_size)))
886 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
887 "Found existing records for `%s' to update expiration date!\n",
890 if ( (crc->rd->expiration_time != rd[c].expiration_time) &&
891 ((crc->rd->flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION)
892 == (rd[c].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION) ) )
898 if (exist == GNUNET_SYSERR)
900 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
901 "No existing record for name `%s'!\n",
903 rd_new = GNUNET_malloc ((rd_count+1) * sizeof (struct GNUNET_NAMESTORE_RecordData));
904 memcpy (rd_new, rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
905 rd_count_new = rd_count + 1;
906 rd_new[rd_count] = *(crc->rd);
908 else if (update == GNUNET_NO)
910 /* Exact same record already exists */
911 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
912 "Matching record for %s' exists, no change required!\n",
920 GNUNET_assert (GNUNET_YES == update);
921 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
922 "Updating existing records for `%s'!\n",
924 rd_new = GNUNET_malloc ((rd_count) * sizeof (struct GNUNET_NAMESTORE_RecordData));
925 memcpy (rd_new, rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
926 rd_count_new = rd_count;
927 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
928 (0 == (crc->rd->flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION))
929 ? "Updating absolute expiration from %llu to %llu!\n"
930 : "Updating relative expiration from %llu to %llu!\n",
931 rd_new[exist].expiration_time, crc->rd->expiration_time);
932 rd_new[exist] = *(crc->rd);
935 block_expiration = GNUNET_TIME_absolute_max(crc->expire, expire);
936 if (block_expiration.abs_value != expire.abs_value)
937 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
938 "Updated block expiration time\n");
940 memset (&dummy_signature, '\0', sizeof (dummy_signature));
942 /* Database operation */
943 GNUNET_assert ((rd_new != NULL) && (rd_count_new > 0));
944 res = GSN_database->put_records(GSN_database->cls,
945 (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) crc->pubkey,
948 rd_count_new, rd_new,
950 GNUNET_break (GNUNET_OK == res);
951 if (res == GNUNET_OK)
952 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully put record for `%s' in database \n", crc->name);
954 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to put record for `%s' in database \n", crc->name);
958 GNUNET_free_non_null (rd_new);
962 /* failed to create the record */
963 crc->res = GNUNET_SYSERR;
966 /* database operations OK */
967 if (GNUNET_YES == update)
969 /* we updated an existing record */
970 crc->res = GNUNET_NO;
974 /* we created a new record */
975 crc->res = GNUNET_YES;
979 /* identical entry existed, so we did nothing */
980 crc->res = GNUNET_NO;
985 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Update result for name `%s' %u\n", crc->name, res);
990 * Handles a 'GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE' message
993 * @param client GNUNET_SERVER_Client sending the message
994 * @param message message of type 'struct RecordCreateMessage'
997 handle_record_create (void *cls,
998 struct GNUNET_SERVER_Client *client,
999 const struct GNUNET_MessageHeader *message)
1001 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_RECORD_CREATE");
1002 struct GNUNET_NAMESTORE_Client *nc;
1003 struct RecordCreateMessage *rp_msg;
1004 struct GNUNET_NAMESTORE_CryptoContainer *cc;
1005 struct CreateRecordContext crc;
1006 struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
1007 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
1008 struct RecordCreateResponseMessage rcr_msg;
1009 struct GNUNET_CRYPTO_ShortHashCode pubkey_hash;
1010 struct GNUNET_HashCode long_hash;
1013 size_t msg_size_exp;
1022 int res = GNUNET_SYSERR;
1023 crc.res = GNUNET_SYSERR;
1025 if (ntohs (message->size) < sizeof (struct RecordCreateMessage))
1027 GNUNET_break_op (0);
1028 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1032 nc = client_lookup(client);
1035 GNUNET_break_op (0);
1036 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1040 rp_msg = (struct RecordCreateMessage *) message;
1041 rid = ntohl (rp_msg->gns_header.r_id);
1042 name_len = ntohs (rp_msg->name_len);
1043 msg_size = ntohs (message->size);
1044 rd_count = ntohs (rp_msg->rd_count);
1045 rd_ser_len = ntohs (rp_msg->rd_len);
1046 key_len = ntohs (rp_msg->pkey_len);
1047 msg_size_exp = sizeof (struct RecordCreateMessage) + key_len + name_len + rd_ser_len;
1049 if (msg_size != msg_size_exp)
1051 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expected message %u size but message size is %u \n", msg_size_exp, msg_size);
1052 GNUNET_break_op (0);
1053 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1057 if ((name_len == 0) || (name_len > 256))
1059 GNUNET_break_op (0);
1060 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1064 pkey_tmp = (char *) &rp_msg[1];
1065 name_tmp = &pkey_tmp[key_len];
1066 rd_ser = &name_tmp[name_len];
1068 if (name_tmp[name_len -1] != '\0')
1070 GNUNET_break_op (0);
1071 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1075 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
1077 res = GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_ser, rd_count, rd);
1078 if ((res != GNUNET_OK) || (rd_count != 1))
1080 GNUNET_break_op (0);
1083 /* Extracting and converting private key */
1084 pkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len);
1085 GNUNET_assert (pkey != NULL);
1086 GNUNET_CRYPTO_rsa_key_get_public(pkey, &pub);
1087 GNUNET_CRYPTO_short_hash (&pub, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pubkey_hash);
1088 GNUNET_CRYPTO_short_hash_double (&pubkey_hash, &long_hash);
1090 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash))
1092 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received new private key for zone `%s'\n",GNUNET_short_h2s(&pubkey_hash));
1094 cc = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_CryptoContainer));
1095 cc->privkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len);
1096 cc->pubkey = GNUNET_malloc(sizeof (pub));
1097 memcpy (cc->pubkey, &pub, sizeof(pub));
1098 cc->zone = pubkey_hash;
1099 GNUNET_CONTAINER_multihashmap_put(zonekeys, &long_hash, cc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1102 crc.expire = GNUNET_TIME_absolute_ntoh(rp_msg->expire);
1103 crc.res = GNUNET_SYSERR;
1107 crc.name = name_tmp;
1109 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating record for name `%s' in zone `%s'\n", name_tmp, GNUNET_short_h2s(&pubkey_hash));
1111 /* Get existing records for name */
1112 res = GSN_database->iterate_records(GSN_database->cls, &pubkey_hash, name_tmp, 0, &handle_create_record_it, &crc);
1113 if (res != GNUNET_SYSERR)
1115 GNUNET_CRYPTO_rsa_key_free(pkey);
1120 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_CREATE_RESPONSE");
1121 rcr_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE);
1122 rcr_msg.gns_header.header.size = htons (sizeof (struct RecordCreateResponseMessage));
1123 rcr_msg.gns_header.r_id = htonl (rid);
1124 if ((GNUNET_OK == res) && (crc.res == GNUNET_YES))
1125 rcr_msg.op_result = htonl (GNUNET_YES);
1126 else if ((GNUNET_OK == res) && (crc.res == GNUNET_NO))
1127 rcr_msg.op_result = htonl (GNUNET_NO);
1129 rcr_msg.op_result = htonl (GNUNET_SYSERR);
1130 GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &rcr_msg, GNUNET_NO);
1132 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1136 struct RemoveRecordContext
1138 struct GNUNET_NAMESTORE_RecordData *rd;
1139 struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
1145 handle_record_remove_it (void *cls,
1146 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
1147 struct GNUNET_TIME_Absolute expire,
1149 unsigned int rd_count,
1150 const struct GNUNET_NAMESTORE_RecordData *rd,
1151 const struct GNUNET_CRYPTO_RsaSignature *signature)
1153 struct RemoveRecordContext *rrc = cls;
1157 unsigned int rd_count_new;
1159 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name `%s 'currently has %u records\n", name, rd_count);
1163 /* Could not find record to remove */
1168 /* Find record to remove */
1169 found = GNUNET_SYSERR;
1170 for (c = 0; c < rd_count; c++)
1173 if (rd[c].flags != rrc->rd->flags)
1175 if (rd[c].record_type != rrc->rd->record_type)
1178 if (rd[c].data_size != rrc->rd->data_size)
1181 if (0 != memcmp (rd[c].data, rrc->rd->data, rrc->rd->data_size))
1184 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found record to remove!\n", rd_count);
1188 if (GNUNET_SYSERR == found)
1190 /* Could not find record to remove */
1195 if (rd_count-1 == 0)
1197 struct GNUNET_CRYPTO_ShortHashCode pubkey_hash;
1198 GNUNET_CRYPTO_short_hash (zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pubkey_hash);
1199 res = GSN_database->remove_records (GSN_database->cls,
1202 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1203 "No records left for name `%s', removing name\n",
1205 if (GNUNET_OK != res)
1207 /* Could put records into database */
1215 rd_count_new = rd_count -1;
1216 struct GNUNET_NAMESTORE_RecordData rd_new[rd_count_new];
1218 unsigned int c2 = 0;
1219 for (c = 0; c < rd_count; c++)
1223 GNUNET_assert (c2 < rd_count_new);
1229 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name `%s' now has %u records\n", name, rd_count_new);
1231 /* Create dummy signature */
1232 struct GNUNET_CRYPTO_RsaSignature dummy_signature;
1233 memset (&dummy_signature, '\0', sizeof (dummy_signature));
1237 res = GSN_database->put_records(GSN_database->cls,
1241 rd_count_new, rd_new,
1243 if (GNUNET_OK != res)
1245 /* Could put records into database */
1254 * Handles a 'GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE' message
1257 * @param client GNUNET_SERVER_Client sending the message
1258 * @param message message of type 'struct RecordRemoveMessage'
1261 handle_record_remove (void *cls,
1262 struct GNUNET_SERVER_Client *client,
1263 const struct GNUNET_MessageHeader *message)
1265 struct GNUNET_NAMESTORE_Client *nc;
1266 const struct RecordRemoveMessage *rr_msg;
1267 struct RecordRemoveResponseMessage rrr_msg;
1268 struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
1269 struct GNUNET_NAMESTORE_CryptoContainer *cc;
1270 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
1271 struct GNUNET_CRYPTO_ShortHashCode pubkey_hash;
1272 struct GNUNET_HashCode long_hash;
1273 const char *pkey_tmp;
1274 const char *name_tmp;
1280 size_t msg_size_exp = 0;
1284 int res = GNUNET_SYSERR;
1286 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_RECORD_REMOVE");
1287 if (ntohs (message->size) < sizeof (struct RecordRemoveMessage))
1289 GNUNET_break_op (0);
1290 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1294 nc = client_lookup(client);
1297 GNUNET_break_op (0);
1298 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1302 rr_msg = (const struct RecordRemoveMessage *) message;
1303 rid = ntohl (rr_msg->gns_header.r_id);
1304 name_len = ntohs (rr_msg->name_len);
1305 rd_ser_len = ntohs (rr_msg->rd_len);
1306 rd_count = ntohs (rr_msg->rd_count);
1307 key_len = ntohs (rr_msg->pkey_len);
1308 msg_size = ntohs (message->size);
1310 if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
1312 GNUNET_break_op (0);
1313 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1317 if ((name_len >=256) || (name_len == 0))
1319 GNUNET_break_op (0);
1320 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1324 msg_size_exp = sizeof (struct RecordRemoveMessage) + key_len + name_len + rd_ser_len;
1325 if (msg_size != msg_size_exp)
1327 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expected message %u size but message size is %u \n", msg_size_exp, msg_size);
1328 GNUNET_break_op (0);
1329 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1333 pkey_tmp = (const char *) &rr_msg[1];
1334 name_tmp = &pkey_tmp[key_len];
1335 rd_ser = &name_tmp[name_len];
1338 if ((name_len == 0) || (name_len > 256))
1340 GNUNET_break_op (0);
1341 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1345 if (name_tmp[name_len -1] != '\0')
1347 GNUNET_break_op (0);
1348 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1352 /* Extracting and converting private key */
1353 pkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len);
1354 GNUNET_assert (pkey != NULL);
1355 GNUNET_CRYPTO_rsa_key_get_public(pkey, &pub);
1356 GNUNET_CRYPTO_short_hash (&pub, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pubkey_hash);
1357 GNUNET_CRYPTO_short_hash_double (&pubkey_hash, &long_hash);
1359 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash))
1361 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1362 "Received new private key for zone `%s'\n",
1363 GNUNET_short_h2s(&pubkey_hash));
1364 cc = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_CryptoContainer));
1365 cc->privkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len);
1366 cc->pubkey = GNUNET_malloc(sizeof (pub));
1367 memcpy (cc->pubkey, &pub, sizeof(pub));
1368 cc->zone = pubkey_hash;
1370 GNUNET_CONTAINER_multihashmap_put(zonekeys, &long_hash, cc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1374 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
1375 res = GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_ser, rd_count, rd);
1376 if ((res != GNUNET_OK) || (rd_count > 1))
1378 GNUNET_break_op (0);
1384 /* remove the whole name and all records */
1385 /* Database operation */
1386 res = GSN_database->remove_records (GSN_database->cls,
1389 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing name `%s': %s\n",
1390 name_tmp, (GNUNET_OK == res) ? "OK" : "FAIL");
1392 if (GNUNET_OK != res)
1393 /* Could not remove entry from database */
1400 /* remove a single record */
1401 struct RemoveRecordContext rrc;
1405 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing record for name `%s' in zone `%s'\n", name_tmp, GNUNET_short_h2s(&pubkey_hash));
1407 /* Database operation */
1408 res = GSN_database->iterate_records (GSN_database->cls,
1412 handle_record_remove_it, &rrc);
1414 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing record for name `%s': %s\n",
1415 name_tmp, (rrc.op_res == 0) ? "OK" : "FAIL");
1420 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_REMOVE_RESPONSE");
1421 rrr_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE);
1422 rrr_msg.gns_header.header.size = htons (sizeof (struct RecordRemoveResponseMessage));
1423 rrr_msg.gns_header.r_id = htonl (rid);
1424 rrr_msg.op_result = htonl (res);
1425 GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &rrr_msg, GNUNET_NO);
1427 GNUNET_CRYPTO_rsa_key_free (pkey);
1429 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1433 struct ZoneToNameCtx
1435 struct GNUNET_NAMESTORE_Client *nc;
1440 handle_zone_to_name_it (void *cls,
1441 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
1442 struct GNUNET_TIME_Absolute expire,
1444 unsigned int rd_count,
1445 const struct GNUNET_NAMESTORE_RecordData *rd,
1446 const struct GNUNET_CRYPTO_RsaSignature *signature)
1448 struct ZoneToNameCtx *ztn_ctx = cls;
1449 struct ZoneToNameResponseMessage *ztnr_msg;
1450 int16_t res = GNUNET_SYSERR;
1451 uint16_t name_len = 0;
1452 uint16_t rd_ser_len = 0 ;
1453 int32_t contains_sig = 0;
1454 size_t msg_size = 0;
1456 char *rd_ser = NULL;
1461 if ((zone_key != NULL) && (name != NULL))
1464 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found results: name is `%s', has %u records\n", name, rd_count);
1466 name_len = strlen (name) +1;
1470 /* no result found */
1471 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found no results\n");
1478 rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
1479 rd_ser = GNUNET_malloc (rd_ser_len);
1480 GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser);
1485 if (signature != NULL)
1486 contains_sig = GNUNET_YES;
1488 contains_sig = GNUNET_NO;
1492 msg_size = sizeof (struct ZoneToNameResponseMessage) + name_len + rd_ser_len + contains_sig * sizeof (struct GNUNET_CRYPTO_RsaSignature);
1493 ztnr_msg = GNUNET_malloc (msg_size);
1495 name_tmp = (char *) &ztnr_msg[1];
1496 rd_tmp = &name_tmp[name_len];
1497 sig_tmp = &rd_tmp[rd_ser_len];
1499 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "ZONE_TO_NAME_RESPONSE");
1500 ztnr_msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE);
1501 ztnr_msg->gns_header.header.size = htons (msg_size);
1502 ztnr_msg->gns_header.r_id = htonl (ztn_ctx->rid);
1503 ztnr_msg->res = htons (res);
1504 ztnr_msg->rd_len = htons (rd_ser_len);
1505 ztnr_msg->rd_count = htons (rd_count);
1506 ztnr_msg->name_len = htons (name_len);
1507 ztnr_msg->expire = GNUNET_TIME_absolute_hton(expire);
1508 if (zone_key != NULL)
1509 ztnr_msg->zone_key = *zone_key;
1511 memset (&ztnr_msg->zone_key, '\0', sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
1513 if ((name_len > 0) && (name != NULL))
1514 memcpy (name_tmp, name, name_len);
1516 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);
1517 if ((rd_ser_len > 0) && (rd_ser != NULL))
1518 memcpy (rd_tmp, rd_ser, rd_ser_len);
1519 if ((GNUNET_YES == contains_sig) && (signature != NULL))
1520 memcpy (sig_tmp, signature, contains_sig * sizeof (struct GNUNET_CRYPTO_RsaSignature));
1522 GNUNET_SERVER_notification_context_unicast (snc, ztn_ctx->nc->client, (const struct GNUNET_MessageHeader *) ztnr_msg, GNUNET_NO);
1523 GNUNET_free (ztnr_msg);
1524 GNUNET_free_non_null (rd_ser);
1528 * Handles a 'GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME' message
1531 * @param client GNUNET_SERVER_Client sending the message
1532 * @param message message of type 'struct ZoneToNameMessage'
1535 handle_zone_to_name (void *cls,
1536 struct GNUNET_SERVER_Client *client,
1537 const struct GNUNET_MessageHeader *message)
1539 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "ZONE_TO_NAME");
1540 struct GNUNET_NAMESTORE_Client *nc;
1541 struct ZoneToNameMessage *ztn_msg;
1542 struct ZoneToNameCtx ztn_ctx;
1543 size_t msg_size = 0;
1546 if (ntohs (message->size) != sizeof (struct ZoneToNameMessage))
1548 GNUNET_break_op (0);
1549 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1553 nc = client_lookup(client);
1556 GNUNET_break_op (0);
1557 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1561 ztn_msg = (struct ZoneToNameMessage *) message;
1563 if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
1565 GNUNET_break_op (0);
1566 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1570 rid = ntohl (ztn_msg->gns_header.r_id);
1575 struct GNUNET_CRYPTO_ShortHashAsciiEncoded z_tmp;
1576 GNUNET_CRYPTO_short_hash_to_enc(&ztn_msg->zone, &z_tmp);
1577 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up name for zone `%s' in zone `%s'\n",
1579 GNUNET_short_h2s (&ztn_msg->value_zone));
1581 GSN_database->zone_to_name (GSN_database->cls, &ztn_msg->zone, &ztn_msg->value_zone, &handle_zone_to_name_it, &ztn_ctx);
1583 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1588 * Copy record, data has to be free separetely
1591 copy_record (const struct GNUNET_NAMESTORE_RecordData *src, struct GNUNET_NAMESTORE_RecordData *dest)
1594 memcpy (dest, src, sizeof (struct GNUNET_NAMESTORE_RecordData));
1595 dest->data = GNUNET_malloc (src->data_size);
1596 memcpy ((void *) dest->data, src->data, src->data_size);
1599 struct ZoneIterationProcResult
1601 struct GNUNET_NAMESTORE_ZoneIteration *zi;
1603 int res_iteration_finished;
1604 int records_included;
1608 struct GNUNET_CRYPTO_ShortHashCode zone_hash;
1609 struct GNUNET_NAMESTORE_RecordData *rd;
1610 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded zone_key;
1611 struct GNUNET_CRYPTO_RsaSignature signature;
1612 struct GNUNET_TIME_Absolute expire;
1617 zone_iteraterate_proc (void *cls,
1618 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
1619 struct GNUNET_TIME_Absolute expire,
1621 unsigned int rd_count,
1622 const struct GNUNET_NAMESTORE_RecordData *rd,
1623 const struct GNUNET_CRYPTO_RsaSignature *signature)
1625 struct ZoneIterationProcResult *proc = cls;
1626 struct GNUNET_NAMESTORE_RecordData *rd_filtered;
1627 struct GNUNET_CRYPTO_RsaSignature *new_signature;
1628 struct GNUNET_NAMESTORE_CryptoContainer *cc;
1629 struct GNUNET_CRYPTO_ShortHashCode hash;
1630 struct GNUNET_HashCode long_hash;
1631 struct GNUNET_TIME_Absolute e;
1632 unsigned int rd_count_filtered = 0;
1636 proc->res_iteration_finished = GNUNET_NO;
1637 proc->records_included = 0;
1639 if ((zone_key == NULL) && (name == NULL))
1641 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
1642 proc->res_iteration_finished = GNUNET_YES;
1646 else if ((zone_key != NULL) && (name != NULL)) /* just a safety check */
1648 rd_filtered = GNUNET_malloc (rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
1649 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received result for zone iteration: `%s'\n", name);
1650 for (c = 0; c < rd_count; c++)
1652 include = GNUNET_YES;
1653 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: 0x%x must have 0x%x \n",
1654 c, rd[c].flags, proc->zi->must_have_flags);
1655 /* Checking must have flags */
1656 if ((rd[c].flags & proc->zi->must_have_flags) == proc->zi->must_have_flags)
1659 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Include \n", c);
1663 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Not include \n", c);
1664 include = GNUNET_NO;
1667 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: 0x%x must not have 0x%x\n",
1668 c, rd[c].flags, proc->zi->must_not_have_flags);
1669 if ((rd[c].flags & proc->zi->must_not_have_flags) != 0)
1671 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Not include \n", c);
1672 include = GNUNET_NO;
1677 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Include \n", c);
1679 if (GNUNET_YES == include)
1681 copy_record (&rd[c], &rd_filtered[rd_count_filtered]);
1682 rd_count_filtered++;
1686 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Included %i of %i records \n", rd_count_filtered, rd_count);
1688 proc->records_included = rd_count_filtered;
1689 if (0 == rd_count_filtered)
1691 GNUNET_free (rd_filtered);
1694 proc->rd = rd_filtered;
1695 proc->name = GNUNET_strdup(name);
1696 memcpy (&proc->zone_key, zone_key, sizeof (proc->zone_key));
1699 proc->has_signature = GNUNET_NO;
1700 GNUNET_CRYPTO_short_hash (zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &hash);
1701 GNUNET_CRYPTO_short_hash_double(&hash, &long_hash);
1702 proc->zone_hash = hash;
1704 if (GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash))
1706 cc = GNUNET_CONTAINER_multihashmap_get(zonekeys, &long_hash);
1707 e = get_block_expiration_time(rd_count_filtered, rd_filtered);
1709 new_signature = GNUNET_NAMESTORE_create_signature(cc->privkey, e, name, rd_filtered, rd_count_filtered);
1710 GNUNET_assert (signature != NULL);
1711 proc->signature = (*new_signature);
1712 GNUNET_free (new_signature);
1713 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating signature for `%s' in zone `%s' with %u records and expiration %llu\n",
1714 name, GNUNET_short_h2s(&hash), rd_count_filtered, e.abs_value);
1715 proc->has_signature = GNUNET_YES;
1717 else if (rd_count_filtered == rd_count)
1719 proc->expire = expire;
1720 if (NULL != signature)
1722 proc->signature = (*signature);
1723 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using provided signature for `%s' in zone `%s' with %u records and expiration %llu\n",
1724 name, GNUNET_short_h2s(&hash), rd_count_filtered, expire.abs_value);
1725 proc->has_signature = GNUNET_YES;
1729 memset (&proc->signature, '\0', sizeof (proc->signature));
1730 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No signature provided for `%s'\n", name);
1743 find_next_zone_iteration_result (struct ZoneIterationProcResult *proc)
1746 struct GNUNET_CRYPTO_ShortHashCode *zone;
1748 if (GNUNET_YES == proc->zi->has_zone)
1749 zone = &proc->zi->zone;
1755 GSN_database->iterate_records (GSN_database->cls, zone , NULL, proc->zi->offset, &zone_iteraterate_proc, proc);
1758 while ((proc->records_included == 0) && (GNUNET_NO == proc->res_iteration_finished));
1763 send_zone_iteration_result (struct ZoneIterationProcResult *proc)
1765 struct GNUNET_NAMESTORE_ZoneIteration *zi = proc->zi;
1767 if (GNUNET_YES == proc->res_iteration_finished)
1769 struct ZoneIterationResponseMessage zir_msg;
1770 if (zi->has_zone == GNUNET_YES)
1771 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No more results for zone `%s'\n", GNUNET_short_h2s(&zi->zone));
1773 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No more results for all zones\n");
1775 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending empty `%s' message\n", "ZONE_ITERATION_RESPONSE");
1776 zir_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE);
1777 zir_msg.gns_header.header.size = htons (sizeof (struct ZoneIterationResponseMessage));
1778 zir_msg.gns_header.r_id = htonl(zi->request_id);
1779 zir_msg.expire = GNUNET_TIME_absolute_hton(GNUNET_TIME_UNIT_ZERO_ABS);
1780 zir_msg.name_len = htons (0);
1781 zir_msg.reserved = htons (0);
1782 zir_msg.rd_count = htons (0);
1783 zir_msg.rd_len = htons (0);
1784 memset (&zir_msg.public_key, '\0', sizeof (zir_msg.public_key));
1785 memset (&zir_msg.signature, '\0', sizeof (zir_msg.signature));
1786 GNUNET_SERVER_notification_context_unicast (snc, zi->client->client, (const struct GNUNET_MessageHeader *) &zir_msg, GNUNET_NO);
1788 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing zone iterator\n");
1789 GNUNET_CONTAINER_DLL_remove (zi->client->op_head, zi->client->op_tail, zi);
1795 GNUNET_assert (proc->records_included > 0);
1797 struct ZoneIterationResponseMessage *zir_msg;
1798 if (zi->has_zone == GNUNET_YES)
1799 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending name `%s' for iteration over zone `%s'\n",
1800 proc->name, GNUNET_short_h2s(&zi->zone));
1801 if (zi->has_zone == GNUNET_NO)
1802 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending name `%s' for iteration over all zones\n",
1810 name_len = strlen (proc->name) +1;
1812 rd_ser_len = GNUNET_NAMESTORE_records_get_size(proc->records_included, proc->rd);
1813 char rd_ser[rd_ser_len];
1814 GNUNET_NAMESTORE_records_serialize(proc->records_included, proc->rd, rd_ser_len, rd_ser);
1815 msg_size = sizeof (struct ZoneIterationResponseMessage) + name_len + rd_ser_len;
1816 zir_msg = GNUNET_malloc(msg_size);
1818 name_tmp = (char *) &zir_msg[1];
1819 rd_tmp = &name_tmp[name_len];
1821 zir_msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE);
1822 zir_msg->gns_header.header.size = htons (msg_size);
1823 zir_msg->gns_header.r_id = htonl(zi->request_id);
1824 zir_msg->expire = GNUNET_TIME_absolute_hton(proc->expire);
1825 zir_msg->reserved = htons (0);
1826 zir_msg->name_len = htons (name_len);
1827 zir_msg->rd_count = htons (proc->records_included);
1828 zir_msg->rd_len = htons (rd_ser_len);
1829 zir_msg->signature = proc->signature;
1830 zir_msg->public_key = proc->zone_key;
1831 memcpy (name_tmp, proc->name, name_len);
1832 memcpy (rd_tmp, rd_ser, rd_ser_len);
1834 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message with size %u\n", "ZONE_ITERATION_RESPONSE", msg_size);
1835 GNUNET_SERVER_notification_context_unicast (snc, zi->client->client, (const struct GNUNET_MessageHeader *) zir_msg, GNUNET_NO);
1836 GNUNET_free (zir_msg);
1841 clean_up_zone_iteration_result (struct ZoneIterationProcResult *proc)
1844 GNUNET_free_non_null (proc->name);
1845 for (c = 0; c < proc->records_included; c++)
1847 GNUNET_free ((void *) proc->rd[c].data);
1849 GNUNET_free_non_null (proc->rd);
1856 * Handles a 'GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START' message
1859 * @param client GNUNET_SERVER_Client sending the message
1860 * @param message message of type 'struct ZoneIterationStartMessage'
1863 handle_iteration_start (void *cls,
1864 struct GNUNET_SERVER_Client *client,
1865 const struct GNUNET_MessageHeader *message)
1867 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "ZONE_ITERATION_START");
1869 struct ZoneIterationStartMessage *zis_msg = (struct ZoneIterationStartMessage *) message;
1870 struct GNUNET_NAMESTORE_Client *nc;
1871 struct GNUNET_NAMESTORE_ZoneIteration *zi;
1872 struct GNUNET_CRYPTO_ShortHashCode dummy;
1873 struct ZoneIterationProcResult proc;
1875 nc = client_lookup(client);
1878 GNUNET_break_op (0);
1879 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1883 zi = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_ZoneIteration));
1884 zi->request_id = ntohl (zis_msg->gns_header.r_id);
1887 zi->must_have_flags = ntohs (zis_msg->must_have_flags);
1888 zi->must_not_have_flags = ntohs (zis_msg->must_not_have_flags);
1890 memset (&dummy, '\0', sizeof (dummy));
1891 if (0 == memcmp (&dummy, &zis_msg->zone, sizeof (dummy)))
1893 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting to iterate over all zones\n");
1894 zi->zone = zis_msg->zone;
1895 zi->has_zone = GNUNET_NO;
1899 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting to iterate over zone `%s'\n", GNUNET_short_h2s (&zis_msg->zone));
1900 zi->zone = zis_msg->zone;
1901 zi->has_zone = GNUNET_YES;
1904 GNUNET_CONTAINER_DLL_insert (nc->op_head, nc->op_tail, zi);
1907 find_next_zone_iteration_result (&proc);
1908 if (GNUNET_YES == proc.res_iteration_finished)
1910 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration done\n");
1912 else if (proc.records_included != 0)
1914 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration return %u records\n", proc.records_included);
1916 send_zone_iteration_result (&proc);
1917 clean_up_zone_iteration_result (&proc);
1919 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1924 * Handles a 'GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP' message
1927 * @param client GNUNET_SERVER_Client sending the message
1928 * @param message message of type 'struct ZoneIterationStopMessage'
1931 handle_iteration_stop (void *cls,
1932 struct GNUNET_SERVER_Client *client,
1933 const struct GNUNET_MessageHeader *message)
1935 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "ZONE_ITERATION_STOP");
1937 struct GNUNET_NAMESTORE_Client *nc;
1938 struct GNUNET_NAMESTORE_ZoneIteration *zi;
1939 struct ZoneIterationStopMessage *zis_msg;
1942 nc = client_lookup(client);
1945 GNUNET_break_op (0);
1946 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1950 zis_msg = (struct ZoneIterationStopMessage *) message;
1951 rid = ntohl (zis_msg->gns_header.r_id);
1952 for (zi = nc->op_head; zi != NULL; zi = zi->next)
1954 if (zi->request_id == rid)
1959 GNUNET_break_op (0);
1960 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1964 GNUNET_CONTAINER_DLL_remove(nc->op_head, nc->op_tail, zi);
1965 if (GNUNET_YES == zi->has_zone)
1966 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopped zone iteration for zone `%s'\n", GNUNET_short_h2s (&zi->zone));
1968 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopped zone iteration all zones\n");
1971 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1976 * Handles a 'GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP' message
1979 * @param client GNUNET_SERVER_Client sending the message
1980 * @param message message of type 'struct ZoneIterationNextMessage'
1983 handle_iteration_next (void *cls,
1984 struct GNUNET_SERVER_Client *client,
1985 const struct GNUNET_MessageHeader *message)
1987 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "ZONE_ITERATION_NEXT");
1989 struct GNUNET_NAMESTORE_Client *nc;
1990 struct GNUNET_NAMESTORE_ZoneIteration *zi;
1991 struct ZoneIterationNextMessage *zis_msg;
1994 nc = client_lookup(client);
1997 GNUNET_break_op (0);
1998 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2002 zis_msg = (struct ZoneIterationNextMessage *) message;
2003 rid = ntohl (zis_msg->gns_header.r_id);
2004 for (zi = nc->op_head; zi != NULL; zi = zi->next)
2006 if (zi->request_id == rid)
2011 GNUNET_break_op (0);
2012 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2016 struct ZoneIterationProcResult proc;
2019 find_next_zone_iteration_result (&proc);
2020 if (GNUNET_YES == proc.res_iteration_finished)
2022 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration done\n");
2024 else if (proc.records_included != 0)
2026 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration return %u records\n", proc.records_included);
2028 send_zone_iteration_result (&proc);
2029 clean_up_zone_iteration_result (&proc);
2031 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2035 zonekey_file_it (void *cls, const char *filename)
2037 struct GNUNET_HashCode long_hash;
2039 if ((filename != NULL) && (NULL != strstr(filename, ".zkey")))
2041 struct GNUNET_CRYPTO_RsaPrivateKey *privkey;
2042 struct GNUNET_NAMESTORE_CryptoContainer *c;
2043 privkey = GNUNET_CRYPTO_rsa_key_create_from_file(filename);
2044 if (privkey == NULL)
2047 c = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_CryptoContainer));
2048 c->pubkey = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
2049 c->privkey = privkey;
2050 GNUNET_CRYPTO_rsa_key_get_public(privkey, c->pubkey);
2051 GNUNET_CRYPTO_short_hash(c->pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &c->zone);
2053 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found zonefile for zone `%s'\n", GNUNET_short_h2s (&c->zone));
2054 GNUNET_CRYPTO_short_hash_double (&c->zone, &long_hash);
2055 GNUNET_CONTAINER_multihashmap_put(zonekeys, &long_hash, c, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
2063 * Process template requests.
2065 * @param cls closure
2066 * @param server the initialized server
2067 * @param cfg configuration to use
2070 run (void *cls, struct GNUNET_SERVER_Handle *server,
2071 const struct GNUNET_CONFIGURATION_Handle *cfg)
2075 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n");
2077 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
2078 {&handle_start, NULL,
2079 GNUNET_MESSAGE_TYPE_NAMESTORE_START, sizeof (struct StartMessage)},
2080 {&handle_lookup_name, NULL,
2081 GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME, 0},
2082 {&handle_record_put, NULL,
2083 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT, 0},
2084 {&handle_record_create, NULL,
2085 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE, 0},
2086 {&handle_record_remove, NULL,
2087 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE, 0},
2088 {&handle_zone_to_name, NULL,
2089 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME, 0},
2090 {&handle_iteration_start, NULL,
2091 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START, sizeof (struct ZoneIterationStartMessage)},
2092 {&handle_iteration_next, NULL,
2093 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT, 0},
2094 {&handle_iteration_stop, NULL,
2095 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP, 0},
2101 /* Load private keys from disk */
2103 GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore", "zonefile_directory",
2104 &zonefile_directory))
2106 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("No directory to load zonefiles specified in configuration\n"));
2107 GNUNET_SCHEDULER_add_now (&cleanup_task, NULL);
2111 if (GNUNET_NO == GNUNET_DISK_file_test (zonefile_directory))
2113 if (GNUNET_SYSERR == GNUNET_DISK_directory_create (zonefile_directory))
2115 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Creating directory `%s' for zone files failed!\n"), zonefile_directory);
2116 GNUNET_SCHEDULER_add_now (&cleanup_task, NULL);
2119 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created directory `%s' for zone files\n", zonefile_directory);
2122 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scanning directory `%s' for zone files\n", zonefile_directory);
2123 zonekeys = GNUNET_CONTAINER_multihashmap_create (10);
2124 GNUNET_DISK_directory_scan (zonefile_directory, zonekey_file_it, &counter);
2125 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u zone files\n", counter);
2127 /* Loading database plugin */
2129 GNUNET_CONFIGURATION_get_value_string (cfg, "namestore", "database",
2131 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
2133 GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database);
2134 GSN_database = GNUNET_PLUGIN_load (db_lib_name, (void *) GSN_cfg);
2135 GNUNET_free (database);
2136 if (GSN_database == NULL)
2138 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not load database backend `%s'\n",
2140 GNUNET_SCHEDULER_add_now (&cleanup_task, NULL);
2144 /* Configuring server handles */
2145 GNUNET_SERVER_add_handlers (server, handlers);
2146 snc = GNUNET_SERVER_notification_context_create (server, 16);
2147 GNUNET_SERVER_disconnect_notify (server,
2148 &client_disconnect_notification,
2151 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task,
2158 * The main function for the template service.
2160 * @param argc number of arguments from the command line
2161 * @param argv command line arguments
2162 * @return 0 ok, 1 on error
2165 main (int argc, char *const *argv)
2167 return (GNUNET_OK ==
2168 GNUNET_SERVICE_run (argc, argv, "namestore",
2169 GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1;
2172 /* end of gnunet-service-namestore.c */