From 9b187e018ab2565f4ce119eda94f916ec053cc7e Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Mon, 5 Mar 2012 21:49:42 +0000 Subject: [PATCH] -started some gns service api --- src/gns/gns.h | 62 ++++- src/gns/gns_api.c | 371 ++++++++++++++++++++-------- src/gns/test_gns_simple_lookup.conf | 2 +- src/include/gnunet_gns_service.h | 45 +++- 4 files changed, 367 insertions(+), 113 deletions(-) diff --git a/src/gns/gns.h b/src/gns/gns.h index cb47c817a..df964939a 100644 --- a/src/gns/gns.h +++ b/src/gns/gns.h @@ -18,6 +18,8 @@ Boston, MA 02111-1307, USA. */ +#include "gnunet_gns_service.h" + /** * @file gns/gns.h * @brief IPC messages between GNS API and GNS service @@ -46,14 +48,13 @@ struct GNUNET_GNS_ClientLookupMessage /** * Unique identifier for this request (for key collisions). */ - // FIXME: unaligned - uint64_t unique_id; + uint64_t unique_id GNUNET_PACKED; /** * the type of record to look up */ // FIXME: bad type - should be of GNUNET_GNS_RecordType - int type; + enum GNUNET_GNS_RecordType type; /* Followed by the name to look up */ }; @@ -62,7 +63,7 @@ struct GNUNET_GNS_ClientLookupMessage /** * Message from GNS service to client: new results. */ -struct GNUNET_GNS_ClientResultMessage +struct GNUNET_GNS_ClientLookupResultMessage { /** * Header of type GNUNET_MESSAGE_TYPE_GNS_CLIENT_RESULT @@ -84,14 +85,63 @@ struct GNUNET_GNS_ClientResultMessage /** * The number of records contained in response */ - uint32_t num_records; + uint32_t rd_count; // FIXME: what format has a GNS_Record? - /* followed by num_records GNUNET_GNS_Records*/ + /* followed by rd_count GNUNET_NAMESTORE_RecordData structs*/ }; +/** + * Message from client to GNS service to lookup records. + */ +struct GNUNET_GNS_ClientShortenMessage +{ + /** + * Header of type GNUNET_MESSAGE_TYPE_GNS_CLIENT_SHORTEN + */ + struct GNUNET_MessageHeader header; + + /** + * A key. TODO some uid + */ + GNUNET_HashCode key; + + /** + * Unique identifier for this request (for key collisions). + */ + // FIXME: unaligned + uint64_t unique_id GNUNET_PACKED; + + /* Followed by the name to shorten up */ +}; + +/** + * Message from GNS service to client: shorten result. + */ +struct GNUNET_GNS_ClientShortenResultMessage +{ + /** + * Header of type GNUNET_MESSAGE_TYPE_GNS_CLIENT_SHORTEN_RESULT + */ + struct GNUNET_MessageHeader header; + + /** + * Unique identifier for this request (for key collisions). + */ + // FIXME: unaligned + uint64_t unique_id GNUNET_PACKED; + + /** + * A key. TODO some uid + * // FIXME: why hash? + */ + GNUNET_HashCode key; + + /* followed by the shortened name or '\0' for no result*/ + +}; GNUNET_NETWORK_STRUCT_END #endif diff --git a/src/gns/gns_api.c b/src/gns/gns_api.c index ec9c15979..521ddce87 100644 --- a/src/gns/gns_api.c +++ b/src/gns/gns_api.c @@ -19,7 +19,6 @@ */ /** - * TODO: Do we really need a client API? * * @file gns/gns_api.c * @brief library to access the GNS service @@ -42,7 +41,9 @@ /* TODO into gnunet_protocols */ #define GNUNET_MESSAGE_TYPE_GNS_CLIENT_LOOKUP 23 -#define GNUNET_MESSAGE_TYPE_GNS_CLIENT_RESULT 24 +#define GNUNET_MESSAGE_TYPE_GNS_CLIENT_LOOKUP_RESULT 24 +#define GNUNET_MESSAGE_TYPE_GNS_CLIENT_SHORTEN 25 +#define GNUNET_MESSAGE_TYPE_GNS_CLIENT_SHORTEN_RESULT 26 /** * Entry in our list of messages to be (re-)transmitted. @@ -81,11 +82,6 @@ struct PendingMessage */ void *cont_cls; - /** - * Timeout task for this message - */ - GNUNET_SCHEDULER_TaskIdentifier timeout_task; - /** * Unique ID for this request */ @@ -141,6 +137,43 @@ struct GNUNET_GNS_LookupHandle }; + +/** + * Handle to a shorten request + */ +struct GNUNET_GNS_ShortenHandle +{ + + /** + * Processor to call on data receipt + */ + GNUNET_GNS_ShortenResultProcessor proc; + + /** + * Closure for the processor + */ + void *proc_cls; + + /** + * Main handle to this GNS api + */ + 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; + +}; + + /** * Connection to the GNS service. */ @@ -173,9 +206,10 @@ struct GNUNET_GNS_Handle struct PendingMessage *pending_tail; /** - * Hash map containing the current outstanding unique requests. + * Hash maps containing the current outstanding unique requests. */ - struct GNUNET_CONTAINER_MultiHashMap *active_requests; + struct GNUNET_CONTAINER_MultiHashMap *active_lookup_requests; + struct GNUNET_CONTAINER_MultiHashMap *active_shorten_requests; GNUNET_SCHEDULER_TaskIdentifier reconnect_task; @@ -234,25 +268,55 @@ try_connect (struct GNUNET_GNS_Handle *handle) * @return GNUNET_YES (always) */ static int -add_request_to_pending (void *cls, const GNUNET_HashCode * key, void *value) +add_lookup_request_to_pending (void *cls, const GNUNET_HashCode * key, + void *value) { struct GNUNET_GNS_Handle *handle = cls; - struct GNUNET_GNS_LookupHandle *rh = value; + struct GNUNET_GNS_LookupHandle *lh = value; - if (GNUNET_NO == rh->message->in_pending_queue) + if (GNUNET_NO == lh->message->in_pending_queue) { -#if DEBUG_DHT - LOG (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Retransmitting request related to %s to GNS %p\n", GNUNET_h2s(key), handle); -#endif GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, - rh->message); - rh->message->in_pending_queue = GNUNET_YES; + 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). + * + * @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) + */ +static int +add_shorten_request_to_pending (void *cls, const GNUNET_HashCode * key, + void *value) +{ + 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; +} + + /** * Try reconnecting to the GNS service. * @@ -264,9 +328,7 @@ try_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_GNS_Handle *handle = cls; -#if DEBUG_GNS - LOG (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting with GNS %p\n", handle); -#endif + 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; @@ -277,13 +339,13 @@ try_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; if (GNUNET_YES != try_connect (handle)) { -#if DEBUG_GNS - LOG (GNUNET_ERROR_TYPE_DEBUG, "GNS reconnect failed(!)\n"); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GNS reconnect failed(!)\n"); return; } - GNUNET_CONTAINER_multihashmap_iterate (handle->active_requests, - &add_request_to_pending, handle); + 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); } @@ -337,14 +399,17 @@ process_pending_messages (struct GNUNET_GNS_Handle *handle) if (handle->client == NULL) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "process_pending_messages called, but client is null, reconnecting\n"); + "process_pending_messages called, but client is null, reconnecting\n"); do_disconnect (handle); return; } + if (handle->th != NULL) return; + if (NULL == (head = handle->pending_head)) return; + handle->th = GNUNET_CLIENT_notify_transmit_ready (handle->client, ntohs (head->msg->size), @@ -370,6 +435,7 @@ transmit_pending (void *cls, size_t size, void *buf) size_t tsize; handle->th = NULL; + if (buf == NULL) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -377,36 +443,37 @@ transmit_pending (void *cls, size_t size, void *buf) do_disconnect (handle); return 0; } + if (NULL == (head = handle->pending_head)) return 0; tsize = ntohs (head->msg->size); + if (size < tsize) { process_pending_messages (handle); return 0; } + memcpy (buf, head->msg, tsize); + GNUNET_CONTAINER_DLL_remove (handle->pending_head, handle->pending_tail, head); + head->in_pending_queue = GNUNET_NO; - if (head->timeout_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (head->timeout_task); - head->timeout_task = GNUNET_SCHEDULER_NO_TASK; - } + if (GNUNET_YES == head->free_on_send) GNUNET_free (head); + process_pending_messages (handle); -#if DEBUG_GNS - LOG (GNUNET_ERROR_TYPE_DEBUG, + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Forwarded request of %u bytes to GNS service\n", (unsigned int) tsize); -#endif + if (GNUNET_NO == handle->in_receive) { -#if DEBUG_GNS - LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting to process replies from GNS\n"); -#endif + 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); @@ -425,48 +492,101 @@ transmit_pending (void *cls, size_t size, void *buf) * GNUNET_NO if the reply is malformed */ static int -process_reply (void *cls, const GNUNET_HashCode * key, void *value) +process_shorten_reply (void *cls, const GNUNET_HashCode * key, void *value) { - const struct GNUNET_GNS_ClientResultMessage *gns_msg = cls; - struct GNUNET_GNS_LookupHandle *lookup_handle = value; - const char *name = (const char*) &lookup_handle[1]; - const struct GNUNET_NAMESTORE_RecordData *records; - uint32_t num_records; - size_t meta_length; - size_t msize; + const struct GNUNET_GNS_ClientShortenResultMessage *gns_msg = cls; + struct GNUNET_GNS_ShortenHandle *shorten_handle = value; + const char *name = (const char*) &shorten_handle[1]; + const char *short_name; - if (gns_msg->unique_id != lookup_handle->unique_id) + if (ntohs (((struct GNUNET_MessageHeader*)gns_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 %p\n", + name, shorten_handle->gns_handle); + + if (gns_msg->unique_id != shorten_handle->unique_id) { /* UID mismatch */ -#if DEBUG_GNS - LOG (GNUNET_ERROR_TYPE_DEBUG, + 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); -#endif + gns_msg->unique_id, shorten_handle->unique_id); return GNUNET_YES; } - msize = ntohs (gns_msg->header.size); - num_records = ntohl (gns_msg->num_records); - meta_length = - sizeof (struct GNUNET_GNS_ClientResultMessage) + - sizeof (struct GNUNET_NAMESTORE_RecordData) * (num_records); - if ((msize < meta_length) || - (num_records > - GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_NAMESTORE_RecordData))) + short_name = (char*)&gns_msg[1]; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Giving shorten reply %s for %s to application\n", + short_name, 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; +} + + +/** + * Process a given reply to the lookup request + * + * @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_lookup_reply (void *cls, const GNUNET_HashCode * key, void *value) +{ + 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; } -#if DEBUG_GNS - LOG (GNUNET_ERROR_TYPE_DEBUG, "Giving %u byte reply for %s to application\n", - (unsigned int) (msize - meta_length), GNUNET_h2s (key)); -#endif - records = (const struct GNUNET_NAMESTORE_RecordData *) &gns_msg[1]; - lookup_handle->iter (lookup_handle->iter_cls, name, records, num_records); + + 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; } - /** * Handler for messages received from the GNS service * @@ -477,40 +597,40 @@ static void message_handler (void *cls, const struct GNUNET_MessageHeader *msg) { struct GNUNET_GNS_Handle *handle = cls; - const struct GNUNET_GNS_ClientResultMessage *gns_msg; + const struct GNUNET_GNS_ClientLookupResultMessage *lookup_msg; + const struct GNUNET_GNS_ClientShortenResultMessage *shorten_msg; if (msg == NULL) { -#if DEBUG_GNS - LOG (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Error receiving data from GNS service, reconnecting\n"); -#endif do_disconnect (handle); return; } - if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_GNS_CLIENT_RESULT) + + if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_GNS_CLIENT_LOOKUP_RESULT) { - GNUNET_break (0); - do_disconnect (handle); - return; + 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); } - if (ntohs (msg->size) < sizeof (struct GNUNET_GNS_ClientResultMessage)) + else if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_GNS_CLIENT_SHORTEN_RESULT) + { + 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; } - gns_msg = (const struct GNUNET_GNS_ClientResultMessage *) msg; -#if DEBUG_GNS - LOG (GNUNET_ERROR_TYPE_DEBUG, "Received reply for `%s' from GNS service %p\n", - &gns_msg->name, handle); -#endif - /* TODO uniquely identify requests... maybe hash(name) or uid */ - GNUNET_CONTAINER_multihashmap_get_multiple (handle->active_requests, - &gns_msg->key, &process_reply, - (void *) gns_msg); - GNUNET_CLIENT_receive (handle->client, &message_handler, handle, - GNUNET_TIME_UNIT_FOREVER_REL); + } @@ -531,7 +651,10 @@ GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, handle->cfg = cfg; handle->uid_gen = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); - handle->active_requests = GNUNET_CONTAINER_multihashmap_create (ht_len); + handle->active_lookup_requests = + GNUNET_CONTAINER_multihashmap_create (ht_len); + handle->active_shorten_requests = + GNUNET_CONTAINER_multihashmap_create (ht_len); if (GNUNET_NO == try_connect (handle)) { GNUNET_GNS_disconnect (handle); @@ -555,12 +678,8 @@ GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle) /** * Perform an asynchronous Lookup operation on the GNS. - * TODO: - * - Still not sure what we query for... "names" it is for now - * - Do we need such sophisticated message queueing like dht? simplify? * * @param handle handle to the GNS service - * @param timeout how long to wait for transmission of this request to the service * @param name the name to look up * @param iter function to call on each result * @param iter_cls closure for iter @@ -568,7 +687,6 @@ GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle) */ struct GNUNET_GNS_LookupHandle * GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle, - struct GNUNET_TIME_Relative timeout, const char * name, enum GNUNET_GNS_RecordType type, GNUNET_GNS_LookupIterator iter, @@ -589,10 +707,8 @@ GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle, GNUNET_CRYPTO_hash (name, strlen(name), &key); msize = sizeof (struct GNUNET_GNS_ClientLookupMessage) + strlen(name); -#if DEBUG_GNS - LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting lookup for %s in GNS %p\n", - name, handle); -#endif + 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; @@ -612,9 +728,10 @@ GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle, lookup_handle->iter_cls = iter_cls; lookup_handle->message = pending; lookup_handle->unique_id = lookup_msg->unique_id; - GNUNET_CONTAINER_multihashmap_put (handle->active_requests, &lookup_msg->key, - lookup_handle, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + GNUNET_CONTAINER_multihashmap_put (handle->active_lookup_requests, + &lookup_msg->key, + lookup_handle, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); process_pending_messages (handle); return lookup_handle; } @@ -628,8 +745,64 @@ GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle, void GNUNET_GNS_lookup_stop (struct GNUNET_GNS_LookupHandle *lookup_handle) { - /* TODO Stop dht lookups */ + /* TODO Stop gns lookups */ +} + + +/** + * Perform a name shortening operation on the GNS. + * + * @param handle handle to the GNS service + * @param name the name to look up + * @param proc function to call on result + * @param proc_cls closure for processor + * @return handle to the operation + */ +struct GNUNET_GNS_ShortenHandle * +GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle, + const char * name, + GNUNET_GNS_ShortenResultProcessor proc, + void *proc_cls) +{ + /* IPC to shorten gns names, return shorten_handle */ + struct GNUNET_GNS_ClientShortenMessage *shorten_msg; + struct GNUNET_GNS_ShortenHandle *shorten_handle; + size_t msize; + struct PendingMessage *pending; + + if (NULL == name) + { + return NULL; + } + + msize = sizeof (struct GNUNET_GNS_ClientShortenMessage) + strlen(name); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to shorten %s in GNS\n", name); + pending = GNUNET_malloc (sizeof (struct PendingMessage) + 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_CLIENT_SHORTEN); + 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_LookupHandle)); + 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; } + /* end of gns_api.c */ diff --git a/src/gns/test_gns_simple_lookup.conf b/src/gns/test_gns_simple_lookup.conf index d623974ba..cda207a1e 100644 --- a/src/gns/test_gns_simple_lookup.conf +++ b/src/gns/test_gns_simple_lookup.conf @@ -72,7 +72,7 @@ DNS_EXIT = 8.8.8.8 [gns] AUTOSTART = YES -BINARY = ./gnunet-service-gns +BINARY = gnunet-service-gns ZONEKEY = zonekey HIJACK_DNS = YES UNIXPATH = /tmp/gnunet-service-gns.sock diff --git a/src/include/gnunet_gns_service.h b/src/include/gnunet_gns_service.h index ee63c05cb..ba634df1d 100644 --- a/src/include/gnunet_gns_service.h +++ b/src/include/gnunet_gns_service.h @@ -56,6 +56,10 @@ struct GNUNET_GNS_Handle; */ struct GNUNET_GNS_LookupHandle; +/** + * Handle to control a shorten operation + */ + /** * Record types * Based on GNUNET_DNSPARSER_TYPEs (standard DNS) @@ -107,13 +111,13 @@ GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle); * * @param cls closure * @param name "name" of the original lookup - * @param record the records in reply - * @param num_records the number of records in reply + * @param rd_count number of records + * @param rd the records in reply */ typedef void (*GNUNET_GNS_LookupIterator) (void *cls, const char * name, - const struct GNUNET_NAMESTORE_RecordData *record, - unsigned int num_records); + uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd); @@ -121,8 +125,6 @@ typedef void (*GNUNET_GNS_LookupIterator) (void *cls, * Perform an asynchronous lookup operation on the GNS. * * @param handle handle to the GNS service - * @param timeout how long to wait for transmission of this request to the service - * // FIXME: what happens afterwards? * @param name the name to look up * @param type the GNUNET_GNS_RecordType to look for * @param iter function to call on each result @@ -132,7 +134,6 @@ typedef void (*GNUNET_GNS_LookupIterator) (void *cls, */ struct GNUNET_GNS_LookupHandle * GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle, - struct GNUNET_TIME_Relative timeout, const char * name, enum GNUNET_GNS_RecordType type, GNUNET_GNS_LookupIterator iter, @@ -150,7 +151,37 @@ GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle, void GNUNET_GNS_lookup_stop (struct GNUNET_GNS_LookupHandle *lookup_handle); +/* *************** Standard API: shorten ******************* */ + +/** + * Processor called on for a name shortening result + * called only once + * + * @param cls closure + * @param name "name" of the original lookup + * @param short_name the shortened name or NULL if no result + */ +typedef void (*GNUNET_GNS_ShortenResultProcessor) (void *cls, + const char * name, + const char* short_name); + + +/** + * Perform a shorten operation on name using the GNS. + * + * @param handle handle to the GNS service + * @param name the name to shorten + * @param proc processor to call on result + * @param iter_cls closure for processor + * + * @return handle to the shorten operation + */ +struct GNUNET_GNS_ShortenHandle * +GNUNET_GNS_shorten (struct GNUNET_GNS_Handle *handle, + const char * name, + GNUNET_GNS_ShortenResultProcessor proc, + void *iter_cls); #if 0 /* keep Emacsens' auto-indent happy */ { #endif -- 2.25.1