diff options
author | schanzen <schanzen@140774ce-b5e7-0310-ab8b-a85725594a96> | 2012-03-08 14:14:01 +0000 |
---|---|---|
committer | schanzen <schanzen@140774ce-b5e7-0310-ab8b-a85725594a96> | 2012-03-08 14:14:01 +0000 |
commit | 27f029460ee36328647bcd4e11b95ec020f44049 (patch) | |
tree | a3c36e0a87766bd85e450bd1b9c8766965a34710 /src/gns/gns_api.c | |
parent | a0638d923c682ea5f88634d5c5a897e4de2fc134 (diff) |
-GNS service api change, replaced complicated buggy code
git-svn-id: https://gnunet.org/svn/gnunet@20368 140774ce-b5e7-0310-ab8b-a85725594a96
Diffstat (limited to 'src/gns/gns_api.c')
-rw-r--r-- | src/gns/gns_api.c | 680 |
1 files changed, 229 insertions, 451 deletions
diff --git a/src/gns/gns_api.c b/src/gns/gns_api.c index eaae4955f3..47efe5058e 100644 --- a/src/gns/gns_api.c +++ b/src/gns/gns_api.c @@ -46,130 +46,54 @@ #define GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT 26 /** - * Entry in our list of messages to be (re-)transmitted. + * A QueueEntry. */ -struct PendingMessage +struct GNUNET_GNS_QueueEntry { /** - * This is a doubly-linked list. - */ - struct PendingMessage *prev; - - /** - * This is a doubly-linked list. - */ - struct PendingMessage *next; - - /** - * Message that is pending, allocated at the end - * of this struct. - */ - const struct GNUNET_MessageHeader *msg; - - /** - * Handle to the GNS API context. + * DLL */ - struct GNUNET_GNS_Handle *handle; - - /** - * Continuation to call when the request has been - * transmitted (for the first time) to the service; can be NULL. - */ - GNUNET_SCHEDULER_Task cont; - - /** - * Closure for 'cont'. - */ - void *cont_cls; - - /** - * Unique ID for this request - */ - uint64_t unique_id; - - /** - * Free the saved message once sent, set to GNUNET_YES for messages - * that do not receive responses; GNUNET_NO if this pending message - * is aliased from a 'struct GNUNET_DHT_RouteHandle' and will be freed - * from there. - */ - - int free_on_send; - /** - * GNUNET_YES if this message is in our pending queue right now. - */ - int in_pending_queue; - -}; - -/** - * Handle to a Lookup request - */ -struct GNUNET_GNS_LookupHandle -{ - - /** - * Iterator to call on data receipt - */ - GNUNET_GNS_LookupIterator iter; - + struct GNUNET_GNS_QueueEntry *next; + /** - * Closure for the iterator callback + * DLL */ - void *iter_cls; + struct GNUNET_GNS_QueueEntry *prev; - /** - * Main handle to this GNS api - */ + /* request id */ + uint32_t r_id; + + /* handle to gns */ struct GNUNET_GNS_Handle *gns_handle; - - /** - * Key that this get request is for - */ - GNUNET_HashCode key; - - /** - * Unique identifier for this request (for key collisions). - */ - uint64_t unique_id; - - struct PendingMessage *message; - + + /* processor to call on shorten result */ + GNUNET_GNS_ShortenResultProcessor proc; + + /* processor closure */ + void *proc_cls; + }; /** - * Handle to a shorten request + * Entry in our list of messages to be (re-)transmitted. */ -struct GNUNET_GNS_ShortenHandle +struct PendingMessage { - - /** - * Processor to call on data receipt - */ - GNUNET_GNS_ShortenResultProcessor proc; - /** - * Closure for the processor - */ - void *proc_cls; - - /** - * Main handle to this GNS api + * This is a doubly-linked list. */ - struct GNUNET_GNS_Handle *gns_handle; + struct PendingMessage *prev; /** - * Key that this get request is for + * This is a doubly-linked list. */ - GNUNET_HashCode key; + struct PendingMessage *next; /** - * Unique identifier for this request (for key collisions). + * Size of the message. */ - uint64_t unique_id; - - struct PendingMessage *message; + size_t size; }; @@ -194,40 +118,53 @@ struct GNUNET_GNS_Handle * Currently pending transmission request (or NULL). */ struct GNUNET_CLIENT_TransmitHandle *th; - + + uint32_t r_id; + /** - * Head of linked list of messages we would like to transmit. + * Head of linked list of shorten messages we would like to transmit. */ struct PendingMessage *pending_head; /** - * Tail of linked list of messages we would like to transmit. + * Tail of linked list of shorten messages we would like to transmit. */ struct PendingMessage *pending_tail; - + /** - * Hash maps containing the current outstanding unique requests. + * Head of linked list of shorten messages we would like to transmit. */ - struct GNUNET_CONTAINER_MultiHashMap *active_lookup_requests; - struct GNUNET_CONTAINER_MultiHashMap *active_shorten_requests; - - GNUNET_SCHEDULER_TaskIdentifier reconnect_task; + struct GNUNET_GNS_QueueEntry *shorten_head; /** - * How quickly should we retry? Used for exponential back-off on - * connect-errors. + * Tail of linked list of shorten messages we would like to transmit. + */ + struct GNUNET_GNS_QueueEntry *shorten_tail; + + /** + * Head of linked list of lookup messages we would like to transmit. */ - struct GNUNET_TIME_Relative retry_time; + struct GNUNET_GNS_QueueEntry *lookup_head; /** - * Generator for unique ids. + * Tail of linked list of lookup messages we would like to transmit. */ - uint64_t uid_gen; + struct GNUNET_GNS_QueueEntry *lookup_tail; + + /** + * Reconnect task + */ + GNUNET_SCHEDULER_TaskIdentifier reconnect_task; /** * Did we start our receive loop yet? */ int in_receive; + + /** + * Reconnect necessary + */ + int reconnect; }; /** @@ -237,140 +174,52 @@ struct GNUNET_GNS_Handle static void process_pending_messages (struct GNUNET_GNS_Handle *handle); -/** - * Try to (re)connect to the GNS service. - * - * @return GNUNET_YES on success, GNUNET_NO on failure. - */ -static int -try_connect (struct GNUNET_GNS_Handle *handle) -{ - if (handle->client != NULL) - return GNUNET_OK; - handle->in_receive = GNUNET_NO; - handle->client = GNUNET_CLIENT_connect ("gns", handle->cfg); - if (handle->client == NULL) - { - LOG (GNUNET_ERROR_TYPE_WARNING, - _("Failed to connect to the GNS service!\n")); - return GNUNET_NO; - } - return GNUNET_YES; -} - -/** - * Add the request corresponding to the given handle - * to the pending queue (if it is not already in there). - * - * @param cls the 'struct GNUNET_GNS_Handle*' - * @param key key for the request (not used) - * @param value the 'struct GNUNET_GNS_LookupHandle*' - * @return GNUNET_YES (always) - */ -static int -add_lookup_request_to_pending (void *cls, const GNUNET_HashCode * key, - void *value) -{ - struct GNUNET_GNS_Handle *handle = cls; - struct GNUNET_GNS_LookupHandle *lh = value; - - if (GNUNET_NO == lh->message->in_pending_queue) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Retransmitting request related to %s to GNS %p\n", GNUNET_h2s(key), - handle); - GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, - lh->message); - lh->message->in_pending_queue = GNUNET_YES; - } - return GNUNET_YES; -} - /** - * Add the request corresponding to the given handle - * to the pending queue (if it is not already in there). + * Reconnect to GNS service. * - * @param cls the 'struct GNUNET_GNS_Handle*' - * @param key key for the request (not used) - * @param value the 'struct GNUNET_GNS_ShortenHandle*' - * @return GNUNET_YES (always) + * @param h the handle to the namestore service */ -static int -add_shorten_request_to_pending (void *cls, const GNUNET_HashCode * key, - void *value) +static void +reconnect (struct GNUNET_GNS_Handle *h) { - struct GNUNET_GNS_Handle *handle = cls; - struct GNUNET_GNS_ShortenHandle *sh = value; - - if (GNUNET_NO == sh->message->in_pending_queue) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Retransmitting shorten request related to %s to GNS %p\n", - GNUNET_h2s(key), - handle); - GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, - sh->message); - sh->message->in_pending_queue = GNUNET_YES; - } - return GNUNET_YES; + 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); } - /** - * Try reconnecting to the GNS service. + * Reconnect to GNS * - * @param cls GNUNET_GNS_Handle - * @param tc scheduler context + * @param cls the handle + * @param tc task context */ static void -try_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_GNS_Handle *handle = cls; + struct GNUNET_GNS_Handle *h = cls; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting with GNS %p\n", handle); - handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; - if (handle->retry_time.rel_value < GNUNET_CONSTANTS_SERVICE_RETRY.rel_value) - handle->retry_time = GNUNET_CONSTANTS_SERVICE_RETRY; - else - handle->retry_time = GNUNET_TIME_relative_multiply (handle->retry_time, 2); - if (handle->retry_time.rel_value > GNUNET_CONSTANTS_SERVICE_TIMEOUT.rel_value) - handle->retry_time = GNUNET_CONSTANTS_SERVICE_TIMEOUT; - handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; - if (GNUNET_YES != try_connect (handle)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GNS reconnect failed(!)\n"); - return; - } - GNUNET_CONTAINER_multihashmap_iterate (handle->active_lookup_requests, - &add_lookup_request_to_pending, handle); - GNUNET_CONTAINER_multihashmap_iterate (handle->active_shorten_requests, - &add_shorten_request_to_pending, handle); - process_pending_messages (handle); + h->reconnect_task = GNUNET_SCHEDULER_NO_TASK; + reconnect (h); } /** - * Try reconnecting to the GNS service. + * Disconnect from service and then reconnect. * - * @param handle handle to gns to (possibly) disconnect and reconnect + * @param h our handle */ static void -do_disconnect (struct GNUNET_GNS_Handle *handle) +force_reconnect (struct GNUNET_GNS_Handle *h) { - if (handle->client == NULL) - return; - GNUNET_assert (handle->reconnect_task == GNUNET_SCHEDULER_NO_TASK); - if (NULL != handle->th) - GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th); - handle->th = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Disconnecting from GNS service, will try to reconnect in %llu ms\n", - (unsigned long long) handle->retry_time.rel_value); - GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO); - handle->client = NULL; - handle->reconnect_task = - GNUNET_SCHEDULER_add_delayed (handle->retry_time, &try_reconnect, handle); + h->reconnect = GNUNET_NO; + GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); + h->client = NULL; + h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, + &reconnect_task, + h); } /** @@ -386,7 +235,7 @@ transmit_pending (void *cls, size_t size, void *buf); * @param msg the incoming message */ static void -message_handler (void *cls, const struct GNUNET_MessageHeader *msg); +process_message (void *cls, const struct GNUNET_MessageHeader *msg); /** * Try to send messages from list of messages to send @@ -394,33 +243,35 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg); static void process_pending_messages (struct GNUNET_GNS_Handle *handle) { - struct PendingMessage *head; + struct PendingMessage *p; if (handle->client == NULL) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "process_pending_messages called, but client is null, reconnecting\n"); - do_disconnect (handle); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "process_pending_messages called, but client is null\n"); return; } if (handle->th != NULL) return; - if (NULL == (head = handle->pending_head)) + 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, - ntohs (head->msg->size), + p->size, GNUNET_TIME_UNIT_FOREVER_REL, - GNUNET_YES, &transmit_pending, + GNUNET_NO, &transmit_pending, handle); if (NULL != handle->th) return; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "notify_transmit_ready returned NULL, reconnecting\n"); - do_disconnect (handle); + + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "notify_transmit_ready returned NULL!\n"); } @@ -431,53 +282,45 @@ static size_t transmit_pending (void *cls, size_t size, void *buf) { struct GNUNET_GNS_Handle *handle = cls; - struct PendingMessage *head; + struct PendingMessage *p; size_t tsize; + char *cbuf; handle->th = NULL; - if (buf == NULL) + if ((size == 0) || (buf == NULL)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Transmission to GNS service failed! Reconnecting!\n"); - do_disconnect (handle); + "Transmission to GNS service failed!\n"); + force_reconnect(handle); return 0; } - if (NULL == (head = handle->pending_head)) + tsize = 0; + cbuf = buf; + + if (NULL == (p = handle->pending_head)) return 0; - tsize = ntohs (head->msg->size); - - if (size < tsize) + while ((NULL != (p = handle->pending_head)) && (p->size <= size)) { - process_pending_messages (handle); - return 0; + 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); } - - memcpy (buf, head->msg, tsize); - - GNUNET_CONTAINER_DLL_remove (handle->pending_head, handle->pending_tail, - head); - - head->in_pending_queue = GNUNET_NO; - - if (GNUNET_YES == head->free_on_send) - GNUNET_free (head); - process_pending_messages (handle); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Forwarded request of %u bytes to GNS service\n", (unsigned int) tsize); - - if (GNUNET_NO == handle->in_receive) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Starting to process replies from GNS\n"); - handle->in_receive = GNUNET_YES; - GNUNET_CLIENT_receive (handle->client, &message_handler, handle, - GNUNET_TIME_UNIT_FOREVER_REL); - } + "Sending %d bytes\n", tsize); + + process_pending_messages(handle); return tsize; } @@ -488,49 +331,32 @@ transmit_pending (void *cls, size_t size, void *buf) * @param cls the 'struct GNUNET_GNS_ClientResultMessage' * @param key query of the request * @param value the 'struct GNUNET_GNS_LookupHandle' of a request matching the same key - * @return GNUNET_YES to continue to iterate over all results, - * GNUNET_NO if the reply is malformed */ -static int -process_shorten_reply (void *cls, const GNUNET_HashCode * key, void *value) +static void +process_shorten_reply (struct GNUNET_GNS_QueueEntry *qe, + const struct GNUNET_GNS_ClientShortenResultMessage *msg) { - const struct GNUNET_GNS_ClientShortenResultMessage *gns_msg = cls; - struct GNUNET_GNS_ShortenHandle *shorten_handle = value; - const char *name = (const char*)&((struct GNUNET_GNS_ClientShortenMessage *) &((shorten_handle->message)[1]))[1]; //FIXME + struct GNUNET_GNS_Handle *h = qe->gns_handle; const char *short_name; - if (ntohs (((struct GNUNET_MessageHeader*)gns_msg)->size) < + 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)) { GNUNET_break (0); - do_disconnect (shorten_handle->gns_handle); - return GNUNET_NO; - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received reply for `%s' from GNS service\n", - name); - - if (gns_msg->unique_id != shorten_handle->unique_id) - { - /* UID mismatch */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Ignoring reply for %s: UID mismatch: %llu/%llu\n", GNUNET_h2s (key), - gns_msg->unique_id, shorten_handle->unique_id); - return GNUNET_YES; + force_reconnect (h); + return; } - short_name = (char*)&gns_msg[1]; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Giving shorten reply %s for %s to application\n", - short_name, name); + "Received shortened reply `%s' from GNS service\n", + short_name); - shorten_handle->proc (shorten_handle->proc_cls, name, short_name); - - GNUNET_CLIENT_receive (shorten_handle->gns_handle->client, - &message_handler, shorten_handle->gns_handle, - GNUNET_TIME_UNIT_FOREVER_REL); - return GNUNET_YES; + qe->proc(qe->proc_cls, short_name); + } @@ -543,48 +369,10 @@ process_shorten_reply (void *cls, const GNUNET_HashCode * key, void *value) * @return GNUNET_YES to continue to iterate over all results, * GNUNET_NO if the reply is malformed */ -static int -process_lookup_reply (void *cls, const GNUNET_HashCode * key, void *value) +static void +process_lookup_reply (struct GNUNET_GNS_QueueEntry *qe, + const struct GNUNET_GNS_ClientLookupResultMessage *msg) { - const struct GNUNET_GNS_ClientLookupResultMessage *gns_msg = cls; - struct GNUNET_GNS_LookupHandle *lookup_handle = value; - const char *name = (const char*) &lookup_handle[1]; - struct GNUNET_NAMESTORE_RecordData *rd; - uint32_t rd_count; - - if (ntohs (((struct GNUNET_MessageHeader*)gns_msg)->size) < - sizeof (struct GNUNET_GNS_ClientLookupResultMessage)) - { - GNUNET_break (0); - do_disconnect (lookup_handle->gns_handle); - return GNUNET_NO; - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received lookup reply for `%s' from GNS service %p\n", - name, lookup_handle->gns_handle); - - if (gns_msg->unique_id != lookup_handle->unique_id) - { - /* UID mismatch */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Ignoring reply for %s: UID mismatch: %llu/%llu\n", GNUNET_h2s (key), - gns_msg->unique_id, lookup_handle->unique_id); - return GNUNET_YES; - } - - rd_count = ntohl(gns_msg->rd_count); - rd = (struct GNUNET_NAMESTORE_RecordData*)&gns_msg[1]; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Giving lookup reply for %s to application\n", - name); - - lookup_handle->iter (lookup_handle->iter_cls, name, rd_count, rd); - - GNUNET_CLIENT_receive (lookup_handle->gns_handle->client, &message_handler, - lookup_handle->gns_handle, - GNUNET_TIME_UNIT_FOREVER_REL); - return GNUNET_YES; } /** @@ -594,11 +382,15 @@ process_lookup_reply (void *cls, const GNUNET_HashCode * key, void *value) * @param msg the incoming message */ static void -message_handler (void *cls, const struct GNUNET_MessageHeader *msg) +process_message (void *cls, const struct GNUNET_MessageHeader *msg) { struct GNUNET_GNS_Handle *handle = cls; + struct GNUNET_GNS_QueueEntry *qe; const struct GNUNET_GNS_ClientLookupResultMessage *lookup_msg; const struct GNUNET_GNS_ClientShortenResultMessage *shorten_msg; + uint16_t size; + uint16_t type; + uint32_t r_id; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got message\n"); @@ -606,36 +398,68 @@ message_handler (void *cls, const struct GNUNET_MessageHeader *msg) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Error receiving data from GNS service, reconnecting\n"); - do_disconnect (handle); + force_reconnect (handle); return; } - if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT) + size = ntohs (msg->size); + 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; - GNUNET_CONTAINER_multihashmap_get_multiple (handle->active_lookup_requests, - &lookup_msg->key, - &process_lookup_reply, - (void *) lookup_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); + } + + for (qe = handle->lookup_head; qe != NULL; qe = qe->next) + { + if (qe->r_id == r_id) + break; + } + if (qe) + process_lookup_reply(qe, lookup_msg); + + } - else if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT) + else if (type == GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got shorten msg\n"); - shorten_msg = (const struct GNUNET_GNS_ClientShortenResultMessage *) msg; - GNUNET_CONTAINER_multihashmap_get_multiple (handle->active_shorten_requests, - &shorten_msg->key, - &process_shorten_reply, - (void *) shorten_msg); - } - else - { - GNUNET_break (0); - do_disconnect (handle); - return; + 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); + } + + for (qe = handle->shorten_head; qe != NULL; qe = qe->next) + { + if (qe->r_id == r_id) + break; + } + if (qe) + process_shorten_reply(qe, shorten_msg); } + + GNUNET_CLIENT_receive (handle->client, &process_message, handle, + GNUNET_TIME_UNIT_FOREVER_REL); + + if (GNUNET_YES == handle->reconnect) + force_reconnect (handle); } @@ -654,17 +478,10 @@ GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) handle = GNUNET_malloc (sizeof (struct GNUNET_GNS_Handle)); handle->cfg = cfg; - handle->uid_gen = - GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); - handle->active_lookup_requests = - GNUNET_CONTAINER_multihashmap_create (5); - handle->active_shorten_requests = - GNUNET_CONTAINER_multihashmap_create (5); - if (GNUNET_NO == try_connect (handle)) - { - GNUNET_GNS_disconnect (handle); - return NULL; - } + reconnect (handle); + //handle->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect_task, handle); + handle->r_id = 0; + handle->in_receive = GNUNET_NO; return handle; } @@ -680,6 +497,19 @@ GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *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; +} /** * Perform an asynchronous Lookup operation on the GNS. @@ -690,67 +520,14 @@ GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle) * @param iter_cls closure for iter * @return handle to stop the async get */ -struct GNUNET_GNS_LookupHandle * -GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle, +struct GNUNET_GNS_QueueEntry * +GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, const char * name, enum GNUNET_GNS_RecordType type, GNUNET_GNS_LookupIterator iter, void *iter_cls) { - /* IPC to look for local entries, start dht lookup, return lookup_handle */ - struct GNUNET_GNS_ClientLookupMessage *lookup_msg; - struct GNUNET_GNS_LookupHandle *lookup_handle; - GNUNET_HashCode key; - size_t msize; - struct PendingMessage *pending; - - if (NULL == name) - { - return NULL; - } - - GNUNET_CRYPTO_hash (name, strlen(name), &key); - - msize = sizeof (struct GNUNET_GNS_ClientLookupMessage) + strlen(name); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting lookup for %s in GNS %p\n", - name, handle); - pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize); - lookup_msg = (struct GNUNET_GNS_ClientLookupMessage *) &pending[1]; - pending->msg = &lookup_msg->header; - pending->handle = handle; - pending->free_on_send = GNUNET_NO; - lookup_msg->header.size = htons (msize); - lookup_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_LOOKUP); - lookup_msg->key = key; - memcpy(&lookup_msg[1], name, strlen(name)); - handle->uid_gen++; - lookup_msg->unique_id = handle->uid_gen; - GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, - pending); - pending->in_pending_queue = GNUNET_YES; - lookup_handle = GNUNET_malloc (sizeof (struct GNUNET_GNS_LookupHandle)); - lookup_handle->iter = iter; - lookup_handle->iter_cls = iter_cls; - lookup_handle->message = pending; - lookup_handle->unique_id = lookup_msg->unique_id; - GNUNET_CONTAINER_multihashmap_put (handle->active_lookup_requests, - &lookup_msg->key, - lookup_handle, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); - process_pending_messages (handle); - return lookup_handle; -} - - -/** - * Stop async GNS lookup. - * - * @param lookup_handle handle to the GNS lookup operation to stop - */ -void -GNUNET_GNS_lookup_stop (struct GNUNET_GNS_LookupHandle *lookup_handle) -{ - /* TODO Stop gns lookups */ + return NULL; } @@ -763,7 +540,7 @@ GNUNET_GNS_lookup_stop (struct GNUNET_GNS_LookupHandle *lookup_handle) * @param proc_cls closure for processor * @return handle to the operation */ -struct GNUNET_GNS_ShortenHandle * +struct GNUNET_GNS_QueueEntry * GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle, const char * name, GNUNET_GNS_ShortenResultProcessor proc, @@ -771,7 +548,7 @@ GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle, { /* IPC to shorten gns names, return shorten_handle */ struct GNUNET_GNS_ClientShortenMessage *shorten_msg; - struct GNUNET_GNS_ShortenHandle *shorten_handle; + struct GNUNET_GNS_QueueEntry *qe; size_t msize; struct PendingMessage *pending; @@ -780,33 +557,34 @@ GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle, return NULL; } - msize = sizeof (struct GNUNET_GNS_ClientShortenMessage) + strlen(name) +1; + msize = sizeof (struct GNUNET_GNS_ClientShortenMessage) + strlen(name) + 1; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to shorten %s in GNS\n", name); + + qe = GNUNET_malloc(sizeof (struct GNUNET_GNS_QueueEntry)); + qe->gns_handle = handle; + qe->proc = proc; + qe->proc_cls = proc_cls; + qe->r_id = get_request_id(handle); + GNUNET_CONTAINER_DLL_insert_tail(handle->shorten_head, + handle->shorten_tail, qe); + pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize); memset(pending, 0, (sizeof (struct PendingMessage) + msize)); + + pending->size = msize; + shorten_msg = (struct GNUNET_GNS_ClientShortenMessage *) &pending[1]; - pending->msg = &shorten_msg->header; - pending->handle = handle; - pending->free_on_send = GNUNET_NO; - shorten_msg->header.size = htons (msize); shorten_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_SHORTEN); + shorten_msg->header.size = htons (msize); + shorten_msg->id = htonl(qe->r_id); + memcpy(&shorten_msg[1], name, strlen(name)); - handle->uid_gen++; - shorten_msg->unique_id = handle->uid_gen; + GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, pending); - pending->in_pending_queue = GNUNET_YES; - shorten_handle = GNUNET_malloc (sizeof (struct GNUNET_GNS_ShortenHandle)); - shorten_handle->proc = proc; - shorten_handle->proc_cls = proc_cls; - shorten_handle->message = pending; - shorten_handle->unique_id = shorten_msg->unique_id; - GNUNET_CONTAINER_multihashmap_put (handle->active_shorten_requests, - &shorten_msg->key, - shorten_handle, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + process_pending_messages (handle); - return shorten_handle; + return qe; } |