X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fgns%2Fgns_api.c;h=84c4ae189f3ee760450062b39309285fbfc67be4;hb=ab281595eeb270120f89ec954a572f4fcf78fc53;hp=79bd096c5d182d9ef97cb72577882f852874cc08;hpb=36785d69da8cb4b309c0b08d065be86a91f870f2;p=oweals%2Fgnunet.git diff --git a/src/gns/gns_api.c b/src/gns/gns_api.c index 79bd096c5..84c4ae189 100644 --- a/src/gns/gns_api.c +++ b/src/gns/gns_api.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2009, 2010 Christian Grothoff (and other contributing authors) + Copyright (C) 2009-2013, 2016 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -14,17 +14,15 @@ You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ - /** - * * @file gns/gns_api.c * @brief library to access the GNS service * @author Martin Schanzenbach + * @author Christian Grothoff */ - #include "platform.h" #include "gnunet_util_lib.h" #include "gnunet_constants.h" @@ -35,143 +33,49 @@ #include "gns.h" #include "gnunet_gns_service.h" -/* TODO into gnunet_protocols */ -#define GNUNET_MESSAGE_TYPE_GNS_LOOKUP 23 -#define GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT 24 -#define GNUNET_MESSAGE_TYPE_GNS_SHORTEN 25 -#define GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT 26 -#define GNUNET_MESSAGE_TYPE_GNS_GET_AUTH 27 -#define GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT 28 + +#define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__) /** * Handle to a lookup request */ struct GNUNET_GNS_LookupRequest { + /** * DLL */ struct GNUNET_GNS_LookupRequest *next; - - /** - * DLL - */ - struct GNUNET_GNS_LookupRequest *prev; - - /** - * associated pending message - */ - struct PendingMessage *pending_msg; - - /* request id */ - uint64_t r_id; - - /* handle to gns */ - struct GNUNET_GNS_Handle *gns_handle; - - /* processor to call on lookup result */ - GNUNET_GNS_LookupResultProcessor lookup_proc; - - /* processor closure */ - void *proc_cls; - -}; - -/** - * Handle to a shorten request - */ -struct GNUNET_GNS_ShortenRequest -{ /** * DLL */ - struct GNUNET_GNS_ShortenRequest *next; - - /** - * DLL - */ - struct GNUNET_GNS_ShortenRequest *prev; + struct GNUNET_GNS_LookupRequest *prev; /** - * associated pending message + * handle to gns */ - struct PendingMessage *pending_msg; - - /* request id */ - uint64_t r_id; - - /* handle to gns */ struct GNUNET_GNS_Handle *gns_handle; - - /* processor to call on shorten result */ - GNUNET_GNS_ShortenResultProcessor shorten_proc; - - /* processor closure */ - void *proc_cls; - -}; - -/** - * Handle to GetAuthorityRequest - */ -struct GNUNET_GNS_GetAuthRequest -{ /** - * DLL - */ - struct GNUNET_GNS_GetAuthRequest *next; - - /** - * DLL + * processor to call on lookup result */ - struct GNUNET_GNS_GetAuthRequest *prev; + GNUNET_GNS_LookupResultProcessor lookup_proc; /** - * associated pending message + * @e lookup_proc closure */ - struct PendingMessage *pending_msg; - - /* request id */ - uint32_t r_id; - - /* handle to gns */ - struct GNUNET_GNS_Handle *gns_handle; - - /* processor to call on authority lookup result */ - GNUNET_GNS_GetAuthResultProcessor auth_proc; - - /* processor closure */ void *proc_cls; - -}; - - -/** - * Entry in our list of messages to be (re-)transmitted. - */ -struct PendingMessage -{ - /** - * This is a doubly-linked list. - */ - struct PendingMessage *prev; /** - * This is a doubly-linked list. + * Envelope with the message for this queue entry. */ - struct PendingMessage *next; + struct GNUNET_MQ_Envelope *env; /** * request id */ - uint64_t r_id; - - /** - * Size of the message. - */ - size_t size; + uint32_t r_id; }; @@ -188,466 +92,206 @@ struct GNUNET_GNS_Handle const struct GNUNET_CONFIGURATION_Handle *cfg; /** - * Socket (if available). + * Connection to service (if available). */ - struct GNUNET_CLIENT_Connection *client; + struct GNUNET_MQ_Handle *mq; /** - * Currently pending transmission request (or NULL). - */ - struct GNUNET_CLIENT_TransmitHandle *th; - - uint32_t r_id; - - /** - * Head of linked list of shorten messages we would like to transmit. - */ - struct PendingMessage *pending_head; - - /** - * Tail of linked list of shorten messages we would like to transmit. - */ - struct PendingMessage *pending_tail; - - /** - * Head of linked list of shorten messages we would like to transmit. - */ - struct GNUNET_GNS_ShortenRequest *shorten_head; - - /** - * Tail of linked list of shorten messages we would like to transmit. - */ - struct GNUNET_GNS_ShortenRequest *shorten_tail; - - /** - * Head of linked list of lookup messages we would like to transmit. + * Head of linked list of active lookup requests. */ struct GNUNET_GNS_LookupRequest *lookup_head; /** - * Tail of linked list of lookup messages we would like to transmit. + * Tail of linked list of active lookup requests. */ struct GNUNET_GNS_LookupRequest *lookup_tail; - - /** - * Head of linked list of authority lookup messages we would like to transmit. - */ - struct GNUNET_GNS_GetAuthRequest *get_auth_head; - - /** - * Tail of linked list of authority lookup messages we would like to transmit. - */ - struct GNUNET_GNS_GetAuthRequest *get_auth_tail; /** * Reconnect task */ - GNUNET_SCHEDULER_TaskIdentifier reconnect_task; + struct GNUNET_SCHEDULER_Task *reconnect_task; /** - * Did we start our receive loop yet? + * How long do we wait until we try to reconnect? */ - int in_receive; + struct GNUNET_TIME_Relative reconnect_backoff; /** - * Reconnect necessary + * Request Id generator. Incremented by one for each request. */ - int reconnect; -}; + uint32_t r_id_gen; -/** - * Try to send messages from list of messages to send - * @param handle GNS_Handle - */ -static void -process_pending_messages (struct GNUNET_GNS_Handle *handle); +}; /** * Reconnect to GNS service. * - * @param h the handle to the namestore service + * @param handle the handle to the GNS service */ static void -reconnect (struct GNUNET_GNS_Handle *h) -{ - GNUNET_assert (NULL == h->client); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Trying to connect to GNS...\n"); - h->client = GNUNET_CLIENT_connect ("gns", h->cfg); - GNUNET_assert (NULL != h->client); -} +reconnect (struct GNUNET_GNS_Handle *handle); + /** * Reconnect to GNS * * @param cls the handle - * @param tc task context */ static void -reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +reconnect_task (void *cls) { - struct GNUNET_GNS_Handle *h = cls; + struct GNUNET_GNS_Handle *handle = cls; - h->reconnect_task = GNUNET_SCHEDULER_NO_TASK; - reconnect (h); + handle->reconnect_task = NULL; + reconnect (handle); } /** * Disconnect from service and then reconnect. * - * @param h our handle + * @param handle our handle */ static void -force_reconnect (struct GNUNET_GNS_Handle *h) +force_reconnect (struct GNUNET_GNS_Handle *handle) { - h->reconnect = GNUNET_NO; - GNUNET_CLIENT_disconnect (h->client); - h->client = NULL; - h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, - &reconnect_task, - h); + GNUNET_MQ_destroy (handle->mq); + handle->mq = NULL; + handle->reconnect_backoff + = GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff); + handle->reconnect_task + = GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff, + &reconnect_task, + handle); } -/** - * Transmit the next pending message, called by notify_transmit_ready - */ -static size_t -transmit_pending (void *cls, size_t size, void *buf); /** - * Handler for messages received from the GNS service + * Generic error handler, called with the appropriate error code and + * the same closure specified at the creation of the message queue. + * Not every message queue implementation supports an error handler. * - * @param cls the 'struct GNUNET_GNS_Handle' - * @param msg the incoming message - */ -static void -process_message (void *cls, const struct GNUNET_MessageHeader *msg); - -/** - * Try to send messages from list of messages to send + * @param cls closure with the `struct GNUNET_GNS_Handle *` + * @param error error code */ static void -process_pending_messages (struct GNUNET_GNS_Handle *handle) -{ - struct PendingMessage *p; - - if (handle->client == NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "process_pending_messages called, but client is null\n"); - return; - } - - if (handle->th != NULL) - return; - - if (NULL == (p = handle->pending_head)) - return; - - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Trying to transmit %d bytes...\n", p->size); - - handle->th = - GNUNET_CLIENT_notify_transmit_ready (handle->client, - p->size, - GNUNET_TIME_UNIT_FOREVER_REL, - GNUNET_NO, &transmit_pending, - handle); - if (NULL != handle->th) - return; - - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "notify_transmit_ready returned NULL!\n"); -} - - -/** - * Transmit the next pending message, called by notify_transmit_ready - */ -static size_t -transmit_pending (void *cls, size_t size, void *buf) +mq_error_handler (void *cls, + enum GNUNET_MQ_Error error) { struct GNUNET_GNS_Handle *handle = cls; - struct PendingMessage *p; - size_t tsize; - char *cbuf; - - handle->th = NULL; - - if ((size == 0) || (buf == NULL)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Transmission to GNS service failed!\n"); - force_reconnect(handle); - return 0; - } - - tsize = 0; - cbuf = buf; - - if (NULL == (p = handle->pending_head)) - return 0; - while ((NULL != (p = handle->pending_head)) && (p->size <= size)) - { - memcpy (&cbuf[tsize], &p[1], p->size); - tsize += p->size; - size -= p->size; - GNUNET_CONTAINER_DLL_remove (handle->pending_head, handle->pending_tail, p); - if (GNUNET_YES != handle->in_receive) - { - GNUNET_CLIENT_receive (handle->client, &process_message, handle, - GNUNET_TIME_UNIT_FOREVER_REL); - handle->in_receive = GNUNET_YES; - } - GNUNET_free(p); - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending %d bytes\n", tsize); - - process_pending_messages(handle); - return tsize; + LOG (GNUNET_ERROR_TYPE_WARNING, + "Problem with message queue. error: %i\n", + error); + force_reconnect (handle); } + /** - * Process a given reply that might match the given - * request. + * Check validity of message received from the GNS service * - * @param qe a queue entry - * @param msg the shorten msg received + * @param cls the `struct GNUNET_GNS_Handle *` + * @param loookup_msg the incoming message */ -static void -process_shorten_reply (struct GNUNET_GNS_ShortenRequest *qe, - const struct GNUNET_GNS_ClientShortenResultMessage *msg) +static int +check_result (void *cls, + const struct LookupResultMessage *lookup_msg) { - struct GNUNET_GNS_Handle *h = qe->gns_handle; - const char *short_name; - - GNUNET_CONTAINER_DLL_remove (h->shorten_head, h->shorten_tail, qe); - short_name = (char*)(&msg[1]); - - if (ntohs (((struct GNUNET_MessageHeader*)msg)->size) < - sizeof (struct GNUNET_GNS_ClientShortenResultMessage)) + size_t mlen = ntohs (lookup_msg->header.size) - sizeof (*lookup_msg); + uint32_t rd_count = ntohl (lookup_msg->rd_count); + struct GNUNET_GNSRECORD_Data rd[rd_count]; + + if (GNUNET_SYSERR == + GNUNET_GNSRECORD_records_deserialize (mlen, + (const char*) &lookup_msg[1], + rd_count, + rd)) { GNUNET_break (0); - force_reconnect (h); - GNUNET_free(qe); - return; + return GNUNET_SYSERR; } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received shortened reply `%s' from GNS service\n", - short_name); - - GNUNET_CLIENT_receive (h->client, &process_message, h, - GNUNET_TIME_UNIT_FOREVER_REL); - qe->shorten_proc (qe->proc_cls, short_name); - GNUNET_free (qe); - + return GNUNET_OK; } /** - * Process a given reply that might match the given - * request. + * Handler for messages received from the GNS service * - * @param qe the handle to the request - * @param msg the message to process + * @param cls the `struct GNUNET_GNS_Handle *` + * @param loookup_msg the incoming message */ static void -process_get_auth_reply (struct GNUNET_GNS_GetAuthRequest *qe, - const struct GNUNET_GNS_ClientGetAuthResultMessage *msg) +handle_result (void *cls, + const struct LookupResultMessage *lookup_msg) { - struct GNUNET_GNS_Handle *h = qe->gns_handle; - const char *auth_name; - - GNUNET_CONTAINER_DLL_remove (h->get_auth_head, h->get_auth_tail, qe); - auth_name = (char*)&msg[1]; + struct GNUNET_GNS_Handle *handle = cls; + size_t mlen = ntohs (lookup_msg->header.size) - sizeof (*lookup_msg); + uint32_t rd_count = ntohl (lookup_msg->rd_count); + struct GNUNET_GNSRECORD_Data rd[rd_count]; + uint32_t r_id = ntohl (lookup_msg->id); + struct GNUNET_GNS_LookupRequest *lr; + GNUNET_GNS_LookupResultProcessor proc; + void *proc_cls; - if (ntohs (((struct GNUNET_MessageHeader*)msg)->size) < - sizeof (struct GNUNET_GNS_ClientGetAuthResultMessage)) - { - GNUNET_free(qe); - GNUNET_break (0); - force_reconnect (h); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Received lookup reply from GNS service (%u records)\n", + (unsigned int) rd_count); + for (lr = handle->lookup_head; NULL != lr; lr = lr->next) + if (lr->r_id == r_id) + break; + if (NULL == lr) return; - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received GET_AUTH reply `%s' from GNS service\n", - auth_name); - - GNUNET_CLIENT_receive (h->client, &process_message, h, - GNUNET_TIME_UNIT_FOREVER_REL); - qe->auth_proc (qe->proc_cls, auth_name); - GNUNET_free (qe); - + proc = lr->lookup_proc; + proc_cls = lr->proc_cls; + + GNUNET_assert (GNUNET_OK == + GNUNET_GNSRECORD_records_deserialize (mlen, + (const char*) &lookup_msg[1], + rd_count, + rd)); + proc (proc_cls, + rd_count, + rd); + GNUNET_CONTAINER_DLL_remove (handle->lookup_head, + handle->lookup_tail, + lr); + if (NULL != lr->env) + GNUNET_MQ_discard (lr->env); + GNUNET_free (lr); } -/** - * Process a given reply to the lookup request - * - * @param qe a queue entry - * @param msg the lookup message received - */ -static void -process_lookup_reply (struct GNUNET_GNS_LookupRequest *qe, - const struct GNUNET_GNS_ClientLookupResultMessage *msg) -{ - struct GNUNET_GNS_Handle *h = qe->gns_handle; - int rd_count = ntohl(msg->rd_count); - size_t len = ntohs (((struct GNUNET_MessageHeader*)msg)->size); - struct GNUNET_NAMESTORE_RecordData rd[rd_count]; - GNUNET_CONTAINER_DLL_remove (h->lookup_head, h->lookup_tail, qe); - - if (len < sizeof (struct GNUNET_GNS_ClientLookupResultMessage)) - { - GNUNET_free(qe); - GNUNET_break (0); - force_reconnect (h); - return; - } - - len -= sizeof (struct GNUNET_GNS_ClientLookupResultMessage); - GNUNET_CLIENT_receive (h->client, &process_message, h, - GNUNET_TIME_UNIT_FOREVER_REL); - if (GNUNET_SYSERR == GNUNET_NAMESTORE_records_deserialize (len, - (char*)&msg[1], - rd_count, - rd)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to serialize lookup reply from GNS service!\n"); - qe->lookup_proc (qe->proc_cls, 0, NULL); - } - else - { - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received lookup reply from GNS service (count=%d)\n", - ntohl (msg->rd_count)); - qe->lookup_proc (qe->proc_cls, rd_count, rd); - } - GNUNET_free (qe); -} /** - * Handler for messages received from the GNS service + * Reconnect to GNS service. * - * @param cls the 'struct GNUNET_GNS_Handle' - * @param msg the incoming message + * @param handle the handle to the GNS service */ static void -process_message (void *cls, const struct GNUNET_MessageHeader *msg) +reconnect (struct GNUNET_GNS_Handle *handle) { - struct GNUNET_GNS_Handle *handle = cls; - struct GNUNET_GNS_LookupRequest *lr; - struct GNUNET_GNS_ShortenRequest *sr; - struct GNUNET_GNS_GetAuthRequest *gar; - const struct GNUNET_GNS_ClientLookupResultMessage *lookup_msg; - const struct GNUNET_GNS_ClientShortenResultMessage *shorten_msg; - const struct GNUNET_GNS_ClientGetAuthResultMessage *get_auth_msg; - uint16_t type; - uint32_t r_id; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got message\n"); - if (msg == NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error receiving data from GNS service, reconnecting\n"); - force_reconnect (handle); - return; - } - - type = ntohs (msg->type); - - if (type == GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got lookup msg\n"); - lookup_msg = (const struct GNUNET_GNS_ClientLookupResultMessage *) msg; - r_id = ntohl (lookup_msg->id); - - if (r_id > handle->r_id) - { - /** no request found */ - GNUNET_break_op (0); - GNUNET_CLIENT_receive (handle->client, &process_message, handle, - GNUNET_TIME_UNIT_FOREVER_REL); - return; - } - - for (lr = handle->lookup_head; NULL != lr; lr = lr->next) - { - if (lr->r_id == r_id) - break; - } - if (lr) - process_lookup_reply(lr, lookup_msg); - - return; - - } - else if (type == GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got SHORTEN_RESULT msg\n"); - shorten_msg = (struct GNUNET_GNS_ClientShortenResultMessage *) msg; - - r_id = ntohl (shorten_msg->id); - - if (r_id > handle->r_id) - { - /** no request found */ - GNUNET_break_op (0); - GNUNET_CLIENT_receive (handle->client, &process_message, handle, - GNUNET_TIME_UNIT_FOREVER_REL); - return; - } - - for (sr = handle->shorten_head; NULL != sr; sr = sr->next) - { - if (sr->r_id == r_id) - break; - } - if (sr) - process_shorten_reply (sr, shorten_msg); + struct GNUNET_MQ_MessageHandler handlers[] = { + GNUNET_MQ_hd_var_size (result, + GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT, + struct LookupResultMessage, + handle), + GNUNET_MQ_handler_end () + }; + struct GNUNET_GNS_LookupRequest *lh; + + GNUNET_assert (NULL == handle->mq); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Trying to connect to GNS\n"); + handle->mq = GNUNET_CLIENT_connect (handle->cfg, + "gns", + handlers, + &mq_error_handler, + handle); + if (NULL == handle->mq) return; - } - else if (type == GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got GET_AUTH_RESULT msg\n"); - get_auth_msg = (struct GNUNET_GNS_ClientGetAuthResultMessage *) msg; - - r_id = ntohl (get_auth_msg->id); - - if (r_id > handle->r_id) - { - /** no request found */ - GNUNET_break_op (0); - GNUNET_CLIENT_receive (handle->client, &process_message, handle, - GNUNET_TIME_UNIT_FOREVER_REL); - return; - } - - for (gar = handle->get_auth_head; NULL != gar; gar = gar->next) - { - if (gar->r_id == r_id) - break; - } - if (gar) - process_get_auth_reply (gar, get_auth_msg); - return; - } - - - if (GNUNET_YES == handle->reconnect) - force_reconnect (handle); + for (lh = handle->lookup_head; NULL != lh; lh = lh->next) + GNUNET_MQ_send_copy (handle->mq, + lh->env); } @@ -662,13 +306,14 @@ GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) { struct GNUNET_GNS_Handle *handle; - handle = GNUNET_malloc (sizeof (struct GNUNET_GNS_Handle)); - handle->reconnect = GNUNET_NO; + handle = GNUNET_new (struct GNUNET_GNS_Handle); handle->cfg = cfg; reconnect (handle); - handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; - handle->r_id = 0; - handle->in_receive = GNUNET_NO; + if (NULL == handle->mq) + { + GNUNET_free (handle); + return NULL; + } return handle; } @@ -681,33 +326,18 @@ GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) void GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle) { - GNUNET_CLIENT_disconnect (handle->client); - if (GNUNET_SCHEDULER_NO_TASK != handle->reconnect_task) + if (NULL != handle->mq) + { + GNUNET_MQ_destroy (handle->mq); + handle->mq = NULL; + } + if (NULL != handle->reconnect_task) { GNUNET_SCHEDULER_cancel (handle->reconnect_task); - handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; + handle->reconnect_task = NULL; } - GNUNET_assert (NULL == handle->lookup_head); - GNUNET_assert (NULL == handle->shorten_head); - GNUNET_assert (NULL == handle->get_auth_head); - - GNUNET_free(handle); - /* disco from GNS */ -} - -/* - * Helper function to generate request ids - * - * @param h handle - * @return a new id - */ -static uint32_t -get_request_id (struct GNUNET_GNS_Handle *h) -{ - uint32_t r_id = h->r_id; - h->r_id++; - return r_id; + GNUNET_free (handle); } @@ -717,357 +347,80 @@ get_request_id (struct GNUNET_GNS_Handle *h) * @param lr the lookup request to cancel */ void -GNUNET_GNS_cancel_lookup_request (struct GNUNET_GNS_LookupRequest *lr) +GNUNET_GNS_lookup_cancel (struct GNUNET_GNS_LookupRequest *lr) { - GNUNET_assert (NULL == lr->gns_handle); - - GNUNET_CONTAINER_DLL_remove (lr->gns_handle->pending_head, - lr->gns_handle->pending_tail, - lr->pending_msg); + struct GNUNET_GNS_Handle *handle = lr->gns_handle; - GNUNET_free (lr->pending_msg); - - GNUNET_CONTAINER_DLL_remove (lr->gns_handle->lookup_head, - lr->gns_handle->lookup_tail, + GNUNET_CONTAINER_DLL_remove (handle->lookup_head, + handle->lookup_tail, lr); - + GNUNET_MQ_discard (lr->env); GNUNET_free (lr); } /** - * Cancel pending shorten request - * - * @param lr the lookup request to cancel - */ -void -GNUNET_GNS_cancel_shorten_request (struct GNUNET_GNS_ShortenRequest *sr) -{ - GNUNET_assert (NULL != sr->gns_handle); - - GNUNET_CONTAINER_DLL_remove (sr->gns_handle->pending_head, - sr->gns_handle->pending_tail, - sr->pending_msg); - - GNUNET_free (sr->pending_msg); - - GNUNET_CONTAINER_DLL_remove (sr->gns_handle->shorten_head, - sr->gns_handle->shorten_tail, - sr); - - GNUNET_free (sr); -} - - -/** - * Cancel pending get auth request - * - * @param lr the lookup request to cancel - */ -void -GNUNET_GNS_cancel_get_auth_request (struct GNUNET_GNS_GetAuthRequest *gar) -{ - GNUNET_assert (NULL != gar->gns_handle); - - GNUNET_CONTAINER_DLL_remove (gar->gns_handle->pending_head, - gar->gns_handle->pending_tail, - gar->pending_msg); - - GNUNET_free (gar->pending_msg); - - GNUNET_CONTAINER_DLL_remove (gar->gns_handle->get_auth_head, - gar->gns_handle->get_auth_tail, - gar); - - GNUNET_free (gar); -} - -/** - * Perform an asynchronous Lookup operation on the GNS. + * Perform an asynchronous lookup operation on the GNS. * * @param handle handle to the GNS service * @param name the name to look up * @param zone the zone to start the resolution in * @param type the record type to look up - * @param only_cached GNUNET_YES to only check locally not DHT for performance - * @param shorten_key the private key of the shorten zone (can be NULL) + * @param options local options for the lookup * @param proc processor to call on result - * @param proc_cls closure for processor + * @param proc_cls closure for @a proc * @return handle to the get request */ struct GNUNET_GNS_LookupRequest* -GNUNET_GNS_lookup_zone (struct GNUNET_GNS_Handle *handle, - const char * name, - struct GNUNET_CRYPTO_ShortHashCode *zone, - enum GNUNET_GNS_RecordType type, - int only_cached, - struct GNUNET_CRYPTO_RsaPrivateKey *shorten_key, +GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, + const char *name, + const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, + uint32_t type, + enum GNUNET_GNS_LocalOptions options, GNUNET_GNS_LookupResultProcessor proc, void *proc_cls) { /* IPC to shorten gns names, return shorten_handle */ - struct GNUNET_GNS_ClientLookupMessage *lookup_msg; + struct LookupMessage *lookup_msg; struct GNUNET_GNS_LookupRequest *lr; - size_t msize; - struct PendingMessage *pending; - struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *pkey_enc=NULL; - size_t key_len = 0; - char* pkey_tmp; + size_t nlen; if (NULL == name) { + GNUNET_break (0); return NULL; } - - if (NULL != shorten_key) + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Trying to lookup `%s' in GNS\n", + name); + nlen = strlen (name) + 1; + if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (*lr)) { - pkey_enc = GNUNET_CRYPTO_rsa_encode_key (shorten_key); - GNUNET_assert (pkey_enc != NULL); - key_len = ntohs (pkey_enc->len); + GNUNET_break (0); + return NULL; } - - msize = sizeof (struct GNUNET_GNS_ClientLookupMessage) - + key_len + strlen(name) + 1; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to lookup %s in GNS\n", name); - - lr = GNUNET_malloc(sizeof (struct GNUNET_GNS_LookupRequest)); + lr = GNUNET_new (struct GNUNET_GNS_LookupRequest); lr->gns_handle = handle; lr->lookup_proc = proc; lr->proc_cls = proc_cls; - lr->r_id = get_request_id (handle); - GNUNET_CONTAINER_DLL_insert_tail (handle->lookup_head, - handle->lookup_tail, lr); - - pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize); - memset (pending, 0, (sizeof (struct PendingMessage) + msize)); - - pending->size = msize; - lr->pending_msg = pending; - - lookup_msg = (struct GNUNET_GNS_ClientLookupMessage *) &pending[1]; - lookup_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_LOOKUP); - lookup_msg->header.size = htons (msize); + lr->r_id = handle->r_id_gen++; + lr->env = GNUNET_MQ_msg_extra (lookup_msg, + nlen, + GNUNET_MESSAGE_TYPE_GNS_LOOKUP); lookup_msg->id = htonl (lr->r_id); - lookup_msg->only_cached = htonl(only_cached); - - if (NULL != zone) - { - lookup_msg->use_default_zone = htonl (0); - memcpy (&lookup_msg->zone, zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode)); - } - else - { - lookup_msg->use_default_zone = htonl (1); - memset (&lookup_msg->zone, 0, sizeof(struct GNUNET_CRYPTO_ShortHashCode)); - } - + lookup_msg->options = htons ((uint16_t) options); + lookup_msg->zone = *zone; lookup_msg->type = htonl (type); - - pkey_tmp = (char *) &lookup_msg[1]; - - if (pkey_enc != NULL) - { - lookup_msg->have_key = htonl(1); - memcpy (pkey_tmp, pkey_enc, key_len); - } - else - lookup_msg->have_key = htonl (0); - - memcpy (&pkey_tmp[key_len], name, strlen (name)); - - GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head, handle->pending_tail, - pending); - GNUNET_free_non_null (pkey_enc); - process_pending_messages (handle); + GNUNET_memcpy (&lookup_msg[1], + name, + nlen); + GNUNET_CONTAINER_DLL_insert (handle->lookup_head, + handle->lookup_tail, + lr); + if (NULL != handle->mq) + GNUNET_MQ_send_copy (handle->mq, + lr->env); return lr; } -/** - * Perform an asynchronous Lookup operation on the GNS. - * - * @param handle handle to the GNS service - * @param name the name to look up - * @param type the record type to look up - * @param only_cached GNUNET_YES to only check locally not DHT for performance - * @param shorten_key the private key of the shorten zone (can be NULL) - * @param proc processor to call on result - * @param proc_cls closure for processor - * @return handle to the lookup request - */ -struct GNUNET_GNS_LookupRequest* -GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, - const char * name, - enum GNUNET_GNS_RecordType type, - int only_cached, - struct GNUNET_CRYPTO_RsaPrivateKey *shorten_key, - GNUNET_GNS_LookupResultProcessor proc, - void *proc_cls) -{ - return GNUNET_GNS_lookup_zone (handle, name, - NULL, - type, only_cached, - shorten_key, - proc, proc_cls); -} - -/** - * Perform a name shortening operation on the GNS. - * - * @param handle handle to the GNS service - * @param name the name to look up - * @param private_zone the public zone of the private zone - * @param shorten_zone the public zone of the shorten zone - * @param zone the zone to start the resolution in - * @param proc function to call on result - * @param proc_cls closure for processor - * @return handle to the operation - */ -struct GNUNET_GNS_ShortenRequest* -GNUNET_GNS_shorten_zone (struct GNUNET_GNS_Handle *handle, - const char * name, - struct GNUNET_CRYPTO_ShortHashCode *private_zone, - struct GNUNET_CRYPTO_ShortHashCode *shorten_zone, - struct GNUNET_CRYPTO_ShortHashCode *zone, - GNUNET_GNS_ShortenResultProcessor proc, - void *proc_cls) -{ - /* IPC to shorten gns names, return shorten_handle */ - struct GNUNET_GNS_ClientShortenMessage *shorten_msg; - struct GNUNET_GNS_ShortenRequest *sr; - size_t msize; - struct PendingMessage *pending; - - if (NULL == name) - { - return NULL; - } - - msize = sizeof (struct GNUNET_GNS_ClientShortenMessage) + strlen(name) + 1; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to shorten %s in GNS\n", name); - - sr = GNUNET_malloc(sizeof (struct GNUNET_GNS_ShortenRequest)); - sr->gns_handle = handle; - sr->shorten_proc = proc; - sr->proc_cls = proc_cls; - sr->r_id = get_request_id (handle); - GNUNET_CONTAINER_DLL_insert_tail (handle->shorten_head, - handle->shorten_tail, sr); - - pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize); - memset(pending, 0, (sizeof (struct PendingMessage) + msize)); - - pending->size = msize; - sr->pending_msg = pending; - - shorten_msg = (struct GNUNET_GNS_ClientShortenMessage *) &pending[1]; - shorten_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_SHORTEN); - shorten_msg->header.size = htons (msize); - shorten_msg->id = htonl (sr->r_id); - shorten_msg->private_zone = *private_zone; - shorten_msg->shorten_zone = *shorten_zone; - - if (NULL != zone) - { - shorten_msg->use_default_zone = htonl (0); - memcpy (&shorten_msg->zone, zone, - sizeof (struct GNUNET_CRYPTO_ShortHashCode)); - } - else - { - shorten_msg->use_default_zone = htonl (1); - memset (&shorten_msg->zone, 0, sizeof (struct GNUNET_CRYPTO_ShortHashCode)); - } - - memcpy (&shorten_msg[1], name, strlen (name)); - - GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head, handle->pending_tail, - pending); - - process_pending_messages (handle); - return sr; -} - -/** - * Perform a name shortening operation on the GNS. - * - * @param handle handle to the GNS service - * @param name the name to look up - * @param private_zone the public zone of the private zone - * @param shorten_zone the public zone of the shorten zone - * @param proc function to call on result - * @param proc_cls closure for processor - * @return handle to the operation - */ -struct GNUNET_GNS_ShortenRequest* -GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle, - const char * name, - struct GNUNET_CRYPTO_ShortHashCode *private_zone, - struct GNUNET_CRYPTO_ShortHashCode *shorten_zone, - GNUNET_GNS_ShortenResultProcessor proc, - void *proc_cls) -{ - return GNUNET_GNS_shorten_zone (handle, name, - private_zone, shorten_zone, - NULL, proc, proc_cls); -} - - -/** - * Perform an authority lookup for a given name. - * - * @param handle handle to the GNS service - * @param name the name to look up authority for - * @param proc function to call on result - * @param proc_cls closure for processor - * @return handle to the operation - */ -struct GNUNET_GNS_GetAuthRequest* -GNUNET_GNS_get_authority (struct GNUNET_GNS_Handle *handle, - const char * name, - GNUNET_GNS_GetAuthResultProcessor proc, - void *proc_cls) -{ - struct GNUNET_GNS_ClientGetAuthMessage *get_auth_msg; - struct GNUNET_GNS_GetAuthRequest *gar; - size_t msize; - struct PendingMessage *pending; - - if (NULL == name) - { - return NULL; - } - - msize = sizeof (struct GNUNET_GNS_ClientGetAuthMessage) + strlen(name) + 1; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Trying to look up authority for %s in GNS\n", name); - - gar = GNUNET_malloc (sizeof (struct GNUNET_GNS_GetAuthRequest)); - gar->gns_handle = handle; - gar->auth_proc = proc; - gar->proc_cls = proc_cls; - gar->r_id = get_request_id (handle); - GNUNET_CONTAINER_DLL_insert_tail (handle->get_auth_head, - handle->get_auth_tail, gar); - - pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize); - memset (pending, 0, (sizeof (struct PendingMessage) + msize)); - - pending->size = msize; - gar->pending_msg = pending; - - get_auth_msg = (struct GNUNET_GNS_ClientGetAuthMessage *) &pending[1]; - get_auth_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_GET_AUTH); - get_auth_msg->header.size = htons (msize); - get_auth_msg->id = htonl (gar->r_id); - - memcpy(&get_auth_msg[1], name, strlen(name)); - - GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head, handle->pending_tail, - pending); - - process_pending_messages (handle); - return gar; -} - - /* end of gns_api.c */