2 This file is part of GNUnet.
3 (C) 2009, 2010 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
24 * @brief library to access the GNS service
25 * @author Martin Schanzenbach
29 #include "gnunet_util_lib.h"
30 #include "gnunet_constants.h"
31 #include "gnunet_arm_service.h"
32 #include "gnunet_hello_lib.h"
33 #include "gnunet_protocols.h"
34 #include "gnunet_dht_service.h"
36 #include "gnunet_gns_service.h"
38 /* TODO into gnunet_protocols */
39 #define GNUNET_MESSAGE_TYPE_GNS_LOOKUP 23
40 #define GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT 24
41 #define GNUNET_MESSAGE_TYPE_GNS_SHORTEN 25
42 #define GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT 26
43 #define GNUNET_MESSAGE_TYPE_GNS_GET_AUTH 27
44 #define GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT 28
49 struct GNUNET_GNS_QueueEntry
54 struct GNUNET_GNS_QueueEntry *next;
59 struct GNUNET_GNS_QueueEntry *prev;
65 struct GNUNET_GNS_Handle *gns_handle;
67 /* processor to call on shorten result */
68 GNUNET_GNS_ShortenResultProcessor shorten_proc;
70 /* processor to call on lookup result */
71 GNUNET_GNS_LookupResultProcessor lookup_proc;
73 /* processor to call on authority lookup result */
74 GNUNET_GNS_GetAuthResultProcessor auth_proc;
76 /* processor closure */
83 * Entry in our list of messages to be (re-)transmitted.
88 * This is a doubly-linked list.
90 struct PendingMessage *prev;
93 * This is a doubly-linked list.
95 struct PendingMessage *next;
98 * Size of the message.
106 * Connection to the GNS service.
108 struct GNUNET_GNS_Handle
112 * Configuration to use.
114 const struct GNUNET_CONFIGURATION_Handle *cfg;
117 * Socket (if available).
119 struct GNUNET_CLIENT_Connection *client;
122 * Currently pending transmission request (or NULL).
124 struct GNUNET_CLIENT_TransmitHandle *th;
129 * Head of linked list of shorten messages we would like to transmit.
131 struct PendingMessage *pending_head;
134 * Tail of linked list of shorten messages we would like to transmit.
136 struct PendingMessage *pending_tail;
139 * Head of linked list of shorten messages we would like to transmit.
141 struct GNUNET_GNS_QueueEntry *shorten_head;
144 * Tail of linked list of shorten messages we would like to transmit.
146 struct GNUNET_GNS_QueueEntry *shorten_tail;
149 * Head of linked list of lookup messages we would like to transmit.
151 struct GNUNET_GNS_QueueEntry *lookup_head;
154 * Tail of linked list of lookup messages we would like to transmit.
156 struct GNUNET_GNS_QueueEntry *lookup_tail;
159 * Head of linked list of authority lookup messages we would like to transmit.
161 struct GNUNET_GNS_QueueEntry *get_auth_head;
164 * Tail of linked list of authority lookup messages we would like to transmit.
166 struct GNUNET_GNS_QueueEntry *get_auth_tail;
171 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
174 * Did we start our receive loop yet?
179 * Reconnect necessary
185 * Try to send messages from list of messages to send
186 * @param handle GNS_Handle
189 process_pending_messages (struct GNUNET_GNS_Handle *handle);
193 * Reconnect to GNS service.
195 * @param h the handle to the namestore service
198 reconnect (struct GNUNET_GNS_Handle *h)
200 GNUNET_assert (NULL == h->client);
201 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
202 "Trying to connect to GNS...\n");
203 h->client = GNUNET_CLIENT_connect ("gns", h->cfg);
204 GNUNET_assert (NULL != h->client);
210 * @param cls the handle
211 * @param tc task context
214 reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
216 struct GNUNET_GNS_Handle *h = cls;
218 h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
224 * Disconnect from service and then reconnect.
226 * @param h our handle
229 force_reconnect (struct GNUNET_GNS_Handle *h)
231 h->reconnect = GNUNET_NO;
232 GNUNET_CLIENT_disconnect (h->client);
234 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
240 * Transmit the next pending message, called by notify_transmit_ready
243 transmit_pending (void *cls, size_t size, void *buf);
246 * Handler for messages received from the GNS service
248 * @param cls the 'struct GNUNET_GNS_Handle'
249 * @param msg the incoming message
252 process_message (void *cls, const struct GNUNET_MessageHeader *msg);
255 * Try to send messages from list of messages to send
258 process_pending_messages (struct GNUNET_GNS_Handle *handle)
260 struct PendingMessage *p;
262 if (handle->client == NULL)
264 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
265 "process_pending_messages called, but client is null\n");
269 if (handle->th != NULL)
272 if (NULL == (p = handle->pending_head))
275 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
276 "Trying to transmit %d bytes...\n", p->size);
279 GNUNET_CLIENT_notify_transmit_ready (handle->client,
281 GNUNET_TIME_UNIT_FOREVER_REL,
282 GNUNET_NO, &transmit_pending,
284 if (NULL != handle->th)
287 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
288 "notify_transmit_ready returned NULL!\n");
293 * Transmit the next pending message, called by notify_transmit_ready
296 transmit_pending (void *cls, size_t size, void *buf)
298 struct GNUNET_GNS_Handle *handle = cls;
299 struct PendingMessage *p;
305 if ((size == 0) || (buf == NULL))
307 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
308 "Transmission to GNS service failed!\n");
309 force_reconnect(handle);
316 if (NULL == (p = handle->pending_head))
319 while ((NULL != (p = handle->pending_head)) && (p->size <= size))
321 memcpy (&cbuf[tsize], &p[1], p->size);
324 GNUNET_CONTAINER_DLL_remove (handle->pending_head, handle->pending_tail, p);
325 if (GNUNET_YES != handle->in_receive)
327 GNUNET_CLIENT_receive (handle->client, &process_message, handle,
328 GNUNET_TIME_UNIT_FOREVER_REL);
329 handle->in_receive = GNUNET_YES;
334 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
335 "Sending %d bytes\n", tsize);
337 process_pending_messages(handle);
342 * Process a given reply that might match the given
345 * @param qe a queue entry
346 * @param msg the shorten msg received
349 process_shorten_reply (struct GNUNET_GNS_QueueEntry *qe,
350 const struct GNUNET_GNS_ClientShortenResultMessage *msg)
352 struct GNUNET_GNS_Handle *h = qe->gns_handle;
353 const char *short_name;
355 GNUNET_CONTAINER_DLL_remove(h->shorten_head, h->shorten_tail, qe);
357 short_name = (char*)(&msg[1]);
359 if (ntohs (((struct GNUNET_MessageHeader*)msg)->size) <
360 sizeof (struct GNUNET_GNS_ClientShortenResultMessage))
368 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
369 "Received shortened reply `%s' from GNS service\n",
372 GNUNET_CLIENT_receive (h->client, &process_message, h,
373 GNUNET_TIME_UNIT_FOREVER_REL);
374 qe->shorten_proc(qe->proc_cls, short_name);
381 * Process a given reply that might match the given
384 * @param qe the handle to the request
385 * @param msg the message to process
388 process_get_auth_reply (struct GNUNET_GNS_QueueEntry *qe,
389 const struct GNUNET_GNS_ClientGetAuthResultMessage *msg)
391 struct GNUNET_GNS_Handle *h = qe->gns_handle;
392 const char *auth_name;
394 GNUNET_CONTAINER_DLL_remove(h->get_auth_head, h->get_auth_tail, qe);
396 auth_name = (char*)(&msg[1]);
398 if (ntohs (((struct GNUNET_MessageHeader*)msg)->size) <
399 sizeof (struct GNUNET_GNS_ClientGetAuthResultMessage))
407 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
408 "Received GET_AUTH reply `%s' from GNS service\n",
411 GNUNET_CLIENT_receive (h->client, &process_message, h,
412 GNUNET_TIME_UNIT_FOREVER_REL);
413 qe->auth_proc(qe->proc_cls, auth_name);
418 * Process a given reply to the lookup request
420 * @param qe a queue entry
421 * @param msg the lookup message received
424 process_lookup_reply (struct GNUNET_GNS_QueueEntry *qe,
425 const struct GNUNET_GNS_ClientLookupResultMessage *msg)
427 struct GNUNET_GNS_Handle *h = qe->gns_handle;
428 int rd_count = ntohl(msg->rd_count);
429 size_t len = ntohs (((struct GNUNET_MessageHeader*)msg)->size);
430 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
432 GNUNET_CONTAINER_DLL_remove(h->lookup_head, h->lookup_tail, qe);
434 if (len < sizeof (struct GNUNET_GNS_ClientLookupResultMessage))
442 len -= sizeof(struct GNUNET_GNS_ClientLookupResultMessage);
444 GNUNET_CLIENT_receive (h->client, &process_message, h,
445 GNUNET_TIME_UNIT_FOREVER_REL);
446 if (GNUNET_SYSERR == GNUNET_NAMESTORE_records_deserialize (len,
451 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
452 "Failed to serialize lookup reply from GNS service!\n");
453 qe->lookup_proc(qe->proc_cls, 0, NULL);
458 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
459 "Received lookup reply from GNS service (count=%d)\n",
460 ntohl(msg->rd_count));
461 qe->lookup_proc(qe->proc_cls, rd_count, rd);
467 * Handler for messages received from the GNS service
469 * @param cls the 'struct GNUNET_GNS_Handle'
470 * @param msg the incoming message
473 process_message (void *cls, const struct GNUNET_MessageHeader *msg)
475 struct GNUNET_GNS_Handle *handle = cls;
476 struct GNUNET_GNS_QueueEntry *qe;
477 const struct GNUNET_GNS_ClientLookupResultMessage *lookup_msg;
478 const struct GNUNET_GNS_ClientShortenResultMessage *shorten_msg;
479 const struct GNUNET_GNS_ClientGetAuthResultMessage *get_auth_msg;
483 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
487 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
488 "Error receiving data from GNS service, reconnecting\n");
489 force_reconnect (handle);
493 type = ntohs (msg->type);
495 if (type == GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT)
497 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
499 lookup_msg = (const struct GNUNET_GNS_ClientLookupResultMessage *) msg;
500 r_id = ntohl (lookup_msg->id);
502 if (r_id > handle->r_id)
504 /** no request found */
506 GNUNET_CLIENT_receive (handle->client, &process_message, handle,
507 GNUNET_TIME_UNIT_FOREVER_REL);
511 for (qe = handle->lookup_head; qe != NULL; qe = qe->next)
513 if (qe->r_id == r_id)
517 process_lookup_reply(qe, lookup_msg);
522 else if (type == GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT)
524 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
525 "Got SHORTEN_RESULT msg\n");
526 shorten_msg = (struct GNUNET_GNS_ClientShortenResultMessage *) msg;
528 r_id = ntohl (shorten_msg->id);
530 if (r_id > handle->r_id)
532 /** no request found */
534 GNUNET_CLIENT_receive (handle->client, &process_message, handle,
535 GNUNET_TIME_UNIT_FOREVER_REL);
539 for (qe = handle->shorten_head; qe != NULL; qe = qe->next)
541 if (qe->r_id == r_id)
545 process_shorten_reply(qe, shorten_msg);
548 else if (type == GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT)
550 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
551 "Got GET_AUTH_RESULT msg\n");
552 get_auth_msg = (struct GNUNET_GNS_ClientGetAuthResultMessage *) msg;
554 r_id = ntohl (get_auth_msg->id);
556 if (r_id > handle->r_id)
558 /** no request found */
560 GNUNET_CLIENT_receive (handle->client, &process_message, handle,
561 GNUNET_TIME_UNIT_FOREVER_REL);
565 for (qe = handle->get_auth_head; qe != NULL; qe = qe->next)
567 if (qe->r_id == r_id)
571 process_get_auth_reply(qe, get_auth_msg);
576 if (GNUNET_YES == handle->reconnect)
577 force_reconnect (handle);
583 * Initialize the connection with the GNS service.
585 * @param cfg configuration to use
586 * @return handle to the GNS service, or NULL on error
588 struct GNUNET_GNS_Handle *
589 GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
591 struct GNUNET_GNS_Handle *handle;
593 handle = GNUNET_malloc (sizeof (struct GNUNET_GNS_Handle));
594 handle->reconnect = GNUNET_NO;
597 //handle->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect_task, handle);
598 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
600 handle->in_receive = GNUNET_NO;
606 * Shutdown connection with the GNS service.
608 * @param handle handle of the GNS connection to stop
611 GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle)
613 GNUNET_CLIENT_disconnect (handle->client);
614 if (GNUNET_SCHEDULER_NO_TASK != handle->reconnect_task)
616 GNUNET_SCHEDULER_cancel (handle->reconnect_task);
617 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
624 * Helper function to generate request ids
630 get_request_id (struct GNUNET_GNS_Handle *h)
632 uint32_t r_id = h->r_id;
638 * Perform an asynchronous Lookup operation on the GNS.
640 * @param handle handle to the GNS service
641 * @param name the name to look up
642 * @param zone the zone to start the resolution in
643 * @param type the record type to look up
644 * @param only_cached GNUNET_YES to only check locally not DHT for performance
645 * @param shorten_key the private key of the shorten zone (can be NULL)
646 * @param proc processor to call on result
647 * @param proc_cls closure for processor
648 * @return handle to the get
650 struct GNUNET_GNS_QueueEntry *
651 GNUNET_GNS_lookup_zone (struct GNUNET_GNS_Handle *handle,
653 struct GNUNET_CRYPTO_ShortHashCode *zone,
654 enum GNUNET_GNS_RecordType type,
656 struct GNUNET_CRYPTO_RsaPrivateKey *shorten_key,
657 GNUNET_GNS_LookupResultProcessor proc,
660 /* IPC to shorten gns names, return shorten_handle */
661 struct GNUNET_GNS_ClientLookupMessage *lookup_msg;
662 struct GNUNET_GNS_QueueEntry *qe;
664 struct PendingMessage *pending;
665 struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *pkey_enc=NULL;
674 if (NULL != shorten_key)
676 pkey_enc = GNUNET_CRYPTO_rsa_encode_key (shorten_key);
677 GNUNET_assert (pkey_enc != NULL);
678 key_len = ntohs (pkey_enc->len);
681 msize = sizeof (struct GNUNET_GNS_ClientLookupMessage)
682 + key_len + strlen(name) + 1;
683 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to lookup %s in GNS\n", name);
685 qe = GNUNET_malloc(sizeof (struct GNUNET_GNS_QueueEntry));
686 qe->gns_handle = handle;
687 qe->lookup_proc = proc;
688 qe->proc_cls = proc_cls;
689 qe->r_id = get_request_id(handle);
690 GNUNET_CONTAINER_DLL_insert_tail(handle->lookup_head,
691 handle->lookup_tail, qe);
693 pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize);
694 memset(pending, 0, (sizeof (struct PendingMessage) + msize));
696 pending->size = msize;
698 lookup_msg = (struct GNUNET_GNS_ClientLookupMessage *) &pending[1];
699 lookup_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_LOOKUP);
700 lookup_msg->header.size = htons (msize);
701 lookup_msg->id = htonl(qe->r_id);
702 lookup_msg->only_cached = htonl(only_cached);
706 lookup_msg->use_default_zone = htonl(0);
707 memcpy(&lookup_msg->zone, zone, sizeof(struct GNUNET_CRYPTO_ShortHashCode));
711 lookup_msg->use_default_zone = htonl(1);
712 memset(&lookup_msg->zone, 0, sizeof(struct GNUNET_CRYPTO_ShortHashCode));
715 lookup_msg->type = htonl(type);
717 pkey_tmp = (char *) &lookup_msg[1];
719 if (pkey_enc != NULL)
721 lookup_msg->have_key = htonl(1);
722 memcpy(pkey_tmp, pkey_enc, key_len);
725 lookup_msg->have_key = htonl(0);
727 memcpy(&pkey_tmp[key_len], name, strlen(name));
729 GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head, handle->pending_tail,
731 GNUNET_free_non_null (pkey_enc);
732 process_pending_messages (handle);
737 * Perform an asynchronous Lookup operation on the GNS.
739 * @param handle handle to the GNS service
740 * @param name the name to look up
741 * @param type the record type to look up
742 * @param only_cached GNUNET_YES to only check locally not DHT for performance
743 * @param shorten_key the private key of the shorten zone (can be NULL)
744 * @param proc processor to call on result
745 * @param proc_cls closure for processor
746 * @return handle to the get
748 struct GNUNET_GNS_QueueEntry *
749 GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
751 enum GNUNET_GNS_RecordType type,
753 struct GNUNET_CRYPTO_RsaPrivateKey *shorten_key,
754 GNUNET_GNS_LookupResultProcessor proc,
757 return GNUNET_GNS_lookup_zone (handle, name,
765 * Perform a name shortening operation on the GNS.
767 * @param handle handle to the GNS service
768 * @param name the name to look up
769 * @param private_zone the public zone of the private zone
770 * @param shorten_zone the public zone of the shorten zone
771 * @param zone the zone to start the resolution in
772 * @param proc function to call on result
773 * @param proc_cls closure for processor
774 * @return handle to the operation
776 struct GNUNET_GNS_QueueEntry *
777 GNUNET_GNS_shorten_zone (struct GNUNET_GNS_Handle *handle,
779 struct GNUNET_CRYPTO_ShortHashCode *private_zone,
780 struct GNUNET_CRYPTO_ShortHashCode *shorten_zone,
781 struct GNUNET_CRYPTO_ShortHashCode *zone,
782 GNUNET_GNS_ShortenResultProcessor proc,
785 /* IPC to shorten gns names, return shorten_handle */
786 struct GNUNET_GNS_ClientShortenMessage *shorten_msg;
787 struct GNUNET_GNS_QueueEntry *qe;
789 struct PendingMessage *pending;
796 msize = sizeof (struct GNUNET_GNS_ClientShortenMessage) + strlen(name) + 1;
797 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to shorten %s in GNS\n", name);
799 qe = GNUNET_malloc(sizeof (struct GNUNET_GNS_QueueEntry));
800 qe->gns_handle = handle;
801 qe->shorten_proc = proc;
802 qe->proc_cls = proc_cls;
803 qe->r_id = get_request_id(handle);
804 GNUNET_CONTAINER_DLL_insert_tail(handle->shorten_head,
805 handle->shorten_tail, qe);
807 pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize);
808 memset(pending, 0, (sizeof (struct PendingMessage) + msize));
810 pending->size = msize;
812 shorten_msg = (struct GNUNET_GNS_ClientShortenMessage *) &pending[1];
813 shorten_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_SHORTEN);
814 shorten_msg->header.size = htons (msize);
815 shorten_msg->id = htonl(qe->r_id);
816 shorten_msg->private_zone = *private_zone;
817 shorten_msg->shorten_zone = *shorten_zone;
821 shorten_msg->use_default_zone = htonl(0);
822 memcpy(&shorten_msg->zone, zone,
823 sizeof(struct GNUNET_CRYPTO_ShortHashCode));
827 shorten_msg->use_default_zone = htonl(1);
828 memset(&shorten_msg->zone, 0, sizeof(struct GNUNET_CRYPTO_ShortHashCode));
831 memcpy(&shorten_msg[1], name, strlen(name));
833 GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head, handle->pending_tail,
836 process_pending_messages (handle);
841 * Perform a name shortening operation on the GNS.
843 * @param handle handle to the GNS service
844 * @param name the name to look up
845 * @param private_zone the public zone of the private zone
846 * @param shorten_zone the public zone of the shorten zone
847 * @param proc function to call on result
848 * @param proc_cls closure for processor
849 * @return handle to the operation
851 struct GNUNET_GNS_QueueEntry *
852 GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle,
854 struct GNUNET_CRYPTO_ShortHashCode *private_zone,
855 struct GNUNET_CRYPTO_ShortHashCode *shorten_zone,
856 GNUNET_GNS_ShortenResultProcessor proc,
859 return GNUNET_GNS_shorten_zone (handle, name,
860 private_zone, shorten_zone,
861 NULL, proc, proc_cls);
864 * Perform an authority lookup for a given name.
866 * @param handle handle to the GNS service
867 * @param name the name to look up authority for
868 * @param proc function to call on result
869 * @param proc_cls closure for processor
870 * @return handle to the operation
872 struct GNUNET_GNS_QueueEntry *
873 GNUNET_GNS_get_authority (struct GNUNET_GNS_Handle *handle,
875 GNUNET_GNS_GetAuthResultProcessor proc,
878 struct GNUNET_GNS_ClientGetAuthMessage *get_auth_msg;
879 struct GNUNET_GNS_QueueEntry *qe;
881 struct PendingMessage *pending;
888 msize = sizeof (struct GNUNET_GNS_ClientGetAuthMessage) + strlen(name) + 1;
889 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
890 "Trying to look up authority for %s in GNS\n", name);
892 qe = GNUNET_malloc(sizeof (struct GNUNET_GNS_QueueEntry));
893 qe->gns_handle = handle;
894 qe->auth_proc = proc;
895 qe->proc_cls = proc_cls;
896 qe->r_id = get_request_id(handle);
897 GNUNET_CONTAINER_DLL_insert_tail(handle->get_auth_head,
898 handle->get_auth_tail, qe);
900 pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize);
901 memset(pending, 0, (sizeof (struct PendingMessage) + msize));
903 pending->size = msize;
905 get_auth_msg = (struct GNUNET_GNS_ClientGetAuthMessage *) &pending[1];
906 get_auth_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_GET_AUTH);
907 get_auth_msg->header.size = htons (msize);
908 get_auth_msg->id = htonl(qe->r_id);
910 memcpy(&get_auth_msg[1], name, strlen(name));
912 GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head, handle->pending_tail,
915 process_pending_messages (handle);
920 /* end of gns_api.c */