2 This file is part of GNUnet.
3 (C) 2009, 2010, 2012 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 * @brief library to access the GNS service
23 * @author Martin Schanzenbach
24 * @author Christian Grothoff
27 #include "gnunet_util_lib.h"
28 #include "gnunet_constants.h"
29 #include "gnunet_arm_service.h"
30 #include "gnunet_hello_lib.h"
31 #include "gnunet_protocols.h"
32 #include "gnunet_dht_service.h"
34 #include "gnunet_gns_service.h"
38 * Handle to a lookup request
40 struct GNUNET_GNS_LookupRequest
46 struct GNUNET_GNS_LookupRequest *next;
51 struct GNUNET_GNS_LookupRequest *prev;
56 struct GNUNET_GNS_Handle *gns_handle;
59 * processor to call on lookup result
61 GNUNET_GNS_LookupResultProcessor lookup_proc;
77 * Handle to a shorten request
79 struct GNUNET_GNS_ShortenRequest
84 struct GNUNET_GNS_ShortenRequest *next;
89 struct GNUNET_GNS_ShortenRequest *prev;
94 struct GNUNET_GNS_Handle *gns_handle;
97 * processor to call on shorten result
99 GNUNET_GNS_ShortenResultProcessor shorten_proc;
115 * Handle to GetAuthorityRequest
117 struct GNUNET_GNS_GetAuthRequest
122 struct GNUNET_GNS_GetAuthRequest *next;
127 struct GNUNET_GNS_GetAuthRequest *prev;
132 struct GNUNET_GNS_Handle *gns_handle;
135 * processor to call on authority lookup result
137 GNUNET_GNS_GetAuthResultProcessor auth_proc;
153 * Entry in our list of messages to be (re-)transmitted.
155 struct PendingMessage
158 * This is a doubly-linked list.
160 struct PendingMessage *prev;
163 * This is a doubly-linked list.
165 struct PendingMessage *next;
168 * Size of the message.
178 * This message has been transmitted. GNUNET_NO if the message is
179 * in the "pending" DLL, GNUNET_YES if it has been transmitted to
180 * the service via the current client connection.
188 * Connection to the GNS service.
190 struct GNUNET_GNS_Handle
194 * Configuration to use.
196 const struct GNUNET_CONFIGURATION_Handle *cfg;
199 * Socket (if available).
201 struct GNUNET_CLIENT_Connection *client;
204 * Currently pending transmission request (or NULL).
206 struct GNUNET_CLIENT_TransmitHandle *th;
209 * Head of linked list of shorten messages we would like to transmit.
211 struct PendingMessage *pending_head;
214 * Tail of linked list of shorten messages we would like to transmit.
216 struct PendingMessage *pending_tail;
219 * Head of linked list of shorten messages we would like to transmit.
221 struct GNUNET_GNS_ShortenRequest *shorten_head;
224 * Tail of linked list of shorten messages we would like to transmit.
226 struct GNUNET_GNS_ShortenRequest *shorten_tail;
229 * Head of linked list of lookup messages we would like to transmit.
231 struct GNUNET_GNS_LookupRequest *lookup_head;
234 * Tail of linked list of lookup messages we would like to transmit.
236 struct GNUNET_GNS_LookupRequest *lookup_tail;
239 * Head of linked list of authority lookup messages we would like to transmit.
241 struct GNUNET_GNS_GetAuthRequest *get_auth_head;
244 * Tail of linked list of authority lookup messages we would like to transmit.
246 struct GNUNET_GNS_GetAuthRequest *get_auth_tail;
251 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
254 * How long do we wait until we try to reconnect?
256 struct GNUNET_TIME_Relative reconnect_backoff;
259 * Request Id generator. Incremented by one for each request.
264 * Did we start our receive loop yet?
272 * Try to send messages from list of messages to send
273 * @param handle GNS_Handle
276 process_pending_messages (struct GNUNET_GNS_Handle *handle);
280 * Reconnect to GNS service.
282 * @param handle the handle to the GNS service
285 reconnect (struct GNUNET_GNS_Handle *handle)
287 GNUNET_assert (NULL == handle->client);
288 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
289 "Trying to connect to GNS\n");
290 handle->client = GNUNET_CLIENT_connect ("gns", handle->cfg);
291 GNUNET_assert (NULL != handle->client);
292 process_pending_messages (handle);
299 * @param cls the handle
300 * @param tc task context
303 reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
305 struct GNUNET_GNS_Handle *handle = cls;
307 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
313 * Disconnect from service and then reconnect.
315 * @param handle our handle
318 force_reconnect (struct GNUNET_GNS_Handle *handle)
320 struct GNUNET_GNS_ShortenRequest *st;
321 struct GNUNET_GNS_LookupRequest *lh;
322 struct GNUNET_GNS_GetAuthRequest *ga;
323 struct PendingMessage *p;
325 GNUNET_CLIENT_disconnect (handle->client);
326 handle->client = NULL;
327 handle->in_receive = GNUNET_NO;
328 for (st = handle->shorten_head; NULL != st; st = st->next)
330 p = (struct PendingMessage *) &st[1];
331 if (GNUNET_NO == p->transmitted)
333 p->transmitted = GNUNET_NO;
334 GNUNET_CONTAINER_DLL_insert (handle->pending_head,
335 handle->pending_tail,
338 for (lh = handle->lookup_head; NULL != lh; lh = lh->next)
340 p = (struct PendingMessage *) &lh[1];
341 if (GNUNET_NO == p->transmitted)
343 p->transmitted = GNUNET_NO;
344 GNUNET_CONTAINER_DLL_insert (handle->pending_head,
345 handle->pending_tail,
348 for (ga = handle->get_auth_head; NULL != ga; ga = ga->next)
350 p = (struct PendingMessage *) &ga[1];
351 if (GNUNET_NO == p->transmitted)
353 p->transmitted = GNUNET_NO;
354 GNUNET_CONTAINER_DLL_insert (handle->pending_head,
355 handle->pending_tail,
358 handle->reconnect_backoff = GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff);
359 handle->reconnect_task = GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff,
366 * Transmit the next pending message, called by notify_transmit_ready
368 * @param cls the closure
369 * @param size size of pending data
370 * @param buf buffer with pending data
371 * @return size data transmitted
374 transmit_pending (void *cls, size_t size, void *buf);
378 * Handler for messages received from the GNS service
380 * @param cls the 'struct GNUNET_GNS_Handle'
381 * @param msg the incoming message
384 process_message (void *cls, const struct GNUNET_MessageHeader *msg);
388 * Try to send messages from list of messages to send
390 * @param handle the GNS handle
393 process_pending_messages (struct GNUNET_GNS_Handle *handle)
395 struct PendingMessage *p = handle->pending_head;
397 if (NULL == handle->client)
398 return; /* wait for reconnect */
399 if (NULL != handle->th)
400 return; /* transmission request already pending */
402 while ((NULL != p) && (p->transmitted == GNUNET_YES))
405 return; /* no messages pending */
407 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
408 "Trying to transmit %u bytes\n",
409 (unsigned int) p->size);
411 GNUNET_CLIENT_notify_transmit_ready (handle->client,
413 GNUNET_TIME_UNIT_FOREVER_REL,
414 GNUNET_NO, &transmit_pending,
416 GNUNET_break (NULL != handle->th);
421 * Transmit the next pending message, called by notify_transmit_ready
423 * @param cls the closure
424 * @param size size of pending data
425 * @param buf buffer with pending data
426 * @return size data transmitted
429 transmit_pending (void *cls, size_t size, void *buf)
431 struct GNUNET_GNS_Handle *handle = cls;
433 struct PendingMessage *p;
437 if ((0 == size) || (NULL == buf))
439 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
440 "Transmission to GNS service failed!\n");
441 force_reconnect (handle);
444 if (NULL == (p = handle->pending_head))
448 while ((NULL != (p = handle->pending_head)) && (p->size <= size))
450 memcpy (&cbuf[tsize], &p[1], p->size);
453 p->transmitted = GNUNET_YES;
454 GNUNET_CONTAINER_DLL_remove (handle->pending_head,
455 handle->pending_tail,
457 if (GNUNET_YES != handle->in_receive)
459 GNUNET_CLIENT_receive (handle->client, &process_message, handle,
460 GNUNET_TIME_UNIT_FOREVER_REL);
461 handle->in_receive = GNUNET_YES;
464 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
465 "Sending %u bytes\n",
466 (unsigned int) tsize);
467 process_pending_messages (handle);
473 * Process a given reply that might match the given
476 * @param qe a queue entry
477 * @param msg the shorten msg received
480 process_shorten_reply (struct GNUNET_GNS_ShortenRequest *qe,
481 const struct GNUNET_GNS_ClientShortenResultMessage *msg)
483 struct GNUNET_GNS_Handle *handle = qe->gns_handle;
484 struct PendingMessage *p = (struct PendingMessage *)&qe[1];
485 const char *short_name;
488 if (GNUNET_YES != p->transmitted)
490 /* service send reply to query we never managed to send!? */
492 force_reconnect (handle);
495 mlen = ntohs (msg->header.size);
496 if (ntohs (msg->header.size) == sizeof (struct GNUNET_GNS_ClientShortenResultMessage))
498 /* service reports resolution failed */
503 short_name = (const char *) &msg[1];
504 if ('\0' != short_name[mlen - sizeof (struct GNUNET_GNS_ClientShortenResultMessage) - 1])
507 force_reconnect (handle);
511 GNUNET_CONTAINER_DLL_remove (handle->shorten_head, handle->shorten_tail, qe);
512 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
513 "Received shortened reply `%s' from GNS service\n",
515 qe->shorten_proc (qe->proc_cls, short_name);
521 * Process a given reply that might match the given
524 * @param qe the handle to the request
525 * @param msg the message to process
528 process_get_auth_reply (struct GNUNET_GNS_GetAuthRequest *qe,
529 const struct GNUNET_GNS_ClientGetAuthResultMessage *msg)
531 struct GNUNET_GNS_Handle *handle = qe->gns_handle;
532 struct PendingMessage *p = (struct PendingMessage *)&qe[1];
533 const char *auth_name;
536 if (GNUNET_YES != p->transmitted)
538 /* service send reply to query we never managed to send!? */
540 force_reconnect (handle);
543 mlen = ntohs (msg->header.size);
544 if (mlen == sizeof (struct GNUNET_GNS_ClientGetAuthResultMessage))
550 auth_name = (const char*) &msg[1];
551 if ('\0' != auth_name[mlen - sizeof (struct GNUNET_GNS_ClientGetAuthResultMessage) - 1])
554 force_reconnect (handle);
558 GNUNET_CONTAINER_DLL_remove (handle->get_auth_head, handle->get_auth_tail, qe);
559 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
560 "Received GET_AUTH reply `%s' from GNS service\n",
562 qe->auth_proc (qe->proc_cls, auth_name);
568 * Process a given reply to the lookup request
570 * @param qe a queue entry
571 * @param msg the lookup message received
574 process_lookup_reply (struct GNUNET_GNS_LookupRequest *qe,
575 const struct GNUNET_GNS_ClientLookupResultMessage *msg)
577 struct GNUNET_GNS_Handle *handle = qe->gns_handle;
578 struct PendingMessage *p = (struct PendingMessage *) &qe[1];
579 uint32_t rd_count = ntohl (msg->rd_count);
580 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
583 if (GNUNET_YES != p->transmitted)
585 /* service send reply to query we never managed to send!? */
587 force_reconnect (handle);
590 mlen = ntohs (msg->header.size);
591 mlen -= sizeof (struct GNUNET_GNS_ClientLookupResultMessage);
592 if (GNUNET_SYSERR == GNUNET_NAMESTORE_records_deserialize (mlen,
593 (const char*) &msg[1],
597 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
598 _("Failed to serialize lookup reply from GNS service!\n"));
599 qe->lookup_proc (qe->proc_cls, 0, NULL);
603 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
604 "Received lookup reply from GNS service (%u records)\n",
605 (unsigned int) rd_count);
606 qe->lookup_proc (qe->proc_cls, rd_count, rd);
608 GNUNET_CONTAINER_DLL_remove (handle->lookup_head, handle->lookup_tail, qe);
614 * Handler for messages received from the GNS service
616 * @param cls the 'struct GNUNET_GNS_Handle'
617 * @param msg the incoming message
620 process_message (void *cls, const struct GNUNET_MessageHeader *msg)
622 struct GNUNET_GNS_Handle *handle = cls;
623 struct GNUNET_GNS_LookupRequest *lr;
624 struct GNUNET_GNS_ShortenRequest *sr;
625 struct GNUNET_GNS_GetAuthRequest *gar;
626 const struct GNUNET_GNS_ClientLookupResultMessage *lookup_msg;
627 const struct GNUNET_GNS_ClientShortenResultMessage *shorten_msg;
628 const struct GNUNET_GNS_ClientGetAuthResultMessage *get_auth_msg;
633 force_reconnect (handle);
636 switch (ntohs (msg->type))
638 case GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT:
639 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
640 "Got LOOKUP_RESULT msg\n");
641 if (ntohs (msg->size) < sizeof (struct GNUNET_GNS_ClientLookupResultMessage))
644 force_reconnect (handle);
647 lookup_msg = (const struct GNUNET_GNS_ClientLookupResultMessage *) msg;
648 r_id = ntohl (lookup_msg->id);
649 for (lr = handle->lookup_head; NULL != lr; lr = lr->next)
650 if (lr->r_id == r_id)
652 process_lookup_reply(lr, lookup_msg);
656 case GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT:
657 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
658 "Got SHORTEN_RESULT msg\n");
659 if (ntohs (msg->size) < sizeof (struct GNUNET_GNS_ClientShortenResultMessage))
662 force_reconnect (handle);
665 shorten_msg = (const struct GNUNET_GNS_ClientShortenResultMessage *) msg;
666 r_id = ntohl (shorten_msg->id);
667 for (sr = handle->shorten_head; NULL != sr; sr = sr->next)
668 if (sr->r_id == r_id)
670 process_shorten_reply (sr, shorten_msg);
674 case GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT:
675 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
676 "Got GET_AUTH_RESULT msg\n");
677 if (ntohs (msg->size) < sizeof (struct GNUNET_GNS_ClientGetAuthResultMessage))
680 force_reconnect (handle);
683 get_auth_msg = (const struct GNUNET_GNS_ClientGetAuthResultMessage *) msg;
684 r_id = ntohl (get_auth_msg->id);
685 for (gar = handle->get_auth_head; NULL != gar; gar = gar->next)
686 if (gar->r_id == r_id)
688 process_get_auth_reply (gar, get_auth_msg);
694 force_reconnect (handle);
697 GNUNET_CLIENT_receive (handle->client, &process_message, handle,
698 GNUNET_TIME_UNIT_FOREVER_REL);
703 * Initialize the connection with the GNS service.
705 * @param cfg configuration to use
706 * @return handle to the GNS service, or NULL on error
708 struct GNUNET_GNS_Handle *
709 GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
711 struct GNUNET_GNS_Handle *handle;
713 handle = GNUNET_malloc (sizeof (struct GNUNET_GNS_Handle));
721 * Shutdown connection with the GNS service.
723 * @param handle handle of the GNS connection to stop
726 GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle)
728 GNUNET_CLIENT_disconnect (handle->client);
729 if (GNUNET_SCHEDULER_NO_TASK != handle->reconnect_task)
731 GNUNET_SCHEDULER_cancel (handle->reconnect_task);
732 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
734 GNUNET_assert (NULL == handle->lookup_head);
735 GNUNET_assert (NULL == handle->shorten_head);
736 GNUNET_assert (NULL == handle->get_auth_head);
737 GNUNET_free (handle);
742 * Cancel pending lookup request
744 * @param lr the lookup request to cancel
747 GNUNET_GNS_cancel_lookup_request (struct GNUNET_GNS_LookupRequest *lr)
749 struct PendingMessage *p = (struct PendingMessage*) &lr[1];
751 GNUNET_assert (NULL != lr->gns_handle);
752 if (GNUNET_NO == p->transmitted)
753 GNUNET_CONTAINER_DLL_remove (lr->gns_handle->pending_head,
754 lr->gns_handle->pending_tail,
756 GNUNET_CONTAINER_DLL_remove (lr->gns_handle->lookup_head,
757 lr->gns_handle->lookup_tail,
764 * Cancel pending shorten request
766 * @param sr the lookup request to cancel
769 GNUNET_GNS_cancel_shorten_request (struct GNUNET_GNS_ShortenRequest *sr)
771 struct PendingMessage *p = (struct PendingMessage*) &sr[1];
773 GNUNET_assert (NULL != sr->gns_handle);
774 if (GNUNET_NO == p->transmitted)
775 GNUNET_CONTAINER_DLL_remove (sr->gns_handle->pending_head,
776 sr->gns_handle->pending_tail,
778 GNUNET_CONTAINER_DLL_remove (sr->gns_handle->shorten_head,
779 sr->gns_handle->shorten_tail,
786 * Cancel pending get auth request
788 * @param gar the lookup request to cancel
791 GNUNET_GNS_cancel_get_auth_request (struct GNUNET_GNS_GetAuthRequest *gar)
793 struct PendingMessage *p = (struct PendingMessage*) &gar[1];
795 GNUNET_assert (NULL != gar->gns_handle);
796 if (GNUNET_NO == p->transmitted)
797 GNUNET_CONTAINER_DLL_remove (gar->gns_handle->pending_head,
798 gar->gns_handle->pending_tail,
800 GNUNET_CONTAINER_DLL_remove (gar->gns_handle->get_auth_head,
801 gar->gns_handle->get_auth_tail,
808 * Perform an asynchronous Lookup operation on the GNS.
810 * @param handle handle to the GNS service
811 * @param name the name to look up
812 * @param zone the zone to start the resolution in
813 * @param type the record type to look up
814 * @param only_cached GNUNET_YES to only check locally not DHT for performance
815 * @param shorten_key the private key of the shorten zone (can be NULL)
816 * @param proc processor to call on result
817 * @param proc_cls closure for processor
818 * @return handle to the get request
820 struct GNUNET_GNS_LookupRequest*
821 GNUNET_GNS_lookup_zone (struct GNUNET_GNS_Handle *handle,
823 struct GNUNET_CRYPTO_ShortHashCode *zone,
824 enum GNUNET_GNS_RecordType type,
826 struct GNUNET_CRYPTO_RsaPrivateKey *shorten_key,
827 GNUNET_GNS_LookupResultProcessor proc,
830 /* IPC to shorten gns names, return shorten_handle */
831 struct GNUNET_GNS_ClientLookupMessage *lookup_msg;
832 struct GNUNET_GNS_LookupRequest *lr;
834 struct PendingMessage *pending;
835 struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *pkey_enc;
844 if (NULL != shorten_key)
846 pkey_enc = GNUNET_CRYPTO_rsa_encode_key (shorten_key);
847 GNUNET_assert (pkey_enc != NULL);
848 key_len = ntohs (pkey_enc->len);
855 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
856 "Trying to lookup `%s' in GNS\n",
858 msize = sizeof (struct GNUNET_GNS_ClientLookupMessage)
859 + key_len + strlen (name) + 1;
860 if (msize > UINT16_MAX)
863 GNUNET_free (pkey_enc);
866 lr = GNUNET_malloc (sizeof (struct GNUNET_GNS_LookupRequest) +
867 sizeof (struct PendingMessage) + msize);
868 lr->gns_handle = handle;
869 lr->lookup_proc = proc;
870 lr->proc_cls = proc_cls;
871 lr->r_id = handle->r_id_gen++;
872 pending = (struct PendingMessage *)&lr[1];
873 pending->size = msize;
874 pending->r_id = lr->r_id;
875 GNUNET_CONTAINER_DLL_insert_tail (handle->lookup_head,
876 handle->lookup_tail, lr);
878 lookup_msg = (struct GNUNET_GNS_ClientLookupMessage *) &pending[1];
879 lookup_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_LOOKUP);
880 lookup_msg->header.size = htons (msize);
881 lookup_msg->id = htonl (lr->r_id);
882 lookup_msg->only_cached = htonl (only_cached);
885 lookup_msg->use_default_zone = htonl (GNUNET_NO);
886 memcpy (&lookup_msg->zone, zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode));
890 lookup_msg->use_default_zone = htonl (GNUNET_YES);
891 memset (&lookup_msg->zone, 0, sizeof(struct GNUNET_CRYPTO_ShortHashCode));
893 lookup_msg->type = htonl (type);
894 pkey_tmp = (char *) &lookup_msg[1];
895 if (pkey_enc != NULL)
897 lookup_msg->have_key = htonl (GNUNET_YES);
898 memcpy (pkey_tmp, pkey_enc, key_len);
901 lookup_msg->have_key = htonl (GNUNET_NO);
902 GNUNET_free_non_null (pkey_enc);
903 memcpy (&pkey_tmp[key_len], name, strlen (name) + 1);
905 GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head,
906 handle->pending_tail,
908 process_pending_messages (handle);
914 * Perform an asynchronous Lookup operation on the GNS.
916 * @param handle handle to the GNS service
917 * @param name the name to look up
918 * @param type the record type to look up
919 * @param only_cached GNUNET_YES to only check locally not DHT for performance
920 * @param shorten_key the private key of the shorten zone (can be NULL)
921 * @param proc processor to call on result
922 * @param proc_cls closure for processor
923 * @return handle to the lookup request
925 struct GNUNET_GNS_LookupRequest *
926 GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
928 enum GNUNET_GNS_RecordType type,
930 struct GNUNET_CRYPTO_RsaPrivateKey *shorten_key,
931 GNUNET_GNS_LookupResultProcessor proc,
934 return GNUNET_GNS_lookup_zone (handle, name,
943 * Perform a name shortening operation on the GNS.
945 * @param handle handle to the GNS service
946 * @param name the name to look up
947 * @param private_zone the public zone of the private zone
948 * @param shorten_zone the public zone of the shorten zone
949 * @param zone the zone to start the resolution in
950 * @param proc function to call on result
951 * @param proc_cls closure for processor
952 * @return handle to the operation
954 struct GNUNET_GNS_ShortenRequest*
955 GNUNET_GNS_shorten_zone (struct GNUNET_GNS_Handle *handle,
957 struct GNUNET_CRYPTO_ShortHashCode *private_zone,
958 struct GNUNET_CRYPTO_ShortHashCode *shorten_zone,
959 struct GNUNET_CRYPTO_ShortHashCode *zone,
960 GNUNET_GNS_ShortenResultProcessor proc,
963 /* IPC to shorten gns names, return shorten_handle */
964 struct GNUNET_GNS_ClientShortenMessage *shorten_msg;
965 struct GNUNET_GNS_ShortenRequest *sr;
967 struct PendingMessage *pending;
974 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to shorten `%s' in GNS\n", name);
975 msize = sizeof (struct GNUNET_GNS_ClientShortenMessage) + strlen (name) + 1;
976 if (msize > UINT16_MAX)
981 sr = GNUNET_malloc (sizeof (struct GNUNET_GNS_ShortenRequest) +
982 sizeof (struct PendingMessage) + msize);
983 sr->gns_handle = handle;
984 sr->shorten_proc = proc;
985 sr->proc_cls = proc_cls;
986 sr->r_id = handle->r_id_gen++;
987 GNUNET_CONTAINER_DLL_insert_tail (handle->shorten_head,
988 handle->shorten_tail, sr);
989 pending = (struct PendingMessage *)&sr[1];
990 pending->size = msize;
991 pending->r_id = sr->r_id;
993 shorten_msg = (struct GNUNET_GNS_ClientShortenMessage *) &pending[1];
994 shorten_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_SHORTEN);
995 shorten_msg->header.size = htons ((uint16_t) msize);
996 shorten_msg->id = htonl (sr->r_id);
997 shorten_msg->private_zone = *private_zone;
998 shorten_msg->shorten_zone = *shorten_zone;
1001 shorten_msg->use_default_zone = htonl (GNUNET_NO);
1002 memcpy (&shorten_msg->zone, zone,
1003 sizeof (struct GNUNET_CRYPTO_ShortHashCode));
1007 shorten_msg->use_default_zone = htonl (GNUNET_YES);
1008 memset (&shorten_msg->zone, 0, sizeof (struct GNUNET_CRYPTO_ShortHashCode));
1010 memcpy (&shorten_msg[1], name, strlen (name) + 1);
1011 GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head, handle->pending_tail,
1013 process_pending_messages (handle);
1019 * Perform a name shortening operation on the GNS.
1021 * @param handle handle to the GNS service
1022 * @param name the name to look up
1023 * @param private_zone the public zone of the private zone
1024 * @param shorten_zone the public zone of the shorten zone
1025 * @param proc function to call on result
1026 * @param proc_cls closure for processor
1027 * @return handle to the operation
1029 struct GNUNET_GNS_ShortenRequest*
1030 GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle,
1032 struct GNUNET_CRYPTO_ShortHashCode *private_zone,
1033 struct GNUNET_CRYPTO_ShortHashCode *shorten_zone,
1034 GNUNET_GNS_ShortenResultProcessor proc,
1037 return GNUNET_GNS_shorten_zone (handle, name,
1038 private_zone, shorten_zone,
1039 NULL, proc, proc_cls);
1044 * Perform an authority lookup for a given name.
1046 * @param handle handle to the GNS service
1047 * @param name the name to look up authority for
1048 * @param proc function to call on result
1049 * @param proc_cls closure for processor
1050 * @return handle to the operation
1052 struct GNUNET_GNS_GetAuthRequest*
1053 GNUNET_GNS_get_authority (struct GNUNET_GNS_Handle *handle,
1055 GNUNET_GNS_GetAuthResultProcessor proc,
1058 struct GNUNET_GNS_ClientGetAuthMessage *get_auth_msg;
1059 struct GNUNET_GNS_GetAuthRequest *gar;
1061 struct PendingMessage *pending;
1068 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1069 "Trying to look up authority for %s in GNS\n", name);
1070 msize = sizeof (struct GNUNET_GNS_ClientGetAuthMessage) + strlen (name) + 1;
1071 if (msize > UINT16_MAX)
1076 gar = GNUNET_malloc (sizeof (struct GNUNET_GNS_GetAuthRequest) +
1077 sizeof (struct PendingMessage) + msize);
1078 gar->gns_handle = handle;
1079 gar->auth_proc = proc;
1080 gar->proc_cls = proc_cls;
1081 gar->r_id = handle->r_id_gen++;
1082 GNUNET_CONTAINER_DLL_insert_tail (handle->get_auth_head,
1083 handle->get_auth_tail, gar);
1085 pending = (struct PendingMessage *) &gar[1];
1086 pending->size = msize;
1087 pending->r_id = gar->r_id;
1088 get_auth_msg = (struct GNUNET_GNS_ClientGetAuthMessage *) &pending[1];
1089 get_auth_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_GET_AUTH);
1090 get_auth_msg->header.size = htons (msize);
1091 get_auth_msg->id = htonl (gar->r_id);
1092 memcpy (&get_auth_msg[1], name, strlen (name) + 1);
1093 GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head,
1094 handle->pending_tail,
1096 process_pending_messages (handle);
1101 /* end of gns_api.c */