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"
37 * A namestore operation.
39 struct GNUNET_NAMESTORE_ZoneIteration
41 struct GNUNET_NAMESTORE_ZoneIteration *next;
42 struct GNUNET_NAMESTORE_ZoneIteration *prev;
44 struct GNUNET_NAMESTORE_Client * client;
61 struct GNUNET_NAMESTORE_Client
63 struct GNUNET_NAMESTORE_Client *next;
64 struct GNUNET_NAMESTORE_Client *prev;
66 struct GNUNET_SERVER_Client * client;
68 struct GNUNET_NAMESTORE_ZoneIteration *op_head;
69 struct GNUNET_NAMESTORE_ZoneIteration *op_tail;
75 * Configuration handle.
77 const struct GNUNET_CONFIGURATION_Handle *GSN_cfg;
79 static struct GNUNET_NAMESTORE_PluginFunctions *GSN_database;
82 * Our notification context.
84 static struct GNUNET_SERVER_NotificationContext *snc;
86 static char *db_lib_name;
88 static struct GNUNET_NAMESTORE_Client *client_head;
89 static struct GNUNET_NAMESTORE_Client *client_tail;
93 * Task run during shutdown.
99 cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
101 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n");
103 struct GNUNET_NAMESTORE_ZoneIteration * no;
104 struct GNUNET_NAMESTORE_ZoneIteration * tmp;
105 struct GNUNET_NAMESTORE_Client * nc;
106 struct GNUNET_NAMESTORE_Client * next;
108 GNUNET_SERVER_notification_context_destroy (snc);
111 for (nc = client_head; nc != NULL; nc = next)
114 for (no = nc->op_head; no != NULL; no = tmp)
117 GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no);
121 GNUNET_SERVER_client_drop(nc->client);
122 GNUNET_CONTAINER_DLL_remove (client_head, client_tail, nc);
126 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, GSN_database));
127 GNUNET_free (db_lib_name);
130 static struct GNUNET_NAMESTORE_Client *
131 client_lookup (struct GNUNET_SERVER_Client *client)
133 struct GNUNET_NAMESTORE_Client * nc;
135 GNUNET_assert (NULL != client);
137 for (nc = client_head; nc != NULL; nc = nc->next)
139 if (client == nc->client)
146 * Called whenever a client is disconnected. Frees our
147 * resources associated with that client.
150 * @param client identification of the client
153 client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client)
155 struct GNUNET_NAMESTORE_ZoneIteration * no;
156 struct GNUNET_NAMESTORE_Client * nc;
160 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected \n", client);
162 nc = client_lookup (client);
164 if ((NULL == client) || (NULL == nc))
167 for (no = nc->op_head; no != NULL; no = no->next)
169 GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no);
174 GNUNET_SERVER_client_drop(nc->client);
175 GNUNET_CONTAINER_DLL_remove (client_head, client_tail, nc);
181 static void handle_start (void *cls,
182 struct GNUNET_SERVER_Client * client,
183 const struct GNUNET_MessageHeader * message)
185 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
187 struct GNUNET_NAMESTORE_Client * nc = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_Client));
189 GNUNET_SERVER_notification_context_add (snc, client);
190 GNUNET_CONTAINER_DLL_insert(client_head, client_tail, nc);
191 GNUNET_SERVER_client_keep (client);
192 GNUNET_SERVER_receive_done (client, GNUNET_OK);
195 struct LookupNameContext
197 struct GNUNET_NAMESTORE_Client *nc;
199 uint32_t record_type;
200 GNUNET_HashCode *zone;
204 void drop_iterator (void *cls,
205 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
206 struct GNUNET_TIME_Absolute expire,
209 const struct GNUNET_NAMESTORE_RecordData *rd,
210 const struct GNUNET_CRYPTO_RsaSignature *signature)
212 GNUNET_HashCode zone_hash;
214 if (NULL != zone_key)
216 GNUNET_CRYPTO_hash(zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone_hash);
217 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting zone `%s'\n", GNUNET_h2s (&zone_hash));
218 GSN_database->delete_zone (GSN_database->cls, &zone_hash);
222 (*stop) = GNUNET_YES;
228 handle_lookup_name_it (void *cls,
229 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
230 struct GNUNET_TIME_Absolute expire,
232 unsigned int rd_count,
233 const struct GNUNET_NAMESTORE_RecordData *rd,
234 const struct GNUNET_CRYPTO_RsaSignature *signature)
237 struct LookupNameContext *lnc = cls;
238 struct LookupNameResponseMessage *lnr_msg;
239 struct GNUNET_NAMESTORE_RecordData *rd_selected = NULL;
246 int copied_elements = 0;
247 int contains_signature = 0;
251 name_len = strlen(name) + 1;
253 /* count records to copy */
256 if (lnc->record_type != 0)
258 /* special record type needed */
259 for (c = 0; c < rd_count; c ++)
260 if (rd[c].record_type == lnc->record_type)
261 copied_elements++; /* found matching record */
262 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u records with type %u for name `%s' in zone `%s'\n",
263 copied_elements, lnc->record_type, lnc->name, GNUNET_h2s(lnc->zone));
264 rd_selected = GNUNET_malloc (copied_elements * sizeof (struct GNUNET_NAMESTORE_RecordData));
266 for (c = 0; c < rd_count; c ++)
268 if (rd[c].record_type == lnc->record_type)
270 /* found matching record */
271 memcpy (&rd_selected[copied_elements], &rd[c], sizeof (struct GNUNET_NAMESTORE_RecordData));
278 copied_elements = rd_count;
279 rd_selected = (struct GNUNET_NAMESTORE_RecordData *) rd;
287 expire = GNUNET_TIME_UNIT_ZERO_ABS;
290 rd_ser_len = GNUNET_NAMESTORE_records_get_size(copied_elements, rd_selected);
291 char rd_ser[rd_ser_len];
292 GNUNET_NAMESTORE_records_serialize(copied_elements, rd_selected, rd_ser_len, rd_ser);
294 if (rd_selected != rd)
295 GNUNET_free (rd_selected);
297 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u records for name `%s' in zone `%s'\n",
298 copied_elements, lnc->name, GNUNET_h2s(lnc->zone));
300 if ((copied_elements == rd_count) && (NULL != signature))
301 contains_signature = GNUNET_YES;
303 contains_signature = GNUNET_NO;
305 r_size = sizeof (struct LookupNameResponseMessage) +
306 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) +
310 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "NAMESTORE_LOOKUP_NAME_RESPONSE");
311 lnr_msg = GNUNET_malloc (r_size);
312 lnr_msg->gns_header.header.type = ntohs (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE);
313 lnr_msg->gns_header.header.size = ntohs (r_size);
314 lnr_msg->gns_header.r_id = htonl (lnc->request_id);
315 lnr_msg->rd_count = htons (copied_elements);
316 lnr_msg->rd_len = htons (rd_ser_len);
317 lnr_msg->name_len = htons (name_len);
318 lnr_msg->contains_sig = htons (contains_signature);
319 lnr_msg->expire = GNUNET_TIME_absolute_hton(expire);
321 if (zone_key != NULL)
322 lnr_msg->public_key = (*zone_key);
324 memset(&lnr_msg->public_key, '\0', sizeof (lnr_msg->public_key));
325 if (GNUNET_YES == contains_signature)
326 lnr_msg->signature = *signature;
328 memset (&lnr_msg->signature, '\0', sizeof (lnr_msg->signature));
330 name_tmp = (char *) &lnr_msg[1];
331 rd_tmp = &name_tmp[name_len];
333 memcpy (name_tmp, name, name_len);
334 memcpy (rd_tmp, rd_ser, rd_ser_len);
336 GNUNET_SERVER_notification_context_unicast (snc, lnc->nc->client, (const struct GNUNET_MessageHeader *) lnr_msg, GNUNET_NO);
338 GNUNET_free (lnr_msg);
341 static void handle_lookup_name (void *cls,
342 struct GNUNET_SERVER_Client * client,
343 const struct GNUNET_MessageHeader * message)
345 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_LOOKUP_NAME");
346 struct LookupNameContext lnc;
347 struct GNUNET_NAMESTORE_Client *nc;
353 if (ntohs (message->size) < sizeof (struct LookupNameMessage))
356 GNUNET_SERVER_receive_done (client, GNUNET_OK);
360 nc = client_lookup(client);
364 GNUNET_SERVER_receive_done (client, GNUNET_OK);
368 struct LookupNameMessage * ln_msg = (struct LookupNameMessage *) message;
369 rid = ntohl (ln_msg->gns_header.r_id);
370 name_len = ntohl (ln_msg->name_len);
371 type = ntohl (ln_msg->record_type);
373 if ((name_len == 0) || (name_len > 256))
376 GNUNET_SERVER_receive_done (client, GNUNET_OK);
380 name = (char *) &ln_msg[1];
381 if (name[name_len -1] != '\0')
384 GNUNET_SERVER_receive_done (client, GNUNET_OK);
389 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up all records for name `%s' in zone `%s'\n", name, GNUNET_h2s(&ln_msg->zone));
391 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up records with type %u for name `%s' in zone `%s'\n", type, name, GNUNET_h2s(&ln_msg->zone));
393 /* do the actual lookup */
394 lnc.request_id = rid;
396 lnc.record_type = type;
398 lnc.zone = &ln_msg->zone;
399 GSN_database->iterate_records(GSN_database->cls, &ln_msg->zone, name, 0, &handle_lookup_name_it, &lnc);
401 GNUNET_SERVER_receive_done (client, GNUNET_OK);
404 static void handle_record_put (void *cls,
405 struct GNUNET_SERVER_Client * client,
406 const struct GNUNET_MessageHeader * message)
408 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_RECORD_PUT");
409 struct GNUNET_NAMESTORE_Client *nc;
410 struct GNUNET_TIME_Absolute expire;
411 struct GNUNET_CRYPTO_RsaSignature *signature;
412 struct RecordPutResponseMessage rpr_msg;
421 int res = GNUNET_SYSERR;
423 if (ntohs (message->size) < sizeof (struct RecordPutMessage))
426 GNUNET_SERVER_receive_done (client, GNUNET_OK);
430 nc = client_lookup (client);
434 GNUNET_SERVER_receive_done (client, GNUNET_OK);
438 struct RecordPutMessage * rp_msg = (struct RecordPutMessage *) message;
440 rid = ntohl (rp_msg->gns_header.r_id);
441 msg_size = ntohs (rp_msg->gns_header.header.size);
442 name_len = ntohs (rp_msg->name_len);
443 rd_count = ntohs (rp_msg->rd_count);
444 rd_ser_len = ntohs(rp_msg->rd_len);
446 if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
449 GNUNET_SERVER_receive_done (client, GNUNET_OK);
453 if ((rd_count < 1) || (rd_ser_len < 1) || (name_len >=256) || (name_len == 0))
456 GNUNET_SERVER_receive_done (client, GNUNET_OK);
460 msg_size_exp = sizeof (struct RecordPutMessage) + name_len + rd_ser_len;
461 if (msg_size != msg_size_exp)
463 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expected message %u size but message size is %u \n", msg_size_exp, msg_size);
465 GNUNET_SERVER_receive_done (client, GNUNET_OK);
468 if ((name_len == 0) || (name_len > 256))
471 GNUNET_SERVER_receive_done (client, GNUNET_OK);
475 name = (char *) &rp_msg[1];
477 if (name[name_len -1] != '\0')
480 GNUNET_SERVER_receive_done (client, GNUNET_OK);
484 expire = GNUNET_TIME_absolute_ntoh(rp_msg->expire);
485 signature = (struct GNUNET_CRYPTO_RsaSignature *) &rp_msg->signature;
487 rd_ser = &name[name_len];
488 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
489 res = GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_ser, rd_count, rd);
490 if (res != GNUNET_OK)
496 GNUNET_HashCode zone_hash;
497 GNUNET_CRYPTO_hash (&rp_msg->public_key, sizeof (rp_msg->public_key), &zone_hash);
499 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Putting %u record for name `%s' in zone `%s'\n", rd_count, name, GNUNET_h2s(&zone_hash));
501 /* Database operation */
502 res = GSN_database->put_records(GSN_database->cls,
509 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Putting record for name `%s': %s\n",
510 name, (res == GNUNET_OK) ? "OK" : "FAIL");
514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_PUT_RESPONSE");
515 rpr_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE);
516 rpr_msg.gns_header.header.size = htons (sizeof (struct RecordPutResponseMessage));
517 rpr_msg.gns_header.r_id = htonl (rid);
518 rpr_msg.op_result = htonl (res);
519 GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &rpr_msg, GNUNET_NO);
521 GNUNET_SERVER_receive_done (client, GNUNET_OK);
524 struct CreateRecordContext
526 struct GNUNET_NAMESTORE_RecordData *rd;
527 struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
528 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey;
529 struct GNUNET_TIME_Absolute expire;
536 handle_create_record_it (void *cls,
537 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey,
538 struct GNUNET_TIME_Absolute expire,
540 unsigned int rd_count,
541 const struct GNUNET_NAMESTORE_RecordData *rd,
542 const struct GNUNET_CRYPTO_RsaSignature *signature)
544 struct CreateRecordContext * crc = cls;
545 struct GNUNET_CRYPTO_RsaSignature *signature_new = NULL;
546 struct GNUNET_NAMESTORE_RecordData *rd_new = NULL;
547 struct GNUNET_TIME_Absolute block_expiration;
549 int exist = GNUNET_SYSERR;
550 int update = GNUNET_NO;
552 int rd_count_new = 0;
554 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u existing records for `%s'\n", rd_count, crc->name);
556 for (c = 0; c < rd_count; c++)
559 if ((crc->rd->record_type == rd[c].record_type) &&
560 (crc->rd->data_size == rd[c].data_size) &&
561 (0 == memcmp (crc->rd->data, rd[c].data, rd[c].data_size)))
563 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found existing records for `%s' to update expiration date!\n", crc->name);
565 if (crc->rd->expiration.abs_value != rd[c].expiration.abs_value)
571 if (exist == GNUNET_SYSERR)
572 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "NO existing records for `%s' to update!\n", crc->name);
574 if (exist == GNUNET_SYSERR)
576 rd_new = GNUNET_malloc ((rd_count+1) * sizeof (struct GNUNET_NAMESTORE_RecordData));
577 memcpy (rd_new, rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
578 rd_count_new = rd_count + 1;
579 rd_new[rd_count] = *(crc->rd);
580 signature_new = GNUNET_NAMESTORE_create_signature (crc->pkey, crc->name, rd_new, rd_count+1);
582 if (NULL == signature_new)
589 else if (update == GNUNET_NO)
591 /* Exact same record already exists */
592 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No update for %s' record required!\n", crc->name);
596 else if (update == GNUNET_YES)
599 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating existing records for `%s'!\n", crc->name);
600 rd_new = GNUNET_malloc ((rd_count) * sizeof (struct GNUNET_NAMESTORE_RecordData));
601 memcpy (rd_new, rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
602 rd_count_new = rd_count;
603 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating expiration from %llu to %llu!\n", rd_new[exist].expiration.abs_value, crc->rd->expiration.abs_value);
604 rd_new[exist].expiration = crc->rd->expiration;
605 signature_new = GNUNET_NAMESTORE_create_signature (crc->pkey, crc->name, rd_new, rd_count_new);
606 if (NULL == signature_new)
614 block_expiration = GNUNET_TIME_absolute_max(crc->expire, expire);
615 if (block_expiration.abs_value != expire.abs_value)
616 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updated block expiration time\n");
619 /* Database operation */
620 GNUNET_assert ((rd_new != NULL) && (rd_count_new > 0));
621 res = GSN_database->put_records(GSN_database->cls,
622 (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) crc->pubkey,
625 rd_count_new, rd_new,
627 GNUNET_break (GNUNET_OK == res);
628 if (res == GNUNET_OK)
629 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully put record for `%s' in database \n", crc->name);
631 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to put record for `%s' in database \n", crc->name);
635 GNUNET_free_non_null (rd_new);
636 GNUNET_free_non_null (signature_new);
640 /* failed to create the record */
641 crc->res = GNUNET_SYSERR;
644 /* database operations OK */
645 if (GNUNET_YES == update)
646 /* we updated an existing record */
647 crc->res = GNUNET_NO;
649 /* we created a new record */
650 crc->res = GNUNET_YES;
653 /* identical entry existed, so we did nothing */
654 crc->res = GNUNET_NO;
660 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Update result for name `%s' %u\n", crc->name, res);
664 static void handle_record_create (void *cls,
665 struct GNUNET_SERVER_Client * client,
666 const struct GNUNET_MessageHeader * message)
668 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_RECORD_CREATE");
669 struct GNUNET_NAMESTORE_Client *nc;
670 struct CreateRecordContext crc;
671 struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
672 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
673 struct RecordCreateResponseMessage rcr_msg;
674 GNUNET_HashCode pubkey_hash;
686 int res = GNUNET_SYSERR;
687 crc.res = GNUNET_SYSERR;
689 if (ntohs (message->size) < sizeof (struct RecordCreateMessage))
692 GNUNET_SERVER_receive_done (client, GNUNET_OK);
696 nc = client_lookup(client);
700 GNUNET_SERVER_receive_done (client, GNUNET_OK);
704 struct RecordCreateMessage * rp_msg = (struct RecordCreateMessage *) message;
705 rid = ntohl (rp_msg->gns_header.r_id);
706 name_len = ntohs (rp_msg->name_len);
707 msg_size = ntohs (message->size);
708 rd_count = ntohs (rp_msg->rd_count);
709 rd_ser_len = ntohs (rp_msg->rd_len);
710 key_len = ntohs (rp_msg->pkey_len);
711 msg_size_exp = sizeof (struct RecordCreateMessage) + key_len + name_len + rd_ser_len;
713 if (msg_size != msg_size_exp)
715 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expected message %u size but message size is %u \n", msg_size_exp, msg_size);
717 GNUNET_SERVER_receive_done (client, GNUNET_OK);
721 if ((name_len == 0) || (name_len > 256))
724 GNUNET_SERVER_receive_done (client, GNUNET_OK);
728 pkey_tmp = (char *) &rp_msg[1];
729 name_tmp = &pkey_tmp[key_len];
730 rd_ser = &name_tmp[name_len];
732 if (name_tmp[name_len -1] != '\0')
735 GNUNET_SERVER_receive_done (client, GNUNET_OK);
739 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
741 res = GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_ser, rd_count, rd);
742 if ((res != GNUNET_OK) || (rd_count != 1))
748 /* Extracting and converting private key */
749 pkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len);
750 GNUNET_assert (pkey != NULL);
751 GNUNET_CRYPTO_rsa_key_get_public(pkey, &pub);
752 GNUNET_CRYPTO_hash (&pub, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pubkey_hash);
754 crc.expire = GNUNET_TIME_absolute_ntoh(rp_msg->expire);
755 crc.res = GNUNET_SYSERR;
761 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating record for name `%s' in zone `%s'\n", name_tmp, GNUNET_h2s(&pubkey_hash));
763 /* Get existing records for name */
764 res = GSN_database->iterate_records(GSN_database->cls, &pubkey_hash, name_tmp, 0, &handle_create_record_it, &crc);
765 if (res != GNUNET_SYSERR)
767 GNUNET_CRYPTO_rsa_key_free(pkey);
771 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_CREATE_RESPONSE");
772 rcr_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE);
773 rcr_msg.gns_header.header.size = htons (sizeof (struct RecordCreateResponseMessage));
774 rcr_msg.gns_header.r_id = htonl (rid);
775 if ((GNUNET_OK == res) && (crc.res == GNUNET_YES))
776 rcr_msg.op_result = htonl (GNUNET_YES);
777 else if ((GNUNET_OK == res) && (crc.res == GNUNET_NO))
778 rcr_msg.op_result = htonl (GNUNET_NO);
780 rcr_msg.op_result = htonl (GNUNET_SYSERR);
781 GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &rcr_msg, GNUNET_NO);
783 GNUNET_SERVER_receive_done (client, GNUNET_OK);
787 struct RemoveRecordContext
789 struct GNUNET_NAMESTORE_RecordData *rd;
790 struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
795 handle_record_remove_it (void *cls,
796 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
797 struct GNUNET_TIME_Absolute expire,
799 unsigned int rd_count,
800 const struct GNUNET_NAMESTORE_RecordData *rd,
801 const struct GNUNET_CRYPTO_RsaSignature *signature)
803 struct RemoveRecordContext *rrc = cls;
807 unsigned int rd_count_new;
809 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name `%s 'currently has %u records\n", name, rd_count);
813 /* Could not find record to remove */
818 /* Find record to remove */
819 found = GNUNET_SYSERR;
820 for (c = 0; c < rd_count; c++)
822 if ((rd[c].expiration.abs_value == rrc->rd->expiration.abs_value) &&
823 (rd[c].flags == rrc->rd->flags) &&
824 (rd[c].record_type == rrc->rd->record_type) &&
825 (rd[c].data_size == rrc->rd->data_size) &&
826 (0 == memcmp (rd[c].data, rrc->rd->data, rrc->rd->data_size)))
828 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found record to remove!\n", rd_count);
833 if (GNUNET_SYSERR == found)
835 /* Could not find record to remove */
840 rd_count_new = rd_count -1;
841 struct GNUNET_NAMESTORE_RecordData rd_new[rd_count_new];
844 for (c = 0; c < rd_count; c++)
848 GNUNET_assert (c2 < rd_count_new);
854 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name `%s' now has %u records\n", name, rd_count_new);
856 /* Create new signature */
857 struct GNUNET_CRYPTO_RsaSignature * new_signature;
858 new_signature = GNUNET_NAMESTORE_create_signature (rrc->pkey, name, rd_new, rd_count_new);
860 if (new_signature == NULL)
862 /* Signature failed */
868 res = GSN_database->put_records(GSN_database->cls,
872 rd_count_new, rd_new,
874 GNUNET_free (new_signature);
876 if (GNUNET_OK != res)
878 /* Could put records into database */
886 static void handle_record_remove (void *cls,
887 struct GNUNET_SERVER_Client * client,
888 const struct GNUNET_MessageHeader * message)
890 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_RECORD_REMOVE");
891 struct GNUNET_NAMESTORE_Client *nc;
892 struct RecordRemoveResponseMessage rrr_msg;
893 struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
894 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
895 GNUNET_HashCode pubkey_hash;
896 char * pkey_tmp = NULL;
897 char * name_tmp = NULL;
898 char * rd_ser = NULL;
901 size_t rd_ser_len = 0;
903 size_t msg_size_exp = 0;
907 int res = GNUNET_SYSERR;
909 if (ntohs (message->size) < sizeof (struct RecordRemoveMessage))
912 GNUNET_SERVER_receive_done (client, GNUNET_OK);
916 nc = client_lookup(client);
920 GNUNET_SERVER_receive_done (client, GNUNET_OK);
924 struct RecordRemoveMessage * rr_msg = (struct RecordRemoveMessage *) message;
925 rid = ntohl (rr_msg->gns_header.r_id);
926 name_len = ntohs (rr_msg->name_len);
927 rd_ser_len = ntohs (rr_msg->rd_len);
928 rd_count = ntohs (rr_msg->rd_count);
929 key_len = ntohs (rr_msg->pkey_len);
930 msg_size = ntohs (message->size);
932 if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
935 GNUNET_SERVER_receive_done (client, GNUNET_OK);
939 if ((rd_count != 1) || (rd_ser_len < 1) || (name_len >=256) || (name_len == 0))
942 GNUNET_SERVER_receive_done (client, GNUNET_OK);
946 msg_size_exp = sizeof (struct RecordRemoveMessage) + key_len + name_len + rd_ser_len;
947 if (msg_size != msg_size_exp)
949 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expected message %u size but message size is %u \n", msg_size_exp, msg_size);
951 GNUNET_SERVER_receive_done (client, GNUNET_OK);
955 if ((rd_count != 1) || (rd_ser_len < 1) || (name_len >=256) || (name_len == 0))
958 GNUNET_SERVER_receive_done (client, GNUNET_OK);
962 pkey_tmp = (char *) &rr_msg[1];
963 name_tmp = &pkey_tmp[key_len];
964 rd_ser = &name_tmp[name_len];
967 if ((name_len == 0) || (name_len > 256))
970 GNUNET_SERVER_receive_done (client, GNUNET_OK);
974 if (name_tmp[name_len -1] != '\0')
977 GNUNET_SERVER_receive_done (client, GNUNET_OK);
981 /* Extracting and converting private key */
982 pkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len);
983 GNUNET_assert (pkey != NULL);
984 GNUNET_CRYPTO_rsa_key_get_public(pkey, &pub);
985 GNUNET_CRYPTO_hash (&pub, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pubkey_hash);
987 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
988 res = GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_ser, rd_count, rd);
989 if ((res != GNUNET_OK) || (rd_count != 1))
995 struct RemoveRecordContext rrc;
999 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing record for name `%s' in zone `%s'\n", name_tmp, GNUNET_h2s(&pubkey_hash));
1001 /* Database operation */
1002 res = GSN_database->iterate_records (GSN_database->cls,
1006 handle_record_remove_it, &rrc);
1008 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing record for name `%s': %s\n",
1009 name_tmp, (rrc.op_res == 0) ? "OK" : "FAIL");
1014 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_REMOVE_RESPONSE");
1015 rrr_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE);
1016 rrr_msg.gns_header.header.size = htons (sizeof (struct RecordRemoveResponseMessage));
1017 rrr_msg.gns_header.r_id = htonl (rid);
1018 rrr_msg.op_result = htonl (res);
1019 GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &rrr_msg, GNUNET_NO);
1021 GNUNET_CRYPTO_rsa_key_free (pkey);
1023 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1027 struct ZoneToNameCtx
1029 struct GNUNET_NAMESTORE_Client *nc;
1034 handle_zone_to_name_it (void *cls,
1035 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
1036 struct GNUNET_TIME_Absolute expire,
1038 unsigned int rd_count,
1039 const struct GNUNET_NAMESTORE_RecordData *rd,
1040 const struct GNUNET_CRYPTO_RsaSignature *signature)
1042 struct ZoneToNameCtx * ztn_ctx = cls;
1043 struct ZoneToNameResponseMessage *ztnr_msg;
1044 int16_t res = GNUNET_SYSERR;
1045 uint16_t name_len = 0;
1046 uint16_t rd_ser_len = 0 ;
1047 int32_t contains_sig = 0;
1048 size_t msg_size = 0;
1050 char *rd_ser = NULL;
1055 if ((zone_key != NULL) && (name != NULL))
1058 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found results: name is `%s', has %u records\n", name, rd_count);
1060 name_len = strlen (name);
1064 /* no result found */
1065 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found no results\n");
1072 rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
1073 rd_ser = GNUNET_malloc (rd_ser_len);
1074 GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser);
1079 if (signature != NULL)
1080 contains_sig = GNUNET_YES;
1082 contains_sig = GNUNET_NO;
1086 msg_size = sizeof (struct ZoneToNameResponseMessage) + name_len + rd_ser_len + contains_sig * sizeof (struct GNUNET_CRYPTO_RsaSignature);
1087 ztnr_msg = GNUNET_malloc (msg_size);
1089 name_tmp = (char *) &ztnr_msg[1];
1090 rd_tmp = &name_tmp[name_len];
1091 sig_tmp = &rd_tmp[rd_ser_len];
1093 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "ZONE_TO_NAME_RESPONSE");
1094 ztnr_msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE);
1095 ztnr_msg->gns_header.header.size = htons (msg_size);
1096 ztnr_msg->gns_header.r_id = htonl (ztn_ctx->rid);
1097 ztnr_msg->res = htons (res);
1098 ztnr_msg->rd_len = htons (rd_ser_len);
1099 ztnr_msg->rd_count = htons (rd_count);
1100 ztnr_msg->name_len = htons (name_len);
1101 ztnr_msg->expire = GNUNET_TIME_absolute_hton(expire);
1102 if (zone_key != NULL)
1103 ztnr_msg->zone_key = *zone_key;
1105 memset (&ztnr_msg->zone_key, '\0', sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
1107 if ((name_len > 0) && (name != NULL))
1108 memcpy (name_tmp, name, name_len);
1110 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);
1111 if ((rd_ser_len > 0) && (rd_ser != NULL))
1112 memcpy (rd_tmp, rd_ser, rd_ser_len);
1113 if ((GNUNET_YES == contains_sig) && (signature != NULL))
1114 memcpy (sig_tmp, signature, contains_sig * sizeof (struct GNUNET_CRYPTO_RsaSignature));
1116 GNUNET_SERVER_notification_context_unicast (snc, ztn_ctx->nc->client, (const struct GNUNET_MessageHeader *) ztnr_msg, GNUNET_NO);
1117 GNUNET_free (ztnr_msg);
1118 GNUNET_free_non_null (rd_ser);
1122 static void handle_zone_to_name (void *cls,
1123 struct GNUNET_SERVER_Client * client,
1124 const struct GNUNET_MessageHeader * message)
1126 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "ZONE_TO_NAME");
1127 struct GNUNET_NAMESTORE_Client *nc;
1128 struct ZoneToNameCtx ztn_ctx;
1129 size_t msg_size = 0;
1132 if (ntohs (message->size) != sizeof (struct ZoneToNameMessage))
1134 GNUNET_break_op (0);
1135 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1139 nc = client_lookup(client);
1142 GNUNET_break_op (0);
1143 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1147 struct ZoneToNameMessage *ztn_msg = (struct ZoneToNameMessage *) message;
1149 if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
1151 GNUNET_break_op (0);
1152 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1156 rid = ntohl (ztn_msg->gns_header.r_id);
1161 char * z_tmp = strdup (GNUNET_h2s (&ztn_msg->zone));
1162 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up name for zone `%s' in zone `%s'\n",
1164 GNUNET_h2s (&ztn_msg->value_zone));
1165 GNUNET_free (z_tmp);
1167 GSN_database->zone_to_name (GSN_database->cls, &ztn_msg->zone, &ztn_msg->value_zone, &handle_zone_to_name_it, &ztn_ctx);
1169 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1172 struct ZoneIterationProcResult
1175 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded zone_key;
1178 struct GNUNET_CRYPTO_RsaSignature signature;
1179 struct GNUNET_TIME_Absolute expire;
1189 void zone_iteration_proc (void *cls,
1190 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
1191 struct GNUNET_TIME_Absolute expire,
1193 unsigned int rd_count,
1194 const struct GNUNET_NAMESTORE_RecordData *rd,
1195 const struct GNUNET_CRYPTO_RsaSignature *signature)
1197 struct GNUNET_NAMESTORE_ZoneIteration *zi = cls;
1198 struct GNUNET_NAMESTORE_Client *nc = zi->client;
1201 if ((zone_key == NULL) && (name == NULL))
1203 struct ZoneIterationResponseMessage zir_msg;
1204 if (zi->has_zone == GNUNET_YES)
1205 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No more results for zone `%s'\n", GNUNET_h2s(&zi->zone));
1207 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No more results for all zones\n");
1209 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending empty `%s' message\n", "ZONE_ITERATION_RESPONSE");
1210 zir_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE);
1211 zir_msg.gns_header.header.size = htons (sizeof (struct ZoneIterationResponseMessage));
1212 zir_msg.gns_header.r_id = htonl(zi->request_id);
1213 zir_msg.expire = GNUNET_TIME_absolute_hton(GNUNET_TIME_absolute_get_zero());
1214 zir_msg.name_len = htons (0);
1215 zir_msg.reserved = htons (0);
1216 zir_msg.rd_count = htons (0);
1217 zir_msg.rd_len = htons (0);
1218 memset (&zir_msg.public_key, '\0', sizeof (zir_msg.public_key));
1219 memset (&zir_msg.signature, '\0', sizeof (zir_msg.signature));
1220 GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &zir_msg, GNUNET_NO);
1222 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing zone iterator\n");
1223 GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, zi);
1229 struct ZoneIterationResponseMessage *zir_msg;
1230 if (zi->has_zone == GNUNET_YES)
1231 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending name `%s' for iteration over zone `%s'\n",
1232 name, GNUNET_h2s(&zi->zone));
1233 if (zi->has_zone == GNUNET_NO)
1234 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending name `%s' for iteration over all zones\n",
1242 name_len = strlen (name) +1;
1244 rd_ser_len = GNUNET_NAMESTORE_records_get_size(rd_count, rd);
1245 char rd_ser[rd_ser_len];
1246 GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser);
1247 msg_size = sizeof (struct ZoneIterationResponseMessage) + name_len + rd_ser_len;
1248 zir_msg = GNUNET_malloc(msg_size);
1250 name_tmp = (char *) &zir_msg[1];
1251 rd_tmp = &name_tmp[name_len];
1253 zir_msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE);
1254 zir_msg->gns_header.header.size = htons (msg_size);
1255 zir_msg->gns_header.r_id = htonl(zi->request_id);
1256 zir_msg->expire = GNUNET_TIME_absolute_hton(expire);
1257 zir_msg->reserved = htons (0);
1258 zir_msg->name_len = htons (name_len);
1259 zir_msg->rd_count = htons (rd_count);
1260 zir_msg->rd_len = htons (rd_ser_len);
1261 zir_msg->signature = *signature;
1262 GNUNET_assert (NULL == zone_key);
1263 if (zone_key != NULL)
1264 zir_msg->public_key = *zone_key;
1265 memcpy (name_tmp, name, name_len);
1266 memcpy (rd_tmp, rd_ser, rd_ser_len);
1268 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending empty `%s' message with size %u\n", "ZONE_ITERATION_RESPONSE", msg_size);
1269 GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) zir_msg, GNUNET_NO);
1270 GNUNET_free (zir_msg);
1274 static void handle_iteration_start (void *cls,
1275 struct GNUNET_SERVER_Client * client,
1276 const struct GNUNET_MessageHeader * message)
1278 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "ZONE_ITERATION_START");
1280 struct ZoneIterationStartMessage * zis_msg = (struct ZoneIterationStartMessage *) message;
1281 struct GNUNET_NAMESTORE_Client *nc;
1282 struct GNUNET_NAMESTORE_ZoneIteration *zi;
1285 nc = client_lookup(client);
1288 GNUNET_break_op (0);
1289 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1293 zi = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_ZoneIteration));
1294 zi->request_id = ntohl (zis_msg->gns_header.r_id);
1297 zi->zone = zis_msg->zone;
1299 GNUNET_HashCode dummy;
1300 GNUNET_HashCode *zone_tmp;
1301 memset (&dummy, '\0', sizeof (dummy));
1302 if (0 == memcmp (&dummy, &zis_msg->zone, sizeof (dummy)))
1304 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting to iterate over all zones\n");
1305 zi->has_zone = GNUNET_NO;
1310 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting to iterate over zone `%s'\n", GNUNET_h2s (&zis_msg->zone));
1311 zi->has_zone = GNUNET_YES;
1312 zone_tmp = &zis_msg->zone;
1315 GNUNET_CONTAINER_DLL_insert (nc->op_head, nc->op_tail, zi);
1317 res = GSN_database->iterate_records (GSN_database->cls, zone_tmp , NULL, zi->offset , &zone_iteration_proc, zi);
1318 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1321 static void handle_iteration_stop (void *cls,
1322 struct GNUNET_SERVER_Client * client,
1323 const struct GNUNET_MessageHeader * message)
1325 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "ZONE_ITERATION_STOP");
1327 struct GNUNET_NAMESTORE_Client *nc;
1328 struct GNUNET_NAMESTORE_ZoneIteration *zi;
1329 struct ZoneIterationStopMessage * zis_msg = (struct ZoneIterationStopMessage *) message;
1332 nc = client_lookup(client);
1335 GNUNET_break_op (0);
1336 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1340 rid = ntohl (zis_msg->gns_header.r_id);
1341 for (zi = nc->op_head; zi != NULL; zi = zi->next)
1343 if (zi->request_id == rid)
1348 GNUNET_break_op (0);
1349 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1353 GNUNET_CONTAINER_DLL_remove(nc->op_head, nc->op_tail, zi);
1354 if (GNUNET_YES == zi->has_zone)
1355 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopped zone iteration for zone `%s'\n", GNUNET_h2s (&zi->zone));
1357 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopped zone iteration all zones\n");
1360 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1363 static void handle_iteration_next (void *cls,
1364 struct GNUNET_SERVER_Client * client,
1365 const struct GNUNET_MessageHeader * message)
1367 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "ZONE_ITERATION_NEXT");
1369 struct GNUNET_NAMESTORE_Client *nc;
1370 struct GNUNET_NAMESTORE_ZoneIteration *zi;
1371 GNUNET_HashCode *zone_tmp;
1372 struct ZoneIterationStopMessage * zis_msg = (struct ZoneIterationStopMessage *) message;
1375 nc = client_lookup(client);
1378 GNUNET_break_op (0);
1379 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1383 rid = ntohl (zis_msg->gns_header.r_id);
1384 for (zi = nc->op_head; zi != NULL; zi = zi->next)
1386 if (zi->request_id == rid)
1391 GNUNET_break_op (0);
1392 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1396 if (GNUNET_YES == zi->has_zone)
1397 zone_tmp = &zi->zone;
1402 GSN_database->iterate_records (GSN_database->cls, zone_tmp, NULL, zi->offset , &zone_iteration_proc, zi);
1403 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1409 * Process template requests.
1411 * @param cls closure
1412 * @param server the initialized server
1413 * @param cfg configuration to use
1416 run (void *cls, struct GNUNET_SERVER_Handle *server,
1417 const struct GNUNET_CONFIGURATION_Handle *cfg)
1421 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n");
1423 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
1424 {&handle_start, NULL,
1425 GNUNET_MESSAGE_TYPE_NAMESTORE_START, sizeof (struct StartMessage)},
1426 {&handle_lookup_name, NULL,
1427 GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME, 0},
1428 {&handle_record_put, NULL,
1429 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT, 0},
1430 {&handle_record_create, NULL,
1431 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE, 0},
1432 {&handle_record_remove, NULL,
1433 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE, 0},
1434 {&handle_zone_to_name, NULL,
1435 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME, 0},
1436 {&handle_iteration_start, NULL,
1437 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START, sizeof (struct ZoneIterationStartMessage)},
1438 {&handle_iteration_next, NULL,
1439 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT, 0},
1440 {&handle_iteration_stop, NULL,
1441 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP, 0},
1447 /* Loading database plugin */
1449 GNUNET_CONFIGURATION_get_value_string (cfg, "namestore", "database",
1451 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
1453 GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database);
1454 GSN_database = GNUNET_PLUGIN_load (db_lib_name, (void *) GSN_cfg);
1455 if (GSN_database == NULL)
1456 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not load database backend `%s'\n",
1458 GNUNET_free (database);
1460 /* Configuring server handles */
1461 GNUNET_SERVER_add_handlers (server, handlers);
1462 snc = GNUNET_SERVER_notification_context_create (server, 16);
1463 GNUNET_SERVER_disconnect_notify (server,
1464 &client_disconnect_notification,
1467 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task,
1474 * The main function for the template service.
1476 * @param argc number of arguments from the command line
1477 * @param argv command line arguments
1478 * @return 0 ok, 1 on error
1481 main (int argc, char *const *argv)
1483 return (GNUNET_OK ==
1484 GNUNET_SERVICE_run (argc, argv, "namestore",
1485 GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1;
1488 /* end of gnunet-service-namestore.c */