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;
92 struct GNUNET_GNS_Handle *gns_handle;
94 /* processor to call on shorten result */
95 GNUNET_GNS_ShortenResultProcessor shorten_proc;
97 /* processor closure */
108 * Handle to GetAuthorityRequest
110 struct GNUNET_GNS_GetAuthRequest
115 struct GNUNET_GNS_GetAuthRequest *next;
120 struct GNUNET_GNS_GetAuthRequest *prev;
123 struct GNUNET_GNS_Handle *gns_handle;
125 /* processor to call on authority lookup result */
126 GNUNET_GNS_GetAuthResultProcessor auth_proc;
128 /* processor closure */
138 * Entry in our list of messages to be (re-)transmitted.
140 struct PendingMessage
143 * This is a doubly-linked list.
145 struct PendingMessage *prev;
148 * This is a doubly-linked list.
150 struct PendingMessage *next;
158 * Size of the message.
163 * This message has been transmitted. GNUNET_NO if the message is
164 * in the "pending" DLL, GNUNET_YES if it has been transmitted to
165 * the service via the current client connection.
173 * Connection to the GNS service.
175 struct GNUNET_GNS_Handle
179 * Configuration to use.
181 const struct GNUNET_CONFIGURATION_Handle *cfg;
184 * Socket (if available).
186 struct GNUNET_CLIENT_Connection *client;
189 * Currently pending transmission request (or NULL).
191 struct GNUNET_CLIENT_TransmitHandle *th;
194 * Head of linked list of shorten messages we would like to transmit.
196 struct PendingMessage *pending_head;
199 * Tail of linked list of shorten messages we would like to transmit.
201 struct PendingMessage *pending_tail;
204 * Head of linked list of shorten messages we would like to transmit.
206 struct GNUNET_GNS_ShortenRequest *shorten_head;
209 * Tail of linked list of shorten messages we would like to transmit.
211 struct GNUNET_GNS_ShortenRequest *shorten_tail;
214 * Head of linked list of lookup messages we would like to transmit.
216 struct GNUNET_GNS_LookupRequest *lookup_head;
219 * Tail of linked list of lookup messages we would like to transmit.
221 struct GNUNET_GNS_LookupRequest *lookup_tail;
224 * Head of linked list of authority lookup messages we would like to transmit.
226 struct GNUNET_GNS_GetAuthRequest *get_auth_head;
229 * Tail of linked list of authority lookup messages we would like to transmit.
231 struct GNUNET_GNS_GetAuthRequest *get_auth_tail;
236 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
241 * Did we start our receive loop yet?
249 * Try to send messages from list of messages to send
250 * @param handle GNS_Handle
253 process_pending_messages (struct GNUNET_GNS_Handle *handle);
257 * Reconnect to GNS service.
259 * @param h the handle to the GNS service
262 reconnect (struct GNUNET_GNS_Handle *h)
264 GNUNET_assert (NULL == h->client);
265 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
266 "Trying to connect to GNS\n");
267 h->client = GNUNET_CLIENT_connect ("gns", h->cfg);
268 GNUNET_assert (NULL != h->client);
269 process_pending_messages (h);
276 * @param cls the handle
277 * @param tc task context
280 reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
282 struct GNUNET_GNS_Handle *h = cls;
284 h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
290 * Disconnect from service and then reconnect.
292 * @param h our handle
295 force_reconnect (struct GNUNET_GNS_Handle *h)
297 struct GNUNET_GNS_ShortenRequest *st;
298 struct GNUNET_GNS_LookupRequest *lh;
299 struct GNUNET_GNS_GetAuthRequest *ga;
300 struct PendingMessage *p;
302 GNUNET_CLIENT_disconnect (h->client);
304 h->in_receive = GNUNET_NO;
305 for (st = h->shorten_head; NULL != st; st = st->next)
307 p = (struct PendingMessage*) &st[1];
308 if (GNUNET_NO == p->transmitted)
310 p->transmitted = GNUNET_NO;
311 GNUNET_CONTAINER_DLL_insert (h->pending_head,
315 for (lh = h->lookup_head; NULL != lh; lh = lh->next)
317 p = (struct PendingMessage*) &lh[1];
318 if (GNUNET_NO == p->transmitted)
320 p->transmitted = GNUNET_NO;
321 GNUNET_CONTAINER_DLL_insert (h->pending_head,
325 for (ga = h->get_auth_head; NULL != ga; ga = ga->next)
327 p = (struct PendingMessage*) &ga[1];
328 if (GNUNET_NO == p->transmitted)
330 p->transmitted = GNUNET_NO;
331 GNUNET_CONTAINER_DLL_insert (h->pending_head,
335 /* FIXME: 1s too long, exponential-backoff, starting at 1ms! (max = 1s might be OK) */
336 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
343 * Transmit the next pending message, called by notify_transmit_ready
348 transmit_pending (void *cls, size_t size, void *buf);
352 * Handler for messages received from the GNS service
354 * @param cls the 'struct GNUNET_GNS_Handle'
355 * @param msg the incoming message
358 process_message (void *cls, const struct GNUNET_MessageHeader *msg);
362 * Try to send messages from list of messages to send
367 process_pending_messages (struct GNUNET_GNS_Handle *handle)
369 struct PendingMessage *p = handle->pending_head;
371 if (NULL == handle->client)
372 return; /* wait for reconnect */
373 if (NULL != handle->th)
374 return; /* transmission request already pending */
376 while ((NULL != p) && (p->transmitted == GNUNET_YES))
379 return; /* no messages pending */
381 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
382 "Trying to transmit %u bytes\n",
383 (unsigned int) p->size);
385 GNUNET_CLIENT_notify_transmit_ready (handle->client,
387 GNUNET_TIME_UNIT_FOREVER_REL,
388 GNUNET_NO, &transmit_pending,
390 GNUNET_break (NULL != handle->th);
395 * Transmit the next pending message, called by notify_transmit_ready
400 transmit_pending (void *cls, size_t size, void *buf)
402 struct GNUNET_GNS_Handle *h = cls;
404 struct PendingMessage *p;
408 if ((0 == size) || (NULL == buf))
410 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
411 "Transmission to GNS service failed!\n");
415 if (NULL == (p = h->pending_head))
419 while ((NULL != (p = h->pending_head)) && (p->size <= size))
421 memcpy (&cbuf[tsize], &p[1], p->size);
424 p->transmitted = GNUNET_YES;
425 GNUNET_CONTAINER_DLL_remove (h->pending_head,
428 if (GNUNET_YES != h->in_receive)
430 GNUNET_CLIENT_receive (h->client, &process_message, h,
431 GNUNET_TIME_UNIT_FOREVER_REL);
432 h->in_receive = GNUNET_YES;
435 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
436 "Sending %u bytes\n",
437 (unsigned int) tsize);
438 process_pending_messages (h);
444 * Process a given reply that might match the given
447 * @param qe a queue entry
448 * @param msg the shorten msg received
451 process_shorten_reply (struct GNUNET_GNS_ShortenRequest *qe,
452 const struct GNUNET_GNS_ClientShortenResultMessage *msg)
454 struct GNUNET_GNS_Handle *h = qe->gns_handle;
455 struct PendingMessage *p = (struct PendingMessage *)&qe[1];
456 const char *short_name;
459 if (GNUNET_YES != p->transmitted)
461 /* service send reply to query we never managed to send!? */
466 mlen = ntohs (msg->header.size);
467 if (ntohs (msg->header.size) == sizeof (struct GNUNET_GNS_ClientShortenResultMessage))
469 /* service reports resolution failed */
474 short_name = (const char *) &msg[1];
475 if ('\0' != short_name[mlen - sizeof (struct GNUNET_GNS_ClientShortenResultMessage) - 1])
482 GNUNET_CONTAINER_DLL_remove (h->shorten_head, h->shorten_tail, qe);
483 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
484 "Received shortened reply `%s' from GNS service\n",
486 qe->shorten_proc (qe->proc_cls, short_name);
492 * Process a given reply that might match the given
495 * @param qe the handle to the request
496 * @param msg the message to process
499 process_get_auth_reply (struct GNUNET_GNS_GetAuthRequest *qe,
500 const struct GNUNET_GNS_ClientGetAuthResultMessage *msg)
502 struct GNUNET_GNS_Handle *h = qe->gns_handle;
503 struct PendingMessage *p = (struct PendingMessage *)&qe[1];
504 const char *auth_name;
507 if (GNUNET_YES != p->transmitted)
509 /* service send reply to query we never managed to send!? */
514 mlen = ntohs (msg->header.size);
515 if (mlen == sizeof (struct GNUNET_GNS_ClientGetAuthResultMessage))
521 auth_name = (const char*) &msg[1];
522 if ('\0' != auth_name[mlen - sizeof (struct GNUNET_GNS_ClientGetAuthResultMessage) - 1])
529 GNUNET_CONTAINER_DLL_remove (h->get_auth_head, h->get_auth_tail, qe);
530 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
531 "Received GET_AUTH reply `%s' from GNS service\n",
533 qe->auth_proc (qe->proc_cls, auth_name);
539 * Process a given reply to the lookup request
541 * @param qe a queue entry
542 * @param msg the lookup message received
545 process_lookup_reply (struct GNUNET_GNS_LookupRequest *qe,
546 const struct GNUNET_GNS_ClientLookupResultMessage *msg)
548 struct GNUNET_GNS_Handle *h = qe->gns_handle;
549 struct PendingMessage *p = (struct PendingMessage *) &qe[1];
550 uint32_t rd_count = ntohl (msg->rd_count);
551 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
554 if (GNUNET_YES != p->transmitted)
556 /* service send reply to query we never managed to send!? */
561 mlen = ntohs (msg->header.size);
562 mlen -= sizeof (struct GNUNET_GNS_ClientLookupResultMessage);
563 if (GNUNET_SYSERR == GNUNET_NAMESTORE_records_deserialize (mlen,
564 (const char*) &msg[1],
568 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
569 _("Failed to serialize lookup reply from GNS service!\n"));
570 qe->lookup_proc (qe->proc_cls, 0, NULL);
574 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
575 "Received lookup reply from GNS service (%u records)\n",
576 (unsigned int) rd_count);
577 qe->lookup_proc (qe->proc_cls, rd_count, rd);
579 GNUNET_CONTAINER_DLL_remove (h->lookup_head, h->lookup_tail, qe);
585 * Handler for messages received from the GNS service
587 * @param cls the 'struct GNUNET_GNS_Handle'
588 * @param msg the incoming message
591 process_message (void *cls, const struct GNUNET_MessageHeader *msg)
593 struct GNUNET_GNS_Handle *handle = cls;
594 struct GNUNET_GNS_LookupRequest *lr;
595 struct GNUNET_GNS_ShortenRequest *sr;
596 struct GNUNET_GNS_GetAuthRequest *gar;
597 const struct GNUNET_GNS_ClientLookupResultMessage *lookup_msg;
598 const struct GNUNET_GNS_ClientShortenResultMessage *shorten_msg;
599 const struct GNUNET_GNS_ClientGetAuthResultMessage *get_auth_msg;
604 force_reconnect (handle);
607 switch (ntohs (msg->type))
609 case GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT:
610 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
611 "Got LOOKUP_RESULT msg\n");
612 if (ntohs (msg->size) < sizeof (struct GNUNET_GNS_ClientLookupResultMessage))
615 force_reconnect (handle);
618 lookup_msg = (const struct GNUNET_GNS_ClientLookupResultMessage *) msg;
619 r_id = ntohl (lookup_msg->id);
620 for (lr = handle->lookup_head; NULL != lr; lr = lr->next)
621 if (lr->r_id == r_id)
623 process_lookup_reply(lr, lookup_msg);
627 case GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT:
628 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
629 "Got SHORTEN_RESULT msg\n");
630 if (ntohs (msg->size) < sizeof (struct GNUNET_GNS_ClientShortenResultMessage))
633 force_reconnect (handle);
636 shorten_msg = (const struct GNUNET_GNS_ClientShortenResultMessage *) msg;
637 r_id = ntohl (shorten_msg->id);
638 for (sr = handle->shorten_head; NULL != sr; sr = sr->next)
639 if (sr->r_id == r_id)
641 process_shorten_reply (sr, shorten_msg);
645 case GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT:
646 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
647 "Got GET_AUTH_RESULT msg\n");
648 if (ntohs (msg->size) < sizeof (struct GNUNET_GNS_ClientGetAuthResultMessage))
651 force_reconnect (handle);
654 get_auth_msg = (const struct GNUNET_GNS_ClientGetAuthResultMessage *) msg;
655 r_id = ntohl (get_auth_msg->id);
656 for (gar = handle->get_auth_head; NULL != gar; gar = gar->next)
657 if (gar->r_id == r_id)
659 process_get_auth_reply (gar, get_auth_msg);
665 force_reconnect (handle);
668 GNUNET_CLIENT_receive (handle->client, &process_message, handle,
669 GNUNET_TIME_UNIT_FOREVER_REL);
674 * Initialize the connection with the GNS service.
676 * @param cfg configuration to use
677 * @return handle to the GNS service, or NULL on error
679 struct GNUNET_GNS_Handle *
680 GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
682 struct GNUNET_GNS_Handle *handle;
684 handle = GNUNET_malloc (sizeof (struct GNUNET_GNS_Handle));
692 * Shutdown connection with the GNS service.
694 * @param handle handle of the GNS connection to stop
697 GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle)
699 GNUNET_CLIENT_disconnect (handle->client);
700 if (GNUNET_SCHEDULER_NO_TASK != handle->reconnect_task)
702 GNUNET_SCHEDULER_cancel (handle->reconnect_task);
703 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
705 GNUNET_assert (NULL == handle->lookup_head);
706 GNUNET_assert (NULL == handle->shorten_head);
707 GNUNET_assert (NULL == handle->get_auth_head);
708 GNUNET_free (handle);
713 * Cancel pending lookup request
715 * @param lr the lookup request to cancel
718 GNUNET_GNS_cancel_lookup_request (struct GNUNET_GNS_LookupRequest *lr)
720 struct PendingMessage *p = (struct PendingMessage*) &lr[1];
722 GNUNET_assert (NULL != lr->gns_handle);
723 if (GNUNET_NO == p->transmitted)
724 GNUNET_CONTAINER_DLL_remove (lr->gns_handle->pending_head,
725 lr->gns_handle->pending_tail,
727 GNUNET_CONTAINER_DLL_remove (lr->gns_handle->lookup_head,
728 lr->gns_handle->lookup_tail,
735 * Cancel pending shorten request
737 * @param sr the lookup request to cancel
740 GNUNET_GNS_cancel_shorten_request (struct GNUNET_GNS_ShortenRequest *sr)
742 struct PendingMessage *p = (struct PendingMessage*) &sr[1];
744 GNUNET_assert (NULL != sr->gns_handle);
745 if (GNUNET_NO == p->transmitted)
746 GNUNET_CONTAINER_DLL_remove (sr->gns_handle->pending_head,
747 sr->gns_handle->pending_tail,
749 GNUNET_CONTAINER_DLL_remove (sr->gns_handle->shorten_head,
750 sr->gns_handle->shorten_tail,
757 * Cancel pending get auth request
759 * @param gar the lookup request to cancel
762 GNUNET_GNS_cancel_get_auth_request (struct GNUNET_GNS_GetAuthRequest *gar)
764 struct PendingMessage *p = (struct PendingMessage*) &gar[1];
766 GNUNET_assert (NULL != gar->gns_handle);
767 if (GNUNET_NO == p->transmitted)
768 GNUNET_CONTAINER_DLL_remove (gar->gns_handle->pending_head,
769 gar->gns_handle->pending_tail,
771 GNUNET_CONTAINER_DLL_remove (gar->gns_handle->get_auth_head,
772 gar->gns_handle->get_auth_tail,
779 * Perform an asynchronous Lookup operation on the GNS.
781 * @param handle handle to the GNS service
782 * @param name the name to look up
783 * @param zone the zone to start the resolution in
784 * @param type the record type to look up
785 * @param only_cached GNUNET_YES to only check locally not DHT for performance
786 * @param shorten_key the private key of the shorten zone (can be NULL)
787 * @param proc processor to call on result
788 * @param proc_cls closure for processor
789 * @return handle to the get request
791 struct GNUNET_GNS_LookupRequest*
792 GNUNET_GNS_lookup_zone (struct GNUNET_GNS_Handle *handle,
794 struct GNUNET_CRYPTO_ShortHashCode *zone,
795 enum GNUNET_GNS_RecordType type,
797 struct GNUNET_CRYPTO_RsaPrivateKey *shorten_key,
798 GNUNET_GNS_LookupResultProcessor proc,
801 /* IPC to shorten gns names, return shorten_handle */
802 struct GNUNET_GNS_ClientLookupMessage *lookup_msg;
803 struct GNUNET_GNS_LookupRequest *lr;
805 struct PendingMessage *pending;
806 struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *pkey_enc;
815 if (NULL != shorten_key)
817 pkey_enc = GNUNET_CRYPTO_rsa_encode_key (shorten_key);
818 GNUNET_assert (pkey_enc != NULL);
819 key_len = ntohs (pkey_enc->len);
826 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
827 "Trying to lookup `%s' in GNS\n",
829 msize = sizeof (struct GNUNET_GNS_ClientLookupMessage)
830 + key_len + strlen (name) + 1;
831 if (msize > UINT16_MAX)
836 lr = GNUNET_malloc (sizeof (struct GNUNET_GNS_LookupRequest) +
837 sizeof (struct PendingMessage) + msize);
838 lr->gns_handle = handle;
839 lr->lookup_proc = proc;
840 lr->proc_cls = proc_cls;
841 lr->r_id = handle->r_id++;
842 pending = (struct PendingMessage *)&lr[1];
843 pending->size = msize;
844 pending->r_id = lr->r_id;
845 GNUNET_CONTAINER_DLL_insert_tail (handle->lookup_head,
846 handle->lookup_tail, lr);
848 lookup_msg = (struct GNUNET_GNS_ClientLookupMessage *) &pending[1];
849 lookup_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_LOOKUP);
850 lookup_msg->header.size = htons (msize);
851 lookup_msg->id = htonl (lr->r_id);
852 lookup_msg->only_cached = htonl (only_cached);
855 lookup_msg->use_default_zone = htonl (GNUNET_NO);
856 memcpy (&lookup_msg->zone, zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode));
860 lookup_msg->use_default_zone = htonl (GNUNET_YES);
861 memset (&lookup_msg->zone, 0, sizeof(struct GNUNET_CRYPTO_ShortHashCode));
863 lookup_msg->type = htonl (type);
864 pkey_tmp = (char *) &lookup_msg[1];
865 if (pkey_enc != NULL)
867 lookup_msg->have_key = htonl (GNUNET_YES);
868 memcpy (pkey_tmp, pkey_enc, key_len);
871 lookup_msg->have_key = htonl (GNUNET_NO);
872 GNUNET_free_non_null (pkey_enc);
873 memcpy (&pkey_tmp[key_len], name, strlen (name) + 1);
875 GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head,
876 handle->pending_tail,
878 process_pending_messages (handle);
884 * Perform an asynchronous Lookup operation on the GNS.
886 * @param handle handle to the GNS service
887 * @param name the name to look up
888 * @param type the record type to look up
889 * @param only_cached GNUNET_YES to only check locally not DHT for performance
890 * @param shorten_key the private key of the shorten zone (can be NULL)
891 * @param proc processor to call on result
892 * @param proc_cls closure for processor
893 * @return handle to the lookup request
895 struct GNUNET_GNS_LookupRequest*
896 GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
898 enum GNUNET_GNS_RecordType type,
900 struct GNUNET_CRYPTO_RsaPrivateKey *shorten_key,
901 GNUNET_GNS_LookupResultProcessor proc,
904 return GNUNET_GNS_lookup_zone (handle, name,
913 * Perform a name shortening operation on the GNS.
915 * @param handle handle to the GNS service
916 * @param name the name to look up
917 * @param private_zone the public zone of the private zone
918 * @param shorten_zone the public zone of the shorten zone
919 * @param zone the zone to start the resolution in
920 * @param proc function to call on result
921 * @param proc_cls closure for processor
922 * @return handle to the operation
924 struct GNUNET_GNS_ShortenRequest*
925 GNUNET_GNS_shorten_zone (struct GNUNET_GNS_Handle *handle,
927 struct GNUNET_CRYPTO_ShortHashCode *private_zone,
928 struct GNUNET_CRYPTO_ShortHashCode *shorten_zone,
929 struct GNUNET_CRYPTO_ShortHashCode *zone,
930 GNUNET_GNS_ShortenResultProcessor proc,
933 /* IPC to shorten gns names, return shorten_handle */
934 struct GNUNET_GNS_ClientShortenMessage *shorten_msg;
935 struct GNUNET_GNS_ShortenRequest *sr;
937 struct PendingMessage *pending;
944 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to shorten `%s' in GNS\n", name);
945 msize = sizeof (struct GNUNET_GNS_ClientShortenMessage) + strlen (name) + 1;
946 if (msize > UINT16_MAX)
951 sr = GNUNET_malloc (sizeof (struct GNUNET_GNS_ShortenRequest) +
952 sizeof (struct PendingMessage) + msize);
953 sr->gns_handle = handle;
954 sr->shorten_proc = proc;
955 sr->proc_cls = proc_cls;
956 sr->r_id = handle->r_id++;
957 GNUNET_CONTAINER_DLL_insert_tail (handle->shorten_head,
958 handle->shorten_tail, sr);
959 pending = (struct PendingMessage *)&sr[1];
960 pending->size = msize;
961 pending->r_id = sr->r_id;
963 shorten_msg = (struct GNUNET_GNS_ClientShortenMessage *) &pending[1];
964 shorten_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_SHORTEN);
965 shorten_msg->header.size = htons ((uint16_t) msize);
966 shorten_msg->id = htonl (sr->r_id);
967 shorten_msg->private_zone = *private_zone;
968 shorten_msg->shorten_zone = *shorten_zone;
971 shorten_msg->use_default_zone = htonl (GNUNET_NO);
972 memcpy (&shorten_msg->zone, zone,
973 sizeof (struct GNUNET_CRYPTO_ShortHashCode));
977 shorten_msg->use_default_zone = htonl (GNUNET_YES);
978 memset (&shorten_msg->zone, 0, sizeof (struct GNUNET_CRYPTO_ShortHashCode));
980 memcpy (&shorten_msg[1], name, strlen (name) + 1);
981 GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head, handle->pending_tail,
983 process_pending_messages (handle);
989 * Perform a name shortening operation on the GNS.
991 * @param handle handle to the GNS service
992 * @param name the name to look up
993 * @param private_zone the public zone of the private zone
994 * @param shorten_zone the public zone of the shorten zone
995 * @param proc function to call on result
996 * @param proc_cls closure for processor
997 * @return handle to the operation
999 struct GNUNET_GNS_ShortenRequest*
1000 GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle,
1002 struct GNUNET_CRYPTO_ShortHashCode *private_zone,
1003 struct GNUNET_CRYPTO_ShortHashCode *shorten_zone,
1004 GNUNET_GNS_ShortenResultProcessor proc,
1007 return GNUNET_GNS_shorten_zone (handle, name,
1008 private_zone, shorten_zone,
1009 NULL, proc, proc_cls);
1014 * Perform an authority lookup for a given name.
1016 * @param handle handle to the GNS service
1017 * @param name the name to look up authority for
1018 * @param proc function to call on result
1019 * @param proc_cls closure for processor
1020 * @return handle to the operation
1022 struct GNUNET_GNS_GetAuthRequest*
1023 GNUNET_GNS_get_authority (struct GNUNET_GNS_Handle *handle,
1025 GNUNET_GNS_GetAuthResultProcessor proc,
1028 struct GNUNET_GNS_ClientGetAuthMessage *get_auth_msg;
1029 struct GNUNET_GNS_GetAuthRequest *gar;
1031 struct PendingMessage *pending;
1038 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1039 "Trying to look up authority for %s in GNS\n", name);
1040 msize = sizeof (struct GNUNET_GNS_ClientGetAuthMessage) + strlen (name) + 1;
1041 if (msize > UINT16_MAX)
1046 gar = GNUNET_malloc (sizeof (struct GNUNET_GNS_GetAuthRequest) +
1047 sizeof (struct PendingMessage) + msize);
1048 gar->gns_handle = handle;
1049 gar->auth_proc = proc;
1050 gar->proc_cls = proc_cls;
1051 gar->r_id = handle->r_id++;
1052 GNUNET_CONTAINER_DLL_insert_tail (handle->get_auth_head,
1053 handle->get_auth_tail, gar);
1055 pending = (struct PendingMessage *) &gar[1];
1056 pending->size = msize;
1057 pending->r_id = gar->r_id;
1058 get_auth_msg = (struct GNUNET_GNS_ClientGetAuthMessage *) &pending[1];
1059 get_auth_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_GET_AUTH);
1060 get_auth_msg->header.size = htons (msize);
1061 get_auth_msg->id = htonl (gar->r_id);
1062 memcpy (&get_auth_msg[1], name, strlen (name) + 1);
1063 GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head,
1064 handle->pending_tail,
1066 process_pending_messages (handle);
1071 /* end of gns_api.c */