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
345 * @param cls the closure
346 * @param size size of pending data
347 * @param buf buffer with pending data
348 * @return size data transmitted
351 transmit_pending (void *cls, size_t size, void *buf);
355 * Handler for messages received from the GNS service
357 * @param cls the 'struct GNUNET_GNS_Handle'
358 * @param msg the incoming message
361 process_message (void *cls, const struct GNUNET_MessageHeader *msg);
365 * Try to send messages from list of messages to send
367 * @param handle the GNS handle
370 process_pending_messages (struct GNUNET_GNS_Handle *handle)
372 struct PendingMessage *p = handle->pending_head;
374 if (NULL == handle->client)
375 return; /* wait for reconnect */
376 if (NULL != handle->th)
377 return; /* transmission request already pending */
379 while ((NULL != p) && (p->transmitted == GNUNET_YES))
382 return; /* no messages pending */
384 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
385 "Trying to transmit %u bytes\n",
386 (unsigned int) p->size);
388 GNUNET_CLIENT_notify_transmit_ready (handle->client,
390 GNUNET_TIME_UNIT_FOREVER_REL,
391 GNUNET_NO, &transmit_pending,
393 GNUNET_break (NULL != handle->th);
398 * Transmit the next pending message, called by notify_transmit_ready
400 * @param cls the closure
401 * @param size size of pending data
402 * @param buf buffer with pending data
403 * @return size data transmitted
406 transmit_pending (void *cls, size_t size, void *buf)
408 struct GNUNET_GNS_Handle *h = cls;
410 struct PendingMessage *p;
414 if ((0 == size) || (NULL == buf))
416 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
417 "Transmission to GNS service failed!\n");
421 if (NULL == (p = h->pending_head))
425 while ((NULL != (p = h->pending_head)) && (p->size <= size))
427 memcpy (&cbuf[tsize], &p[1], p->size);
430 p->transmitted = GNUNET_YES;
431 GNUNET_CONTAINER_DLL_remove (h->pending_head,
434 if (GNUNET_YES != h->in_receive)
436 GNUNET_CLIENT_receive (h->client, &process_message, h,
437 GNUNET_TIME_UNIT_FOREVER_REL);
438 h->in_receive = GNUNET_YES;
441 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
442 "Sending %u bytes\n",
443 (unsigned int) tsize);
444 process_pending_messages (h);
450 * Process a given reply that might match the given
453 * @param qe a queue entry
454 * @param msg the shorten msg received
457 process_shorten_reply (struct GNUNET_GNS_ShortenRequest *qe,
458 const struct GNUNET_GNS_ClientShortenResultMessage *msg)
460 struct GNUNET_GNS_Handle *h = qe->gns_handle;
461 struct PendingMessage *p = (struct PendingMessage *)&qe[1];
462 const char *short_name;
465 if (GNUNET_YES != p->transmitted)
467 /* service send reply to query we never managed to send!? */
472 mlen = ntohs (msg->header.size);
473 if (ntohs (msg->header.size) == sizeof (struct GNUNET_GNS_ClientShortenResultMessage))
475 /* service reports resolution failed */
480 short_name = (const char *) &msg[1];
481 if ('\0' != short_name[mlen - sizeof (struct GNUNET_GNS_ClientShortenResultMessage) - 1])
488 GNUNET_CONTAINER_DLL_remove (h->shorten_head, h->shorten_tail, qe);
489 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
490 "Received shortened reply `%s' from GNS service\n",
492 qe->shorten_proc (qe->proc_cls, short_name);
498 * Process a given reply that might match the given
501 * @param qe the handle to the request
502 * @param msg the message to process
505 process_get_auth_reply (struct GNUNET_GNS_GetAuthRequest *qe,
506 const struct GNUNET_GNS_ClientGetAuthResultMessage *msg)
508 struct GNUNET_GNS_Handle *h = qe->gns_handle;
509 struct PendingMessage *p = (struct PendingMessage *)&qe[1];
510 const char *auth_name;
513 if (GNUNET_YES != p->transmitted)
515 /* service send reply to query we never managed to send!? */
520 mlen = ntohs (msg->header.size);
521 if (mlen == sizeof (struct GNUNET_GNS_ClientGetAuthResultMessage))
527 auth_name = (const char*) &msg[1];
528 if ('\0' != auth_name[mlen - sizeof (struct GNUNET_GNS_ClientGetAuthResultMessage) - 1])
535 GNUNET_CONTAINER_DLL_remove (h->get_auth_head, h->get_auth_tail, qe);
536 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
537 "Received GET_AUTH reply `%s' from GNS service\n",
539 qe->auth_proc (qe->proc_cls, auth_name);
545 * Process a given reply to the lookup request
547 * @param qe a queue entry
548 * @param msg the lookup message received
551 process_lookup_reply (struct GNUNET_GNS_LookupRequest *qe,
552 const struct GNUNET_GNS_ClientLookupResultMessage *msg)
554 struct GNUNET_GNS_Handle *h = qe->gns_handle;
555 struct PendingMessage *p = (struct PendingMessage *) &qe[1];
556 uint32_t rd_count = ntohl (msg->rd_count);
557 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
560 if (GNUNET_YES != p->transmitted)
562 /* service send reply to query we never managed to send!? */
567 mlen = ntohs (msg->header.size);
568 mlen -= sizeof (struct GNUNET_GNS_ClientLookupResultMessage);
569 if (GNUNET_SYSERR == GNUNET_NAMESTORE_records_deserialize (mlen,
570 (const char*) &msg[1],
574 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
575 _("Failed to serialize lookup reply from GNS service!\n"));
576 qe->lookup_proc (qe->proc_cls, 0, NULL);
580 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
581 "Received lookup reply from GNS service (%u records)\n",
582 (unsigned int) rd_count);
583 qe->lookup_proc (qe->proc_cls, rd_count, rd);
585 GNUNET_CONTAINER_DLL_remove (h->lookup_head, h->lookup_tail, qe);
591 * Handler for messages received from the GNS service
593 * @param cls the 'struct GNUNET_GNS_Handle'
594 * @param msg the incoming message
597 process_message (void *cls, const struct GNUNET_MessageHeader *msg)
599 struct GNUNET_GNS_Handle *handle = cls;
600 struct GNUNET_GNS_LookupRequest *lr;
601 struct GNUNET_GNS_ShortenRequest *sr;
602 struct GNUNET_GNS_GetAuthRequest *gar;
603 const struct GNUNET_GNS_ClientLookupResultMessage *lookup_msg;
604 const struct GNUNET_GNS_ClientShortenResultMessage *shorten_msg;
605 const struct GNUNET_GNS_ClientGetAuthResultMessage *get_auth_msg;
610 force_reconnect (handle);
613 switch (ntohs (msg->type))
615 case GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT:
616 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
617 "Got LOOKUP_RESULT msg\n");
618 if (ntohs (msg->size) < sizeof (struct GNUNET_GNS_ClientLookupResultMessage))
621 force_reconnect (handle);
624 lookup_msg = (const struct GNUNET_GNS_ClientLookupResultMessage *) msg;
625 r_id = ntohl (lookup_msg->id);
626 for (lr = handle->lookup_head; NULL != lr; lr = lr->next)
627 if (lr->r_id == r_id)
629 process_lookup_reply(lr, lookup_msg);
633 case GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT:
634 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
635 "Got SHORTEN_RESULT msg\n");
636 if (ntohs (msg->size) < sizeof (struct GNUNET_GNS_ClientShortenResultMessage))
639 force_reconnect (handle);
642 shorten_msg = (const struct GNUNET_GNS_ClientShortenResultMessage *) msg;
643 r_id = ntohl (shorten_msg->id);
644 for (sr = handle->shorten_head; NULL != sr; sr = sr->next)
645 if (sr->r_id == r_id)
647 process_shorten_reply (sr, shorten_msg);
651 case GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT:
652 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
653 "Got GET_AUTH_RESULT msg\n");
654 if (ntohs (msg->size) < sizeof (struct GNUNET_GNS_ClientGetAuthResultMessage))
657 force_reconnect (handle);
660 get_auth_msg = (const struct GNUNET_GNS_ClientGetAuthResultMessage *) msg;
661 r_id = ntohl (get_auth_msg->id);
662 for (gar = handle->get_auth_head; NULL != gar; gar = gar->next)
663 if (gar->r_id == r_id)
665 process_get_auth_reply (gar, get_auth_msg);
671 force_reconnect (handle);
674 GNUNET_CLIENT_receive (handle->client, &process_message, handle,
675 GNUNET_TIME_UNIT_FOREVER_REL);
680 * Initialize the connection with the GNS service.
682 * @param cfg configuration to use
683 * @return handle to the GNS service, or NULL on error
685 struct GNUNET_GNS_Handle *
686 GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
688 struct GNUNET_GNS_Handle *handle;
690 handle = GNUNET_malloc (sizeof (struct GNUNET_GNS_Handle));
698 * Shutdown connection with the GNS service.
700 * @param handle handle of the GNS connection to stop
703 GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle)
705 GNUNET_CLIENT_disconnect (handle->client);
706 if (GNUNET_SCHEDULER_NO_TASK != handle->reconnect_task)
708 GNUNET_SCHEDULER_cancel (handle->reconnect_task);
709 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
711 GNUNET_assert (NULL == handle->lookup_head);
712 GNUNET_assert (NULL == handle->shorten_head);
713 GNUNET_assert (NULL == handle->get_auth_head);
714 GNUNET_free (handle);
719 * Cancel pending lookup request
721 * @param lr the lookup request to cancel
724 GNUNET_GNS_cancel_lookup_request (struct GNUNET_GNS_LookupRequest *lr)
726 struct PendingMessage *p = (struct PendingMessage*) &lr[1];
728 GNUNET_assert (NULL != lr->gns_handle);
729 if (GNUNET_NO == p->transmitted)
730 GNUNET_CONTAINER_DLL_remove (lr->gns_handle->pending_head,
731 lr->gns_handle->pending_tail,
733 GNUNET_CONTAINER_DLL_remove (lr->gns_handle->lookup_head,
734 lr->gns_handle->lookup_tail,
741 * Cancel pending shorten request
743 * @param sr the lookup request to cancel
746 GNUNET_GNS_cancel_shorten_request (struct GNUNET_GNS_ShortenRequest *sr)
748 struct PendingMessage *p = (struct PendingMessage*) &sr[1];
750 GNUNET_assert (NULL != sr->gns_handle);
751 if (GNUNET_NO == p->transmitted)
752 GNUNET_CONTAINER_DLL_remove (sr->gns_handle->pending_head,
753 sr->gns_handle->pending_tail,
755 GNUNET_CONTAINER_DLL_remove (sr->gns_handle->shorten_head,
756 sr->gns_handle->shorten_tail,
763 * Cancel pending get auth request
765 * @param gar the lookup request to cancel
768 GNUNET_GNS_cancel_get_auth_request (struct GNUNET_GNS_GetAuthRequest *gar)
770 struct PendingMessage *p = (struct PendingMessage*) &gar[1];
772 GNUNET_assert (NULL != gar->gns_handle);
773 if (GNUNET_NO == p->transmitted)
774 GNUNET_CONTAINER_DLL_remove (gar->gns_handle->pending_head,
775 gar->gns_handle->pending_tail,
777 GNUNET_CONTAINER_DLL_remove (gar->gns_handle->get_auth_head,
778 gar->gns_handle->get_auth_tail,
785 * Perform an asynchronous Lookup operation on the GNS.
787 * @param handle handle to the GNS service
788 * @param name the name to look up
789 * @param zone the zone to start the resolution in
790 * @param type the record type to look up
791 * @param only_cached GNUNET_YES to only check locally not DHT for performance
792 * @param shorten_key the private key of the shorten zone (can be NULL)
793 * @param proc processor to call on result
794 * @param proc_cls closure for processor
795 * @return handle to the get request
797 struct GNUNET_GNS_LookupRequest*
798 GNUNET_GNS_lookup_zone (struct GNUNET_GNS_Handle *handle,
800 struct GNUNET_CRYPTO_ShortHashCode *zone,
801 enum GNUNET_GNS_RecordType type,
803 struct GNUNET_CRYPTO_RsaPrivateKey *shorten_key,
804 GNUNET_GNS_LookupResultProcessor proc,
807 /* IPC to shorten gns names, return shorten_handle */
808 struct GNUNET_GNS_ClientLookupMessage *lookup_msg;
809 struct GNUNET_GNS_LookupRequest *lr;
811 struct PendingMessage *pending;
812 struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *pkey_enc;
821 if (NULL != shorten_key)
823 pkey_enc = GNUNET_CRYPTO_rsa_encode_key (shorten_key);
824 GNUNET_assert (pkey_enc != NULL);
825 key_len = ntohs (pkey_enc->len);
832 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
833 "Trying to lookup `%s' in GNS\n",
835 msize = sizeof (struct GNUNET_GNS_ClientLookupMessage)
836 + key_len + strlen (name) + 1;
837 if (msize > UINT16_MAX)
840 GNUNET_free (pkey_enc);
843 lr = GNUNET_malloc (sizeof (struct GNUNET_GNS_LookupRequest) +
844 sizeof (struct PendingMessage) + msize);
845 lr->gns_handle = handle;
846 lr->lookup_proc = proc;
847 lr->proc_cls = proc_cls;
848 lr->r_id = handle->r_id++;
849 pending = (struct PendingMessage *)&lr[1];
850 pending->size = msize;
851 pending->r_id = lr->r_id;
852 GNUNET_CONTAINER_DLL_insert_tail (handle->lookup_head,
853 handle->lookup_tail, lr);
855 lookup_msg = (struct GNUNET_GNS_ClientLookupMessage *) &pending[1];
856 lookup_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_LOOKUP);
857 lookup_msg->header.size = htons (msize);
858 lookup_msg->id = htonl (lr->r_id);
859 lookup_msg->only_cached = htonl (only_cached);
862 lookup_msg->use_default_zone = htonl (GNUNET_NO);
863 memcpy (&lookup_msg->zone, zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode));
867 lookup_msg->use_default_zone = htonl (GNUNET_YES);
868 memset (&lookup_msg->zone, 0, sizeof(struct GNUNET_CRYPTO_ShortHashCode));
870 lookup_msg->type = htonl (type);
871 pkey_tmp = (char *) &lookup_msg[1];
872 if (pkey_enc != NULL)
874 lookup_msg->have_key = htonl (GNUNET_YES);
875 memcpy (pkey_tmp, pkey_enc, key_len);
878 lookup_msg->have_key = htonl (GNUNET_NO);
879 GNUNET_free_non_null (pkey_enc);
880 memcpy (&pkey_tmp[key_len], name, strlen (name) + 1);
882 GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head,
883 handle->pending_tail,
885 process_pending_messages (handle);
891 * Perform an asynchronous Lookup operation on the GNS.
893 * @param handle handle to the GNS service
894 * @param name the name to look up
895 * @param type the record type to look up
896 * @param only_cached GNUNET_YES to only check locally not DHT for performance
897 * @param shorten_key the private key of the shorten zone (can be NULL)
898 * @param proc processor to call on result
899 * @param proc_cls closure for processor
900 * @return handle to the lookup request
902 struct GNUNET_GNS_LookupRequest*
903 GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
905 enum GNUNET_GNS_RecordType type,
907 struct GNUNET_CRYPTO_RsaPrivateKey *shorten_key,
908 GNUNET_GNS_LookupResultProcessor proc,
911 return GNUNET_GNS_lookup_zone (handle, name,
920 * Perform a name shortening operation on the GNS.
922 * @param handle handle to the GNS service
923 * @param name the name to look up
924 * @param private_zone the public zone of the private zone
925 * @param shorten_zone the public zone of the shorten zone
926 * @param zone the zone to start the resolution in
927 * @param proc function to call on result
928 * @param proc_cls closure for processor
929 * @return handle to the operation
931 struct GNUNET_GNS_ShortenRequest*
932 GNUNET_GNS_shorten_zone (struct GNUNET_GNS_Handle *handle,
934 struct GNUNET_CRYPTO_ShortHashCode *private_zone,
935 struct GNUNET_CRYPTO_ShortHashCode *shorten_zone,
936 struct GNUNET_CRYPTO_ShortHashCode *zone,
937 GNUNET_GNS_ShortenResultProcessor proc,
940 /* IPC to shorten gns names, return shorten_handle */
941 struct GNUNET_GNS_ClientShortenMessage *shorten_msg;
942 struct GNUNET_GNS_ShortenRequest *sr;
944 struct PendingMessage *pending;
951 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to shorten `%s' in GNS\n", name);
952 msize = sizeof (struct GNUNET_GNS_ClientShortenMessage) + strlen (name) + 1;
953 if (msize > UINT16_MAX)
958 sr = GNUNET_malloc (sizeof (struct GNUNET_GNS_ShortenRequest) +
959 sizeof (struct PendingMessage) + msize);
960 sr->gns_handle = handle;
961 sr->shorten_proc = proc;
962 sr->proc_cls = proc_cls;
963 sr->r_id = handle->r_id++;
964 GNUNET_CONTAINER_DLL_insert_tail (handle->shorten_head,
965 handle->shorten_tail, sr);
966 pending = (struct PendingMessage *)&sr[1];
967 pending->size = msize;
968 pending->r_id = sr->r_id;
970 shorten_msg = (struct GNUNET_GNS_ClientShortenMessage *) &pending[1];
971 shorten_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_SHORTEN);
972 shorten_msg->header.size = htons ((uint16_t) msize);
973 shorten_msg->id = htonl (sr->r_id);
974 shorten_msg->private_zone = *private_zone;
975 shorten_msg->shorten_zone = *shorten_zone;
978 shorten_msg->use_default_zone = htonl (GNUNET_NO);
979 memcpy (&shorten_msg->zone, zone,
980 sizeof (struct GNUNET_CRYPTO_ShortHashCode));
984 shorten_msg->use_default_zone = htonl (GNUNET_YES);
985 memset (&shorten_msg->zone, 0, sizeof (struct GNUNET_CRYPTO_ShortHashCode));
987 memcpy (&shorten_msg[1], name, strlen (name) + 1);
988 GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head, handle->pending_tail,
990 process_pending_messages (handle);
996 * Perform a name shortening operation on the GNS.
998 * @param handle handle to the GNS service
999 * @param name the name to look up
1000 * @param private_zone the public zone of the private zone
1001 * @param shorten_zone the public zone of the shorten zone
1002 * @param proc function to call on result
1003 * @param proc_cls closure for processor
1004 * @return handle to the operation
1006 struct GNUNET_GNS_ShortenRequest*
1007 GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle,
1009 struct GNUNET_CRYPTO_ShortHashCode *private_zone,
1010 struct GNUNET_CRYPTO_ShortHashCode *shorten_zone,
1011 GNUNET_GNS_ShortenResultProcessor proc,
1014 return GNUNET_GNS_shorten_zone (handle, name,
1015 private_zone, shorten_zone,
1016 NULL, proc, proc_cls);
1021 * Perform an authority lookup for a given name.
1023 * @param handle handle to the GNS service
1024 * @param name the name to look up authority for
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_GetAuthRequest*
1030 GNUNET_GNS_get_authority (struct GNUNET_GNS_Handle *handle,
1032 GNUNET_GNS_GetAuthResultProcessor proc,
1035 struct GNUNET_GNS_ClientGetAuthMessage *get_auth_msg;
1036 struct GNUNET_GNS_GetAuthRequest *gar;
1038 struct PendingMessage *pending;
1045 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1046 "Trying to look up authority for %s in GNS\n", name);
1047 msize = sizeof (struct GNUNET_GNS_ClientGetAuthMessage) + strlen (name) + 1;
1048 if (msize > UINT16_MAX)
1053 gar = GNUNET_malloc (sizeof (struct GNUNET_GNS_GetAuthRequest) +
1054 sizeof (struct PendingMessage) + msize);
1055 gar->gns_handle = handle;
1056 gar->auth_proc = proc;
1057 gar->proc_cls = proc_cls;
1058 gar->r_id = handle->r_id++;
1059 GNUNET_CONTAINER_DLL_insert_tail (handle->get_auth_head,
1060 handle->get_auth_tail, gar);
1062 pending = (struct PendingMessage *) &gar[1];
1063 pending->size = msize;
1064 pending->r_id = gar->r_id;
1065 get_auth_msg = (struct GNUNET_GNS_ClientGetAuthMessage *) &pending[1];
1066 get_auth_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_GET_AUTH);
1067 get_auth_msg->header.size = htons (msize);
1068 get_auth_msg->id = htonl (gar->r_id);
1069 memcpy (&get_auth_msg[1], name, strlen (name) + 1);
1070 GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head,
1071 handle->pending_tail,
1073 process_pending_messages (handle);
1078 /* end of gns_api.c */