2 This file is part of GNUnet.
3 (C) 2009, 2010 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 gns/namestore_api.c
23 * @brief API to access the NAMESTORE service
24 * @author Martin Schanzenbach
25 * @author Matthias Wachs
29 #include "gnunet_util_lib.h"
30 #include "gnunet_constants.h"
31 #include "gnunet_arm_service.h"
32 #include "gnunet_namestore_service.h"
33 #include "namestore.h"
34 #define DEBUG_GNS_API GNUNET_EXTRA_LOGGING
36 #define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__)
41 struct GNUNET_NAMESTORE_QueueEntry
43 char *data; /*stub data pointer*/
48 * Message in linked list we should send to the service. The
49 * actual binary message follows this struct.
57 struct PendingMessage *next;
62 struct PendingMessage *prev;
65 * Size of the message.
70 * Is this the 'START' message?
77 * Connection to the NAMESTORE service.
79 struct GNUNET_NAMESTORE_Handle
83 * Configuration to use.
85 const struct GNUNET_CONFIGURATION_Handle *cfg;
88 * Socket (if available).
90 struct GNUNET_CLIENT_Connection *client;
93 * Currently pending transmission request (or NULL).
95 struct GNUNET_CLIENT_TransmitHandle *th;
100 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
102 struct PendingMessage * pending_head;
103 struct PendingMessage * pending_tail;
106 * Should we reconnect to service due to some serious error?
111 struct GNUNET_NAMESTORE_SimpleRecord
116 struct GNUNET_NAMESTORE_SimpleRecord *next;
121 struct GNUNET_NAMESTORE_SimpleRecord *prev;
124 const GNUNET_HashCode *zone;
125 uint32_t record_type;
126 struct GNUNET_TIME_Absolute expiration;
127 enum GNUNET_NAMESTORE_RecordFlags flags;
133 * Disconnect from service and then reconnect.
135 * @param nsh our handle
138 force_reconnect (struct GNUNET_NAMESTORE_Handle *nsh);
141 * Transmit messages from the message queue to the service
142 * (if there are any, and if we are not already trying).
144 * @param nsh handle to use
147 do_transmit (struct GNUNET_NAMESTORE_Handle *nsh);
151 * Type of a function to call when we receive a message
154 * @param cls the 'struct GNUNET_NAMESTORE_SchedulingHandle'
155 * @param msg message received, NULL on timeout or fatal error
158 process_namestore_message (void *cls, const struct GNUNET_MessageHeader *msg)
160 struct GNUNET_NAMESTORE_Handle *nsh = cls;
166 force_reconnect (nsh);
170 size = ntohs (msg->size);
171 type = ntohs (msg->type);
174 case GNUNET_MESSAGE_TYPE_TEST:
175 /* handle message here */
181 GNUNET_CLIENT_receive (nsh->client, &process_namestore_message, nsh,
182 GNUNET_TIME_UNIT_FOREVER_REL);
184 if (GNUNET_YES == nsh->reconnect)
185 force_reconnect (nsh);
189 * We can now transmit a message to NAMESTORE. Do it.
191 * @param cls the 'struct GNUNET_NAMESTORE_Handle'
192 * @param size number of bytes we can transmit
193 * @param buf where to copy the messages
194 * @return number of bytes copied into buf
197 transmit_message_to_namestore (void *cls, size_t size, void *buf)
199 struct GNUNET_NAMESTORE_Handle *nsh = cls;
200 struct PendingMessage *p;
205 if ((size == 0) || (buf == NULL))
207 force_reconnect (nsh);
212 while ((NULL != (p = nsh->pending_head)) && (p->size <= size))
214 memcpy (&cbuf[ret], &p[1], p->size);
217 GNUNET_CONTAINER_DLL_remove (nsh->pending_head, nsh->pending_tail, p);
218 if (GNUNET_YES == p->is_init)
219 GNUNET_CLIENT_receive (nsh->client, &process_namestore_message, nsh,
220 GNUNET_TIME_UNIT_FOREVER_REL);
229 * Transmit messages from the message queue to the service
230 * (if there are any, and if we are not already trying).
232 * @param nsh handle to use
235 do_transmit (struct GNUNET_NAMESTORE_Handle *nsh)
237 struct PendingMessage *p;
241 if (NULL == (p = nsh->pending_head))
243 if (NULL == nsh->client)
244 return; /* currently reconnecting */
245 nsh->th = GNUNET_CLIENT_notify_transmit_ready (nsh->client, p->size,
246 GNUNET_TIME_UNIT_FOREVER_REL,
247 GNUNET_NO, &transmit_message_to_namestore,
253 * Try again to connect to namestore service.
255 * @param cls the handle to the namestore service
256 * @param tc scheduler context
259 reconnect (struct GNUNET_NAMESTORE_Handle *nsh)
261 struct PendingMessage *p;
262 struct StartMessage *init;
264 GNUNET_assert (NULL == nsh->client);
265 nsh->client = GNUNET_CLIENT_connect ("namestore", nsh->cfg);
266 GNUNET_assert (NULL != nsh->client);
268 if ((NULL == (p = nsh->pending_head)) || (GNUNET_YES != p->is_init))
270 p = GNUNET_malloc (sizeof (struct PendingMessage) +
271 sizeof (struct StartMessage));
272 p->size = sizeof (struct StartMessage);
273 p->is_init = GNUNET_YES;
274 init = (struct StartMessage *) &p[1];
275 init->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_START);
276 init->header.size = htons (sizeof (struct StartMessage));
277 GNUNET_CONTAINER_DLL_insert (nsh->pending_head, nsh->pending_tail, p);
283 * Re-establish the connection to the service.
285 * @param cls handle to use to re-connect.
286 * @param tc scheduler context
289 reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
291 struct GNUNET_NAMESTORE_Handle *nsh = cls;
293 nsh->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
299 * Disconnect from service and then reconnect.
301 * @param nsh our handle
304 force_reconnect (struct GNUNET_NAMESTORE_Handle *nsh)
306 nsh->reconnect = GNUNET_NO;
307 GNUNET_CLIENT_disconnect (nsh->client, GNUNET_NO);
309 nsh->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
317 * Initialize the connection with the NAMESTORE service.
319 * @param cfg configuration to use
320 * @return handle to the GNS service, or NULL on error
322 struct GNUNET_NAMESTORE_Handle *
323 GNUNET_NAMESTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
325 struct GNUNET_NAMESTORE_Handle *nsh;
327 nsh = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_Handle));
329 nsh->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect_task, nsh);
335 * Shutdown connection with the NAMESTORE service.
337 * @param handle handle of the NAMESTORE connection to stop
340 GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *nsh, int drop)
342 struct PendingMessage *p;
344 while (NULL != (p = nsh->pending_head))
346 GNUNET_CONTAINER_DLL_remove (nsh->pending_head, nsh->pending_tail, p);
349 if (NULL != nsh->client)
351 GNUNET_CLIENT_disconnect (nsh->client, GNUNET_NO);
354 if (GNUNET_SCHEDULER_NO_TASK != nsh->reconnect_task)
356 GNUNET_SCHEDULER_cancel (nsh->reconnect_task);
357 nsh->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
364 * Sign a record. This function is used by the authority of the zone
367 * @param h handle to the namestore
368 * @param zone_privkey private key of the zone
369 * @param record_hash hash of the record to be signed
370 * @param cont continuation to call when done
371 * @param cont_cls closure for cont
372 * @return handle to abort the request
374 struct GNUNET_NAMESTORE_QueueEntry *
375 GNUNET_NAMESTORE_stree_extend (struct GNUNET_NAMESTORE_Handle *h,
376 const struct GNUNET_CRYPTO_RsaPrivateKey *zone_privkey,
377 const GNUNET_HashCode *record_hash,
378 GNUNET_NAMESTORE_ContinuationWithSignature cont,
381 struct GNUNET_NAMESTORE_QueueEntry *qe;
382 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
387 * Rebalance the signature tree of our zone. This function should
388 * be called "rarely" to rebalance the tree.
390 * @param h handle to the namestore
391 * @param zone_privkey private key for the zone to rebalance
392 * @param cont continuation to call when done
393 * @param cont_cls closure for cont
394 * @return handle to abort the request
396 struct GNUNET_NAMESTORE_QueueEntry *
397 GNUNET_NAMESTORE_stree_rebalance (struct GNUNET_NAMESTORE_Handle *h,
398 const struct GNUNET_CRYPTO_RsaPrivateKey *zone_privkey,
399 GNUNET_NAMESTORE_ContinuationWithStatus cont,
402 struct GNUNET_NAMESTORE_QueueEntry *qe;
403 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
408 * Provide the root of a signature tree. This function is
409 * used by non-authorities as the first operation when
410 * adding a foreign zone.
412 * @param h handle to the namestore
413 * @param zone_key public key of the zone
414 * @param signature signature of the top-level entry of the zone
415 * @param revision revision number of the zone
416 * @param top_hash top-level hash of the zone
417 * @param cont continuation to call when done
418 * @param cont_cls closure for cont
419 * @return handle to abort the request
421 struct GNUNET_NAMESTORE_QueueEntry *
422 GNUNET_NAMESTORE_stree_start (struct GNUNET_NAMESTORE_Handle *h,
423 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
424 const struct GNUNET_CRYPTO_RsaSignature *signature,
426 const GNUNET_HashCode *top_hash,
427 GNUNET_NAMESTORE_ContinuationWithSignature cont,
430 struct GNUNET_NAMESTORE_QueueEntry *qe;
431 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
436 * Store part of a signature B-tree in the namestore. This function
437 * is used by non-authorities to cache parts of a zone's signature tree.
438 * Note that the tree must be build top-down. This function must check
439 * that the nodes being added are valid, and if not refuse the operation.
441 * @param h handle to the namestore
442 * @param zone_key public key of the zone
443 * @param loc location in the B-tree
444 * @param ploc parent's location in the B-tree (must have depth = loc.depth - 1)
445 * @param num_entries number of entries at this node in the B-tree
446 * @param entries the 'num_entries' entries to store (hashes over the
448 * @param cont continuation to call when done
449 * @param cont_cls closure for cont
450 * @return handle to abort the request
452 struct GNUNET_NAMESTORE_QueueEntry *
453 GNUNET_NAMESTORE_stree_put (struct GNUNET_NAMESTORE_Handle *h,
454 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
455 const struct GNUNET_NAMESTORE_SignatureLocation *loc,
456 const struct GNUNET_NAMESTORE_SignatureLocation *ploc,
457 unsigned int num_entries,
458 const GNUNET_HashCode *entries,
459 GNUNET_NAMESTORE_ContinuationWithStatus cont,
462 struct GNUNET_NAMESTORE_QueueEntry *qe;
463 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
468 * Store an item in the namestore. If the item is already present,
469 * the expiration time is updated to the max of the existing time and
470 * the new time. The operation must fail if there is no matching
471 * entry in the signature tree.
473 * @param h handle to the namestore
474 * @param zone hash of the public key of the zone
475 * @param name name that is being mapped (at most 255 characters long)
476 * @param record_type type of the record (A, AAAA, PKEY, etc.)
477 * @param expiration expiration time for the content
478 * @param flags flags for the content
479 * @param sig_loc where is the information about the signature for this record stored?
480 * @param data_size number of bytes in data
481 * @param data value, semantics depend on 'record_type' (see RFCs for DNS and
482 * GNS specification for GNS extensions)
483 * @param cont continuation to call when done
484 * @param cont_cls closure for cont
485 * @return handle to abort the request
487 struct GNUNET_NAMESTORE_QueueEntry *
488 GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h,
489 const GNUNET_HashCode *zone,
491 uint32_t record_type,
492 struct GNUNET_TIME_Absolute expiration,
493 enum GNUNET_NAMESTORE_RecordFlags flags,
494 const struct GNUNET_NAMESTORE_SignatureLocation *sig_loc,
497 GNUNET_NAMESTORE_ContinuationWithStatus cont,
500 struct GNUNET_NAMESTORE_QueueEntry *qe;
501 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
503 struct GNUNET_NAMESTORE_SimpleRecord *sr;
504 sr = GNUNET_malloc(sizeof(struct GNUNET_NAMESTORE_SimpleRecord));
506 sr->record_type = record_type;
507 sr->expiration = expiration;
509 sr->data_size = data_size;
511 GNUNET_CONTAINER_DLL_insert(h->records_head, h->records_tail, sr);
517 * Explicitly remove some content from the database. The
518 * "cont"inuation will be called with status "GNUNET_OK" if content
519 * was removed, "GNUNET_NO" if no matching entry was found and
520 * "GNUNET_SYSERR" on all other types of errors.
522 * @param h handle to the namestore
523 * @param zone hash of the public key of the zone
524 * @param name name that is being mapped (at most 255 characters long)
525 * @param record_type type of the record (A, AAAA, PKEY, etc.)
526 * @param size number of bytes in data
527 * @param data content stored
528 * @param cont continuation to call when done
529 * @param cont_cls closure for cont
530 * @return handle to abort the request
532 struct GNUNET_NAMESTORE_QueueEntry *
533 GNUNET_NAMESTORE_record_remove (struct GNUNET_NAMESTORE_Handle *h,
534 const GNUNET_HashCode *zone,
536 uint32_t record_type,
539 GNUNET_NAMESTORE_ContinuationWithStatus cont,
542 struct GNUNET_NAMESTORE_QueueEntry *qe;
543 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
545 struct GNUNET_NAMESTORE_SimpleRecord *iter;
546 for (iter=h->records_head; iter != NULL; iter=iter->next)
548 if (strcmp ( iter->name, name ) &&
549 iter->record_type == record_type &&
550 GNUNET_CRYPTO_hash_cmp (iter->zone, zone))
554 GNUNET_CONTAINER_DLL_remove(h->records_head,
562 * Get a result for a particular key from the namestore. The processor
563 * will only be called once.
565 * @param h handle to the namestore
566 * @param zone zone to look up a record from
567 * @param name name to look up
568 * @param record_type desired record type
569 * @param proc function to call on each matching value;
570 * will be called once with a NULL value at the end
571 * @param proc_cls closure for proc
572 * @return a handle that can be used to
575 struct GNUNET_NAMESTORE_QueueEntry *
576 GNUNET_NAMESTORE_lookup_name (struct GNUNET_NAMESTORE_Handle *h,
577 const GNUNET_HashCode *zone,
579 uint32_t record_type,
580 GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls)
582 struct GNUNET_NAMESTORE_QueueEntry *qe;
583 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
585 struct GNUNET_NAMESTORE_SimpleRecord *iter;
586 for (iter=h->records_head; iter != NULL; iter=iter->next)
588 proc(proc_cls, iter->zone, iter->name, iter->record_type,
592 iter->data_size /*size*/,
593 iter->data /* data */);
595 proc(proc_cls, zone, name, record_type,
596 GNUNET_TIME_absolute_get_forever(), 0, NULL, 0, NULL); /*TERMINATE*/
603 * Get the hash of a record (what will be signed in the Stree for
606 * @param zone hash of the public key of the zone
607 * @param name name that is being mapped (at most 255 characters long)
608 * @param record_type type of the record (A, AAAA, PKEY, etc.)
609 * @param expiration expiration time for the content
610 * @param flags flags for the content
611 * @param data_size number of bytes in data
612 * @param data value, semantics depend on 'record_type' (see RFCs for DNS and.
613 * GNS specification for GNS extensions)
614 * @param record_hash hash of the record (set)
617 GNUNET_NAMESTORE_record_hash (struct GNUNET_NAMESTORE_Handle *h,
618 const GNUNET_HashCode *zone,
620 uint32_t record_type,
621 struct GNUNET_TIME_Absolute expiration,
622 enum GNUNET_NAMESTORE_RecordFlags flags,
625 GNUNET_HashCode *record_hash)
627 char* teststring = "namestore-stub";
628 GNUNET_CRYPTO_hash(teststring, strlen(teststring), record_hash);
632 * Obtain part of a signature B-tree. The processor
633 * will only be called once.
635 * @param h handle to the namestore
636 * @param zone zone to look up a record from
637 * @param sig_loc location to look up
638 * @param proc function to call on each matching value;
639 * will be called once with a NULL value at the end
640 * @param proc_cls closure for proc
641 * @return a handle that can be used to
644 struct GNUNET_NAMESTORE_QueueEntry *
645 GNUNET_NAMESTORE_lookup_stree (struct GNUNET_NAMESTORE_Handle *h,
646 const GNUNET_HashCode *zone,
647 const struct GNUNET_NAMESTORE_SignatureLocation *sig_loc,
648 GNUNET_NAMESTORE_StreeProcessor proc, void *proc_cls)
650 struct GNUNET_NAMESTORE_QueueEntry *qe;
651 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
657 * Get all records of a zone.
659 * @param h handle to the namestore
660 * @param zone zone to access
661 * @param proc function to call on a random value; it
662 * will be called repeatedly with a value (if available)
663 * and always once at the end with a zone and name of NULL.
664 * @param proc_cls closure for proc
665 * @return a handle that can be used to
668 struct GNUNET_NAMESTORE_QueueEntry *
669 GNUNET_NAMESTORE_zone_transfer (struct GNUNET_NAMESTORE_Handle *h,
670 const GNUNET_HashCode *zone,
671 GNUNET_NAMESTORE_RecordProcessor proc,
674 struct GNUNET_NAMESTORE_QueueEntry *qe;
675 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
683 * Cancel a namestore operation. The final callback from the
684 * operation must not have been done yet.
686 * @param qe operation to cancel
689 GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe)
695 /* end of namestore_api.c */