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);
150 * We can now transmit a message to NAMESTORE. Do it.
152 * @param cls the 'struct GNUNET_NAMESTORE_Handle'
153 * @param size number of bytes we can transmit
154 * @param buf where to copy the messages
155 * @return number of bytes copied into buf
158 transmit_message_to_namestore (void *cls, size_t size, void *buf)
160 struct GNUNET_NAMESTORE_Handle *nsh = cls;
161 struct PendingMessage *p;
166 if ((size == 0) || (buf == NULL))
168 force_reconnect (nsh);
173 while ((NULL != (p = nsh->pending_head)) && (p->size <= size))
175 memcpy (&cbuf[ret], &p[1], p->size);
178 GNUNET_CONTAINER_DLL_remove (nsh->pending_head, nsh->pending_tail, p);
179 if (GNUNET_YES == p->is_init)
180 GNUNET_CLIENT_receive (nsh->client,/* &process_namestore_message*/ NULL, nsh,
181 GNUNET_TIME_UNIT_FOREVER_REL);
190 * Transmit messages from the message queue to the service
191 * (if there are any, and if we are not already trying).
193 * @param nsh handle to use
196 do_transmit (struct GNUNET_NAMESTORE_Handle *nsh)
198 struct PendingMessage *p;
202 if (NULL == (p = nsh->pending_head))
204 if (NULL == nsh->client)
205 return; /* currently reconnecting */
206 nsh->th = GNUNET_CLIENT_notify_transmit_ready (nsh->client, p->size,
207 GNUNET_TIME_UNIT_FOREVER_REL,
208 GNUNET_NO, &transmit_message_to_namestore,
214 * Try again to connect to namestore service.
216 * @param cls the handle to the namestore service
217 * @param tc scheduler context
220 reconnect (struct GNUNET_NAMESTORE_Handle *nsh)
222 struct PendingMessage *p;
223 struct StartMessage *init;
225 GNUNET_assert (NULL == nsh->client);
226 nsh->client = GNUNET_CLIENT_connect ("namestore", nsh->cfg);
227 GNUNET_assert (NULL != nsh->client);
229 if ((NULL == (p = nsh->pending_head)) || (GNUNET_YES != p->is_init))
231 p = GNUNET_malloc (sizeof (struct PendingMessage) +
232 sizeof (struct StartMessage));
233 p->size = sizeof (struct StartMessage);
234 p->is_init = GNUNET_YES;
235 init = (struct StartMessage *) &p[1];
236 init->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_START);
237 init->header.size = htons (sizeof (struct StartMessage));
238 GNUNET_CONTAINER_DLL_insert (nsh->pending_head, nsh->pending_tail, p);
244 * Re-establish the connection to the service.
246 * @param cls handle to use to re-connect.
247 * @param tc scheduler context
250 reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
252 struct GNUNET_NAMESTORE_Handle *nsh = cls;
254 nsh->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
260 * Disconnect from service and then reconnect.
262 * @param nsh our handle
265 force_reconnect (struct GNUNET_NAMESTORE_Handle *nsh)
267 nsh->reconnect = GNUNET_NO;
268 GNUNET_CLIENT_disconnect (nsh->client, GNUNET_NO);
270 nsh->reconnect_task =
271 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &reconnect_task,
278 * Initialize the connection with the NAMESTORE service.
280 * @param cfg configuration to use
281 * @return handle to the GNS service, or NULL on error
283 struct GNUNET_NAMESTORE_Handle *
284 GNUNET_NAMESTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
286 struct GNUNET_NAMESTORE_Handle *nsh;
288 nsh = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_Handle));
290 nsh->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect, nsh);
296 * Shutdown connection with the NAMESTORE service.
298 * @param handle handle of the NAMESTORE connection to stop
301 GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *handle, int drop)
307 * Sign a record. This function is used by the authority of the zone
310 * @param h handle to the namestore
311 * @param zone_privkey private key of the zone
312 * @param record_hash hash of the record to be signed
313 * @param cont continuation to call when done
314 * @param cont_cls closure for cont
315 * @return handle to abort the request
317 struct GNUNET_NAMESTORE_QueueEntry *
318 GNUNET_NAMESTORE_stree_extend (struct GNUNET_NAMESTORE_Handle *h,
319 const struct GNUNET_CRYPTO_RsaPrivateKey *zone_privkey,
320 const GNUNET_HashCode *record_hash,
321 GNUNET_NAMESTORE_ContinuationWithSignature cont,
324 struct GNUNET_NAMESTORE_QueueEntry *qe;
325 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
330 * Rebalance the signature tree of our zone. This function should
331 * be called "rarely" to rebalance the tree.
333 * @param h handle to the namestore
334 * @param zone_privkey private key for the zone to rebalance
335 * @param cont continuation to call when done
336 * @param cont_cls closure for cont
337 * @return handle to abort the request
339 struct GNUNET_NAMESTORE_QueueEntry *
340 GNUNET_NAMESTORE_stree_rebalance (struct GNUNET_NAMESTORE_Handle *h,
341 const struct GNUNET_CRYPTO_RsaPrivateKey *zone_privkey,
342 GNUNET_NAMESTORE_ContinuationWithStatus cont,
345 struct GNUNET_NAMESTORE_QueueEntry *qe;
346 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
351 * Provide the root of a signature tree. This function is
352 * used by non-authorities as the first operation when
353 * adding a foreign zone.
355 * @param h handle to the namestore
356 * @param zone_key public key of the zone
357 * @param signature signature of the top-level entry of the zone
358 * @param revision revision number of the zone
359 * @param top_hash top-level hash of the zone
360 * @param cont continuation to call when done
361 * @param cont_cls closure for cont
362 * @return handle to abort the request
364 struct GNUNET_NAMESTORE_QueueEntry *
365 GNUNET_NAMESTORE_stree_start (struct GNUNET_NAMESTORE_Handle *h,
366 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
367 const struct GNUNET_CRYPTO_RsaSignature *signature,
369 const GNUNET_HashCode *top_hash,
370 GNUNET_NAMESTORE_ContinuationWithSignature cont,
373 struct GNUNET_NAMESTORE_QueueEntry *qe;
374 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
379 * Store part of a signature B-tree in the namestore. This function
380 * is used by non-authorities to cache parts of a zone's signature tree.
381 * Note that the tree must be build top-down. This function must check
382 * that the nodes being added are valid, and if not refuse the operation.
384 * @param h handle to the namestore
385 * @param zone_key public key of the zone
386 * @param loc location in the B-tree
387 * @param ploc parent's location in the B-tree (must have depth = loc.depth - 1), NULL for root
388 * @param top_sig signature at the top, NULL if 'loc.depth > 0'
389 * @param num_entries number of entries at this node in the B-tree
390 * @param entries the 'num_entries' entries to store (hashes over the
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_put (struct GNUNET_NAMESTORE_Handle *h,
398 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
399 const struct GNUNET_NAMESTORE_SignatureLocation *loc,
400 const struct GNUNET_NAMESTORE_SignatureLocation *ploc,
401 const struct GNUNET_CRYPTO_RsaSignature *sig,
402 unsigned int num_entries,
403 const GNUNET_HashCode *entries,
404 GNUNET_NAMESTORE_ContinuationWithStatus cont,
407 struct GNUNET_NAMESTORE_QueueEntry *qe;
408 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
413 * Store an item in the namestore. If the item is already present,
414 * the expiration time is updated to the max of the existing time and
415 * the new time. The operation must fail if there is no matching
416 * entry in the signature tree.
418 * @param h handle to the namestore
419 * @param zone hash of the public key of the zone
420 * @param name name that is being mapped (at most 255 characters long)
421 * @param record_type type of the record (A, AAAA, PKEY, etc.)
422 * @param expiration expiration time for the content
423 * @param flags flags for the content
424 * @param sig_loc where is the information about the signature for this record stored?
425 * @param data_size number of bytes in data
426 * @param data value, semantics depend on 'record_type' (see RFCs for DNS and
427 * GNS specification for GNS extensions)
428 * @param cont continuation to call when done
429 * @param cont_cls closure for cont
430 * @return handle to abort the request
432 struct GNUNET_NAMESTORE_QueueEntry *
433 GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h,
434 const GNUNET_HashCode *zone,
436 uint32_t record_type,
437 struct GNUNET_TIME_Absolute expiration,
438 enum GNUNET_NAMESTORE_RecordFlags flags,
439 const struct GNUNET_NAMESTORE_SignatureLocation *sig_loc,
442 GNUNET_NAMESTORE_ContinuationWithStatus cont,
445 struct GNUNET_NAMESTORE_QueueEntry *qe;
446 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
448 struct GNUNET_NAMESTORE_SimpleRecord *sr;
449 sr = GNUNET_malloc(sizeof(struct GNUNET_NAMESTORE_SimpleRecord));
451 sr->record_type = record_type;
452 sr->expiration = expiration;
454 sr->data_size = data_size;
456 GNUNET_CONTAINER_DLL_insert(h->records_head, h->records_tail, sr);
462 * Explicitly remove some content from the database. The
463 * "cont"inuation will be called with status "GNUNET_OK" if content
464 * was removed, "GNUNET_NO" if no matching entry was found and
465 * "GNUNET_SYSERR" on all other types of errors.
467 * @param h handle to the namestore
468 * @param zone hash of the public key of the zone
469 * @param name name that is being mapped (at most 255 characters long)
470 * @param record_type type of the record (A, AAAA, PKEY, etc.)
471 * @param size number of bytes in data
472 * @param data content stored
473 * @param cont continuation to call when done
474 * @param cont_cls closure for cont
475 * @return handle to abort the request
477 struct GNUNET_NAMESTORE_QueueEntry *
478 GNUNET_NAMESTORE_record_remove (struct GNUNET_NAMESTORE_Handle *h,
479 const GNUNET_HashCode *zone,
481 uint32_t record_type,
484 GNUNET_NAMESTORE_ContinuationWithStatus cont,
487 struct GNUNET_NAMESTORE_QueueEntry *qe;
488 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
490 struct GNUNET_NAMESTORE_SimpleRecord *iter;
491 for (iter=h->records_head; iter != NULL; iter=iter->next)
493 if (strcmp ( iter->name, name ) &&
494 iter->record_type == record_type &&
495 GNUNET_CRYPTO_hash_cmp (iter->zone, zone))
499 GNUNET_CONTAINER_DLL_remove(h->records_head,
507 * Get a result for a particular key from the namestore. The processor
508 * will only be called once.
510 * @param h handle to the namestore
511 * @param zone zone to look up a record from
512 * @param name name to look up
513 * @param record_type desired record type
514 * @param proc function to call on each matching value;
515 * will be called once with a NULL value at the end
516 * @param proc_cls closure for proc
517 * @return a handle that can be used to
520 struct GNUNET_NAMESTORE_QueueEntry *
521 GNUNET_NAMESTORE_lookup_name (struct GNUNET_NAMESTORE_Handle *h,
522 const GNUNET_HashCode *zone,
524 uint32_t record_type,
525 GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls)
527 struct GNUNET_NAMESTORE_QueueEntry *qe;
528 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
530 struct GNUNET_NAMESTORE_SimpleRecord *iter;
531 for (iter=h->records_head; iter != NULL; iter=iter->next)
533 proc(proc_cls, iter->zone, iter->name, iter->record_type,
537 iter->data_size /*size*/,
538 iter->data /* data */);
540 proc(proc_cls, zone, name, record_type,
541 GNUNET_TIME_absolute_get_forever(), 0, NULL, 0, NULL); /*TERMINATE*/
548 * Get the hash of a record (what will be signed in the Stree for
551 * @param zone hash of the public key of the zone
552 * @param name name that is being mapped (at most 255 characters long)
553 * @param record_type type of the record (A, AAAA, PKEY, etc.)
554 * @param expiration expiration time for the content
555 * @param flags flags for the content
556 * @param data_size number of bytes in data
557 * @param data value, semantics depend on 'record_type' (see RFCs for DNS and.
558 * GNS specification for GNS extensions)
559 * @param record_hash hash of the record (set)
562 GNUNET_NAMESTORE_record_hash (struct GNUNET_NAMESTORE_Handle *h,
563 const GNUNET_HashCode *zone,
565 uint32_t record_type,
566 struct GNUNET_TIME_Absolute expiration,
567 enum GNUNET_NAMESTORE_RecordFlags flags,
570 GNUNET_HashCode *record_hash)
572 char* teststring = "namestore-stub";
573 GNUNET_CRYPTO_hash(teststring, strlen(teststring), record_hash);
577 * Obtain part of a signature B-tree. The processor
578 * will only be called once.
580 * @param h handle to the namestore
581 * @param zone zone to look up a record from
582 * @param sig_loc location to look up
583 * @param proc function to call on each matching value;
584 * will be called once with a NULL value at the end
585 * @param proc_cls closure for proc
586 * @return a handle that can be used to
589 struct GNUNET_NAMESTORE_QueueEntry *
590 GNUNET_NAMESTORE_lookup_stree (struct GNUNET_NAMESTORE_Handle *h,
591 const GNUNET_HashCode *zone,
592 const struct GNUNET_NAMESTORE_SignatureLocation *sig_loc,
593 GNUNET_NAMESTORE_StreeProcessor proc, void *proc_cls)
595 struct GNUNET_NAMESTORE_QueueEntry *qe;
596 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
602 * Get all records of a zone.
604 * @param h handle to the namestore
605 * @param zone zone to access
606 * @param proc function to call on a random value; it
607 * will be called repeatedly with a value (if available)
608 * and always once at the end with a zone and name of NULL.
609 * @param proc_cls closure for proc
610 * @return a handle that can be used to
613 struct GNUNET_NAMESTORE_QueueEntry *
614 GNUNET_NAMESTORE_zone_transfer (struct GNUNET_NAMESTORE_Handle *h,
615 const GNUNET_HashCode *zone,
616 GNUNET_NAMESTORE_RecordProcessor proc,
619 struct GNUNET_NAMESTORE_QueueEntry *qe;
620 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
628 * Cancel a namestore operation. The final callback from the
629 * operation must not have been done yet.
631 * @param qe operation to cancel
634 GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe)
640 /* end of namestore_api.c */