-started some gns service api
authorMartin Schanzenbach <mschanzenbach@posteo.de>
Mon, 5 Mar 2012 21:49:42 +0000 (21:49 +0000)
committerMartin Schanzenbach <mschanzenbach@posteo.de>
Mon, 5 Mar 2012 21:49:42 +0000 (21:49 +0000)
src/gns/gns.h
src/gns/gns_api.c
src/gns/test_gns_simple_lookup.conf
src/include/gnunet_gns_service.h

index cb47c817a8d99e92269ec83dee7d5afa56204897..df964939a93324f9b465360b9027108818e23df2 100644 (file)
@@ -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
index ec9c15979190966e7fa53c8900efdb1db21a9ec7..521ddce87312608de3482079321c66aa575c3deb 100644 (file)
@@ -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 */
index d623974ba89727e899b07fdb499cd4a464044dd3..cda207a1e35aeca45dfe75d80c1a52133f4f127c 100644 (file)
@@ -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
index ee63c05cb7c3ef5e30cc976999f506a7f0e246d2..ba634df1d25f9cfa929d72330e9d81a2ab402bca 100644 (file)
@@ -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