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;
173 * 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;
256 * Did we start our receive loop yet?
264 * Try to send messages from list of messages to send
265 * @param handle GNS_Handle
268 process_pending_messages (struct GNUNET_GNS_Handle *handle);
272 * Reconnect to GNS service.
274 * @param h the handle to the GNS service
277 reconnect (struct GNUNET_GNS_Handle *h)
279 GNUNET_assert (NULL == h->client);
280 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
281 "Trying to connect to GNS\n");
282 h->client = GNUNET_CLIENT_connect ("gns", h->cfg);
283 GNUNET_assert (NULL != h->client);
284 process_pending_messages (h);
291 * @param cls the handle
292 * @param tc task context
295 reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
297 struct GNUNET_GNS_Handle *h = cls;
299 h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
305 * Disconnect from service and then reconnect.
307 * @param h our handle
310 force_reconnect (struct GNUNET_GNS_Handle *h)
312 struct GNUNET_GNS_ShortenRequest *st;
313 struct GNUNET_GNS_LookupRequest *lh;
314 struct GNUNET_GNS_GetAuthRequest *ga;
315 struct PendingMessage *p;
317 GNUNET_CLIENT_disconnect (h->client);
319 h->in_receive = GNUNET_NO;
320 for (st = h->shorten_head; NULL != st; st = st->next)
322 p = (struct PendingMessage*) &st[1];
323 if (GNUNET_NO == p->transmitted)
325 p->transmitted = GNUNET_NO;
326 GNUNET_CONTAINER_DLL_insert (h->pending_head,
330 for (lh = h->lookup_head; NULL != lh; lh = lh->next)
332 p = (struct PendingMessage*) &lh[1];
333 if (GNUNET_NO == p->transmitted)
335 p->transmitted = GNUNET_NO;
336 GNUNET_CONTAINER_DLL_insert (h->pending_head,
340 for (ga = h->get_auth_head; NULL != ga; ga = ga->next)
342 p = (struct PendingMessage*) &ga[1];
343 if (GNUNET_NO == p->transmitted)
345 p->transmitted = GNUNET_NO;
346 GNUNET_CONTAINER_DLL_insert (h->pending_head,
350 /* FIXME: 1s too long, exponential-backoff, starting at 1ms! (max = 1s might be OK) */
351 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
358 * Transmit the next pending message, called by notify_transmit_ready
360 * @param cls the closure
361 * @param size size of pending data
362 * @param buf buffer with pending data
363 * @return size data transmitted
366 transmit_pending (void *cls, size_t size, void *buf);
370 * Handler for messages received from the GNS service
372 * @param cls the 'struct GNUNET_GNS_Handle'
373 * @param msg the incoming message
376 process_message (void *cls, const struct GNUNET_MessageHeader *msg);
380 * Try to send messages from list of messages to send
382 * @param handle the GNS handle
385 process_pending_messages (struct GNUNET_GNS_Handle *handle)
387 struct PendingMessage *p = handle->pending_head;
389 if (NULL == handle->client)
390 return; /* wait for reconnect */
391 if (NULL != handle->th)
392 return; /* transmission request already pending */
394 while ((NULL != p) && (p->transmitted == GNUNET_YES))
397 return; /* no messages pending */
399 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
400 "Trying to transmit %u bytes\n",
401 (unsigned int) p->size);
403 GNUNET_CLIENT_notify_transmit_ready (handle->client,
405 GNUNET_TIME_UNIT_FOREVER_REL,
406 GNUNET_NO, &transmit_pending,
408 GNUNET_break (NULL != handle->th);
413 * Transmit the next pending message, called by notify_transmit_ready
415 * @param cls the closure
416 * @param size size of pending data
417 * @param buf buffer with pending data
418 * @return size data transmitted
421 transmit_pending (void *cls, size_t size, void *buf)
423 struct GNUNET_GNS_Handle *h = cls;
425 struct PendingMessage *p;
429 if ((0 == size) || (NULL == buf))
431 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
432 "Transmission to GNS service failed!\n");
436 if (NULL == (p = h->pending_head))
440 while ((NULL != (p = h->pending_head)) && (p->size <= size))
442 memcpy (&cbuf[tsize], &p[1], p->size);
445 p->transmitted = GNUNET_YES;
446 GNUNET_CONTAINER_DLL_remove (h->pending_head,
449 if (GNUNET_YES != h->in_receive)
451 GNUNET_CLIENT_receive (h->client, &process_message, h,
452 GNUNET_TIME_UNIT_FOREVER_REL);
453 h->in_receive = GNUNET_YES;
456 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
457 "Sending %u bytes\n",
458 (unsigned int) tsize);
459 process_pending_messages (h);
465 * Process a given reply that might match the given
468 * @param qe a queue entry
469 * @param msg the shorten msg received
472 process_shorten_reply (struct GNUNET_GNS_ShortenRequest *qe,
473 const struct GNUNET_GNS_ClientShortenResultMessage *msg)
475 struct GNUNET_GNS_Handle *h = qe->gns_handle;
476 struct PendingMessage *p = (struct PendingMessage *)&qe[1];
477 const char *short_name;
480 if (GNUNET_YES != p->transmitted)
482 /* service send reply to query we never managed to send!? */
487 mlen = ntohs (msg->header.size);
488 if (ntohs (msg->header.size) == sizeof (struct GNUNET_GNS_ClientShortenResultMessage))
490 /* service reports resolution failed */
495 short_name = (const char *) &msg[1];
496 if ('\0' != short_name[mlen - sizeof (struct GNUNET_GNS_ClientShortenResultMessage) - 1])
503 GNUNET_CONTAINER_DLL_remove (h->shorten_head, h->shorten_tail, qe);
504 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
505 "Received shortened reply `%s' from GNS service\n",
507 qe->shorten_proc (qe->proc_cls, short_name);
513 * Process a given reply that might match the given
516 * @param qe the handle to the request
517 * @param msg the message to process
520 process_get_auth_reply (struct GNUNET_GNS_GetAuthRequest *qe,
521 const struct GNUNET_GNS_ClientGetAuthResultMessage *msg)
523 struct GNUNET_GNS_Handle *h = qe->gns_handle;
524 struct PendingMessage *p = (struct PendingMessage *)&qe[1];
525 const char *auth_name;
528 if (GNUNET_YES != p->transmitted)
530 /* service send reply to query we never managed to send!? */
535 mlen = ntohs (msg->header.size);
536 if (mlen == sizeof (struct GNUNET_GNS_ClientGetAuthResultMessage))
542 auth_name = (const char*) &msg[1];
543 if ('\0' != auth_name[mlen - sizeof (struct GNUNET_GNS_ClientGetAuthResultMessage) - 1])
550 GNUNET_CONTAINER_DLL_remove (h->get_auth_head, h->get_auth_tail, qe);
551 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
552 "Received GET_AUTH reply `%s' from GNS service\n",
554 qe->auth_proc (qe->proc_cls, auth_name);
560 * Process a given reply to the lookup request
562 * @param qe a queue entry
563 * @param msg the lookup message received
566 process_lookup_reply (struct GNUNET_GNS_LookupRequest *qe,
567 const struct GNUNET_GNS_ClientLookupResultMessage *msg)
569 struct GNUNET_GNS_Handle *h = qe->gns_handle;
570 struct PendingMessage *p = (struct PendingMessage *) &qe[1];
571 uint32_t rd_count = ntohl (msg->rd_count);
572 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
575 if (GNUNET_YES != p->transmitted)
577 /* service send reply to query we never managed to send!? */
582 mlen = ntohs (msg->header.size);
583 mlen -= sizeof (struct GNUNET_GNS_ClientLookupResultMessage);
584 if (GNUNET_SYSERR == GNUNET_NAMESTORE_records_deserialize (mlen,
585 (const char*) &msg[1],
589 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
590 _("Failed to serialize lookup reply from GNS service!\n"));
591 qe->lookup_proc (qe->proc_cls, 0, NULL);
595 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
596 "Received lookup reply from GNS service (%u records)\n",
597 (unsigned int) rd_count);
598 qe->lookup_proc (qe->proc_cls, rd_count, rd);
600 GNUNET_CONTAINER_DLL_remove (h->lookup_head, h->lookup_tail, qe);
606 * Handler for messages received from the GNS service
608 * @param cls the 'struct GNUNET_GNS_Handle'
609 * @param msg the incoming message
612 process_message (void *cls, const struct GNUNET_MessageHeader *msg)
614 struct GNUNET_GNS_Handle *handle = cls;
615 struct GNUNET_GNS_LookupRequest *lr;
616 struct GNUNET_GNS_ShortenRequest *sr;
617 struct GNUNET_GNS_GetAuthRequest *gar;
618 const struct GNUNET_GNS_ClientLookupResultMessage *lookup_msg;
619 const struct GNUNET_GNS_ClientShortenResultMessage *shorten_msg;
620 const struct GNUNET_GNS_ClientGetAuthResultMessage *get_auth_msg;
625 force_reconnect (handle);
628 switch (ntohs (msg->type))
630 case GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT:
631 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
632 "Got LOOKUP_RESULT msg\n");
633 if (ntohs (msg->size) < sizeof (struct GNUNET_GNS_ClientLookupResultMessage))
636 force_reconnect (handle);
639 lookup_msg = (const struct GNUNET_GNS_ClientLookupResultMessage *) msg;
640 r_id = ntohl (lookup_msg->id);
641 for (lr = handle->lookup_head; NULL != lr; lr = lr->next)
642 if (lr->r_id == r_id)
644 process_lookup_reply(lr, lookup_msg);
648 case GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT:
649 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
650 "Got SHORTEN_RESULT msg\n");
651 if (ntohs (msg->size) < sizeof (struct GNUNET_GNS_ClientShortenResultMessage))
654 force_reconnect (handle);
657 shorten_msg = (const struct GNUNET_GNS_ClientShortenResultMessage *) msg;
658 r_id = ntohl (shorten_msg->id);
659 for (sr = handle->shorten_head; NULL != sr; sr = sr->next)
660 if (sr->r_id == r_id)
662 process_shorten_reply (sr, shorten_msg);
666 case GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT:
667 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
668 "Got GET_AUTH_RESULT msg\n");
669 if (ntohs (msg->size) < sizeof (struct GNUNET_GNS_ClientGetAuthResultMessage))
672 force_reconnect (handle);
675 get_auth_msg = (const struct GNUNET_GNS_ClientGetAuthResultMessage *) msg;
676 r_id = ntohl (get_auth_msg->id);
677 for (gar = handle->get_auth_head; NULL != gar; gar = gar->next)
678 if (gar->r_id == r_id)
680 process_get_auth_reply (gar, get_auth_msg);
686 force_reconnect (handle);
689 GNUNET_CLIENT_receive (handle->client, &process_message, handle,
690 GNUNET_TIME_UNIT_FOREVER_REL);
695 * Initialize the connection with the GNS service.
697 * @param cfg configuration to use
698 * @return handle to the GNS service, or NULL on error
700 struct GNUNET_GNS_Handle *
701 GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
703 struct GNUNET_GNS_Handle *handle;
705 handle = GNUNET_malloc (sizeof (struct GNUNET_GNS_Handle));
713 * Shutdown connection with the GNS service.
715 * @param handle handle of the GNS connection to stop
718 GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle)
720 GNUNET_CLIENT_disconnect (handle->client);
721 if (GNUNET_SCHEDULER_NO_TASK != handle->reconnect_task)
723 GNUNET_SCHEDULER_cancel (handle->reconnect_task);
724 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
726 GNUNET_assert (NULL == handle->lookup_head);
727 GNUNET_assert (NULL == handle->shorten_head);
728 GNUNET_assert (NULL == handle->get_auth_head);
729 GNUNET_free (handle);
734 * Cancel pending lookup request
736 * @param lr the lookup request to cancel
739 GNUNET_GNS_cancel_lookup_request (struct GNUNET_GNS_LookupRequest *lr)
741 struct PendingMessage *p = (struct PendingMessage*) &lr[1];
743 GNUNET_assert (NULL != lr->gns_handle);
744 if (GNUNET_NO == p->transmitted)
745 GNUNET_CONTAINER_DLL_remove (lr->gns_handle->pending_head,
746 lr->gns_handle->pending_tail,
748 GNUNET_CONTAINER_DLL_remove (lr->gns_handle->lookup_head,
749 lr->gns_handle->lookup_tail,
756 * Cancel pending shorten request
758 * @param sr the lookup request to cancel
761 GNUNET_GNS_cancel_shorten_request (struct GNUNET_GNS_ShortenRequest *sr)
763 struct PendingMessage *p = (struct PendingMessage*) &sr[1];
765 GNUNET_assert (NULL != sr->gns_handle);
766 if (GNUNET_NO == p->transmitted)
767 GNUNET_CONTAINER_DLL_remove (sr->gns_handle->pending_head,
768 sr->gns_handle->pending_tail,
770 GNUNET_CONTAINER_DLL_remove (sr->gns_handle->shorten_head,
771 sr->gns_handle->shorten_tail,
778 * Cancel pending get auth request
780 * @param gar the lookup request to cancel
783 GNUNET_GNS_cancel_get_auth_request (struct GNUNET_GNS_GetAuthRequest *gar)
785 struct PendingMessage *p = (struct PendingMessage*) &gar[1];
787 GNUNET_assert (NULL != gar->gns_handle);
788 if (GNUNET_NO == p->transmitted)
789 GNUNET_CONTAINER_DLL_remove (gar->gns_handle->pending_head,
790 gar->gns_handle->pending_tail,
792 GNUNET_CONTAINER_DLL_remove (gar->gns_handle->get_auth_head,
793 gar->gns_handle->get_auth_tail,
800 * Perform an asynchronous Lookup operation on the GNS.
802 * @param handle handle to the GNS service
803 * @param name the name to look up
804 * @param zone the zone to start the resolution in
805 * @param type the record type to look up
806 * @param only_cached GNUNET_YES to only check locally not DHT for performance
807 * @param shorten_key the private key of the shorten zone (can be NULL)
808 * @param proc processor to call on result
809 * @param proc_cls closure for processor
810 * @return handle to the get request
812 struct GNUNET_GNS_LookupRequest*
813 GNUNET_GNS_lookup_zone (struct GNUNET_GNS_Handle *handle,
815 struct GNUNET_CRYPTO_ShortHashCode *zone,
816 enum GNUNET_GNS_RecordType type,
818 struct GNUNET_CRYPTO_RsaPrivateKey *shorten_key,
819 GNUNET_GNS_LookupResultProcessor proc,
822 /* IPC to shorten gns names, return shorten_handle */
823 struct GNUNET_GNS_ClientLookupMessage *lookup_msg;
824 struct GNUNET_GNS_LookupRequest *lr;
826 struct PendingMessage *pending;
827 struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *pkey_enc;
836 if (NULL != shorten_key)
838 pkey_enc = GNUNET_CRYPTO_rsa_encode_key (shorten_key);
839 GNUNET_assert (pkey_enc != NULL);
840 key_len = ntohs (pkey_enc->len);
847 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
848 "Trying to lookup `%s' in GNS\n",
850 msize = sizeof (struct GNUNET_GNS_ClientLookupMessage)
851 + key_len + strlen (name) + 1;
852 if (msize > UINT16_MAX)
855 GNUNET_free (pkey_enc);
858 lr = GNUNET_malloc (sizeof (struct GNUNET_GNS_LookupRequest) +
859 sizeof (struct PendingMessage) + msize);
860 lr->gns_handle = handle;
861 lr->lookup_proc = proc;
862 lr->proc_cls = proc_cls;
863 lr->r_id = handle->r_id++;
864 pending = (struct PendingMessage *)&lr[1];
865 pending->size = msize;
866 pending->r_id = lr->r_id;
867 GNUNET_CONTAINER_DLL_insert_tail (handle->lookup_head,
868 handle->lookup_tail, lr);
870 lookup_msg = (struct GNUNET_GNS_ClientLookupMessage *) &pending[1];
871 lookup_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_LOOKUP);
872 lookup_msg->header.size = htons (msize);
873 lookup_msg->id = htonl (lr->r_id);
874 lookup_msg->only_cached = htonl (only_cached);
877 lookup_msg->use_default_zone = htonl (GNUNET_NO);
878 memcpy (&lookup_msg->zone, zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode));
882 lookup_msg->use_default_zone = htonl (GNUNET_YES);
883 memset (&lookup_msg->zone, 0, sizeof(struct GNUNET_CRYPTO_ShortHashCode));
885 lookup_msg->type = htonl (type);
886 pkey_tmp = (char *) &lookup_msg[1];
887 if (pkey_enc != NULL)
889 lookup_msg->have_key = htonl (GNUNET_YES);
890 memcpy (pkey_tmp, pkey_enc, key_len);
893 lookup_msg->have_key = htonl (GNUNET_NO);
894 GNUNET_free_non_null (pkey_enc);
895 memcpy (&pkey_tmp[key_len], name, strlen (name) + 1);
897 GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head,
898 handle->pending_tail,
900 process_pending_messages (handle);
906 * Perform an asynchronous Lookup operation on the GNS.
908 * @param handle handle to the GNS service
909 * @param name the name to look up
910 * @param type the record type to look up
911 * @param only_cached GNUNET_YES to only check locally not DHT for performance
912 * @param shorten_key the private key of the shorten zone (can be NULL)
913 * @param proc processor to call on result
914 * @param proc_cls closure for processor
915 * @return handle to the lookup request
917 struct GNUNET_GNS_LookupRequest *
918 GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
920 enum GNUNET_GNS_RecordType type,
922 struct GNUNET_CRYPTO_RsaPrivateKey *shorten_key,
923 GNUNET_GNS_LookupResultProcessor proc,
926 return GNUNET_GNS_lookup_zone (handle, name,
935 * Perform a name shortening operation on the GNS.
937 * @param handle handle to the GNS service
938 * @param name the name to look up
939 * @param private_zone the public zone of the private zone
940 * @param shorten_zone the public zone of the shorten zone
941 * @param zone the zone to start the resolution in
942 * @param proc function to call on result
943 * @param proc_cls closure for processor
944 * @return handle to the operation
946 struct GNUNET_GNS_ShortenRequest*
947 GNUNET_GNS_shorten_zone (struct GNUNET_GNS_Handle *handle,
949 struct GNUNET_CRYPTO_ShortHashCode *private_zone,
950 struct GNUNET_CRYPTO_ShortHashCode *shorten_zone,
951 struct GNUNET_CRYPTO_ShortHashCode *zone,
952 GNUNET_GNS_ShortenResultProcessor proc,
955 /* IPC to shorten gns names, return shorten_handle */
956 struct GNUNET_GNS_ClientShortenMessage *shorten_msg;
957 struct GNUNET_GNS_ShortenRequest *sr;
959 struct PendingMessage *pending;
966 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to shorten `%s' in GNS\n", name);
967 msize = sizeof (struct GNUNET_GNS_ClientShortenMessage) + strlen (name) + 1;
968 if (msize > UINT16_MAX)
973 sr = GNUNET_malloc (sizeof (struct GNUNET_GNS_ShortenRequest) +
974 sizeof (struct PendingMessage) + msize);
975 sr->gns_handle = handle;
976 sr->shorten_proc = proc;
977 sr->proc_cls = proc_cls;
978 sr->r_id = handle->r_id++;
979 GNUNET_CONTAINER_DLL_insert_tail (handle->shorten_head,
980 handle->shorten_tail, sr);
981 pending = (struct PendingMessage *)&sr[1];
982 pending->size = msize;
983 pending->r_id = sr->r_id;
985 shorten_msg = (struct GNUNET_GNS_ClientShortenMessage *) &pending[1];
986 shorten_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_SHORTEN);
987 shorten_msg->header.size = htons ((uint16_t) msize);
988 shorten_msg->id = htonl (sr->r_id);
989 shorten_msg->private_zone = *private_zone;
990 shorten_msg->shorten_zone = *shorten_zone;
993 shorten_msg->use_default_zone = htonl (GNUNET_NO);
994 memcpy (&shorten_msg->zone, zone,
995 sizeof (struct GNUNET_CRYPTO_ShortHashCode));
999 shorten_msg->use_default_zone = htonl (GNUNET_YES);
1000 memset (&shorten_msg->zone, 0, sizeof (struct GNUNET_CRYPTO_ShortHashCode));
1002 memcpy (&shorten_msg[1], name, strlen (name) + 1);
1003 GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head, handle->pending_tail,
1005 process_pending_messages (handle);
1011 * Perform a name shortening operation on the GNS.
1013 * @param handle handle to the GNS service
1014 * @param name the name to look up
1015 * @param private_zone the public zone of the private zone
1016 * @param shorten_zone the public zone of the shorten zone
1017 * @param proc function to call on result
1018 * @param proc_cls closure for processor
1019 * @return handle to the operation
1021 struct GNUNET_GNS_ShortenRequest*
1022 GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle,
1024 struct GNUNET_CRYPTO_ShortHashCode *private_zone,
1025 struct GNUNET_CRYPTO_ShortHashCode *shorten_zone,
1026 GNUNET_GNS_ShortenResultProcessor proc,
1029 return GNUNET_GNS_shorten_zone (handle, name,
1030 private_zone, shorten_zone,
1031 NULL, proc, proc_cls);
1036 * Perform an authority lookup for a given name.
1038 * @param handle handle to the GNS service
1039 * @param name the name to look up authority for
1040 * @param proc function to call on result
1041 * @param proc_cls closure for processor
1042 * @return handle to the operation
1044 struct GNUNET_GNS_GetAuthRequest*
1045 GNUNET_GNS_get_authority (struct GNUNET_GNS_Handle *handle,
1047 GNUNET_GNS_GetAuthResultProcessor proc,
1050 struct GNUNET_GNS_ClientGetAuthMessage *get_auth_msg;
1051 struct GNUNET_GNS_GetAuthRequest *gar;
1053 struct PendingMessage *pending;
1060 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1061 "Trying to look up authority for %s in GNS\n", name);
1062 msize = sizeof (struct GNUNET_GNS_ClientGetAuthMessage) + strlen (name) + 1;
1063 if (msize > UINT16_MAX)
1068 gar = GNUNET_malloc (sizeof (struct GNUNET_GNS_GetAuthRequest) +
1069 sizeof (struct PendingMessage) + msize);
1070 gar->gns_handle = handle;
1071 gar->auth_proc = proc;
1072 gar->proc_cls = proc_cls;
1073 gar->r_id = handle->r_id++;
1074 GNUNET_CONTAINER_DLL_insert_tail (handle->get_auth_head,
1075 handle->get_auth_tail, gar);
1077 pending = (struct PendingMessage *) &gar[1];
1078 pending->size = msize;
1079 pending->r_id = gar->r_id;
1080 get_auth_msg = (struct GNUNET_GNS_ClientGetAuthMessage *) &pending[1];
1081 get_auth_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_GET_AUTH);
1082 get_auth_msg->header.size = htons (msize);
1083 get_auth_msg->id = htonl (gar->r_id);
1084 memcpy (&get_auth_msg[1], name, strlen (name) + 1);
1085 GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head,
1086 handle->pending_tail,
1088 process_pending_messages (handle);
1093 /* end of gns_api.c */